Commit Graph
324 Commits
Author SHA1 Message Date
Yichen Jiang a2497a0dc1 Merge remote-tracking branch 'origin/master' into worktree/open-settings-config-file
# Conflicts:
#	packages/client/connection/README.i18n.yaml
#	packages/client/connection/README.md
#	packages/client/connection/README.zh.md
2026-08-05 11:05:52 +08:00
imccyu ca27512529 fix(packages): omit source publication payloads 2026-08-05 01:15:19 +08:00
Turtle e2049910d5 refactor(client): keep pending interaction change UI-scoped 2026-08-04 20:28:23 +08:00
Turtle 3a54694d28 fix(client): preserve pending waits across reconnect 2026-08-04 18:52:11 +08:00
Yichen Jiang 4f717f2da7 fix(web): address settings document review 2026-08-04 17:31:36 +08:00
Turtle 00d4349eb4 feat(client): surface pending session interactions 2026-08-04 17:15:10 +08:00
Yichen Jiang e31b7221e7 feat(web): open the local settings file 2026-08-04 16:59:37 +08:00
imccyu b4a4f337e4 test(client): derive retry timing expectation 2026-08-04 16:02:19 +08:00
imccyu cc435a9c0c fix(web): use exact turn boundaries for run time 2026-08-04 15:55:07 +08:00
imccyu 6f1d443c59 feat: optimize chat think 2026-08-04 14:37:35 +08:00
imccyu fc5ee9f786 refactor(client): expose loopback state through connection 2026-08-03 18:35:26 +08:00
kingwl c5050f018e fix(web): keep ineligible message forks disabled 2026-08-03 16:19:49 +08:00
kingwl c43eaaec82 Merge remote-tracking branch 'origin/master' into codex/pr-1150-disabled
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-03 16:02:33 +08:00
kingwl 038b6063ee Merge remote-tracking branch 'origin/master' into codex/pr-1150-conflict-fix
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-03 11:34:26 +08:00
kingwl 6b6acbe0c5 Merge master into subagent usage branch
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.md
#	.agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.zh.md
#	apps/web/tests/snapshots/subagent-conversation/tree.expected.md
#	apps/web/tests/subagent-conversation.e2e.ts
#	packages/client/ui-subagent/src/client/SubagentCatalogAction.tsx
2026-08-02 23:37:17 +08:00
kingwl b30686d634 show subagent usage and active duration 2026-08-02 23:31:24 +08:00
Tianyi Cui 1ea72962eb Merge master into fix/subagent-stack-end-result 2026-08-02 23:13:00 +08:00
Tianyi Cui 7b40fd5419 perf(web): trail only membership-invalidated catalogs
refreshSubagents previously treated every overlapping caller as proof that the in-flight response was stale. Selection, menu opening, and reconnect paths can legitimately request the same catalog concurrently without any host mutation, so those reads were coalesced and then followed by an unnecessary second RPC.

Restore ordinary in-flight coalescing at the public refresh boundary. The debounced host/session-added path now owns the membership-specific stale mark: if its timer fires during an older pull, it queues one trailing request; otherwise it starts the refresh directly. Parent removal keeps its separate explicit invalidation and trailing-refresh path.

Add a regression proving two overlapping reads share one Promise and issue one RPC. Rework the membership test to start from a restored selected parent, so only the host membership frame can request the trailing pull instead of the test priming the stale bit with an unrelated duplicate read.

Validated with both focused catalog cases, all 40 SessionManager tests, and the client runtime TypeScript project build.
2026-08-02 20:13:28 +08:00
Tianyi Cui 069f2644ff fix(web): preserve removal across stale catalog pulls
The earlier removal fix invalidated parentAvailable immediately and queued a trailing subagent.list request, but it still applied the already in-flight success verbatim. That stale success reopened the composer and became the trailing request baseline. If the trailing request failed, its error snapshot preserved parentAvailable:true indefinitely.

Record a false-only parent availability override on the exact in-flight catalog request when the owner removal frame arrives. Successful and failed responses now replay that request-local invalidation before publishing a snapshot, and addressed child Sessions receive the same effective value. The trailing request therefore starts from a false baseline and a later transport or business failure cannot resurrect the removed parent.

