Commit Graph

80 Commits

Author SHA1 Message Date
_Kerman
1aefcbf4d7 fix(apiproxy): derive queued steering on the client, drop it from the wire
The session/queued frame no longer carries steering — AgentMessage no longer
has the field. The client derives it from the same ordered turn boundaries the
host saw (a frame arriving while a turn is open joined the steering FIFO).
2026-07-27 10:22:28 +08:00
_Kerman
2f74ac98ba Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	.agents/notes/archived/feature/2026-07-21-tui-steering-queue-badge.i18n.yaml
#	.agents/notes/archived/simplification/2026-06-20-drop-unconsumed-llm-assembled-surfaces.i18n.yaml
#	.agents/notes/archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.i18n.yaml
#	.agents/notes/archived/simplification/2026-07-04-remove-agent-steering-mirror.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-22-unified-send-and-coalesced-user-messages.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-07-session-prefix.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-02-remove-stream-chunk-mirror.i18n.yaml
#	docs/core-data-structures/session.i18n.yaml
#	docs/event-producer-consumer.md
#	examples/acp-agent/tests/snapshots/code-mode-workspace-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-promptsubmit-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-promptsubmit-context/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-fork/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-mixed/session.2.jsonl
#	packages/core/session/README.i18n.yaml
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/support/acp-snapshot/README.i18n.yaml
#	packages/support/acp-snapshot/README.md
#	packages/support/acp-snapshot/README.zh.md
2026-07-27 09:57:51 +08:00
imccyu
f6396f2573 style: fix lint across client packages
eslint --fix autofixes plus manual repairs: max-len line splits
(fake-api handlers, notifier/slots JSDoc, spec signatures), charAt over
non-null-asserted indexing in slash detect/menu cores, Array.from for
code-point capping, typeof assertions for unbound-method in specs,
generic getByRole for the send-button cast, effect disposer void-wrap in
command register, and dropped unused type imports.
2026-07-27 04:13:00 +08:00
imccyu
a27be43ac1 feat: slash system / input service / agent scope 2026-07-27 03:28:39 +08:00
_Kerman
8117f61396 Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	packages/context/workspace-context/README.md
#	packages/llm/llm-retry/README.md
#	packages/session-persistence/session-checkpoint-policy/README.md
#	scripts/type-equiv.manifest.json
2026-07-26 16:45:27 +08:00
_Kerman
3d1fe7b45f Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	docs/event-producer-consumer.md
2026-07-26 15:46:29 +08:00
_Kerman
57d90c343d Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.md
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.zh.md
#	.agents/notes/implemented/feature/2026-06-30-hook-bridges.i18n.yaml
#	.agents/notes/implemented/feature/2026-06-30-interception-seams.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-sandbox.md
#	.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-same-session-goal-round-driver.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-25-workspace-ui-product-flow.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-02-remove-stream-chunk-mirror.i18n.yaml
#	docs/architecture.i18n.yaml
#	docs/cookbook/adding-a-tool.i18n.yaml
#	docs/cookbook/extension-cookbook.i18n.yaml
#	docs/core-data-structures/llm-streaming.i18n.yaml
#	docs/core-data-structures/session.i18n.yaml
#	docs/core-data-structures/tools.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	examples/acp-agent/tests/snapshots/plan-mode-reject/session.jsonl
#	examples/acp-agent/tests/snapshots/plan-mode/session.jsonl
#	examples/acp-agent/tests/snapshots/session-sandbox-root/session.jsonl
#	packages/context/session-reference/README.md
#	packages/core/agent-loop/tests/agent.spec.ts
#	packages/hooks/hooks-claude/tests/coverage-cases.ts
#	packages/host/runtime/tests/host-runtime.spec.ts
#	packages/llm/llm-retry/tests/retry.spec.ts
#	packages/session-persistence/session-persistence/src/coordinator.ts
#	packages/support/acp-snapshot/README.md
#	packages/support/acp-snapshot/src/normalize.ts
#	packages/ui/acp/acp-feature-support.md
#	packages/ui/acp/src/codec.ts
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/bridge.spec.ts
#	packages/ui/acp/tests/codec.spec.ts
#	packages/ui/acp/tests/config-options.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/edges.spec.ts
#	packages/ui/acp/tests/stream-update.spec.ts
#	packages/ui/acp/tests/turns.spec.ts
2026-07-26 14:05:33 +08:00
Tianyi Cui
030973e4ab Merge branch 'master' into worktree/i18n-complete-non-readme 2026-07-26 13:31:20 +08:00
_Kerman
af3311e1f6 test: close per-file coverage gaps opened by the message-machine refactor
Downstream packages lost the tests that exercised their agent-loop-facing
edges when the loop was rewritten. Restore 100% per-file coverage with
behavior tests through public seams: llm-retry config validation and
cancellation races, goal replay drift/staleness/teardown edges, plan-mode
disposed-flush, workspace-context empty-change commits, api-proxy
synchronous send failures, acp-snapshot spill-path extraction and refresh
write-back, ACP injection-triggered turns, cli-demo and tui inbox
lifecycle edges, and agent-loop retry/settlement/lifecycle branches.
The only source changes are narrowly-justified v8 ignore annotations on
invariant guards and one redundant-guard removal (workspace-context).
2026-07-26 11:49:19 +08:00
Tianyi Cui
226dc7a249 docs: translate remaining READMEs 2026-07-26 05:06:39 +08:00
imccyu
d147673dfd refactor(apiproxy): share the workspace-not-found response
The rename/insertSessionBefore lookups tripped the cross-file clone gate;
one helper owns the error row now.
2026-07-26 01:58:53 +08:00
imccyu
9fc8a616a9 test(web): close the per-file coverage gate for the session-list surfaces
New and touched sources reach the CI per-file 100% thresholds: HoverCard
(timers, placement clamp, disabled guard), Menu label/danger/pointer-leave
branches, WorkspaceBrowser (mode switch, search, rail icons, rename dialog,
drag), rows and tree derivations, the workspace fixture stubs, the rename/
insertSessionBefore wire rows, and the entity move semantics. HoverCard's
position state narrows to {left, top} (equivalent refactor, no behavior
change).
2026-07-26 01:48:36 +08:00
imccyu
ea8b1178cd feat(web): session list one-list, hover card, row menus, rename, manual ordering
Sidebar session list grows the figma 239-10458 feature set and the
workspace/session browsing region moves wholesale into ui-workspace:

