Commit Graph
6049 Commits
Author SHA1 Message Date
imccyu 6d2e5a7cd7 feat: command.execute returns the lifecycle pairing id ({matched, commandId?})
CommandService.execute now returns a CommandExecution — the normalized
result plus the commandId minted for its command/run/command/done records —
and the wire admission value carries commandId exactly when matched, so the
issuing client can correlate its RPC acknowledgment with the flow node the
lifecycle events produce. apiproxy api/schema/handler, the connection
fixture, and the TUI/plan/goal consumers follow the new shape.
2026-07-27 23:07:13 +08:00
imccyu 2ebaa30c6d refactor: structured command/run payload {commandId, name, args, source}
The line field is deleted (pre-release, no shim): name and args are
parseCommand's own split — name plus verbatim rawInput with its separator
whitespace — so a consumer (a projection unit folding its own command
records, a rich command card) never re-parses a line. CommandNode mirrors
the split (name/args, both null on a run-less cross-window node); the
generic card rebuilds its display line as /name + args. The connection
fixture logs the same structured payload.
2026-07-27 23:06:52 +08:00
imccyu 4fcfcf32d5 test: replace tuple casts with structural lifecycle assertions in command specs
Two aggregate-typecheck errors the package-level tsc -b (rootDir=src) never
saw: the commands spec's two-tuple as-cast over the lifecycle slice
(TS2352, host aggregate) becomes a plain commandId projection, and the
fixture spec still read the deleted result member off the pure-admission
execute value (TS2339, client aggregate) — the matched bit is now asserted
as the whole response shape.
2026-07-27 23:06:52 +08:00
imccyu 4ddec0ba2f refactor: command.execute degrades to pure admission; composer notice channel retired
The wire response now carries only the matched bit — CommandExecuteResult
is deleted from the api, schema, and client mirrors (pre-release, no shim);
outcomes ride the durably logged command/run/command/done pair broadcast on
the mux stream and render as flow nodes. ui-command's runDetached→noticeFor
outcome routing is retired: admitted commands surface nothing through the
composer, while admission misses (matched:false, syntax feedback) and
transport failures keep their immediate notice. The connection fixture
mirrors the host: an admitted command appends the lifecycle pair to the
session log instead of returning result text.
2026-07-27 23:06:49 +08:00
imccyu ba928c5517 feat(gui): generic command flow node and the conversation.chat.commandview keyed slot
The FoldAdapter folds the log-only command/run + command/done pair (paired
by commandId) into a CommandNode outside the surface fold and merges the
nodes into the flow by seq; cross-window cuts soft-fall like tool pairs (a
done-only window builds the node from the done, a run with no done renders
as still executing). ChatView renders command nodes through the new keyed
'conversation.chat.commandview' hole (key = command name) with
GenericCommandCard — a stripped-down GenericToolCard showing the command
line and outcome text — as the render-site fallback, so any slash command
renders durably with zero registration and survives refresh, other tabs,
and resume via the mux-broadcast events.
2026-07-27 23:05:21 +08:00
imccyu 4e50369eb6 feat: durable command lifecycle logging in the executor (command/run + command/done)
CommandService.execute appends the log-only pair around every resolved
handler — run before invocation, done at settlement, including thrown and
aborted handlers (kind:'error'); admission misses log nothing. commandId is
minted monotonically per instance; per-session appends serialize through a
tail queue over SessionStore.appendOutOfBand (zero-step wrap on an idle log,
direct join inside an open turn). The invariant companion now asserts the
pairing relation (unique run ids; a done requires a prior in-log run).
CommandSource is a minimal merge-extensible map (user variant only).
Dependent benches mount SessionStore; TUI/e2e snapshots re-recorded for the
executor's durable-append timing and the /status event counts.
2026-07-27 23:04:57 +08:00
Tianyi Cui 676fd97319 Merge branch 'master' into codex/bump-pi-ai-0.82.1 2026-07-27 23:01:27 +08:00
imccyu e900ebd4c6 feat: todos session-projection provider in tool-todo (knife-4 domain probe) 2026-07-27 22:58:58 +08:00
imccyu 555a6aa7cc refactor(gui): read the typed projections block off the history response
The wire type now carries projections?: SessionProjectionsBlock (host-base
landed), so the structural projectionsOf narrowing and its TODO(gui) go away —
Session reads result.value.projections directly at all three installWindow
sites. ProjectionsBaseline stays as the cell framework's structural twin
(React-free layer keeps depending on the type table only) with values typed
Partial<SessionProjectionMap>; the erased walk moves inside resetBaseline
where per-key typing is re-established by schema.parse.
2026-07-27 22:58:57 +08:00
imccyu 95a3794e68 refactor(gui): source SessionProjectionMap from the interface package's pure-type outlet
Swap the client runtime's parallel-construction placeholder for
import type from @deepseek-ai/dsh-session-projection/types — the zero-import
outlet, never the package root, whose dsh-agent → dsh-session chain would drag
the host Context.sessions merge into the client program. One type table end to
end (host provider, wire block, client cell, React hook); the spec's test key
now declare-merges the real module. Adds the workspace dep and the tsconfig
project reference.
2026-07-27 22:58:57 +08:00
imccyu 70cc77eab0 feat: pure-type /types outlet for dsh-session-projection (client-aggregate import path) 2026-07-27 22:58:57 +08:00
imccyu 65e41f1cb0 feat: projections block on the session.history tail page 2026-07-27 22:58:56 +08:00
imccyu fa331c6399 feat: dsh-session-projection seam package (ctx.sessionProjections registry) 2026-07-27 22:58:56 +08:00
imccyu 90addbf53c feat(gui): useProjection — the fifth framework hook seat through the standard kit
React half of the session-projection client base: the renderer contract gains
an open-key projections face on SessionMaybeProvideInfo (cellOf(key), distinct
from the static hooks roster), web-react mints projectionHook (per-bundle cache;
per-cell uSES binding via the shared observableHook cache; unresolved keys read
undefined through the absent source so hook order stays constant), standardKit
delivers kit.useProjection, and the runtime merges UseProjection into
SessionStandardProps/SessionMaybeStandardProps (overloads mirror useSession).
3 jsdom specs (kit delivery + live re-render, selector over undefined, faceless
bundle = all absent); existing direct-prop-feed specs gain the one-line stub the
new required seat mandates.
2026-07-27 22:58:53 +08:00
imccyu fbebe1757a feat(gui): client projection cells — session dispatch seam, one-watermark fold, service roster
Object layer of the session-projection RFC client base: ProjectionCellSpec/
ProjectionCell/ProjectionCellSet with the single seq-watermark rule (live and
window-replace events share one filter; baseline reset re-seeds value+watermark
unless a newer commit applied; absent key = capability absent), Session
dispatch at appendLive/installWindow (projections block read structurally,
TODO(gui) switch to the interface package), SessionsService.registerProjectionCell
roster (live scopes now + future scopes at mint; disposer sweeps every session),
and the provideInfo projections face (key-addressed bare cell sources).
15 object-layer specs: watermark no-rollback, late-baseline seq rule,
capability absence, schema-failure degrade, duplicate-key throw, resync e2e.
2026-07-27 22:56:58 +08:00
Chinesezjc 4e8fd98110 Merge remote-tracking branch 'origin/master' into fix/worker-timer-clamp 2026-07-27 22:45:00 +08:00
Tianyi Cui 8a952ab433 Merge remote-tracking branch 'origin/master' into worktree/pr628-merge-20260727
# Conflicts:
#	.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.md
#	docs/architecture.i18n.yaml
#	docs/config-catalog.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/llm-streaming.i18n.yaml
#	docs/core-data-structures/llm-streaming.md
#	docs/core-data-structures/llm-streaming.zh.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	examples/headless-agent/tests/headless.snapshot.ts
#	packages/compact/compact-basic/tests/compact-loop-repro.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/src/loop.ts
#	packages/examples/agent-spine-demo/README.md
#	packages/llm/README.md
#	packages/llm/llm-deepseek/src/adapter.ts
#	packages/llm/llm-pi-ai/src/adapter.ts
#	packages/llm/llm-retry/README.md
#	packages/llm/llm/README.md
#	packages/llm/llm/src/index.ts
#	packages/llm/llm/tests/service.spec.ts
#	packages/support/llm-replay/src/index.ts
#	packages/support/llm-replay/tests/llm-replay.spec.ts
2026-07-27 22:44:43 +08:00
Tianyi Cui 7f333d8837 Merge branch 'master' into sdk/ts-client-and-subagent 2026-07-27 22:41:23 +08:00
Tianyi Cui 55247b80b2 Merge origin/master (tsx lint lanes, session-telemetry-otel example dep) 2026-07-27 22:35:43 +08:00
Tianyi Cui 096d2dc06a Merge branch 'master' into xtr/agent-loop-message-machine 2026-07-27 22:34:21 +08:00
Tianyi Cui 7a60a523f9 Merge branch 'master' into feature/cordis-temporary-tools 2026-07-27 22:26:49 +08:00
imccyu cdd4d59ea0 chore(lint): clear the semantic .tsx backlog
Hand fixes for the findings --fix cannot touch, mirroring the fixes
already applied on the fe-docs feature branch (same file, same shape)
so its eventual rebase resolves cleanly:

- restore the return the no-confusing-void-expression autofix ate in
  useAbsentSnapshot (typed S | undefined; hook call kept for hook-order
  stability, undefined returned explicitly);
- re-type DOM queries the no-unnecessary-type-assertion autofix broke:
  getByRole<HTMLButtonElement>(...) generics instead of the removed
  as-casts (the eslint program and the client tsconfig aggregate
  disagree about these casts; the generic form satisfies both);
- justified eslint-disable for the deliberate legacy paths: keyCode 229
  IME-composition detection, execCommand clipboard fallbacks, lib.dom
  clipboard optionality, and the any-typed Reflect.get/this probes in
  test fakes;
- drop the dead react/no-danger directive (eslint-plugin-react is not
  loaded, so the rule never applied) keeping its shiki rationale;
- delete the tautological 'Z' comparison and the renameTarget null
  check already implied by renameBlocked;
- css-module non-null assertions replaced by type widening
  (Button className, TAG_CLASS Record) per the established pattern;
- misc: max-len comment wraps, void generic drop in the deferred test
  helper, unused type imports, floating selectWorkspace promises voided,
  member-delimiter newlines in inline type literals.
2026-07-27 22:23:41 +08:00
imccyu 2adf44fb80 chore(lint): declare contract callbacks property-style
unbound-method flags destructuring a method-style member (method
signatures are bivariant and exempt from the this-context check).
These contract members are all plain callbacks — declare them as
property-style function types so consumers can destructure them
without a false this-binding hazard. Type-level only.
2026-07-27 22:23:10 +08:00
07akioni 560dc1d8d8 Merge branch 'master' into fix/todo-tool-ui 2026-07-27 22:22:40 +08:00
Chinesezjc ff4c9d9f9d Merge remote-tracking branch 'origin/master' into fix/pty-handoff-grace 2026-07-27 22:17:23 +08:00
Tianyi Cui ed8f9c2808 refactor: rename the backend to dsh-subagent-dsh-sdk
The group's convention is package suffix == provider default
(subagent-acp/'acp', subagent-spawn/'spawn', subagent-fork/'fork'), and the
provider default became dsh-sdk in the last review round — so the package
follows: @deepseek-ai/dsh-subagent-dsh-sdk at
packages/subagent/subagent-dsh-sdk, plugin name subagent-dsh-sdk,
diagnostics prefixed subagent-dsh-sdk:. The dsh echo has precedent
(dsh-llm-deepseek). Directory, fixture path, knip/tsconfig/examples
registrations, catalogs, READMEs (en+zh), and the Agent Note follow; the
sdk-client dispose ladder moves to its own module (src/dispose.ts) with the
deterministic FakeChild tier tests restored alongside it.
2026-07-27 22:17:10 +08:00
Tianyi Cui 87a249106f Merge origin/master: port the SDK stack onto the subprocess seam
Master's #660 replaced dsh-subagent-subprocess with the dsh-subprocess
capability seam (ctx.subprocess + scrubbedParentEnv, tree-scoped teardown)
and moved subagent-acp onto it. Convergence for this branch's packages:

- The shared out-of-process provider vocabulary this branch had grown in
  the deleted library (NO_START_CAPABILITIES, assertPositiveFinite, cwd
  resolution, settleRunResult, subprocessRunHandle) moves into the subagent
  seam package as out-of-process.ts — it enforces subagent-seam contracts,
  not process mechanics, and both out-of-process backends now import it
  from there (subagent-acp keeps master's shape otherwise).
- subagent-sdk spawns THROUGH the SDK client (the subprocess README's
  documented exception for SDK-managed transports) and now applies the
  seam's scrubbedParentEnv() + explicit-env merge in place of the deleted
  buildChildEnv.
- sdk-client inlines the EOF→SIGTERM→SIGKILL ladder as private helpers (it
  runs outside any harness context, so it cannot ride ctx.subprocess).
- The child harness fixture gains the now-required dsh-subprocess-local
  entry for bash-local; the fixture cordis.yml keeps exercising the
  shipped provider default.
2026-07-27 21:52:40 +08:00
_Kerman fb1dc6d117 Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/session.i18n.yaml
#	docs/event-producer-consumer.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
2026-07-27 21:51:37 +08:00
imccyu 49c2e85ac7 chore(lint): apply eslint auto-fixes across the .tsx backlog
Mechanical --fix output over the newly linted .tsx files (indent,
arrow-parens, comma-dangle, member-delimiter-style, unnecessary type
assertions), plus the three generic-arrow test hooks converted to
function declarations up front: the comma-dangle fixer strips the
<T,> disambiguation comma and turns them into parse errors otherwise.
2026-07-27 21:49:40 +08:00
Chinesezjc e5ea0efdfb Merge remote-tracking branch 'origin/master' into fix/worker-timer-clamp 2026-07-27 21:45:01 +08:00
Tianyi Cui 605df45928 Merge remote-tracking branch 'origin/master' into feat/telemetry-otel-plugin 2026-07-27 21:32:50 +08:00
Tianyi Cui 0af16387ae fix(telemetry): rename record waterfall 2026-07-27 21:30:28 +08:00
NI0317 1ef285d038 Restore Cordis mount and unmount names
Keep temporary lifecycle descriptions and UI labels explicit.
2026-07-27 21:20:06 +08:00
_Kerman ed67ad53d2 refactor(agent): return request retry action 2026-07-27 21:17:49 +08:00
Chinesezjc 583d7e18fd Merge remote-tracking branch 'origin/master' into fix/pty-handoff-grace 2026-07-27 21:17:37 +08:00
Chinesezjc 207bab0c21 Merge remote-tracking branch 'origin/master' into fix/question-composer-row-shrink 2026-07-27 21:11:15 +08:00
Turtle 4efc90d798 cleanup(tui): give xml-tool-output.ts a module header like its peers
Every other tui source file opens with a multi-line description ending
in @module; xml-tool-output.ts had only a one-line header. Align it.
2026-07-27 21:04:11 +08:00
Turtle 46bbbce109 refactor(tui): split createTuiChat into chat/ sub-controllers
Extract model-command, questions, and resume sub-machines from the
~1600-line createTuiChat closure into src/chat/ factories that take
explicit dependency bundles (shared ChatChannelDeps/ChannelNotice).
Reorganize src/ so chat/ holds all chat-channel concerns (former input
and session/ files move under it); xml-tool-output moves to components/;
TuiRuntime/TuiResumeHost move to runtime.ts. index.ts drops 2067->~1530
lines. Behavior identical: 167 tests and all TUI snapshots pass unchanged.
2026-07-27 21:04:11 +08:00
kingwl 7d4b984037 Merge remote-tracking branch 'origin/master' into feat/telemetry-otel-plugin
Resolutions: regenerate the conflicted generated docs (cordis services
catalog, event-producer-consumer, module-graph); take master's
packages/README pair and re-insert the telemetry row on both sides;
re-record the README and session-doc translation pairs.
2026-07-27 20:26:21 +08:00
Chinesezjc ccab63cc79 Merge remote-tracking branch 'origin/master' into fix/pty-handoff-grace 2026-07-27 20:20:28 +08:00
Chinesezjc 82f66f8fde Merge remote-tracking branch 'origin/master' into fix/question-composer-row-shrink 2026-07-27 20:20:16 +08:00
kingwl bf76c52d76 fix(telemetry): reject non-positive maxExportBatchSize at plugin load
Review finding, pinned red-first: the SDK accepts
processor.maxExportBatchSize <= 0 (or fractional), but its shutdown
drain then splices empty batches without consuming the queue —
disposing telemetry hangs forever whenever records are queued. The
constructor now rejects a non-positive-integer batch size before
building the SDK processor, per the misconfiguration-fails-loud rule;
everything else in the processor block remains the SDK's verbatim
passthrough.
2026-07-27 20:11:30 +08:00
Ziya 91d85773ac Merge branch 'master' into feat/workspace-native-folder-picker 2026-07-27 08:06:44 -04:00
Chinesezjc 393bbe8dea Merge remote-tracking branch 'origin/master' into fix/worker-timer-clamp 2026-07-27 20:06:15 +08:00
Tianyi Cui 08851a1a3e Merge branch 'master' into turtle1999-patch-1 2026-07-27 19:57:43 +08:00
_Kerman c6073f07c2 Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/architecture.md
#	docs/architecture.zh.md
#	docs/core-data-structures/core.i18n.yaml
2026-07-27 19:55:55 +08:00
Tianyi Cui a843c37749 Merge branch 'master' into codex/bump-pi-ai-0.82.1 2026-07-27 19:55:54 +08:00
Chinesezjc 63623a87e3 Merge remote-tracking branch 'origin/master' into fix/worker-timer-clamp
# Conflicts:
#	docs/module-graph.md
2026-07-27 19:54:23 +08:00
Chinesezjc 8f06c561ee docs(code-runtime): state the maxWallMs upper bound in the public Config contract
The load-time range check rejects a maxWallMs above Node's maximum
setTimeout delay, but the constraint appeared only in the README design
section. Deployments reading the Config field JSDoc, the generated config
catalog, or the README config summary saw maxWallMs described as a
positive finite wall-clock ceiling, so an out-of-range value looked valid
until plugin load failed.
2026-07-27 19:53:57 +08:00
kingwl a72436105b docs(telemetry): state the crash-repair export semantics for resumed streams
Review finding: synthetic turn closers written by SessionPersistence
.load() at crash-resume sit below firstLiveSeq and are never exported,
leaving the remote turn unbalanced. Kept deliberately — exporting a
synthetic closer cannot complete a turn whose real tail records died
in the crashed process's queue; it can only make an incomplete turn
look closed. The OTel README now states the receiver rule (a
never-closed turn on a resumed stream marks the previous process dying
inside it; a later clean shutdown marker attests only to the resumed
process's exit), and the revival Agent Note records why the repair
suffix stays local.
2026-07-27 19:49:19 +08:00