Commit Graph

38262 Commits

Author SHA1 Message Date
Peter Steinberger
b58a75d726 refactor(html): share entity decoding 2026-07-14 00:00:05 -07:00
Peter Steinberger
25a0f270ea test: isolate queued CLI progress ordering (#107212) 2026-07-13 23:57:49 -07:00
krissding
e588f2c0ce fix(extra-params): preserve resolved cacheRetention against undefined own-property clobber (#106069)
* fix(extra-params): preserve resolved cacheRetention when options carries undefined own-property

When the proxy transport emits cacheRetention as an own property set to
undefined, JS spread semantics clobber the resolved cacheRetention value
from per-model params. Re-assert the resolved value after the spread so
it takes precedence over an undefined own-property in the caller's options.

Fixes #106014

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

* test(agents): strengthen cache retention precedence proof

* refactor(agents): keep cache retention merge compact

* style(agents): format cache retention matrix

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 23:54:56 -07:00
Peter Steinberger
044392684b test(release): repair scheduled E2E regressions (#107173)
* test(release): repair scheduled E2E regressions

* test(release): refresh generated protocol bindings

* docs(agents): harden remote proof invocations
2026-07-13 23:49:36 -07:00
Peter Steinberger
3c82249ab9 test: accelerate session concurrency coverage (#107186) 2026-07-13 23:32:53 -07:00
Peter Steinberger
d3ac854e31 refactor(agents): extract attempt execution phases 2026-07-13 22:54:42 -07:00
Peter Steinberger
304beb22e1 refactor(concurrency): use p-map skip results 2026-07-13 22:43:26 -07:00
Jason (Json)
5f8b2a4670 fix: complete Codex login handoff during onboarding (#107174) 2026-07-13 23:40:55 -06:00
Peter Steinberger
df5097b6e7 fix(native): keep platform validation warning-free (#107101)
* build(android): keep Gradle warning-free

* ci(native): pin XcodeGen tooling

* test(macos): avoid concurrency warnings
2026-07-13 22:33:12 -07:00
Peter Steinberger
b241d4a12d refactor(agents): extract attempt session runtime setup 2026-07-13 22:32:01 -07:00
Peter Steinberger
1d02cc83dd refactor(skills): use chokidar all events 2026-07-13 22:31:00 -07:00
Peter Steinberger
ee858fc9f2 refactor(types): remove stale node-llama declarations 2026-07-13 22:26:47 -07:00
Peter Steinberger
d8d2f83cc1 feat(terminal): open Codex/Claude catalog sessions in a terminal on their owning host
Catalog session rows (sidebar context menu + click), the built-in viewer
header, and a new "Open Codex/Claude sessions in" preference can launch the
native CLI (codex resume / claude --resume) in the operator terminal on the
machine that owns the session.

- Gateway-local sessions spawn through the existing terminal launch policy
  (sandbox/enabled gates preserved) with the resume command in the session cwd.
- Paired-node sessions run through a new seq-ordered node PTY relay: a
  duplex node-host command streams PTY output via node.invoke.progress and
  receives keystrokes/resize via a new node.invoke.input event, behind the
  unchanged terminal.* client protocol (TerminalSessionManager gains a backend
  abstraction; node relay reuses the streaming-invoke controller).
- Owner boundary: each plugin owns its resume command and builds argv from a
  validated thread id; the gateway routes node opens through the node command
  allowlist and plugin invoke policy (no advertisement-only trust), and nodes
  re-verify session eligibility before spawning.
- UI setting catalogOpenTarget + canOpenTerminal capability gate every entry
  point; capability requires the owning host to actually have the CLI.

Node PATH is normalized before command-availability probes, Windows .cmd/.bat
shims spawn via ComSpec, and catalog terminal opens reattach persisted tabs
before opening the new tab.
2026-07-13 22:20:50 -07:00
Bek
beb0aace72 fix: prevent completed Codex hook relays from lingering (#106899) 2026-07-14 01:19:59 -04:00
Peter Steinberger
eb91c593d3 test(plugin-sdk): harden temp directory cleanup (#107151) 2026-07-13 22:12:49 -07:00
Peter Steinberger
73838101df refactor(agents): extract attempt stream runtime setup 2026-07-13 22:01:22 -07:00
Peter Steinberger
bf5fb5b760 fix(tui): preserve input across gateway restarts (#107115)
* fix(tui): recover input after gateway reconnects

* refactor(tui): extract submit state helpers
2026-07-13 21:51:38 -07:00
Peter Steinberger
61986571bb fix(plugins): forward-port bundled SDK fallback hardening (#107131)
* fix(plugins): avoid bundled SDK fallback races

* fix(ci): satisfy plugin SDK LOC ratchet

* fix(ci): align fallback forward-port guards

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-13 21:50:46 -07:00
zengLingbiao
692cb8dd9b fix(cron): reject non-string values in delivery target validation (#106952)
* fix(cron): reject non-string values in delivery target validation

assertNonBlankStringField had inverted logic — non-string values
(number, boolean, object) were silently accepted because typeof !== 'string'
was grouped with the undefined/null early return. The function name says
'assert non-blank string field' but it was bypassing validation for any
non-string type, defeating the purpose of input validation.

* test(cron): cover invalid delivery fields at entrypoints

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 21:48:15 -07:00
Peter Steinberger
352cf819bc improve: speed up agent command tests (#107107)
* test: avoid plugin discovery in agent command suites

* style: format agent command test imports

* test: preserve agent command mock ordering

* test: classify agent mock state as test support
2026-07-13 21:46:50 -07:00
moguangyu5-design
8419675fa1 fix(session): swallow onRecordError throw to avoid unhandled rejection (#106951)
* fix(session): swallow onRecordError throw to avoid unhandled rejection

* fix(session): settle async record error handlers

* fix(session): assimilate record handler results

---------

Co-authored-by: moguangyu5-design <moguangyu5-design@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 21:45:57 -07:00
Peter Steinberger
05fb55eb7b feat: discover OpenCode and Pi sessions on paired nodes (#106941)
* feat(sessions): add opencode and pi catalogs

* fix(sessions): satisfy catalog lint

* fix(sessions): validate pi storage paths

* fix(sessions): index growing pi transcripts

* refactor(sessions): split pi path resolution

* docs(sessions): refresh catalog map

* refactor(sessions): privatize pi catalog internals

* fix(sessions): validate node catalog payloads

* fix(sessions): harden external catalog discovery

* fix(sessions): normalize catalog transcript data

* refactor(gateway): keep node scope gate compact

* fix(opencode): reject option-like session ids

* fix(sessions): align external id validation
2026-07-13 21:45:53 -07:00
Peter Steinberger
889b4f7dcf fix(control-ui): rotate branded progress labels (#107111)
* fix(control-ui): rotate branded progress labels

* chore: keep progress note in PR body
2026-07-13 21:42:35 -07:00
xingzhou
6b0a835116 fix(diagnostics): prevent broken emoji in long model identifiers (#106986)
* fix(diagnostics): preserve Unicode boundaries in timeline attributes

* fix(diagnostics): keep timeline truncation within LOC guard

* test(diagnostics): strengthen Unicode timeline regression

* test(diagnostics): type Unicode boundary cases

* test(diagnostics): await wrapped timeline call

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 21:41:15 -07:00
Peter Steinberger
0ecbbe2382 fix(workboard): keep dispatch inside caller workspace authority (#107087)
* fix(workboard): inherit caller workspace authority

* docs(plugin-sdk): refresh API baseline

* fix(workboard): pin restricted worker authority

* fix(workboard): avoid host git for restricted dispatch

* refactor(worktrees): extract owner matching

* refactor(workboard): reuse sdk workspace helpers

* fix(workboard): narrow cleanup owner

* refactor(workboard): clarify claim value handling

* fix(workboard): inherit caller workspace authority

* test(worktrees): use managed temp directories

* chore: keep release notes in PR body

* fix(workboard): keep internal authority helpers private
2026-07-13 21:36:26 -07:00
Peter Steinberger
f82895d416 refactor(agents): extract attempt prompt phase 2026-07-13 21:32:56 -07:00
Vincent Koc
3a55f8d800 refactor(agents): remove dead test surfaces (#107113) 2026-07-14 12:23:41 +08:00
Peter Steinberger
be5558cb4e fix(plugin-sdk): preserve runtime contexts in test mocks (#107059)
* test(plugin-sdk): make runtime context mock stateful

* docs(agents): record Testbox invocation contracts
2026-07-13 21:21:09 -07:00
Peter Steinberger
66e6923929 test: accelerate session status suite (#107054) 2026-07-13 21:21:00 -07:00
Peter Steinberger
f69e1263d3 fix(ui): restore reload history and bundled icons (#106981)
* fix(ui): restore chat history after reload

* refactor(ui): keep chat pane within size limit

* test(ui): satisfy chat pane lint

* fix(ui): allow bundled Web Awesome icons
2026-07-13 21:20:34 -07:00
Peter Steinberger
37c7de0148 refactor(ai): remove redundant tool argument finalization 2026-07-13 21:17:38 -07:00
Peter Steinberger
27f2a45c54 fix(onboarding): harden live inference handoff (#107041)
* fix(onboarding): harden live inference handoff

* fix(crestodian): preserve auto runtime probes

* fix(ci): restore current main lint gates
2026-07-13 21:15:36 -07:00
Jason (Json)
f72e936f26 fix: restore grouped AI auth options in guided onboarding (#107038)
Restore the grouped provider/auth picker for fresh guided onboarding, keep secondary providers under More, expose OAuth and device-code methods, and bound the setup probe session identifier so ChatGPT login is not rejected by the prompt cache key limit.
2026-07-13 22:12:19 -06:00
Peter Steinberger
632b17618e refactor(agents): extract attempt prompt dispatch phase 2026-07-13 21:06:46 -07:00
Vincent Koc
63c7c21bdf refactor(core): privatize new internal helpers (#107096) 2026-07-14 12:02:46 +08:00
Peter Steinberger
ea33260491 refactor(agents): privatize prompt error outcome (#107097) 2026-07-13 21:01:48 -07:00
Peter Steinberger
87b2b4eaab refactor(agents): extract session lock preparation 2026-07-13 21:01:28 -07:00
Peter Steinberger
8d465d71b5 fix(channels): progress drafts only for long tasks, with the model's own preamble as the status headline (#106026)
* fix(channels): time-gate progress drafts and defer narration until visible

Progress drafts started immediately on the second work event, so the 5s
initial delay never filtered small fast tasks and Discord showed narrated
status for turns that finish in seconds. The gate is now purely time-based
(explicit startNow paths like approvals/patches are unchanged), and the
progress narrator no longer spends utility-model completions before the
channel draft is visible - notes buffer so the first visible narration has
full context.

Surface: src/channels/streaming.ts gate, src/auto-reply/reply/progress-narrator.ts,
Discord draft-preview wiring; test updates across discord/matrix/msteams/slack.

Refs #105872

* feat(channels): model-preamble status headline for progress drafts

In progress mode the draft's status line is now the model's own typed pre-tool
preamble whenever it is fresh (always on, no new config); utility-model
narration fills the slot only when the model has been quiet for ~20s or emits
no preamble. Preambles never start the draft early - the time gate still owns
the small-vs-big decision - and narration generation is suppressed while a
fresh preamble exists, saving utility calls. Discord and Telegram render the
headline; the opt-in streaming.progress.commentary lane and its receipt
counters are unchanged.

Refs #105872

* refactor(channels): split status-text and telegram preview helpers to honor the LOC ratchet

The LOC ratchet forbids raising baseline entries, so the headline feature's
growth is paid for with clean splits: reasoning/commentary text normalization
moves to src/channels/progress-draft-status-text.ts, Telegram progress preview
rendering to extensions/telegram/src/progress-draft-preview.ts, and small
ownership moves (formatCompactionModelRef, resolveFollowupAbortSignal, shared
CLI preamble gate, Discord preamble item-event handling) shrink the runners
back under their pins. Baseline entries lowered to exact new counts; the
compositor entry is removed (424 lines, under the 500 ceiling).

Refs #105872

* test(auto-reply): add resolveFollowupAbortSignal to the queue mock factory

The explicit ./queue.js vi.mock factory must export every binding prod touches;
the relocated resolveFollowupAbortSignal was missing and failed the whole
followup-runner suite.

Refs #105872

* fix(channels): sanitize preamble headlines and retry skipped narration

Review findings: preamble headlines now strip inline delivery directives and
reject silent-control tokens (NO_REPLY) before rendering, sharing the
commentary sanitizer; rejected input keeps the previous valid headline. The
narrator schedules cancellation-aware retries when a run is skipped for draft
invisibility or preamble freshness, so single long tool calls still narrate
and the ~20s utility filler fires without needing another event. Silent
preambles no longer stamp freshness or add narration notes.

Refs #105872

* fix(channels): bound narrator visibility polling and gate Telegram headline mode on accepted preambles

Visibility retries stop after 30 one-second attempts (turn completion has no
narrator disposal signal) and re-arm on new activity; Telegram derives its
headline-rendering state from the compositor's sanitized headline instead of
raw payload text, so directive-only or NO_REPLY preambles keep structured
tool-line rendering. Docs scope the preamble headline to Discord and Telegram.

Refs #105872

* fix(telegram): read headline state from the compositor at render time

The progressHeadlineActive mirror flag was set after pushPreambleHeadline had
already rendered, so the first valid preamble arriving after the draft opened
rendered through the structured-line path and the headline never appeared
until the next event. The renderer and formatLine now read the compositor's
sanitized hasStatusHeadline directly and the mirror flag is deleted; adds an
ordering regression test. LOC baseline lowered to the exact new count.

Refs #105872

* fix(channels): let the opt-in commentary lane own preambles and scope narration docs to Discord

With streaming.progress.commentary enabled, the status headline would replace
the documented interleaved 💬 lines for any turn with a preamble (the exact
event the lane consumes). The compositor headline now declines when the
commentary lane is enabled, preserving that lane's shipped shape, and docs
state the utility-model filler is Discord-only today (Telegram's headline is
preamble-only; it has no narrator wiring).

Refs #105872

* fix(msteams): cancel the pending progress gate at finalize

With the purely time-based gate, every fast Teams progress turn leaves a
pending 5s start timer; the SDK resets its stream id on close, so a late
timer fired renderInformativeUpdate against the closed stream and posted a
stale working card below the final answer. finalize() now cancels the gate
and the informative renderer refuses to run once final text is queued.

Refs #105872

* docs(channels): record the headline-vs-commentary ownership decision inline

Refs #105872

* style: oxfmt the late review-fix rounds

Four files from the final review-fix commits were never oxfmt-formatted and
failed the shared CI formatting step; baseline lowered for the one-line
telegram shrink.

Refs #105872

* fix(channels): harden progress draft lifecycle

* fix(channels): refresh repeated preamble items

* fix(plugin-sdk): expose progress lifecycle options

* style(auto-reply): simplify narrator reset

* docs(channels): refresh progress draft docs map

* fix(auto-reply): clear queued narrator request context

* fix(discord): cancel delayed progress gate at final

* docs: refresh plugin sdk api baseline
2026-07-13 20:55:44 -07:00
Vincent Koc
3aab2ce6a9 refactor(packages): remove dead internal helpers (#107077) 2026-07-14 11:48:14 +08:00
Peter Steinberger
0ab9e625c2 refactor(agents): extract stream finalization phase 2026-07-13 20:47:47 -07:00
Peter Steinberger
e79cbbfb2e refactor(resources): use native minimatch list matching 2026-07-13 20:45:18 -07:00
Peter Steinberger
fe715a1b88 refactor(daemon): trim internal exports (#107075) 2026-07-13 20:43:08 -07:00
Peter Steinberger
e55e3ffbdd refactor(agents): extract attempt prompt execution lifecycle 2026-07-13 20:39:12 -07:00
Peter Steinberger
fce1d16493 fix(infra): preserve APNs proxy error cause (#107057) 2026-07-13 20:35:29 -07:00
Peter Steinberger
c5a74b4949 refactor(tailscale): use exec timeout directly 2026-07-13 20:30:35 -07:00
Peter Steinberger
604eb6af2d refactor(concurrency): use native p-limit APIs 2026-07-13 20:23:00 -07:00
Peter Steinberger
69f1da11a3 refactor(agents): privatize attempt lifecycle details (#107055) 2026-07-13 20:21:34 -07:00
Vincent Koc
4bff6b188e refactor(agents): privatize computer tool helpers (#107048) 2026-07-14 11:13:48 +08:00
Peter Steinberger
6efec6d28c refactor(version): use native SemVer ordering 2026-07-13 20:13:19 -07:00
Peter Steinberger
661cf9644d refactor(agents): extract attempt prompt observability 2026-07-13 20:09:00 -07:00