- Group-by menu (WorkSpace / In one list): flat mode lists every session
  top-level, strictly newest-first; the choice persists across reloads.
- Session rows get a 500ms hover detail card (title / relative time /
  status line) and a ... menu (Rename / Fork session / Delete session,
  visual-only for now); workspace headers get ... with Rename (wired) and
  Delete workspace (visual-only).
- workspace.rename RPC: trims, rejects duplicate titles on the create
  chain (workspace-name-conflict), no-op on same title; modal dialog with
  client-side duplicate pre-check.
- workspace.insertSessionBefore RPC (DOM-insertBefore semantics, omitted
  anchor appends): HTML5 drag reorder of root sessions inside a workspace
  group; order truth stays host-side, the view refreshes from the
  response/changed frame.
- Activity pinning removed: the session/event touchSession chain is gone;
  workspace accounts are manually owned (new sessions prepend, explicit
  reordering only). Contracts and tests updated, api catalog regenerated.
- ui-sidebar reduced to the column shell (brand, fold state machine, New
  Session, Settings) exposing one sidebar.workspaces hole with a two-fact
  owner share {wide, expandSidebar}; ui-workspace owns the whole region
  (header, search, grouped/flat lists, dialogs, drag) plus the picker via
  a shared WorkspaceCreateFlow. The old sidebar.workspace picker slot and
  its deferral indirection are gone.
- ui-primitives: Menu gains label entries, danger rows, and
  closeOnPointerLeave; new HoverCard (portaled, open-delay, disabled
  guard). Hover card and row menu never coexist.
