Commit Graph

1775 Commits

Author SHA1 Message Date
Yichen Jiang
33e3871c77 Merge remote-tracking branch 'origin/master' into claude/unified-environment-credentials-c8841a
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-24-web-config-tree-boot-and-transport-layering.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-24-web-config-tree-boot-and-transport-layering.zh.md
#	.agents/notes/implemented/architecture/2026-07-29-request-level-llm-config-credentials.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-30-credential-boundaries-and-atomic-registration.i18n.yaml
#	apps/cli/package.json
#	apps/cli/src/web.ts
#	examples/mcp-memory/README.i18n.yaml
#	packages/cordis/repository-plugin/README.i18n.yaml
#	packages/credentials/credentials-local/README.i18n.yaml
#	packages/credentials/credentials-local/README.zh.md
#	packages/llm/llm-deepseek/README.i18n.yaml
#	packages/web/web-search-deepseek/README.i18n.yaml
2026-08-05 12:40:20 +08:00
Yichen Jiang
590b76a7f0 fix(config): close the review findings on configuration source ownership
Two had real security consequences:

The bootstrap rejection ran on npm dotenv's parser while process.loadEnvFile
applied the file with Node's own. Two independently maintained dialects meant
the check and the thing it guards could disagree: a name Node accepts but the
checker misses would reach process.env unchecked, and BASH_ENV there runs a
file of the project's choosing on every `bash -c` the bash tool issues. Parse
once with node:util's parseEnv — the same engine loadEnvFile uses — and assign
the entries already checked, which also drops the dotenv dependency.

llm-pi-ai still returned a literal profile.apiKey ahead of everything, and it
registers a settings namespace, so the defect removed from llm-deepseek
survived intact in its design twin. The field is gone from the profile schema,
the resolution path, and the tests.

The rest are consistency and documentation defects the review named:

- verify-config-source-ownership did not scan the Python runtime's bundled
  cordis.yml, which still inlined apiKey and baseURL. Both are covered now, and
  the line-anchored INLINE_DENY documents that it is a tripwire, not a parser.
- The deny list missed NODE_TLS_REJECT_UNAUTHORIZED, the askpass hooks, the
  GIT_CONFIG_* redirections, and PYTHONHOME — all implied by its own stated
  rule about what a variable does.
- Snapshot lookups folded case on Windows, where environment names are
  case-insensitive and an exact-match Map could miss a higher-ranked layer.
- The credentials note claimed a read-time permission check was "not taken"
  while this PR implemented it; the credentials-local README still described
  two layers, live process.env reads, dotenv-era limitations, and a renamed
  anchor; the llm-deepseek README still advertised the removed literal apiKey;
  and web.ts and base.cordis.yml kept personal-overlay wording.
- The ownership note's literal-apiKey claim now names its scope: the
  web-search providers keep a literal field but register no settings
  namespace, so nothing can shadow a stored credential through them.
2026-08-05 11:18:06 +08:00
xjt
7bd111b2af Merge origin/master into xjt/proofreading-active-docs-2-apply 2026-08-05 10:57:53 +08:00
imccyu
59133cb8a3 fix(npm): promote dsh after baseline publication 2026-08-05 01:44:13 +08:00
imccyu
957050c47e fix(npm): probe installed Web startup 2026-08-05 01:15:48 +08:00
imccyu
50ae954ebf fix(npm): publish vendored baseline packages 2026-08-05 01:15:47 +08:00
imccyu
ca27512529 fix(packages): omit source publication payloads 2026-08-05 01:15:19 +08:00
imccyu
7557de1131 fix(packages): ship web and theme assets 2026-08-05 01:11:50 +08:00
imccyu
958e1bd157 fix(npm): harden baseline publication 2026-08-05 01:11:49 +08:00
imccyu
b7c0e4ea08 fix: dsh exports
fix: pty-local postinstall
2026-08-05 01:11:49 +08:00
imccyu
6a5f0e169f docs: rfc 2026-08-05 01:11:49 +08:00
Huanqi Cao
020ce50414 fix(picker): correct crash-isolation and DPI claims, wire the built-worker guard, and tidy round-four nits
The round-four review's v6 pass found three factual gaps and the v5 pass two
nits. Correct them before merge:

