Commit Graph

456 Commits

Author SHA1 Message Date
Tianyi Cui
5f295de096 Merge remote-tracking branch 'origin/master' into simpl-f-steering-mirror
# Conflicts:
#	docs/rfc/README.md
2026-07-04 22:50:47 +08:00
Tianyi Cui
3977f1d63c Merge remote-tracking branch 'origin/master' into codex/docs-graph-brainstorm
# Conflicts:
#	docs/architecture.md
#	docs/development.i18n.yaml
#	docs/development.md
#	docs/development.zh.md
#	docs/rfc/README.md
#	package.json
2026-07-04 22:39:16 +08:00
Tianyi Cui
456cb3b532 Merge remote-tracking branch 'origin/master' into simpl-a1-drop-image
# Conflicts:
#	docs/architecture.md
#	packages/compact/compact-basic/README.md
2026-07-04 21:12:33 +08:00
Tianyi Cui
582caee90a Merge remote-tracking branch 'origin/master' into simpl-f-steering-mirror
# Conflicts:
#	docs/cordis-catalog/events-and-services.md
#	packages/core/agent/src/types.ts
2026-07-04 20:44:34 +08:00
Tianyi Cui
2745879132 refactor(llm): drop the image content block until a path can honor it
ImageBlock had no production producer and every consumer dropped it:
the deepseek serializer skipped it, the pi-ai converter skipped it as
unrepresentable, the ACP bridge neither advertises image prompt
capability nor forwards image blocks, and compact-basic charged a flat
85-token estimate and rendered an [image] placeholder. A block
constructed today would silently vanish from the wire — the vocabulary
advertised a capability no path honors, the silent-data-loss shape the
defensive patterns warn against. The only constructors were tests
pinning the skip/estimate branches.

Remove ImageBlock and its ContentBlockMap entry (its cache?: CacheHint
field leaves with it; CacheHint itself and the other two cache? fields
are out of scope). compact-basic loses its explicit image estimate and
placeholder arms (the merge-extensible default arms absorb the case);
the deepseek serializer, pi-ai converter, and ACP codec already handled
image in their default arms, so only their image-naming comments
change. The codec's inbound rejection of ACP-protocol image prompt
content stays — that guards wire content a client can send regardless
of our vocabulary.

Tests that constructed harness image blocks to pin the removed branches
are dropped (the 85-token estimate pin) or retargeted onto plugin-added
block types / other non-text blocks, which the surviving default arms
own. Docs, the type-equiv pastes, and the content-block vocabulary
RFC's block list and multimodal-home consequence are updated in the
same change; the RFC moves to implemented/ and the index is
regenerated. A real multimodal feature reintroduces image via
declaration merging together with the adapter mapping, ACP
advertisement, and compaction pricing that honor it.
2026-07-04 17:21:13 +08:00
Tianyi Cui
c6d2eeea6b refactor(events): remove the agent/steering mirror emit
agent/steering was the last transient mirror of a durable session event:
drainSteering appended the durable steering/message {turn, content, source}
and emitted the identical fact one line later. Zero production listeners
existed — every steering consumer (hook bridges, goldens, deriveMessages)
reads the durable event — and the one regression test subscriber asserted
a fact the log already records.

Remove the declaration (dsh-agent types + JSDoc list + README row), the
emit in drainSteering (its ctx parameter goes too), and the emit line in
the loop-pseudocode blocks (loop.ts module doc, architecture.md); the
cordis catalog is regenerated. The regression test now pins source
preservation on the durable steering/message event. Live-notification
needs keep their surviving homes: agent/queued at enqueue time,
session/event at drain time.

RFC: docs/rfc/implemented/simplification/2026-07-04-remove-agent-steering-mirror.md
(moved from proposed/, amended to shipped reality). The three implemented
RFCs that stated the retention — the boundary-mirror removal, the
stream-chunk removal, and event-domain-semantics — are amended to point
at that RFC as the record of the removal, per implemented/AGENTS.md.
The rejected retire-mid-turn-steering RFC keeps its frozen text (it
records the declined proposal); the steering capability itself —
steer(), the durable event, continuation forcing — is untouched.
2026-07-04 15:36:40 +08:00
Tianyi Cui
6227cfd03d docs(architecture): rewrite the system map to the 1,800-word budget
architecture.md is the behavior map: layering, service map, seam
pattern, and the loop — everything else defers to its owning tier.