2026-07-26 00:55:17 +08:00
imccyu
08ce02da2b docs(web): finalize workspace UI product flow 2026-07-25 17:46:04 +08:00
imccyu
9eb9c70a8a feat(web): add workspace-aware session flow 2026-07-25 17:45:26 +08:00
imccyu
f7d85bf9f5 fix(headless): CI green + review-bot findings for the shared composition
Coverage: api-proxy.ts joins the web-transport exclusion block (its
behavior specs moved here with it; the assembled-entry coverage lands with
the GUI test lane). Static: config-catalog regenerated after the log-round
revert shifted a source anchor. Prose brought current per review: the cli
README now describes the one shared composition (and its build
prerequisite), the apiproxy README points at the api-gateway row instead of
the deleted runtime package, and the config-tree agent note's headless
deferral paragraph records what actually landed (bilingual pair
re-recorded).
2026-07-25 14:40:45 +08:00
imccyu
4a27da44cf test(web): real-composition webserver spec
Boots a test-only cordis.yml through the real Loader and asserts the route
service's behavior surface: exact/longest-prefix matching, tapIndex
transform order and unsubscription, traversal 403, non-GET 405, SPA-200
fallback, malformed-request 400 without process exit, duplicate-pattern
throw, dispose closing held connections with register/disposer symmetry,
and a listen-failure fail-loud case (EADDRINUSE -> FAILED fiber + late
rejection). Replaces the retired factory-era specs.
2026-07-25 14:40:45 +08:00
Tianyi Cui
dc9c3fb1ae Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol
# Conflicts:
#	docs/capability-seams.md
#	docs/event-producer-consumer.md
#	tsconfig.base.json
2026-07-25 13:05:30 +08:00
imccyu
2e27b8aeef chore(web): gate repairs for the config-tree boot round
Lint (bridge JSDoc params, service-class export shape, async invariant
listener form), regenerated doc catalogs/graphs with role classifications
for httpServer and clientModuleHost, catalog type-link exemptions for the
route/graph contracts, knip alignment (apps/cli composes via cordis.yml so
its yml-named deps are runtime edges knip cannot see; webserver's deleted
test dir), the zh side of the loading-model note brought along with its
pairing records, and coverage exclusions for the new web-transport halves
under the GUI test-lane TODO (real-composition harnesses land with that
lane).
2026-07-25 10:38:54 +08:00
imccyu
f499872cec refactor(web): rewrite webserver as a plain route-registration plugin
HttpServerService provides ctx.httpServer: register(route) -> disposer
(duplicate patterns throw), tapIndex transforms in registration order, and
the bound port; matching is exact > longest prefix > static dist fallback
(403/405/SPA semantics preserved). The server listens on activation, answers
per-request failures with 400 + a log line instead of exiting the process,
and knows no harness concepts — the boot graph, bundle routes, SSE channel,
and /api prefix all moved to their owning plugins.
2026-07-25 10:23:39 +08:00
imccyu
3cad7f6957 refactor(web): upgrade apiproxy to the api-gateway service plugin
createApiProxy moves from dsh-host-runtime into dsh-host-apiproxy (the
dependency direction already pointed this way); the package now
default-exports ApiProxyService (config {provider, model}, provides
ctx.apiProxy) while staying transport-agnostic — it registers no routes.
Runtime keeps bootHost/startHost for the headless path with its import
re-anchored, and drops the mountWebPlugins roster mounting helper.
2026-07-25 10:22:43 +08:00
Tianyi Cui
2beaa18f42 Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol
# Conflicts:
#	packages/support/acp-snapshot/README.md
2026-07-25 02:07:28 +08:00
Tianyi Cui
1d066e0f74 Fix remaining PTY and bundle watch races
Keep inherited child prompt markers bounded by the normal silence fallback. Stage web-plugin rescans atomically and retain missing watch state until a successful rebuild.
2026-07-25 00:33:33 +08:00
Tianyi Cui
f9a638b8a6 Stabilize master CI across platforms 2026-07-25 00:10:37 +08:00
Tianyi Cui
440384fdb4 Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol
# Conflicts:
#	.agents/notes/implemented/architecture/2026-06-14-session-persistence.md
#	.agents/notes/implemented/architecture/2026-06-20-package-hierarchy.md
#	.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.md
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.md
#	.agents/notes/implemented/feature/2026-06-14-acp-multi-session.md
#	.agents/notes/implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.zh.md
#	.agents/notes/implemented/simplification/2026-07-04-trim-acp-bridge-unreachable-surface.md
#	docs/architecture.i18n.yaml
#	docs/cookbook/extension-cookbook.i18n.yaml
#	docs/cookbook/extension-cookbook.md
#	docs/cookbook/extension-cookbook.zh.md
#	docs/core-data-structures/approval.md
#	docs/core-data-structures/user-interaction.md
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	docs/testing.md
#	docs/tool-catalog.md
#	examples/acp-agent/tests/fixtures/live-mode-switching-2026-07-07.session.jsonl
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	packages/goal/tool-goal/README.md
#	packages/ui/acp/README.md
#	packages/ui/acp/acp-feature-support.md
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/bridge.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/edges.spec.ts
#	packages/ui/acp/tests/turns.spec.ts
2026-07-24 23:43:10 +08:00
_Kerman
992cf894af refactor(agent): unify sourced message delivery 2026-07-24 22:38:50 +08:00
_Kerman
b73eb7663c refactor(agent-loop): simplify observable state machine 2026-07-24 21:18:48 +08:00
_Kerman
fb0ef82aa6 Merge remote-tracking branch 'origin/feat/send-unify' into xtr/agent-loop-message-machine
# Conflicts:
#	packages/client/runtime/src/client/sessions/fold-adapter.ts
2026-07-24 18:24:28 +08:00
Turtle
081bb1a8fd Merge remote-tracking branch 'origin/master' into feat/send-unify
# Conflicts:
#	packages/client/runtime/src/client/sessions/fold-adapter.ts
2026-07-24 17:17:35 +08:00
_Kerman
76d0e450ce fix(agent): preserve thrown error values 2026-07-24 17:11:58 +08:00
_Kerman
6945a2c37d Merge remote-tracking branch 'origin/feat/send-unify' into xtr/agent-loop-message-machine 2026-07-24 16:31:49 +08:00
Turtle
bb124c2869 Merge branch 'master' into feat/send-unify 2026-07-24 16:31:00 +08:00
_Kerman
66645638fb Merge remote-tracking branch 'origin/feat/send-unify' into xtr/agent-loop-message-machine
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-22-unified-send-and-coalesced-user-messages.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-22-unified-send-and-coalesced-user-messages.md
#	.agents/notes/implemented/architecture/2026-07-22-unified-send-and-coalesced-user-messages.zh.md
#	docs/architecture.i18n.yaml
#	docs/architecture.md
#	docs/architecture.zh.md
#	docs/core-data-structures/core.md
#	packages/context/session-reference/README.md
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/src/agent.ts
#	packages/core/agent-loop/src/inbox.ts
#	packages/core/agent-loop/tests/agent.spec.ts
#	packages/core/agent-loop/tests/cancel.spec.ts
#	packages/core/agent-loop/tests/contract-regressions.spec.ts
#	packages/core/agent-loop/tests/coverage-edges.spec.ts
#	packages/core/agent-loop/tests/interception.spec.ts
#	packages/core/agent-loop/tests/loop.spec.ts
#	packages/core/agent/README.md
#	packages/core/agent/src/types.ts
#	packages/core/agent/tests/agent.spec.ts
#	packages/ui/acp/src/index.ts
#	packages/ui/tui/src/index.ts
#	packages/ui/tui/tests/harness.ts
2026-07-24 16:25:53 +08:00
_Kerman
e23960b8ad refactor(agent): require complete send options 2026-07-24 16:23:20 +08:00
07akioni
6f5321cb37 feat: workspace select menu 2026-07-24 16:09:58 +08:00
Turtle
b02b438667 refactor(agent): align delivery method names 2026-07-24 15:08:36 +08:00
_Kerman
7d5c8b12c0 fix(agent-loop): preserve unified send contracts 2026-07-24 13:20:51 +08:00
Tianyi Cui
d7ebe848dc Merge remote-tracking branch 'origin/master' into worktree/acp-automation-protocol 2026-07-24 11:51:17 +08:00
imccyu
d5cd73a9d9 fix(gui): CI activation order + review-bot findings
The session-title snapshot exposed a real activation race: ui-trajectory
and ui-question register into conversation-declared slots but only
injected 'slots', so nothing ordered their applies after ui-conversation's
— register() into the undeclared slot threw and the entry FAILED. Both now
inject 'conversation' as an ordering edge (documented as such; specs stub
the service where the bench declares the slot itself).