- The in-process note claimed a koffi signature mistake is 'contained to
  the worker thread' — worker_threads share the process, so a native access
  violation takes down the whole Node process with no PowerShell fallback.
  State the real blast radius and record the deferred pkg-VFS worker-spawn
  arm in Consequences (both languages, pairing re-recorded).
- The 2026-07-27 picker note claimed unconditional 'per-monitor-v2 DPI';
  PMv2-less hosts (Server 2016 / Win10 1607) cascade to per-monitor or
  system-aware. Say 'the best thread DPI awareness the host accepts'
  (both languages, pairing re-recorded).
- built-worker.e2e.ts was not in any keyless gate (vitest.e2e config is
  not part of the default unit run and builtBinSmokeGate's explicit list
  missed it), so lib/worker.cjs load regressions passed keyless CI. Add it
  to builtBinSmokeGate alongside the workflow-workerthread sibling.
- Remove the dead trailing 'void bindings' in win32-dialog-logic.spec.ts
  and give native-picker.spec.ts the sibling module header it lacked.
2026-08-05 00:31:43 +08:00
Huanqi Cao
acda0e39bc Merge remote-tracking branch 'origin/master' into feat/pwsh-tool 2026-08-04 20:39:17 +08:00
xjt
c522053cef Merge origin/master into xjt/proofreading-active-docs-2-apply 2026-08-04 19:51:18 +08:00
Huanqi Cao
39b0695d48 Merge remote-tracking branch 'origin/master' into feat/pwsh-tool
# Conflicts:
#	apps/cli/composition.md
#	docs/testing.i18n.yaml
#	docs/testing.md
#	docs/testing.zh.md
2026-08-04 17:54:45 +08:00
Yichen Jiang
a45aa28ca6 Merge branch 'master' into claude/unified-environment-credentials-c8841a
Master removed the TUI package, the `meta` and `upgrade` subcommands, and
`--config-replace`, and made raw `dsh` require a `--config` overlay. Resolved
onto that shape:

- Dropped this branch's TUI edits with the surface itself, including
  `tui.cordis.yml`, `runTui`, and the TUI keyless PTY smoke.
- Dropped the `--config-replace` plumbing rather than reintroducing a flag
  master deliberately removed. The gap this branch fixed remains: `dsh -p`
  still could not name its composition, so it keeps `--config`.
- Kept this branch's deletion of the personal `$DSH_HOME/config.yaml` layer,
  which master still carried, and provided the environment snapshot in the new
  raw `runConfig` surface alongside web and headless.
- Ported the headless shutdown PTY test off the personal overlay onto a named
  `--config` file, which is what proves that flag now exists on `-p`.
2026-08-04 17:51:44 +08:00
xjt
2db712eec7 docs(i18n): proofread active Chinese documentation 2026-08-04 17:36:14 +08:00
imccyu
a36c641db6 chore(docs): refresh WebSocket API catalogs 2026-08-04 16:21:09 +08:00
Yichen Jiang
0512b12714 feat(config)!: one ordering for configuration sources, and a bootstrap deny rule
$DSH_HOME/.env had just become an ordinary environment layer, which left the
harness resolving user-facing values from a flattened process.env that could
no longer say where a value came from. A key stored through the web page
stayed shadowed by an older key in the user's own .env. An endpoint could be
redirected by the project: the invoking directory's .env is materialized like
every other layer, and a base URL decides where a resolved API key is sent, so
a DEEPSEEK_BASE_URL written into a model-editable workspace would send the
user's credential — and the prompts carrying their code — to whatever host
that file named.