- Seam narrations compress to two-to-four sentences plus links to the
  RFC and type-catalog homes that carry the detail (turn-end variant
  semantics -> session.md, derivation mapping -> session.md, StreamChunk
  conventions -> llm-streaming.md + source).
- The MVP feature-to-mechanism checklist moves de-statused into the
  extension cookbook as 'The feature -> mechanism map' — mechanisms
  only, no implementation-status bolding to rot; the microkernel RFC's
  proof-obligation pointer follows it.
- The layering diagram describes layers by family instead of
  enumerating packages (the stale 'future plugins: hooks, compaction'
  row is gone); the dependency rule defers to packages/README.md.
- The loop pseudocode, the three externally-cited anchors (the
  vocabulary, event taxonomy, waterfall semantics), and the filename
  are unchanged.
- Budget ratchet: docs/architecture.md 3897 -> 1800 (now 1,797 words);
  the doc-tiers RFC's deferred list prunes the item this ships.
2026-07-04 14:43:48 +08:00
Tianyi Cui
d30f42ddcd Merge origin/master and refresh doc graphs 2026-07-04 12:50:06 +08:00
Tianyi Cui
81c27bed36 Merge branch 'worktree-hooks-f-bridges' into worktree-hooks-g-stream-chunk
# Conflicts:
#	docs/rfc/README.md
2026-07-04 03:21:00 +08:00
Tianyi Cui
9033837081 Merge branch 'worktree-hooks-b-bash-seam' into worktree-hooks-c-interception
# Conflicts:
#	docs/architecture.md
#	docs/cordis-catalog/events-and-services.md
#	docs/core-data-structures/tools.md
#	packages/core/tools/README.md
#	packages/core/tools/src/index.ts
2026-07-04 02:44:26 +08:00
Tianyi Cui
c5ed5ff490 Merge remote-tracking branch 'origin/master' into worktree-hooks-a-taxonomy
# Conflicts:
#	docs/rfc/README.md
2026-07-04 02:15:52 +08:00
Dudu-0223
005db3c610 Merge remote-tracking branch 'origin/master' into web-capability-seam
# Conflicts:
#	docs/architecture.md
#	docs/module-graph.md
#	docs/rfc/README.md
#	packages/README.md
#	tsconfig.build.json
#	tsconfig.json
2026-07-03 16:49:00 +08:00
Yichen Jiang
5870bc2e1a Merge origin/master into skill system branch
Use the new filesystem seam for skill file reads and system skill writes when ctx.fs is available, and include the skill tool in the generated tool catalog.
2026-07-03 12:26:58 +08:00
Yichen Jiang
a52cac00b1 fix(project-instructions): load files through fs service 2026-07-03 11:56:58 +08:00
Yichen Jiang
19abd0a357 Merge remote-tracking branch 'origin/master' into codex/project-instruction-files 2026-07-03 11:36:11 +08:00
Tianyi Cui
665c10ff19 docs(graphs): add generated documentation atlas 2026-07-03 01:13:52 +08:00
Tianyi Cui
b84d4828a8 refactor(events): remove the agent/stream-chunk mirror of assistant/chunk
The loop recorded every model token delta as a durable `assistant/chunk`
session event AND emitted an identical live `agent/stream-chunk` Cordis event
one line later. Same StreamChunk, same turn/step; the emit added only the live
Agent handle, which the sole consumer discarded. This is the boundary-mirror
duplication the event-domain work removed for turn/step boundaries, applied to
the token stream — a follow-up the boundary RFC explicitly deferred.

The premise is settled: chunk persistence is authoritative (the proposal to
stop persisting chunks was rejected — replay/snapshots depend on it), so
`assistant/chunk` on `session/event` is the load-bearing token stream and
`agent/stream-chunk` is pure redundancy.