Strengthen the regression to assert the catalog and selected child remain read-only immediately after a stale parentAvailable:true success, then fail the trailing pull and assert the error snapshot remains unavailable. The complete SessionManager test file passes all 39 tests, and the client runtime TypeScript project builds cleanly.
2026-08-02 20:11:34 +08:00
kingwl 4329b93989 Merge remote-tracking branch 'origin/master' into codex/fork-real-turn-tail
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/src/client/chat/ChatView.tsx
#	packages/client/ui-conversation/src/client/chat/MessageIconActions.tsx
2026-08-02 18:14:32 +08:00
imccyu 7d08e43720 fix(web): address steering review feedback 2026-08-02 17:53:07 +08:00
imccyu dffe955ed2 feat(web): surface and configure composer steering 2026-08-02 17:53:07 +08:00
kingwl 955a12cca4 feat(web): steer queued messages into active turns 2026-08-02 17:53:07 +08:00
kingwl 76547dfe0c fix(web): restrict message forks to completed turn tails 2026-08-02 16:25:02 +08:00
Tianyi Cui d004c694f1 test(web): narrow the stale-pull assertion to the root catalog's calls 2026-08-02 14:05:37 +08:00
Tianyi Cui 295e56b61e fix(web): keep removal-time availability invalidation across an in-flight pull
The `host/session-removed` invalidation flipped the owned catalog and
addressed children to `parentAvailable:false`, but a `subagent.list` pull
already in flight was requested before the removal and its ok-response
carries the pre-removal `parentAvailable:true` — the response then
overwrote both the catalog and every addressed child, resurrecting the
writable-editor-against-a-dead-continuation-owner bug the invalidation
closes, with no refresh scheduled to converge afterwards.

Mark the owner stale when a pull is in flight at removal time, so one
trailing refresh runs after the in-flight response settles and the
post-removal host truth lands. Adds a regression test: removal mid-pull,
stale ok response, trailing pull, final state stays unavailable on the
catalog and the addressed child.
2026-08-02 14:05:37 +08:00
Tianyi Cui 8431dbead3 fix(web): invalidate catalog availability when the owning parent is removed
A removed session can no longer be the delivery owner of its continuable
children, but the `host/session-removed` handler only reconciled the
removed row's own activity. `parentAvailable` was updated exclusively from
`refreshSubagents` success, and removal schedules no catalog refresh — so
after the parent's Activation detaches, an addressed child kept a writable
editor against a dead continuation owner until an unrelated refresh (or
forever, for a closed menu).

Flip `parentAvailable` to false on the owned catalog and push
`handleSubagentParentAvailable(false)` to every addressed child Session at
removal time, matching the refresh path's notification. New Session
instances already read `parentAvailable` from the catalog, so they inherit
the invalidated state.

Adds a regression test: removing the catalog's owning parent flips the
snapshot's `parentAvailable` and notifies the addressed child instance.
2026-08-02 14:05:36 +08:00
Tianyi Cui b270b3ef9f fix(web): run a trailing catalog refresh for coalesced membership changes
`refreshSubagents` single-flights per catalog owner: a request arriving
while a pull is in flight returns the in-flight promise and is silently
coalesced into it. The in-flight response was requested before the
triggering change, so it can never contain that change — a debounced
membership refresh (50ms after `host/session-added`) firing during a slow
pull therefore lost the new child, and the catalog stayed stale until an
unrelated trigger (reselection, menu reopen, reconnect).

Mark the owner stale on coalescing and re-arm one trailing pull in the
settlement `finally`, so every membership change observed during a pull is
carried by a follow-up refresh exactly once. Bounded: the trailing pull
only runs when a refresh request was actually coalesced, and a new
coalescing during the trailing pull re-marks the same set.

Adds a fake-timer regression test: a `host/session-added` debounce firing
mid-pull yields exactly two `subagent.list` calls and the catalog
eventually contains the new child.
2026-08-02 14:05:36 +08:00
imccyu 23680e838b fix(web): synchronize subagent navigation state 2026-08-02 12:51:11 +08:00
imccyu b94d2f9c1d fix(web): stabilize nested subagent navigation 2026-08-02 12:51:11 +08:00
imccyu 130410bb98 fix(web): preserve subagent navigation and fork grouping 2026-08-02 12:51:11 +08:00
imccyu 8c9cd4c15d feat: optimize subagent list children query 2026-08-02 12:51:11 +08:00
Dudu-0223 8a518e353b feat(web): rewrite subagent conversations for FIFO activation 2026-08-02 12:51:09 +08:00
Dudu-0223 f0ab04273d fix(web): deduplicate subagent navigation 2026-08-02 12:51:09 +08:00
Dudu-0223 16ffd63115 feat(web): add nested subagent conversations 2026-08-02 12:51:09 +08:00
Dudu-0223 a27492507d feat(web): add subagent conversation transport 2026-08-02 12:51:09 +08:00
imccyu 3dfbfb4e72 Merge branch 'master' into fix/web-fork-interrupted-seq 2026-08-01 02:19:51 +08:00
kingwl 32a0e871b7 fix(web): preserve queue on stop 2026-07-31 20:51:05 +08:00
ZiyaZhang 344ad0d6fb fix(client): floor the fork anchor to a real event seq
The fork button on a stopped assistant message was inert. Frozen
interrupted nodes carry a flow-ordering seq of turnEnd.seq - 0.9, and
session.fork takes a non-negative integer on the wire, so every such
request was rejected as invalid-params before reaching the host — where
an aborted turn's logged turn/end has always made it forkable.