Give every user-facing value one ordering, with four kinds of source:

  explicit for this run     per-operation override, CLI argument
  > authored by deployment  --config / --config-replace
  > this launch's shell     inherited process environment
  > product-managed store   settings.yaml, .credentials.yaml
  > discovered file         $DSH_HOME/.env
  > defaults                schema default, shipped base, public default

The domains differ only in which tiers exist. The earlier split — credentials
ranking the environment over the managed file while settings ranked over the
environment — was inconsistent: the distinguishing fact is who authored the
source, not the domain.

packages/util/environment owns an immutable snapshot with per-layer
provenance. getFrom(name, sources) searches only the layers a caller names,
and omitting one is a refusal rather than a demotion: the adapters ask for
['process', 'user-env'], so no reordering can let a project file back into a
decision it was excluded from.

isBootstrapOnly rejects, before anything is materialized, any .env setting a
variable that governs how a process launches (PATH, SHELL, NODE_OPTIONS,
LD_PRELOAD), where code or model-visible instructions load from (the whole
DSH_* namespace, HOME, XDG_*), or how the network is reached (proxy and CA
variables). The namespace is denied wholesale so a switch added later cannot
become settable by being forgotten, and there is no opt-out.

verify-config-source-ownership keeps both rules: no unregistered process.env
read under packages/*/*/src (26 allowlisted with reasons), and no apiKey,
baseURL, or headers inlined from the environment in shipped Cordis config —
removing those inlines is what makes the deployment tier meaningful.
2026-08-04 16:17:32 +08:00
imccyu
6c6d933732 fix(client): load plugin bundles as external scripts 2026-08-04 14:18:47 +08:00
Turtle
10bb9cbf4a cleanup: remove TUI package and legacy dsh entrypoints 2026-08-04 13:20:28 +08:00
Huanqi Cao
37bceb7dad Merge branch 'feat/ripgrep-packaged-binary' into feat/pwsh-tool 2026-08-02 22:29:44 +08:00
Huanqi Cao
ffb7d681f4 Merge remote-tracking branch 'origin/master' into feat/ripgrep-packaged-binary 2026-08-02 22:28:21 +08:00
Huanqi Cao
b2838fb2be fix(pwsh): close the remaining review threads
- scrubbedParentEnv folds case before the DSH_ prefix check (Windows env
  names are case-insensitive; a parent dsh_* entry read back as \*
  in the child) and the service spec pins the lowercase probe.
- The acp.snapshot.ts pwsh probe follows resolvePwshPath() like the package
  suites, so a Windows host with only an install-location pwsh still runs
  the scenario.
- pwsh-tool-turn is re-recorded around [Console]::Out.Write('PWSH_OK'):
  the fixture carries no platform newline, so one recording replays on
  Windows and POSIX alike (record + refresh; replay-verified keyless).
- The pwsh-local Known Limitations bullet drops the self-defeating no-op
  advice: & { } is scoped to param(...), using/#requires scripts run from a
  file (both languages, pairing re-recorded).
- The capability-seams graph moves ctx.bashEnv ownership to bash-env and
  lists pwsh-local/tool-pwsh on the ctx.bash seam (source updated,
  docs regenerated).
- The tool-bash presenter fixture retires the stale 'command aborted'
  literal for the shipped 'tool call aborted' message.
2026-08-02 21:46:53 +08:00
Huanqi Cao
7b7525c091 fix(fixtures): repair the cancel-fixture abort error placement; exempt pwsh-local coverage on pwsh-less hosts
The hand-edit in 348ab41151 put the seq-17 abort error inside the tool-result
message and dropped a closing brace, breaking every JSONL consumer; tool-calls.ts
appends 'error' as a data-level sibling of 'message' (the seq-19 shape), so the
fixture now matches the emitter.