- Remove the `agent/stream-chunk` declaration + emit; drop the now-unused
  StreamChunk import from dsh-agent's types.
- Migrate `dsh-ui-stdio` (the only live consumer; ACP already reads
  assistant/chunk off session/event) to render assistant/chunk in its existing
  session/event listener. Consolidating to one listener also makes the
  inReasoning dim-SGR flag deterministic across chunk/boundary events (they no
  longer race across two listeners).
- Repoint the agent-loop tests (cancel/loop) and ui-stdio tests to the
  session/event assistant/chunk feed.
- New RFC (implemented/simplification/2026-07-02-remove-stream-chunk-mirror);
  amend the boundary RFC's retained-list entry to cross-link; update
  architecture, cookbook, event-domain-semantics, the ACP proposal, and the
  regenerated cordis catalog.

Snapshot goldens unchanged (ACP never used the mirror), confirming no
editor-facing transcript change.
2026-07-02 23:42:16 +08:00
Tianyi Cui
a334395f0c feat(coding-agent): wire the filesystem tools into the demo
Load dsh-fs-local + dsh-fs-policy + dsh-tool-fs after tool-todo (mirroring the
acp-agent wiring), and steer the system prompt to prefer read/write/edit for
file ops with bash for shell/tests/search. Update the welcome line and the
FIXME(config-comments) bash note.

Doc sweep now that both demos ship the fs tools and the seam resolves per-session
cwd: architecture.md and the event-gate RFC no longer say the demos do file ops
through bash / that no config wires the tools; the coding-agent + examples
READMEs and the AGENTS.md layout blurb list the fs tools; the acp-agent README
drops the launch-dir caveat (per-session cwd now works, so the server can launch
anywhere).

(stdio-agent is single-session, so fs-local's cwd = process.cwd() is the
workspace. Keyless boot smoke is blocked locally by an unrelated inotify
watcher-limit ENOSPC that also hits demo:echo; the config parses and the same fs
stack boots green in the acp-agent snapshot tier.)
2026-07-02 19:46:59 +08:00
Hypatia May
09e81f4179 Merge remote-tracking branch 'origin/master' into session-fork
# Conflicts:
#	docs/architecture.md
#	packages/README.md
#	tsconfig.build.json
#	tsconfig.json
2026-07-02 17:56:49 +08:00
Tianyi Cui
1323366da3 Merge worktree-hooks-b-bash-seam into worktree-hooks-c-interception
Bring the interception-seams branch onto current master (via A→B). The
substantive reconciliation is master's compaction `agent/pre-step` serial seam
meeting C's interception seams:

- types.ts: keep BOTH master's `agent/pre-step` AND C's new interception events
  (`agent/prompt-submit`, `agent/session-start`, `agent/turn-continuation`→
  `ContinuationDecision`); drop the turn-mirror declarations (removed on A).
- loop.ts: the merged per-turn order is `turn/start` → per queued msg
  `agent/prompt-submit` (rewrite/inject/block) → (fully-blocked ⇒ zero-step
  `rejected`) → per step: drain steering → assemble system prompt →
  `agent/pre-step` (compaction, OUTSIDE the step) → `step/start` → single
  `deriveMessages()` → model → tools/pre-execute·dispatch·post-execute. No
  turn-mirror emits; `closeTurn()` is the A-simplified single-call form.
- Docs (architecture, core.md, agent/agent-loop READMEs, catalog) reconciled to
  show C's interception seams alongside `agent/pre-step`, no turn/step mirrors.
- rfc/README: dropped the stale `proposed/` compaction row (master moved that RFC
  to implemented/); kept C's new `pre-tool-input-rewrite` proposed row.
- interception.spec.ts: migrated its two `agent/turn-end` reason collectors to
  the `turn/end` session event, and ADDED a cross-test proving a
  `prompt-submit` rewrite + additionalContext is VISIBLE to an `agent/pre-step`
  listener on the same turn — pinning the merged seam ordering (compaction sees
  the post-prompt-submit surface, not stale history).
