Commit Graph

478 Commits

Author SHA1 Message Date
imccyu 34d5f8f2e2 Merge branch 'master' into feat/ask-question-gui 2026-07-30 16:55:54 +08:00
Tianyi Cui 9e679c89b6 Merge branch 'master' into feat/session-inherited-boundary 2026-07-30 16:30:42 +08:00
imccyu 69a58ddd6f Merge branch 'master' into feat/ask-question-gui 2026-07-30 15:50:59 +08:00
Hypatia May 8527137230 refactor(session): rename the seed boundary to end-seed 2026-07-30 15:32:06 +08:00
Tianyi Cui 2550882875 Merge branch 'master' into worktree/persistent-bash-str-replace-editor 2026-07-30 15:19:27 +08:00
imccyu 6ea1238714 docs(web): the composer bar is one session-maybe slot, not a swapped pair
fix(web): keep one composer bar DOM across the no-workspace transition

The composer.bar slot moves from session to session-maybe scope: with no
current session the entry still mounts, the machine faces (keyboard, stop,
command) arrive undefined, and the bar renders its normal DOM inert via the
disabled owner prop. DisabledInputBar and its parallel tree are gone, so the
textarea node survives the cold-start workspace pick instead of flashing
through a remount. A blank session whose workspace was deleted takes the
same inert path through owner props.

test(web): add the composer DOM-continuity acceptance probe

Drives a real dsh web server with headless chromium through the cold-start
-> pick-workspace -> type flow and asserts the composer textarea is the
same DOM node throughout (a marker property must survive). Rerun
prerequisites are in the header comment.

docs(web): session-maybe identity is adoption, not hold-forever

fix(web): session-maybe entries adopt the first session, then remount like strict entries