SessionsService.fork floors atSeq at the wire boundary. Flooring stays
inside the anchor's own turn (every turn opens with turn/start), so the
host's first-turn/end-at-or-after cut still closes on that turn.
2026-07-31 05:41:45 -07:00
Tianyi Cui 2d73157099 docs(client): refresh runtime README pairing 2026-07-31 19:18:08 +08:00
Ziya 9473951c79 Merge branch 'master' into fix/web-turn-error-surface 2026-07-31 07:13:02 -04:00
ZiyaZhang 215bf15f78 fix(web): surface terminal turn failures 2026-07-31 03:10:48 -07:00
Tianyi Cui e371311203 Merge latest Web transcript parent into manual compaction
# Conflicts:
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	packages/client/runtime/README.i18n.yaml
2026-07-31 14:39:20 +08:00
Tianyi Cui 5c394b1743 Merge latest master into web transcript projection
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
2026-07-31 14:31:14 +08:00
imccyu 9ed87a6dba refactor(client): archivedSessionIds public face becomes a plain array
Public snapshot state stays in the store engine's plain-data vocabulary
(immer drafts reject Sets without the MapSet plugin, which stays off):
manager/service/contract carry readonly SessionId[] in Host order, and
the tree derivations build their own transient Set — the
expandedProjects pattern. Membership-unchanged installs still keep the
array reference for Object.is short-circuits.
2026-07-31 14:08:13 +08:00
imccyu d3e8f17a54 fix: review follow-ups for the session archive set
- WorkspaceRegistry.archiveSession no longer wraps persistence-listing
  failures as WorkspaceUnknownSessionError: only a definite miss (live
  lookup, header index, then a fresh list) maps to session-not-found;
  storage faults propagate as internal errors, with a negative test.
- The archived-current sweep moves from the unary path into the
  projection: any install path (local echo, another tab's frame, a
  reconnect baseline) clears a selection that landed in the archive set.
- An archive set installed while workspace.list is in flight supersedes
  the stale baseline's set instead of being rolled back by it.
- The workspace-management e2e anchors the archived row by its session
  actions button and asserts the single-stray fixture assumption loudly.
- Drop the stale touchSession rows from the workspace READMEs (the
  method was removed with its Agent Note).
2026-07-31 14:08:13 +08:00
imccyu fc0042e47e fix(client-runtime): never reuse an archived blank session in connectWorkspace
Reusing one would open a session no grouping surface can show; the New
Session flow mints a fresh blank instead.
2026-07-31 14:08:13 +08:00
imccyu c764ed7e64 feat(client-runtime): project the archive set and the archiveSession action
WorkspaceListState gains archivedSessionIds (ReadonlySet, replaced only
on membership change), installed as full snapshots from the list
baseline, the unary echo, and the changed frame. Archiving the current
session clears the selection into the New Session view state. Test
doubles (test-runtime, fake APIs, fixture client) follow the widened
IWorkspaces/IApiClient faces.
2026-07-31 14:08:13 +08:00
Tianyi Cui 98f48fd83a Merge finalized Web transcript parent
# Conflicts:
#	apps/cli/README.i18n.yaml
#	packages/client/runtime/README.i18n.yaml
#	packages/client/ui-trajectory/README.i18n.yaml
#	packages/client/ui-trajectory/README.zh.md
2026-07-31 13:42:47 +08:00
Tianyi Cui bb3d6a0de8 Merge latest master into Web transcript
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
#	packages/client/runtime/src/client/index.ts
#	packages/client/runtime/src/client/sessions/conversation.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/src/client/chat/MessageItem.module.css
#	packages/client/ui-conversation/src/client/chat/MessageItem.tsx
#	packages/client/ui-conversation/src/client/chat/chat-flow.ts
#	packages/client/ui-conversation/tests/chat-branch-tails.spec.tsx
2026-07-31 13:12:37 +08:00