Review-bot findings, all three applied: the module loader's load sink
cross-checks the handoff id against the arriving row (a mis-stamped bundle
can no longer register under another entry's identity); the default
execute seam removes the inline script node right after its synchronous
execution (repeated HMR rebuilds no longer accumulate dead nodes); a
throwing onRebuilt subscriber is contained per-listener and routed to
onError instead of escaping the fs.watchFile callback.
2026-07-24 02:09:43 +08:00
imccyu
e903a864f7 fix(gui): reconcile the rebase — ui-question joins the client roster
ui-question landed on master as a full dshClient plugin package (composer
question flow); it enters the flat roster, apps/cli deps/refs, and the
smoke graph. Restore the workspace-context and user-interaction host deps
the conflict resolution had dropped.
2026-07-24 02:09:42 +08:00
imccyu
fb47f61a83 refactor(gui): host graph from dshClient discovery; webserver self-watches bundles for HMR
The registry scans mounted Loader entries' dshClient declarations and
composes __DSH_BOOT__ {rev, entries} — inject edges and the immediately
mark come from manifests, never hand-copied; malformed fields fail loud
at load. The composing app owns one flat roster plus the --dev switch
(hmr row and bundle watching are dev-graph decisions).

The rebuild signal is the webserver's own observation: in dev mode the
registry stat-polls each scanned bundle (fs.watchFile; polling because
network mounts deliver no inotify), re-hashes on change, and broadcasts
a rebuilt frame on the /plugins/events SSE channel only when the rev
actually changed. Watch membership follows the table across rescans;
dispose drops all watches; a torn read self-heals on the next tick.
The POST /plugins/rebuilt endpoint is gone — builders and the host
share zero protocol. dsh web --dev logs the watched bundle list and
each rebuilt id with its rev transition.
2026-07-24 02:09:42 +08:00
imccyu
c2e0c16d6a refactor(gui): one plugin-package shape — dshClient manifests, clientBundle preset, purity gate over all nine
Every client plugin package carries dshClient ({platform, inject,
immediately?}) and emits lib/client.js through the shared clientBundle
preset; exports["./client"] points at the bundle. The infrastructure
tier (connection, runtime, ui-theme, i18n, hmr) declares immediately: true
in its manifest — absent means lazy. The bundle purity gate covers all
nine packages: platform modules stay external, INLINE_SAFE wire layers
inline, any other cross-plugin value import is a build error. Migrations
that rule forced: scopeOf became a SessionsService method and
transportError moved into dsh-host-apiproxy's wire layer; the store
engine stays in runtime under a documented temporary exemption
(TODO(webload/store-rehome)).
2026-07-24 02:09:42 +08:00
Tianyi Cui
e819a586b0 refactor(acp): reduce bridge to automation protocol 2026-07-24 01:40:25 +08:00
Tianyi Cui
404da65595 Merge branch 'master' into worktree/web-session-titles
# Conflicts:
#	apps/web/tests/smoke-real.e2e.ts
#	packages/client/connection/tests/fixture.spec.ts
#	packages/host/runtime/README.md
#	packages/host/runtime/src/api-proxy.ts
2026-07-23 22:00:17 +08:00
imccyu
6e94810973 feat(gui): carry the question detail field over the wire and render it
AskUserQuestionItem.detail is part of the user-interaction seam contract
but the web frame schema dropped it and the composer never rendered it
(review r3635427108). askUserQuestionItemSchema now forwards detail, the
composer renders it under the title in the description text style, and
the fixture's multi-select question carries one.
2026-07-23 20:26:48 +08:00
imccyu
38af17a2f5 fix(apiproxy): reject empty question batches at the wire boundary
ask() already fails EMPTY_QUESTIONS before a request exists, so a
question/requested frame with zero items is host breakage; muxFrameSchema
now refuses it instead of letting an undefined first question reach the
composer (review r3635427102).
2026-07-23 20:23:54 +08:00
Tianyi Cui
d7c4822f95 Merge origin/master into worktree/web-session-titles
# Conflicts:
#	packages/client/connection/src/client/fixture.ts
2026-07-23 20:12:40 +08:00
imccyu
0f63666522 Merge branch 'worktree/web-carrier-chain' into worktree/web-ask-user-question 2026-07-23 20:09:11 +08:00
Tianyi Cui
29f293675a fix(host): opt in to model titles from web 2026-07-23 20:08:33 +08:00
imccyu
6a896e62a1 Merge branch 'worktree/web-carrier-chain' into worktree/web-ask-user-question 2026-07-23 19:45:41 +08:00