Coverage: pwsh-local's executor suites self-skip without a real pwsh, which left
per-file 100% unreachable on pwsh-less contributor hosts (mirror of the existing
windowsCoverageExclusions contract). A PATH-only probe exempts only
pwsh-local/src/index.ts; CI runners ship pwsh and still enforce the full bar.
docs/testing.md (+zh, pairing re-recorded) names the prerequisite; the testing.md
budget rises 1120->1150 because the coverage-gate contract genuinely grew.
2026-08-02 21:28:22 +08:00
Huanqi Cao
ed39ff096f test(fixtures): pin the TOOL_ABORTED message and keep the pwsh fixture replayable; restore trimmed testing.md clauses 2026-08-02 20:07:26 +08:00
Huanqi Cao
5e437d3996 docs(pwsh): scope the encoding claim, document the PATH probe and preamble limitation, and fix catalog requires lists 2026-08-02 19:37:45 +08:00
Huanqi Cao
a30f3f1a04 docs(catalog): refresh the pwsh tool entry to the parity tool and fix requires lists 2026-08-02 19:00:51 +08:00
Tianyi Cui
089f921663 Merge pull request #983 from deepseek-harness/codex/install-pnpm-stderr
fix(install): show pnpm version errors
2026-08-02 17:41:43 +08:00
Huanqi Cao
ab4963c43d fix(scripts): mount bash-env in the tool-catalog harvest 2026-08-02 16:25:27 +08:00
Huanqi Cao
1361e9718e Merge remote-tracking branch 'origin/feat/ripgrep-packaged-binary' into feat/pwsh-tool
# Conflicts:
#	apps/cli/package.json
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
2026-08-02 16:22:24 +08:00
Huanqi Cao
782894ff8c Merge remote-tracking branch 'origin/master' into feat/ripgrep-packaged-binary 2026-08-02 16:18:46 +08:00
Huanqi Cao
d73888478a feat(bash-env): extract the shared DSH_* environment registry into its own package 2026-08-02 14:17:46 +08:00
Huanqi Cao
bf47f14bb9 Merge remote-tracking branch 'origin/feat/ripgrep-packaged-binary' into feat/pwsh-tool
# Conflicts:
#	apps/cli/package.json
2026-08-02 13:08:56 +08:00
Dudu-0223
431fb4b035 feat(subagent): add explicit child reports 2026-08-02 12:51:10 +08:00
Dudu-0223
774ee34b9a feat(subagent): catalog one-shot child sessions 2026-08-02 12:51:09 +08:00
Dudu-0223
2e5c439ecf fix(subagent): decouple child listing runtime 2026-08-02 12:51:09 +08:00
Dudu-0223
4240c7dd7b feat(subagent): durable child catalog and list_agents
Implements the durable-subagent-catalog RFC: SubagentControlService.listChildren()
enumerates a parent's direct continuable children from one sessionQuery trace,
validates each child's sole subagent/descriptor event (now carrying the durable
creation label), and returns one ordered SubagentListEntry[] with per-child
corrupt/unsupported/unavailable diagnostics. The list_agents tool ships as a
separately loadable plugin of dsh-tool-subagent-control requiring sessionQuery
at load; send_message stays usable without it.
2026-08-02 12:51:09 +08:00
Dudu-0223
a91b20f6be fix(subagent): close continuation lifecycle gaps 2026-08-02 12:51:08 +08:00
Dudu-0223
853f4d5cfb refactor(subagent): drop host-user authority and split lifecycle publication
Remove the host-user continuation capability and the public residency query,
then separate the seam's public event payloads from its internal lifecycle
control interfaces.

`followup()` now takes the exact live direct parent `Agent` instead of a
`SubagentAuthority` union. No production adapter ever supplied user authority,
so the `UserAuthorityGrant` brand token existed only to stop a forged
discriminant from bypassing the direct-parent check — deleting the branch
retires the token, its mint method, and that attack surface together.

Narrowing `parent` from `Agent | undefined` to `Agent` removes three special
cases, including the path where a parentless epoch dispatched its lifecycle
events unscoped. Scoped-versus-global dispatch is now decided by the event, not
by whether a caller happened to have a parent.

`activationState()` had no caller; `ActivationState`, `ActivationObserver`, and
`ContinuationHost` are package-private.

