Commit Graph

66965 Commits

Author SHA1 Message Date
Peter Steinberger
2d319961d5 fix(browser): block interaction-triggered navigation SSRF (#104254)
* fix(browser): guard interaction navigation requests

* fix(browser): preserve pages on blocked navigation

* fix(browser): enforce interaction navigation policy

* test(browser): type navigation guard fixtures

* fix(browser): execute guarded wait predicates

* style(browser): satisfy interaction lint

* fix(browser): guard hover drag and scroll navigation

* fix(browser): type policy check outcomes

* test(browser): type navigation guard mocks

* fix(browser): preserve proxy policy for guarded interactions

* fix(browser): carry navigation policy through actions

* fix(browser): retain policy for existing-session guards

* fix(browser): guard existing-session waits

* test(browser): avoid shadowed guard pages

* fix(browser): expose scroll action to agents

* fix(browser): disable speculative managed preconnects

* docs(browser): bound managed preconnect hardening

* fix(browser): keep wait behavior outside interaction guards

* chore(browser): leave release notes to release automation

* fix(browser): guard all interaction navigations
2026-07-11 04:30:33 -07:00
Peter Steinberger
3902adf9f6 refactor(channels): adopt core retryAsync for hand-rolled retry loops (#104431) 2026-07-11 04:30:21 -07:00
Peter Steinberger
5a26748c3e fix(commitments): isolate extraction batches by agent (#104426)
* fix(commitments): isolate extraction batches by agent

* chore: leave release notes to release workflow
2026-07-11 04:23:30 -07:00
llagy007
cba9ffb177 fix(memory): skip blank search provider bootstrap (#103728)
* fix(memory): skip blank search provider bootstrap

* refactor(memory): simplify blank search preflight

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-11 04:19:40 -07:00
Peter Steinberger
c49e5c480d fix(agents): keep exec finalization suspension-safe (#104419) 2026-07-11 04:16:21 -07:00
Vincent Koc
cce2d39d0c fix(ci): preserve performance target compatibility 2026-07-11 19:13:52 +08:00
Vincent Koc
163227a0af perf(ci): use source performance build profile 2026-07-11 19:13:52 +08:00
Vincent Koc
6013e78f5a perf(build): add source performance profile 2026-07-11 19:13:52 +08:00
Peter Steinberger
234e8f4fae test(discord): exercise multipart proxy fetch path (#104421) 2026-07-11 04:13:00 -07:00
Peter Steinberger
93fcfa40ee fix(release): wait for Telegram proc marker (#104418) 2026-07-11 04:12:44 -07:00
llagy007
f8aa995856 fix(google-meet): validate chrome node policy params (#103752) 2026-07-11 04:00:28 -07:00
Peter Steinberger
8756cc4a3b fix(googlechat): keep off-mode replies out of threads (#104402)
* fix(googlechat): align reply and typing targets

Co-authored-by: Jai Govindani <jai.g@ewa-services.com>

Co-authored-by: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com>

Co-authored-by: banddude <127166397+banddude@users.noreply.github.com>

Co-authored-by: Novan Adrian <novan.adrian@qasir.id>

* chore(googlechat): leave changelog to release automation

* style(googlechat): apply canonical formatting

* chore(googlechat): leave changelog to release automation

* style(googlechat): keep monitor imports canonical

* style(googlechat): keep monitor imports canonical

---------

Co-authored-by: Novan Adrian <novan.adrian@qasir.id>
2026-07-11 03:57:16 -07:00
qingminlong
b322a8e311 fix(gateway): stop watch result after invalid body (#104293) 2026-07-11 03:57:07 -07:00
Peter Steinberger
fe608a8dcb fix(ui): give sidebar build chip breathing room from the status dot (#104411) 2026-07-11 03:56:15 -07:00
Peter Steinberger
b4a9a4c3d4 fix(mac): silence lock result warning (#104408) 2026-07-11 03:53:28 -07:00
Peter Steinberger
cfd2dc2346 fix(telegram): mark durable webhook acceptance (#104407) 2026-07-11 03:51:39 -07:00
Peter Steinberger
7ec0d4abb8 chore: update Peekaboo to 3.9.0 (#104398)
* build(macos): update Peekaboo to 3.9.0

* chore: keep release notes in PR body

* fix(macos): trust current Peekaboo release signers
2026-07-11 03:44:13 -07:00
Peter Steinberger
591bb49d67 fix(release): tolerate exited Telegram proc probe (#104400) 2026-07-11 03:40:56 -07:00
Peter Steinberger
de282b4d0d refactor(matrix): adopt core claimable dedupe with doctor-owned state migration (#104391)
* refactor(matrix): adopt core claimable dedupe for inbound events

* fix(matrix): migrate legacy inbound dedupe markers via doctor

* fix(matrix): single-pool dedupe namespace and capacity-aware legacy import

* fix(matrix): keep unreadable legacy dedupe JSON in place during doctor import
2026-07-11 03:38:54 -07:00
Peter Steinberger
4fc147105b fix(ui): delay scrolling truncated session titles (#104392)
* fix(ui): delay session title hover scroll

* chore: keep release notes out of PR
2026-07-11 03:36:49 -07:00
Peter Steinberger
e683a974ba fix(gateway): track cron settlement recovery during suspend (#104397)
* fix(gateway): track cron settlement recovery during suspend

* test(gateway): cover rotated cron recovery admission
2026-07-11 03:35:13 -07:00
Peter Steinberger
0af8467137 feat(workspaces): add agent-composable Workspaces (#104139)
* feat(dashboard): modular dashboard — workspace store, Workspaces tab, sandboxed custom widgets

Squashes openclaw/openclaw#101094 + #101097 + #101098 onto current main and
applies the maintainer review fixes to the backend control plane.

Co-authored-by: 100yenadmin <239388517+100yenadmin@users.noreply.github.com>

* fix(dashboard): UI review fixes — grid, error boundary, embed sandbox, locale

* fix(dashboard): make the CLI and agent broadcasts actually reachable

Three defects only a live run surfaces, all invisible to the unit suites:

- The plugin claimed the CLI command name `dashboard`, which core already owns
  (it opens the Control UI). A plugin CLI group that overlaps a core command is
  dropped at registration behind a `logger.debug`, so the entire CLI face was
  unreachable while `cli.test.ts` kept passing against its own Commander
  program. Renamed to `openclaw workspaces`, matching the tab it drives.

- The manifest never declared `activation.onCommands`, so the CLI root resolved
  to no owning plugin even once the name was free.

- `dashboard.widget.approve` needs `operator.approvals`; the CLI asked for
  `operator.write` on every call. It now requests the approvals scope only for
  the approve call, matching `operator-approvals-client.ts`.

Also: agent tools resolved their broadcast from the plugin runtime's
gateway-request scope, an AsyncLocalStorage set only around gateway RPCs and
plugin HTTP routes. An agent turn started from a channel, cron, or heartbeat
therefore wrote the document without emitting `plugin.dashboard.changed`, so an
open Control UI never saw the edit — the feature's headline promise. The gateway
broadcast is server-lifetime, so the plugin now remembers it in a single slot and
agent tools fall back to it.

* docs(web): document dashboard workspaces, provenance, and the custom-widget sandbox

* fix(dashboard): agent-tool ergonomics + close two approval-boundary gaps

From a source-blind agent driving the dashboard_* tools with nothing but their
schemas, and from a Codex review of the hardening delta.

- dashboard_widget_update could never succeed. It passed its whole parameter
  record to the patch reader, whose allowlist rejects the very `tab`/`id` keys
  the tool's own schema marks required, so every call died on
  "unexpected param: tab". Its test only ran Value.Check against the schema and
  never executed the tool.
- dashboard_data_read surfaced an `rpc` binding as a thrown error, though its
  description promised `binding_client_resolved`. It now returns that as a
  result the model can act on.
- Valid widget kinds and the rpc allowlist were undiscoverable: a model saw only
  "builtin:<name> or custom:<name>" and "Allowlisted gateway read method", then
  brute-forced ~40 calls against errors that named no alternatives. Both schemas
  and both validator errors now enumerate them, and the kind description says
  what each builtin renders and which binding id it reads. widget_move documents
  that grid and toTab are exclusive; widget_scaffold says an operator must
  approve, because no agent tool can.
- workspace.replace could mint a pending registry entry for a name that was
  never scaffolded. An operator could then approve a widget whose code did not
  exist yet, and the agent could write it afterwards. Registry entries now come
  from dashboard_widget_scaffold and nowhere else, and approve refuses a name
  with no manifest on disk.
- dashboard.widget.approve answered with the whole workspace document, so a
  connection holding only operator.approvals could read it through the approvals
  door. It now returns the registry entry it changed.

* fix(dashboard): approval pins the code it approves

Codex review found the scaffold-before-approval gate still nameable rather than
binding: approve only proved that widget.json parsed, and the Control UI loaded a
hardcoded index.html rather than the manifest's entrypoint. An agent could
scaffold a widget, win approval on an innocuous or absent entrypoint, then write
the real payload afterwards — code appearing after the human said yes.

Approval now hashes every servable file in the widget directory and stores the
digests on the registry entry, refusing a manifest whose declared entrypoint is
missing. The asset route re-hashes each file it reads and 404s anything that does
not match, so a file edited or added after approval never reaches a browser. The
Control UI loads the manifest's entrypoint, which is the file that was hashed.

The content-type allowlist moves to manifest.ts so the set of files approval
hashes and the set the route can serve cannot drift apart.

Proof, against a running gateway: scaffold -> 404, approve -> 200, rewrite
index.html -> 404, add late.js -> 404.

* fix(dashboard): parse the approved manifest from the bytes that were hashed

Codex found a TOCTOU in the approval path: it loaded and validated widget.json,
then walked the directory again to compute the digests. An agent could swap
widget.json between the two reads, so the operator validated one entrypoint while
the digest froze — and the Control UI later mounted — a different one.

snapshotApprovedWidget now reads the widget directory once: it hashes every
servable file, parses the manifest out of the same widget.json bytes it hashed,
and requires the declared entrypoint to be among them.

Proof, against a running gateway: approve -> index.html 200; rewrite widget.json
to point at evil.html and drop evil.html in -> both 404.

* fix(dashboard): cap approval asset reads; bound the grid fallback search

Two findings from the fourth Codex pass.

Approval hashes agent-authored files that are untrusted until it runs, and read
each one into memory with no size check — dropping one huge .png into a scaffold
directory would stall or OOM the gateway during approve. Sizes are now checked
before the read, with a 2 MB per-file and 8 MB total cap.

nearestFreeSlot searched one band below the lowest occupied row, so a crowded
layout near the bottom could return y=500 as the closest free slot: a placement
the store rejects, which the UI applies optimistically and then snaps back. The
search now stops at the last row a widget of that height can legally occupy.

* fix(dashboard): refuse oversized widget assets before reading them

Approved widget files stay writable and the asset route is unauthenticated, so
swapping an approved small file for a very large one made every GET buffer the
whole file before the digest check rejected it. The route now refuses anything
past the same per-file cap approval enforces, on the stat it already performs.

* fix(dashboard): enforce widget approval boundaries

* docs(changelog): note modular dashboard workspaces

* fix(dashboard): enforce static custom-widget data boundary

* fix(dashboard): satisfy UI lint

* test(dashboard): avoid legacy proto access

* feat(dashboard): make plugin opt-in

* docs(dashboard): refresh workspaces map

* refactor(workspaces): standardize plugin naming

* fix(workspaces): make widget prompt sends idempotent

* docs(workspaces): fix internal path references

* test(workspaces): make prompt assertion lint-safe

* test(workspaces): type prompt request mock

* fix(workspaces): harden approval and binding boundaries

* test(workspaces): complete stale binding client mock

* fix(workspaces): harden widget file boundaries

* fix(workspaces): scope custom widget capabilities

* fix(workspaces): align approval provenance

* fix(workspaces): close branch contract gaps

* test(workspaces): complete builtin context fixtures

* fix(workspaces): aggregate overview usage

* chore(workspaces): defer release note

* chore(workspaces): refresh i18n metadata

---------

Co-authored-by: 100yenadmin <239388517+100yenadmin@users.noreply.github.com>
2026-07-11 03:30:23 -07:00
Peter Steinberger
a8e2da7d5e refactor(feishu): adopt core claimable dedupe for inbound events (#104384) 2026-07-11 03:27:14 -07:00
Vincent Koc
8917dac5de style(ci): format performance workflow test 2026-07-11 18:23:30 +08:00
Vincent Koc
37649e947f perf(ci): fetch only source performance baseline 2026-07-11 18:23:30 +08:00
Vincent Koc
5196d06348 Merge remote-tracking branch 'origin/main'
* origin/main:
  fix(macos): host the dashboard sidebar toggle beside back/forward in the titlebar (#104380)
2026-07-11 18:21:01 +08:00
Peter Steinberger
df16372af3 fix(macos): host the dashboard sidebar toggle beside back/forward in the titlebar (#104380)
* fix(macos): host the dashboard sidebar toggle beside back/forward in the titlebar

The Control UI's floating sidebar-expand button rendered as a bordered web
control crowding the traffic lights in the dashboard window. The toggle now
lives as a native borderless button in the leading titlebar accessory ahead
of back/forward (Safari ordering) and bridges to the web UI via the
openclaw:native-toggle-sidebar event; the injected chrome script advertises
the capability with an openclaw-native-nav class so the web control retires
itself visually while staying keyboard/screen-reader reachable.

* docs: note the macOS app's native titlebar sidebar toggle in the Control UI guide
2026-07-11 03:19:33 -07:00
Vincent Koc
ba12348620 Merge remote-tracking branch 'origin/main'
* origin/main:
  fix(cron): abort superseded reconciliation hooks (#104368)
  ci(release): expose Telegram runtime preflight stage (#104387)
  fix(status): avoid false shell-wrapper audit warnings (#81778)
  fix: retry live Gateway readiness proof (#104374)
  fix(exec-approval): stop misattributing Allow Always unavailability to policy (#97740)
  fix: preserve Mac bundle during live builds (#104376)
  chore(docs): translate with GPT-5.6 xhigh
  test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface (#104361)
  fix(ui): hide group submenu separator when New group is the only entry (#104370)
  fix(discord): reset progress drafts across queued turns (#102341)
  docs(cli): clarify that exec-policy show and approvals get exclude per-session /exec overrides (#94999)
  fix(discord): single-source thread-binding default placement and guard artifact parity (#104342)
  fix(agents): add tool-activity heartbeat to keep subagent alive during tool calls (#95536)
  fix(maint): reuse recent same-PR hosted gates (#104355)
2026-07-11 18:18:15 +08:00
Peter Steinberger
7875dd97a1 fix(cron): abort superseded reconciliation hooks (#104368)
* fix(cron): abort superseded reconciliation hooks

* fix(ci): align plugin SDK surface budget
2026-07-11 03:16:59 -07:00
Peter Steinberger
8d96790b44 ci(release): expose Telegram runtime preflight stage (#104387) 2026-07-11 03:12:41 -07:00
Andi Liao
410e6db74c fix(status): avoid false shell-wrapper audit warnings (#81778) 2026-07-11 18:12:32 +08:00
Peter Steinberger
5e8a534fad fix: retry live Gateway readiness proof (#104374)
* fix: retry live Gateway readiness proof

* style: format live updater readiness helper
2026-07-11 03:11:34 -07:00
saju01
cbc84767bd fix(exec-approval): stop misattributing Allow Always unavailability to policy (#97740)
* fix(exec-approval): stop misattributing Allow Always unavailability to policy

Allow Always is dropped both when policy ask=always AND when a command is
non-persistable (e.g. shell redirect `2>&1` -> one-shot), but the prompt always
claimed 'effective approval policy requires approval every time'. That's
misleading for the non-persistable case (#97069). Reword to reason-neutral
'Allow Always is unavailable for this command.' across all approval surfaces,
update en + 20 locale bundles, refresh i18n meta, and the matching tests.

Closes #97069

* fix(exec-approval): stop misattributing Allow Always unavailability to policy

* test(ui): await exec approval render updates

* chore(ui): sync approval i18n metadata

---------

Co-authored-by: saju01 <saju01@users.noreply.github.com>
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-07-11 18:09:51 +08:00
Peter Steinberger
c702719eda fix: preserve Mac bundle during live builds (#104376) 2026-07-11 03:06:50 -07:00
Peter Steinberger
cfda86babe chore(docs): translate with GPT-5.6 xhigh 2026-07-11 06:06:18 -04:00
Peter Steinberger
6268eeef15 test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface (#104361)
* test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface

- fix 7 Control UI tests broken on main: module-mock factories are unreliable
  under isolate:false shared workers; use RealtimeTalkSession prototype spies
  and real jsdom storage instead (chat-realtime, chat-pull-requests)
- add gated checks-ui CI job (runUiTests changed-scope output): chromium
  provisioning, lint:ui:no-raw-window-open, pnpm --dir ui test; ~30s on a
  4vcpu runner, runs only when ui-affecting paths change
- add weekly node22-compat workflow exercising the supported lower Node bound
  with the same command set as the dispatch-only ci.yml job
- delete the unreachable channels entry in EXTENSION_TEST_CONFIG_ROUTES and
  the never-populated extensionRoutedChannelTestFiles override machinery
  (born empty in 2ccb5cff22); resolved globs are provably identical
- guard run-vitest.mjs hardcoded path maps with existence tests so renames
  cannot silently drop extended stall watchdogs
- remove unenforced coverage thresholds; test:coverage is informational, docs
  updated (reference/test, help/testing, plugins/sdk-testing)

Closes #104321

* test: pin OPENCLAW_CI_RUN_UI_TESTS in the manifest env expectation

* test(ui): capture the realtime start spy instead of referencing the unbound prototype method

* test(ui): raise ui vitest timeouts for real-browser layout tests on small CI runners
2026-07-11 03:04:11 -07:00
Peter Steinberger
aeab8e7faf fix(ui): hide group submenu separator when New group is the only entry (#104370) 2026-07-11 03:02:02 -07:00
Peter Lee
ef95c5d74e fix(discord): reset progress drafts across queued turns (#102341)
* fix(discord): guard progress draft collapse to prevent re-collapse on cleaned stream

Commit 86ea382 added a progressDraftStartedBeforeFinal latch that snapshots
hasStarted at markFinalReplyStarted time. This correctly preserves collapse
eligibility when an abort cancels the compositor gate before
shouldCollapseProgressDraft runs.

However the latch was never cleared. After markPreviewFinalized turned the
draft into a summary, hasProgressDraftStarted remained true permanently. In
multi-tool turns with multiple final-payload deliveries, this caused
shouldCollapseProgressDraft to re-trigger collapse on an already-cleaned or
sealed draft stream, corrupting downstream delivery state and causing tool
results to render as image content blocks instead of text.

Fix: add a progressDraftCollapsed guard set by markPreviewFinalized that
prevents hasProgressDraftStarted from returning true after the draft has been
collapsed into a summary. Reset the guard on handleAssistantMessageBoundary
so followup/queued turns start fresh.

Per Discord channel session, all tool results rendered as image content
blocks. Model received (see attached image) placeholders instead of text.

Fixes #100782

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(discord): use valid table/chunk mode literals in collapse-guard tests

* test(discord): add abort-race gate-cancellation latch survival test

* fix(discord): consume progress draft collapse once

Co-authored-by: xialonglee <li.xialong@xydigit.com>

* fix(discord): retain progress receipt on retry

Co-authored-by: xialonglee <li.xialong@xydigit.com>

* fix(discord): rearm queued progress drafts

Co-authored-by: xialonglee <li.xialong@xydigit.com>

* test(discord): assert progress lifecycle outcomes

Co-authored-by: xialonglee <li.xialong@xydigit.com>

* fix(discord): reset queued progress turn state

Co-authored-by: xialonglee <li.xialong@xydigit.com>

* test(discord): model recreated progress drafts

Co-authored-by: xialonglee <li.xialong@xydigit.com>

* fix(discord): serialize progress draft rotation

Co-authored-by: xialonglee <li.xialong@xydigit.com>

* fix(discord): isolate queued draft generations

Co-authored-by: Peter Lee <xialonglee@users.noreply.github.com>

* test(discord): align synchronous draft rotation

Co-authored-by: Peter Lee <xialonglee@users.noreply.github.com>

* fix(discord): distinguish draft rotation ownership

Co-authored-by: Peter Lee <xialonglee@users.noreply.github.com>

* chore: keep release notes in pull request

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 02:59:29 -07:00
NIO
98fb858769 docs(cli): clarify that exec-policy show and approvals get exclude per-session /exec overrides (#94999)
* docs(cli): clarify exec-policy show and approvals get exclude per-session /exec overrides

* refactor(cli): centralize session exec override note

* test(cli): cover node exec override note

* test(cli): use complete node policy fixture

---------

Co-authored-by: NIO <nocodet@mail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 02:58:37 -07:00
Peter Steinberger
d8bf51b462 fix(discord): single-source thread-binding default placement and guard artifact parity (#104342)
* fix(discord): single-source thread-binding default placement and guard artifact parity

* fix(tests): load thread-binding parity artifacts via sanctioned contract test helpers
2026-07-11 02:50:53 -07:00
xydt-tanshanshan
eb2f763674 fix(agents): add tool-activity heartbeat to keep subagent alive during tool calls (#95536)
* [AI] fix(agents): add run-scoped tool-activity heartbeat to prevent premature subagent idle timeout

Subagent LLM idle watchdog tripped during long-running tool calls because
tool completions did not reset the idle timer.

Implement a per-run tool-activity heartbeat:
1. notifyToolActivity(runId) — published from embedded-runner tool
   execution wrappers (attempt.ts) whenever a tool completes
2. onToolActivity(runId, listener) — consumed by streamWithIdleTimeout
   to reset the idle watchdog on tool completion
3. getLastToolActivityMs(runId) — shared timestamp Map so pre-stream
   activity is visible to armTimer before the first stream iteration
4. clearToolActivityRun(runId) — wired into the run lifecycle finally
   block to clean up listener sets and timestamps when the run exits

Scoped per-run via runId-keyed Maps to prevent concurrent runs from
resetting each other's idle watchdogs.

Related to #94124

* [AI] fix(agents): copy plugin/channel/before-tool-call metadata onto heartbeat tool wrappers

* [AI] test(agents): add metadata preservation regression tests for heartbeat tool wrapper

* [AI] fix(agents): preserve terminal presentation metadata on heartbeat tool wrapper

* [AI] chore: update test comment for four metadata copy calls

* fix: add periodic heartbeat during tool execution

Fire notifyToolActivity at tool start and every 60s via setInterval
so long-running tools survive the 120s LLM idle watchdog.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: remove useless catch clause (no-useless-catch)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: preserve Code Mode control-tool identity through heartbeat wrapper

Adds copyCodeModeControlToolIdentity() to replicate the WeakSet
membership that markCodeModeControlTool() sets. Without this,
the heartbeat wrapper drops Code Mode identity for exec/wait
tools, weakening before_tool_call policy and approval handling.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: wrap deferred directory tools with heartbeat

resolveDeferredTool hydrates hidden catalog tools outside the
effectiveTools.map() wrapper, so they bypassed the periodic
notifyToolActivity heartbeat. Wrap the hydrated execute function
with the same start/interval/complete notification pattern.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-11 17:50:33 +08:00
Peter Steinberger
a94498cf6f fix(maint): reuse recent same-PR hosted gates (#104355)
* fix(maint): reuse recent same-PR hosted gates

* style(maint): format hosted gate verifier
2026-07-11 02:49:53 -07:00
Vincent Koc
a8ce892909 fix(release): keep plugin pack output machine-readable 2026-07-11 17:47:06 +08:00
Peter Steinberger
14a056ac83 fix: stop Gateway without source rebuild (#104357) 2026-07-11 02:45:07 -07:00
Peter Steinberger
b361390356 ci(release): preserve Telegram launcher stage (#104356) 2026-07-11 02:44:25 -07:00
Peter Steinberger
0e1e077f4f feat(control-ui): show build identity chip in sidebar footer (#104350) 2026-07-11 02:42:01 -07:00
Vincent Koc
8e2ddd60ad fix(ci): sync Control UI raw-copy baseline (#104352) 2026-07-11 17:39:00 +08:00
Vincent Koc
38c49b1f9d test(ci): cover split performance artifacts 2026-07-11 17:38:41 +08:00
Vincent Koc
730b9fa9bc perf(ci): parallelize Kova source probes 2026-07-11 17:38:41 +08:00
Peter Steinberger
2e2366b6d3 chore(tooling): typecheck scripts/** with a dedicated tsgo lane (#104348)
* feat(tooling): add tsgo typecheck lane for scripts/**

* fix(scripts): burn down scripts type debt surfaced by the new lane

Typing-only except bugs the lane surfaced: gh-read timeout race,
Discord Headers spread dropping entries, undefined allowedHeadBranches
match, plugin-boundary matchAll crash. Deletes retired config keys from
fixtures/benches (prompt snapshots regenerated, config dump only) and
the orphaned non-runnable sync-moonshot-docs script. Adds full-surface
.d.mts declarations for existing .mjs boundaries.
2026-07-11 02:31:17 -07:00