2026-07-02 04:51:24 +08:00
Tianyi Cui
9e575a2a2c docs(events): fix stale turn-mirror references caught in review
Codex review of the turn-mirror removal found current-state docs/comments that
still claimed the removed `agent/turn-start`/`agent/turn-end` events exist:

- docs/architecture.md: the loop diagram's turn-start line still said "emit
  agent/turn-start" (the turn-end line was already fixed).
- event-domain-semantics RFC: the `agent/*` domain description listed "the turn
  boundaries" among the transient emits.
- docs/core-data-structures/core.md: the agent/* taxonomy blurb listed
  "turn/step boundaries" as agent events.
- the proposed ACP RFC: the settle-signal rows named agent/turn-start /
  agent/turn-end; retargeted to the durable `turn/end` session event + the
  session/event owning-turn correlation.
- loop.ts outer-catch comment: said "closeTurn/failTurn are idempotent" — after
  the emit-param removal closeTurn is called exactly once (mutually exclusive
  normal/catch paths), so corrected to state that and to scope idempotency to
  closeStep (which is still guarded by stepOpen).

Regenerated the cordis catalog. No behavior change.
2026-07-02 03:47:37 +08:00
Tianyi Cui
140f818a42 refactor(events): remove the turn boundary mirror events
Complete the boundary-mirror removal begun with the step mirrors: drop
`agent/turn-start` and `agent/turn-end` from the agent event taxonomy. Turn and
step boundaries are now read exclusively off the durable `session/event` feed
(`turn/start`/`turn/end`/`step/start`/`step/end`) — there is no `agent/*` mirror
for any boundary.

- loop.ts: delete both turn emits; `closeTurn` loses its `emit` parameter and
  its now-unreachable idempotency guard (it is called exactly once per turn, on
  mutually exclusive normal/catch paths); `failTurn` loses the dead post-close
  branch that only a throwing turn-end LISTENER could reach.
- ui-stdio: render turn boundaries from `session/event`, recovering the short
  agent label from an `agent/created`→id map (the `turn/start` event carries only
  the turn number, and the session id is not reliably the agent id). ui-stdio is
  a disposable test REPL, so this migration retires the sole justification the
  event-domain-semantics RFC gave for KEEPING the turn mirrors.
- Tests: reason/turn-number collectors and the boundary-ordering test now read
  `session/event`; the throwing-turn-boundary-LISTENER tests are deleted (that
  code path no longer exists). A new test covers the outer-catch disposed branch
  via a pre-step listener that disposes-then-throws (the surviving real path).
- Docs: promote the "remove agent boundary mirror events" RFC to implemented
  (amended/narrowed — `agent/steering` is RETAINED, not a boundary mirror);
  update the event-domain-semantics + turn-enclosure RFCs, architecture.md, the
  cookbook, the ACP/agent/ui-stdio prose, and regenerate the cordis catalog.

`agent/steering` and `agent/stream-chunk` are explicitly out of scope (not
durable-boundary mirrors). ACP is unaffected — it already settles from the log's
`turn/end` + `agent/status`; snapshot goldens are byte-unchanged.
2026-07-02 03:26:45 +08:00
Tianyi Cui
30c1863755 fix(fs): address review — rename to dsh-fs-policy, fs/*-intent events, RFC currency, ENOTDIR
Rename per review naming decisions:
- package dsh-file-context → dsh-fs-policy (dir, package name, plugin name,
  tsconfig refs, importers, type-equiv manifest, generated catalog + module-graph)
- events fs/write-expectation → fs/write-intent, fs/edit-expectation → fs/edit-intent
  (fs/observed unchanged); type FsWriteExpectation → FsWriteIntent, "expectation"
  wording → "intent" throughout
- exported FileContextExec → FsPolicyExec

Make the implemented RFCs describe what shipped, not the superseded designs:
the 2026-06-17 capability-seam + tool-schemas RFCs no longer place policy on
ctx.fs or use full/partial-view authorization, and the fsspec RFC's ctx.fileContext
service prose is rewritten to the fs/* event-gate reality (freshness-based auth).
Sharpen docs/rfc/implemented/AGENTS.md: a rename is a fact to fix IN PLACE — the
"new RFC" escape hatch is for macro decision reversals only, not renames.

Code fixes from review:
- fsio.ts resolveLocalTarget/probe translate ENOTDIR (a parent path segment is a
  file) into the structured FsError taxonomy instead of leaking a raw Node error;
  resolve reports FS_NOT_FOUND, probe reports absent. Regression tests proven to
  fail on the unfixed code.
- tool-fs HMR test now asserts prompt sections (not just tool schemas) are
  withdrawn on disposal.
- fs/observed is a plain (unguarded) ctx.emit: correct the fs-policy comment,
  filesystem.md, and tool-fs module doc that wrongly claimed the tool "contains"
  a throwing listener; a throw surfaces as the tool's isError result.
- drop the false "loaded by the default product config" claim (no config wires
  the fs tools yet), the duplicate ctx.bash service-map row, the stale
  FileReadRequest catalog link-map entry, and the fs/fs README EOF blank line;
  correct the dsh-fs package.json description.
2026-07-02 03:12:38 +08:00
Tianyi Cui
bdf390679b Merge origin/master into worktree-hooks-a-taxonomy
Bring the event-taxonomy branch up to date with master's compaction work.
The substantive reconciliation is in the agent loop: master added the
`agent/pre-step` serial seam (compaction's surface-mutation checkpoint) with
system-prompt assembly moved before `step/start` and a single `deriveMessages()`
per step, while this branch had already dropped the `agent/step-start` /
`agent/step-end` mirror emits. Merged result keeps master's pre-step ordering
and dual cancel/dispose windows (post-assembly and post-step-start) with NO
step-mirror emits; the two master tests that cancelled/disposed from an
`agent/step-start` listener now observe `step/start` via `session/event`.

Regenerated the cordis catalog and module graph from source. Gates: typecheck
clean, agent-loop + compact suites green (226 tests).

Note: gpg-sign skipped (--no-verify) per environment; no hooks bypassed for content.
2026-07-02 02:16:07 +08:00
Tianyi Cui
e4b4eaaf38 Merge remote-tracking branch 'origin/master' into fs-tool-clean
# Conflicts:
#	docs/architecture.md
#	docs/cordis-catalog/events-and-services.md
#	docs/module-graph.md
#	packages/README.md
2026-07-02 01:41:58 +08:00
Tianyi Cui
8a8b88b0a7 Merge remote-tracking branch 'origin/master' into compact-basic-refactor
# Conflicts:
#	docs/architecture.md
#	examples/coding-agent/README.md
#	packages/core/session/README.md
2026-07-01 23:29:20 +08:00
Yichen Jiang
d181e6ba33 Merge origin/master into codex/skill-system 2026-07-01 18:54:41 +08:00
Yichen Jiang
0691048e47 Merge remote-tracking branch 'origin/master' into codex/project-instruction-files 2026-07-01 18:44:30 +08:00
Tianyi Cui
cf71c0b215 fix: address web seam review findings 2026-07-01 17:08:53 +08:00
Tianyi Cui
29ce2df315 Merge remote-tracking branch 'origin/master' into web-capability-seam
# Conflicts:
#	docs/architecture.md
#	docs/cordis-catalog/events-and-services.md
#	docs/module-graph.md
#	packages/README.md
#	tsconfig.base.json
2026-07-01 17:00:44 +08:00
Tianyi Cui
5bdb40ff34 Merge remote-tracking branch 'origin/worktree-hooks-b-bash-seam' into worktree-hooks-c-interception
# Conflicts:
#	docs/architecture.md
#	packages/core/agent-loop/README.md
2026-07-01 15:37:54 +08:00
Tianyi Cui
3e26102baf Merge remote-tracking branch 'origin/master' into worktree-hooks-a-taxonomy 2026-07-01 15:10:31 +08:00
kingwl
643b77dabf docs: sync implementation docs and doc gates 2026-07-01 10:29:47 +08:00
Tianyi Cui
dc95a7881d feat(events): interception seams — the typed-Decision surface for hooks
Reshape the agent's interception surface so every seam returns a small, typed
Decision union, and the set covers the hook points a CC/Codex bridge (and a
native plugin) needs. "Native hooks" are not a package — a native hook is just a
cordis plugin on these canonical events; the bridges (a later PR) only translate
an external protocol onto the same surface.

dsh-agent:
- NEW agent/session-start(agent, source) emit (once before turn 1; SessionStartSource
  startup|resume|clear|compact) — a pure notification, seeds context via inject().
- NEW agent/prompt-submit waterfall → PromptDecision (allow, optionally rewriting the
  prompt or attaching additionalContext, or block).
- RESHAPE agent/turn-continuation boolean → ContinuationDecision ({action:'stop'} |
  {action:'continue', reason?}; a continue reason is recorded as next-step steering).
- New HookContext envelope (required source — inject() would mislabel a missing one).

dsh-tools: split the single tools/execute waterfall into tools/pre-execute
(PreToolDecision allow/deny/ask gate) and tools/post-execute (PostToolDecision
accept/block, optionally replacing content or attaching additionalContext). Core
dispatch sits between as plain code; the tool body keeps its inner try/catch so a
thrown tool still reaches post-execute as an isError. ToolExecutionResult gains
additionalContext (ferried to the loop's per-step buffer). Input rewrite is
deliberately NOT offered (a proposed RFC designs it consistently).

dsh-session: new `rejected` TurnEndReason — a turn whose whole prompt batch was
blocked by prompt-submit.

agent-loop firing points: session-start emitted at create (source threaded —
startup for create/fork, resume for resume()); prompt-submit per drained message
with the always-open-turn rule (a fully-blocked batch is a zero-step rejected
turn); the continuation reshape; post-tool additionalContext buffered and appended
after all tool/results (adjacency). ACP codec maps rejected→cancelled.

A worked native-plugin example (interception.spec.ts) proves all four seams compose
end-to-end through the real loop with NO hook/* events (those belong to the bridge
lib). All existing tools/execute + turn-continuation tests migrated. The
tool-subagent abort test now aborts after a microtask so it still exercises the
live onAbort bridge (execute() awaits pre-execute before the body runs).

RFCs: implemented/feature/2026-06-30-interception-seams.md (the reshape) +
proposed/feature/2026-06-30-pre-tool-input-rewrite.md (the deferred rewrite design).
2026-06-30 17:11:18 +08:00
Hypatia May
da94bfd37c feat: add session fork service 2026-06-30 12:53:46 +08:00
Tianyi Cui
a821dcbe0d fix(events): address Codex confirmation review — strengthen /goal guard, fix doc drift
Second-round Codex review of the PR-A taxonomy change found four issues, all
verified against the code:

- The /goal regression guard asserted only that the steered content reached
  requests[1], which passes even with the hasSteering override (loop.ts) disabled:
  leftover steering is re-enqueued as a next-turn queued message and also lands in
  requests[1], one turn later. The guard now asserts the same-turn shape — ONE
  turn, TWO steps, a steering/message recorded before step 2 — which is the
  mechanism the override drives. Proven to fail red with the override disabled.
- The event-domain-semantics RFC's consequence list still described the pre-fix
  behavior (step marked open AFTER step/start, so no step/end owed). It now states
  the shipped behavior: the loop marks the step open BEFORE the append, so a
  throwing step/start listener gets a balancing step/end via closeStep().
- architecture.md's loop pseudocode said only continuation listeners force
  continuation; step/end session-event listeners (the /goal pattern) do too.
- The agent/turn-end JSDoc listed a `rejected` TurnEndReason that does not exist on
  this branch (it belongs to the later interception work). Removed it and
  regenerated the cordis catalog; `interrupted` (a real variant) stays.
2026-06-30 12:46:59 +08:00
Tianyi Cui
05b75abbca refactor(events): document event-domain semantics, drop step-boundary mirror emits
Pin the three-domain rule (session = durable fact log, agent = live runtime
surface, tools = registry/exec): a durable replayable fact is a SessionEvent; a
live interception or transient/live-object signal is an agent/tools Cordis
event. A boundary that is both is mirrored as an agent/* emit ONLY where a live
consumer needs the Agent handle.

Apply it to the boundary twins: drop agent/step-start and agent/step-end (no
production consumer needs the live Agent at a step boundary — consumers read the
durable step/start/step/end session events). Keep agent/turn-start/turn-end (the
stdio UI labels output by agent.id). Tests that observed step boundaries via the
removed emits now observe the durable session events; the pinned behavior is
unchanged.

Conservative subset of the proposed "remove boundary mirror events"
simplification; foundation for the Hooks subsystem's canonical event surface.
2026-06-30 10:32:55 +08:00
Hypatia May
0c4059fc84 Merge remote-tracking branch 'origin/master' into compact-basic-refactor
# Conflicts:
#	docs/cordis-catalog/events-and-services.md
#	examples/AGENTS.md
#	examples/coding-agent/cordis.yml
#	examples/coding-agent/tests/harness.ts
#	scripts/gen-cordis-catalog.ts
2026-06-30 09:13:15 +08:00
Yichen Jiang
f5bb544ded Merge remote-tracking branch 'origin/master' into codex/project-instruction-files 2026-06-29 21:54:54 +08:00
Yichen Jiang
21ae734839 fix: tighten project instruction path handling 2026-06-29 21:42:23 +08:00
Tianyi Cui
9f1caf7c5b fix(todo): address todo_write review feedback 2026-06-29 19:44:38 +08:00
Yichen Jiang
234ffe4604 refactor: move project instructions to prompt group 2026-06-29 13:41:32 +08:00
Yichen Jiang
86519889c5 Merge remote-tracking branch 'origin/master' into codex/project-instruction-files 2026-06-29 10:53:18 +08:00
Tianyi Cui
46e31d8481 feat(tool-todo): add the model-facing todo_write tool
Add @deepseek-ai/dsh-tool-todo (a new packages/todo/ group): a model-facing
todo_write(todos: [{content, status}]) tool with whole-list-replace semantics.
Each call appends the full list as a todo/write event to the calling agent's
session log; the current list is the most recent such event (last-write-wins).
Single-owner — a non-agent caller is rejected. Beyond the schema's
type/required/enum checks, execute rejects empty/duplicate content and more than
one in_progress task, narrowing the loosely-typed args into a real TodoItem[].

Both UIs render off the existing session/event: the stdio UI prints a glyphed
checklist; the ACP bridge maps the list to a `plan` sessionUpdate (todosToPlan
synthesizes the priority ACP requires; status maps 1:1). Wired into the
coding-agent, acp-agent, and snapshot example configs with a system-prompt nudge.

Tests: unit (schema, validation, append/replace, no-agent rejection, presentCall,
HMR-safety, Loader export-shape guard), full-loop integration through the agent
loop, the ACP todosToPlan mapping + stream-update arm, the stdio render arm, and
a session/load replay that re-emits the plan. New-group TS wiring added to
tsconfig.base/json/build. RFC + a doc-inventory sweep (architecture, packages
README, AGENTS layout, cookbook group list, example READMEs) ship with it.

The todo-plan ACP snapshot scenario is recorded separately (needs an API key).
2026-06-29 10:30:52 +08:00
Dudu-0223
89b27ad442 Merge remote-tracking branch 'origin/master' into fs-tool-clean
# Conflicts:
#	docs/architecture.md
#	docs/cordis-catalog/events-and-services.md
#	docs/core-data-structures/core.md
#	docs/module-graph.md
#	packages/README.md
#	scripts/type-equiv.manifest.json
#	tsconfig.base.json
#	tsconfig.typecheck.json
2026-06-28 17:24:45 +08:00
Dudu-0223
f9f475cbea fix: address codex review round 1
Correct the filesystem-wiring claims flagged by codex: no default/example
config wires the fs tools yet (the demo agents do file ops through bash), so
the docs and RFC no longer assert that "the default product config loads
dsh-file-context". They now state the intended stance — a deployment that
loads the fs tools is expected to also load dsh-file-context for
read-before-write/edit.
2026-06-28 14:02:51 +08:00
Dudu-0223
90dceea0e4 refactor(fs): make dsh-file-context an event-gate plugin, not a method service
Invert the tool↔policy control flow per the file-context event-gate RFC.
dsh-tool-fs becomes the executor — it reads/writes/edits through ctx.fs
directly, owns read windowing, and dispatches fs/write-expectation /
fs/edit-expectation (single-slot waterfalls) plus a contained fs/observed
emit. dsh-file-context drops its ctx.fileContext service and becomes a pure
event-gate plugin (observed-state + read-before-edit + version-guarded
write/edit, decided on those events). The provider's version guard becomes
optional so ctx.fs alone is a complete unconstrained text-storage seam:
removing the policy plugin gracefully loses the policy instead of breaking
the tool at a service-injection boundary.
2026-06-28 13:49:02 +08:00
Dudu-0223
d01f5f73b7 Add web capability seam: ctx.web, search/fetch providers, web tools
Introduce web access as a first-class capability seam so the model-facing
web tools stay stable while backends change. dsh-web owns ctx.web as a
provider registry with registration-order-independent selection and the
WebError taxonomy; dsh-web-search-exa, dsh-web-search-perplexity, and
dsh-web-fetch-local register capabilities into it; dsh-tool-web is the sole
owner of the model-facing web_search/web_fetch schemas, prompt sections, and
HTML-to-markdown presentation. Search and fetch are deliberately one seam.

Providers ship as namespace plugins that register into ctx.web (like an
LlmAdapter into ctx.llm), not key-owning services, since multiple search
providers cannot each own the key. Tool registration follows product
enablement, not backend availability, so load order/credentials never enter
the model contract; the seam resolves the provider at execution time and
surfaces a structured WebError otherwise.

Moves the RFC to implemented/ amended to match what shipped. Example/app
configs are intentionally not wired yet (RFC migration step 6).
2026-06-26 19:12:13 +08:00
Dudu-0223
ef37ce3b9d refactor(fs): split filesystem seam into provider ctx.fs + policy ctx.fileContext
Implements the split-the-filesystem-seam RFC. ctx.fs shrinks to a text-storage
provider seam (resolve/stat/readText/streamText/writeText/editText with branded
FsTargetKey/FsVersion and an explicit FsWriteExpectation); the new
dsh-file-context package owns the model-facing policy (read windowing,
observed-state, write/edit freshness) as the concrete ctx.fileContext service.

Authorization is now freshness-based rather than full/partial view: a windowed
read records the file version and authorizes a later edit when the file is
unchanged, removing the dead-end where reading lines 100-150 of a large file
could not edit line 120. editText stays a provider primitive so version guard +
literal match + atomic rewrite remain one critical section, and the stale check
runs before matching so a stale edit reports FS_STALE_VERSION. tool-fs injects
fileContext, never reaching around to ctx.fs (the no-bypass contract).
2026-06-26 17:23:18 +08:00
Hypatia May
b13586ff8e docs(compact): align seam docs with the pre-step seam and record session/invariants changes (CBR-003)
Codex round 1 CBR-003: several docs still described compaction as an
`agent/request` waterfall concern, and the implemented compaction RFC
claimed "No changes to dsh-session or dsh-invariants" while the diff
changed both.

- Package READMEs / JSDoc (agent, agent-loop, system-prompt, compact,
  compact-basic): compaction now lives on the serial `agent/pre-step`
  seam (fired after turn/start, before step/start); the structural guard
  is tool-pairing balance (`isToolPairingBalanced`), not step-alignment;
  the convergence bound is strict (`>=` rejects).
- architecture.md / core-data-structures/compaction.md: same seam +
  predicate + dispatch-mode updates; regenerated cordis catalog.
- Implemented compaction RFC, updated in place to describe shipped
  reality: the seam is `agent/pre-step` (@mode serial) fired before
  step/start; alignment is surface tool-pairing balance; the convergence
  invariant rejects `>=`; and the "no dsh-session/dsh-invariants changes"
  claim is corrected — dsh-session gains the tool-pairing predicate and
  dsh-invariants drops its `start <= end` replace assertion (a positional
  replace makes start > end normal).
2026-06-26 13:51:45 +08:00