A session-maybe entry used to keep one React instance across every
transition, so component-local state leaked between sessions once the
composer bar moved to that scope (PermissionSelect's optimistic pick, the
IME composition guard). Identity is now adoption: an incarnation born
session-less holds through the arrival of the first session (the blank
shell's DOM survives the workspace pick), and afterwards behaves exactly
like a strict session entry — a switch or a drop to no-session remounts,
clearing local state by construction. The child key is an incarnation
counter kept in the stable outlet wrapper via render-phase setState.

chore: knip knows the root acceptance probe's playwright dependency

scripts/hero-composer-dom-continuity.mjs resolves playwright through
apps/web's devDependency tree (createRequire), which knip cannot follow;
ignore it at the root workspace.
2026-07-30 15:18:06 +08:00
Hypatia May 9e6f251a4c Merge remote-tracking branch 'origin/master' into feat/session-inherited-boundary
# Conflicts:
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	packages/host/apiproxy/README.i18n.yaml
#	packages/host/apiproxy/src/api-proxy.ts
2026-07-30 14:20:35 +08:00
Hypatia May 39ebd8f745 fix(session): close the review gaps the boundary opened
- `SessionSummary.updatedAt`'s wire doc still said "Persisted file mtime",
  which stopped being true for attached sessions.
- The core invariant let `session/inherited` fall through the merge-extensible
  default. It is core-owned, so it gets an explicit case; an unbalanced seed
  legally places it inside an open turn, which the relation permits.
- The Agent Note claimed the boundary reaches disk via `live.pending`/
  `scheduleDrain`. Verified false: the constructor append precedes `enter()`,
  so it never publishes on `session/event` and rides the creation seed instead.
  Attaching is therefore a write where none happened before — recorded, since
  only `load()` stays a pure read.
- The deferred-index proposal asserted this change documented the cold-mtime
  skew on `dsh-host-apiproxy`. It did not; the README entry now exists.
- `firstLiveSeq`'s firehose gap runs through its own seq, not below it.
- The boundary is not always at `firstLiveSeq` (the idempotence guard), so
  consumers scan for the last one.
- `lastActivityTime` excludes by type, so a pickup time still leaks onto a
  synthetic closer when a boundary ends an open turn. Documented.
- Pin the fork claim end-to-end: a child inherits a still-running parent's
  open bracket below its own boundary, while the parent has none. Fails if the
  write moves back to the load path.
- Fix the telemetry title that contradicted its own assertions.

The `/status` call site cannot be pinned the way the other two are: the
command appends its own `command/run` before rendering, so the boundary is
never the log tail there. Its fixture now at least renders over a
boundary-bearing log.
2026-07-30 13:59:08 +08:00
Hypatia May a00786362f refactor(session): drop the unused predicate helper and tighten the docs
`isInheritedSeq` had no production caller — only its own tests — so it was
a public core export shaped by nothing. A bracket owner reads the boundary
positionally; the helper belongs with the compaction seam, where a real
consumer decides its signature.

Also condense the `session/inherited` and `lastActivityTime` docs.
2026-07-30 12:01:45 +08:00
Tianyi Cui 3f195f1dd1 Merge remote-tracking branch 'origin/master' into codex/experimental-plugin-group-note 2026-07-30 11:57:55 +08:00
Hypatia May b341155652 feat(session): project the inherited-history boundary into the log
A plugin owning a standalone open/close bracket cannot tell a dead marker
from a live one: an unmatched `compact/start` reads identically whether the
previous writer died mid-compaction or a compaction is running now.
`Session.firstLiveSeq` already holds that answer exactly, but only in memory.

Append the log-only `session/inherited` event at that seq from the seeded
constructor — the single waist all six seeded-start paths pass through
(resume, configured startup on a persisted id, `sessions.fork()`, a subagent
fork child, `adopt()`'s live prefix, and a bare seeded `create`). Read it
through the new `isInheritedSeq(events, seq)`.

The constructor placement means persistence needs no changes: the marker is
already in `events` when a backend captures the creation seed, so it rides
the ordinary seed path with no load-time write. It also covers fork, where
the inherited bracket's owner may still be running — the case a
persistence-layer boundary could not reach.

Activity ordering excludes the boundary through `lastActivityTime()`, since
lazy resume makes browsing a pickup and the three call sites would otherwise
float every opened session to the top of a picker or list.
2026-07-30 11:39:26 +08:00
kingwl 7ce330f0e4 refactor(agent): scope queue actions to edit and remove 2026-07-30 01:58:51 +08:00
Tianyi Cui 401afde164 Merge remote-tracking branch 'origin/master' into codex/experimental-plugin-group-note
# Conflicts:
#	packages/README.i18n.yaml
#	packages/README.md
#	packages/README.zh.md
2026-07-30 01:32:41 +08:00
Tianyi Cui b7dbb25c08 docs: clarify release tooling exclusion 2026-07-30 01:14:25 +08:00
kingwl 76e14793a9 Merge remote-tracking branch 'origin/master' into codex/web-queue-actions
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/cordis-catalog/events.md
#	docs/core-data-structures/core.i18n.yaml
#	docs/event-producer-consumer.md
2026-07-30 01:04:25 +08:00
kingwl c97b1d025e Merge remote-tracking branch 'origin/master' into codex/web-queue-actions
# Conflicts:
#	apps/web/tsconfig.json
#	docs/architecture.i18n.yaml
#	docs/event-producer-consumer.md
#	packages/client/runtime/README.i18n.yaml
#	packages/client/tsdown.client.ts
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/core/agent-loop/README.i18n.yaml
#	packages/core/agent/README.i18n.yaml
#	packages/core/agent/README.zh.md
#	packages/host/apiproxy/README.i18n.yaml
#	tsconfig.host.json
2026-07-30 00:30:38 +08:00
kingwl f893e2281d feat(agent): add addressable queue operations 2026-07-30 00:05:00 +08:00
imccyu f773985e71 feat(typert): add compiler-independent type pipeline 2026-07-29 23:45:42 +08:00
Tianyi Cui 5de69975f0 test(python): stabilize executable snapshot 2026-07-29 22:56:14 +08:00
Tianyi Cui c0bd88430a fix(build): stage platform-specific PTY artifacts 2026-07-29 22:44:19 +08:00
imccyu 20c446e033 Merge branch 'master' into worktree-renameweb 2026-07-29 22:28:34 +08:00
imccyu fd356b92c8 Merge branch 'master' into feat/input-command-interaction 2026-07-29 22:10:39 +08:00
Tianyi Cui a5446e3160 Merge master into fix/subprocess-password-scrub
# Conflicts:
#	packages/lsp/lsp-local/README.i18n.yaml
#	packages/subprocess/subprocess-local/README.i18n.yaml
#	packages/subprocess/subprocess-local/README.zh.md
2026-07-29 21:38:24 +08:00
imccyu 76b4563380 Merge remote-tracking branch 'origin/master' into feat/input-command-interaction 2026-07-29 21:23:13 +08:00
Yif be9042e5a1 docs(client): sync package READMEs and agent notes with the input interaction rework
Update the six touched client package README pairs (slash menu ordering,
localized group titles and dismiss, permission label twin, goal pause,
plan hint localization, useAnchoredMaxHeight) and keep the owning agent
notes current: SlashSource.order and the MenuView dismiss/localize/clamp
face in the slash-pipeline note, the pause verb in the goal bar note.
2026-07-29 20:46:29 +08:00
imccyu 19336686a6 feat(apiproxy): session.rename RPC delegating to the session-title service
New unary method in RpcMethodMap with the title-invalid error code; the impl
resolves the agent (cold sessions resume first) and delegates to
ctx.sessionTitle.rename, returning the normalized title plus its event seq so
clients settle the title projection cell ahead of the push frame. session.fork
stays on the reserved-seam list.
2026-07-29 18:59:23 +08:00
kingwl 2ca6f54c9e Merge remote-tracking branch 'origin/master' into xtr/dsh-source-launch-tsx-esm
# Conflicts:
#	apps/cli/README.i18n.yaml
2026-07-29 13:39:57 +08:00
kingwl aebf9c863b feat(cli): launch dsh source through the tsx ESM hook
Node 26.0.0 removed --experimental-transform-types, so the native
source-launch chain cannot start anywhere on that line, and strip-only
mode rejects the vendored syntax (parameter properties, decorators,
runtime enums/namespaces). Switch bin/dsh, the root dsh/demo:tui/
demo:web scripts, and the Code Mode TUI overlay to node --import
tsx/esm: one launch vector across the whole engines range, ~0.4s faster
than the full tsx default (the CJS hook stays off; the graph is
ESM-only).

Delete scripts/tspath-loader.ts and apps/cli/src/tsconfig-paths-loader.ts:
tsx owns both transformation and tsconfig paths projection. Add
dsh-source-launch-smoke to the node-compat gates so the 22.19/26 matrix
executes the real launch vector; no CI job did, which is how the Node 26
breakage shipped silently.

Supersedes the native-TypeScript-source-launch Agent Note (new note
records the profiling evidence and rejected alternatives).
2026-07-29 13:15:24 +08:00
imccyu 8d0249d392 Merge branch 'feat/directory-picker' into feat/workspace-directory-browser 2026-07-29 10:42:19 +08:00
imccyu ecc447daf5 Merge branch 'doc/host-client-group-readmes' into feat/directory-picker 2026-07-29 10:42:13 +08:00
imccyu fa64ad39cb Merge branch 'master' into doc/host-client-group-readmes 2026-07-29 10:42:00 +08:00
Turtle 7a3295e0bf docs: consolidate TUI Agent Notes 2026-07-29 10:30:27 +08:00
Turtle c7e6cb5753 fix(tui): complete launcher integration and rationale 2026-07-29 10:25:07 +08:00
creatixchu fd7f081ff1 Merge remote-tracking branch 'origin/feat/directory-picker' into feat/workspace-directory-browser
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.i18n.yaml
2026-07-29 05:32:53 +08:00
creatixchu 7d07ab0c9d fix(host): abandon close behind a stalled read; race symlink probes; observe cleanup failures
The aborted exit no longer awaits close (Node queues it behind any
in-flight read, chaining the departed caller back onto the very stall
the abort escaped) — the abandoned close's failure is swallowed, it has
no consumer. Symlink stat probes race the signal too, with a
per-candidate abort check between probes, so a stalled probe target
cannot keep a departed request alive. The deferred handle cleanup after
a lost opendir race now consumes its own close failure instead of
leaking it as an unhandled rejection.
2026-07-29 05:32:12 +08:00
creatixchu 48141b0007 Merge remote-tracking branch 'origin/feat/directory-picker' into feat/workspace-directory-browser
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.i18n.yaml
#	packages/host/directory-picker-browse/README.i18n.yaml
2026-07-29 04:42:57 +08:00
creatixchu 7503390590 fix(host): cancellable listing scans and O(log window) insertion
capability.list gains an optional AbortSignal threaded from the RPC
carrier's request signal (the pickDirectory pattern): a disconnected or
timed-out caller stops the opendir loop instead of the scan outliving
its caller, and the abort surfaces as its own reason rather than a
directory-unreadable dressing. boundedInsert rejects a full window's
at-or-beyond-tail candidate on one comparison and binary-inserts
retained candidates, so an oversized level no longer pays a window scan
per dirent.
2026-07-29 04:42:13 +08:00
creatixchu deb37b8edf Merge remote-tracking branch 'origin/feat/directory-picker' into feat/workspace-directory-browser
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.i18n.yaml
#	packages/host/directory-picker-browse/README.i18n.yaml
#	packages/host/directory-picker-browse/package.json
#	pnpm-lock.yaml
2026-07-29 04:12:44 +08:00
creatixchu da970ea269 fix(host,client): stream bounded listings, declare schemastery, guard Choose again
The browse level now streams through opendir into a name-sorted window of
maxEntries + 1 candidates (boundedInsert), so memory stays O(maxEntries)
no matter how many children a directory holds and enterability probing
touches only windowed candidates; a windowed broken symlink is not
backfilled since the eviction already marks the level truncated.
schemastery joins the package's runtime dependencies (the source launcher
and isolated installs failed to resolve the value import). The
folder-error dialog's Choose again goes inert while the flow hole is
empty, and the withdrawal effect also keys on the open transition, so a
flow can never open over a hole nobody serves.
2026-07-29 04:11:41 +08:00
creatixchu 02c142e536 Merge remote-tracking branch 'origin/feat/directory-picker' into feat/workspace-directory-browser
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.i18n.yaml
#	packages/host/directory-picker-browse/README.i18n.yaml
2026-07-29 03:46:15 +08:00
creatixchu 5245182db2 fix(host): bound listDirectory levels at a configurable maxEntries
One list call now materializes at most maxEntries child rows (config,
default 1000 - GitHub's web-UI directory-listing bound). Candidates sort
before probing so a cut level keeps the name-sorted head and symlink
probing stops with the bound, and DirectoryListing carries a required
truncated flag on the seam and the wire so clients can state
incompleteness instead of silently missing tail entries.
2026-07-29 03:45:26 +08:00
creatixchu e9e9c1397a Merge remote-tracking branch 'origin/feat/directory-picker' into feat/workspace-directory-browser
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-28-directory-picker-capability-seam.i18n.yaml
2026-07-29 02:12:55 +08:00
creatixchu e7c9877ac5 fix(build,doc): native paths aliases; the note states browse's client half is stacked
- tsconfig.base.json still aliased the removed directory-picker-dialog and
  offered no mapping for -native: on a clean tree, package-name imports and
  source launches fell through to a missing lib/ until a build ran.
- The seam note (and the generated seam prose) no longer describe the
  browse browser half as shipped here: it lands in the stacked follow-up,
  and a -browse composition meanwhile shows the documented empty-hole
  default (ds-review-bot).
2026-07-29 02:11:31 +08:00
creatixchu da71e1eef2 Merge remote-tracking branch 'origin/feat/directory-picker' into feat/workspace-directory-browser 2026-07-29 01:10:33 +08:00
creatixchu 6a78bf4dd0 Merge remote-tracking branch 'origin/doc/host-client-group-readmes' into feat/directory-picker 2026-07-29 01:09:33 +08:00
creatixchu 51b70f5864 Merge remote-tracking branch 'origin/master' into doc/host-client-group-readmes
# Conflicts:
#	apps/cli/README.i18n.yaml
2026-07-29 01:08:17 +08:00
ZiyaZhang 03a8805da7 Merge remote-tracking branch 'upstream/master' into fix/subprocess-password-scrub 2026-07-28 09:56:23 -07:00
ZiyaZhang 8d77e5149c Merge remote-tracking branch 'upstream/master' into fix/subprocess-password-scrub 2026-07-28 08:15:08 -07:00
imccyu c804dfde3e docs: document native TypeScript source launch 2026-07-28 23:13:28 +08:00
Turtle 2f3ac10da0 docs: implement experimental and internal package group 2026-07-28 22:30:12 +08:00