New `src/lifecycle.ts` owns the contained emitter, the one-shot run observer,
and the Activation observer, while `SubagentRunInfo`/`SubagentRunEndInfo` move
to `src/types.ts` beside the other consumer-facing contracts. Those payloads are
public API — dsh-jsonrpc, hooks-claude, and the package invariant all consume
them — whereas the observer is a contract between two in-package collaborators,
so they no longer share a home merely for both being lifecycle-shaped. The
service keeps ownership of the scope carrier: `scopeTarget()` composes the
service's own context filter, so a narrowed stand-in would silently change
scope filtering.

Also drops now-unused dsh-tasks-local and dsh-tool-tasks dev dependencies, and
corrects the README claim that a pre-residency failure emits a terminal edge —
that path only ever rethrew.
2026-08-02 12:51:08 +08:00
Dudu-0223
ae6976cbbd docs(subagent): regenerate catalogs for the activation-based seam
Adds the new continuable types to the cordis-catalog type-link map and
regenerates the cordis api/service/event catalogs, tool catalog, config
catalog, and doc graphs.
2026-08-02 12:51:08 +08:00
Dudu-0223
4e7a5f19cf docs(subagent): rewrite the subagent data-structure doc for activations
wip: Chinese pair and remaining generated catalogs follow.
2026-08-02 12:51:08 +08:00
Huanqi Cao
7c30ac7fe0 Merge remote-tracking branch 'origin/master' into feat/ripgrep-packaged-binary
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-31-even-out-shipped-tool-rosters.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-31-even-out-shipped-tool-rosters.md
#	.agents/notes/implemented/feature/2026-07-31-even-out-shipped-tool-rosters.zh.md
2026-08-02 12:17:35 +08:00
Tianyi Cui
f14121a4c2 refactor(subagent): narrow continuation interface 2026-08-02 04:34:17 +08:00
Dudu
88f913a9ae refactor(subagent): merge continuation control service 2026-08-02 04:34:16 +08:00
Dudu-0223
e1f7eeeb95 fix(subagent): confirm steering request admission 2026-08-02 04:34:16 +08:00
Dudu-0223
189502e4ac fix(subagent): preserve follow-up provenance 2026-08-02 04:34:16 +08:00
Dudu-0223
99a778d63f feat(subagent): continuable background subagents
Implement the continuable background subagents RFC: a durable child
session with a series of Task-backed activations, each disposing its
run before the Task settles.

- dsh-subagent: rename SubagentRun.sendMessage to strict steer, drop
  run-level resume, add SubagentProvider.resume dispatch via
  SubagentService.resume, the continuation start field, and the
  versioned model-hidden subagent/descriptor session event.
- dsh-subagent-inprocess/-spawn/-fork: publish the control-allocated
  child id, append the descriptor inside the initial turn, implement
  cold resume from the child's own transcript under the live parent
  scope, and strict running-only steer.
- dsh-subagent-control (new): SubagentControlService owning stable
  child ids, descriptor snapshot/fold/authorization, Task-backed
  activation with settle-then-dispose ordering, the process-local
  active-run association, and steer-or-resume sendMessage routing.
- dsh-tool-subagent: background route branches on the provider's
  resume capability (continuable via the control service; one-shot
  task for ACP), returning both child and task ids.
- dsh-tool-subagent-control (new): the globally named send_message
  tool rendering steered/started routes.

Keyless coverage spans Task ownership and disposal ordering, running
delivery, cold follow-up, descriptor rejection and rollback, known-id
reconstruction, kill during lookup, admission races, and a new
subagent-continuable ACP snapshot scenario.
2026-08-02 04:34:15 +08:00
Huanqi Cao
4c0b4c3558 Merge remote-tracking branch 'origin/feat/ripgrep-packaged-binary' into feat/pwsh-tool 2026-08-02 01:28:48 +08:00
Huanqi Cao
468cd27842 Merge remote-tracking branch 'origin/master' into feat/ripgrep-packaged-binary 2026-08-02 01:26:21 +08:00