2026-07-19 01:09:20 +08:00
<!-- Generated by scripts/gen - doc - graphs.ts - do not edit by hand.
Run `pnpm run gen-doc-graphs` to regenerate. -->
2026-08-04 10:07:17 +08:00
# DSH Base Composition
2026-07-19 01:09:20 +08:00
docs(python): define the standalone minimal profile
Record sdk-minimal as the narrow repository-owned exception to base-first profile composition: callers still launch only dsh and cannot provide an arbitrary Cordis tree, while the shipped bundle may own a complete explicit roster. Cross-link the launcher, profile-bundle, Python-runtime, minimal-agent, snapshot, and telemetry decisions; the supersession audit keeps each older note active because its remaining rationale is independent.
Update the CLI, architecture, Python tutorial/reference, example, runtime-wheel reference, and bundle documentation. The docs distinguish the full sdk profile from sdk-minimal, explain explicit-home/plugin/patch customization, state the minimal permission and persistence choices, and retain the separately packaged web profile and frontend assets for direct dsh use.
Correct dsh-base descriptions to cover base-backed profiles, make SDK startup configuration visible in the generated config catalog, add sdk-minimal to the module graph, and regenerate the base-composition graph. English and Chinese pairs are re-recorded at the exact reviewed contents.
2026-08-24 15:39:43 +08:00
The dsh-base bundle patch shared by the web, headless, sdk, and acp profiles; their mode bundles and user layers patch over it, while sdk-minimal owns a separate standalone tree.
2026-07-19 01:09:20 +08:00
```mermaid
flowchart LR
2026-08-06 04:40:32 +08:00
cfg["packages/bundle/base/cordis.patch.yml< br / > cordis.yml"]
build(vendor): rescope the vendored Cordis packages into @deepseek-ai
Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it
prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`,
`verify-translation-pairing --write` for the touched bilingual pairs,
`gen-doc-graphs`, and one typert snapshot whose ids embed character offsets.
`pnpm run rescope-vendor --check` verifies the result.
Renames nine vendored packages (cordis, cosmokit, schemastery and the six
@cordisjs plugins) and every reference that resolves them: manifest names and
dependency keys, module specifiers including declare-module merges, cordis.yml
plugin names, tsconfig paths, every Markdown fence, and `docs/` prose.
Directory names, upstream versions, and dependency ranges are unchanged, so
vendor/README.md still reads as an upstream snapshot; its manifest table gains
an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed
at each fork's origin.
The tutorial tier follows the rename end to end: its yaml fences named plugins
the Loader can no longer resolve, its `ts ignore-check` fences disagreed with
the compiled fences beside them, and its prose quoted both. The contracts that
told readers to keep upstream names — the root convention and the vendoring
cookbook's tree comment and manifest invariant — now say to rescope instead.
Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle
purity gate now names the vendored libraries a browser bundle inlines, and the
files where a bare `cordis` is an agent-preset id keep that product data.
2026-08-10 22:04:06 +08:00
plugin_dsh_base_timer["timer< br /> @deepseek -ai/cordis-plugin-timer"]
2026-08-04 10:07:17 +08:00
cfg --> plugin_dsh_base_timer
build(vendor): rescope the vendored Cordis packages into @deepseek-ai
Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it
prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`,
`verify-translation-pairing --write` for the touched bilingual pairs,
`gen-doc-graphs`, and one typert snapshot whose ids embed character offsets.
`pnpm run rescope-vendor --check` verifies the result.
Renames nine vendored packages (cordis, cosmokit, schemastery and the six
@cordisjs plugins) and every reference that resolves them: manifest names and
dependency keys, module specifiers including declare-module merges, cordis.yml
plugin names, tsconfig paths, every Markdown fence, and `docs/` prose.
Directory names, upstream versions, and dependency ranges are unchanged, so
vendor/README.md still reads as an upstream snapshot; its manifest table gains
an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed
at each fork's origin.
The tutorial tier follows the rename end to end: its yaml fences named plugins
the Loader can no longer resolve, its `ts ignore-check` fences disagreed with
the compiled fences beside them, and its prose quoted both. The contracts that
told readers to keep upstream names — the root convention and the vendoring
cookbook's tree comment and manifest invariant — now say to rescope instead.
Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle
purity gate now names the vendored libraries a browser bundle inlines, and the
files where a bare `cordis` is an agent-preset id keep that product data.
2026-08-10 22:04:06 +08:00
plugin_dsh_base_hmr["hmr< br /> @deepseek -ai/cordis-plugin-hmr"]
2026-08-04 10:07:17 +08:00
cfg --> plugin_dsh_base_hmr
plugin_dsh_base_llm["llm< br /> @deepseek -ai/dsh-llm"]
cfg --> plugin_dsh_base_llm
2026-08-22 20:03:23 +08:00
plugin_dsh_base_deepseek_llm_api_extensions["deepseek-llm-api-extensions< br /> @deepseek -ai/dsh-deepseek-llm-api-extensions"]
cfg --> plugin_dsh_base_deepseek_llm_api_extensions
2026-08-04 10:07:17 +08:00
plugin_dsh_base_session["session< br /> @deepseek -ai/dsh-session"]
cfg --> plugin_dsh_base_session
2026-08-22 02:02:38 +08:00
plugin_dsh_base_session_log_deepseek["session-log-deepseek< br /> @deepseek -ai/dsh-session-log-deepseek"]
cfg --> plugin_dsh_base_session_log_deepseek
2026-08-05 11:17:47 +08:00
plugin_dsh_base_typert["typert< br /> @deepseek -ai/dsh-typert-registry"]
cfg --> plugin_dsh_base_typert
plugin_dsh_base_typert_loader["typert-loader< br /> @deepseek -ai/dsh-typert-loader"]
cfg --> plugin_dsh_base_typert_loader
2026-08-07 15:48:29 +08:00
plugin_dsh_base_typert_gateway["typert-gateway< br /> @deepseek -ai/dsh-api-gateway"]
2026-08-05 11:17:47 +08:00
cfg --> plugin_dsh_base_typert_gateway
2026-08-04 10:07:17 +08:00
plugin_dsh_base_session_title["session-title< br /> @deepseek -ai/dsh-session-title"]
cfg --> plugin_dsh_base_session_title
2026-08-13 00:36:22 +08:00
plugin_dsh_base_session_title_llm["session-title-llm< br /> @deepseek -ai/dsh-session-title-first-prompt-llm"]
2026-08-04 10:07:17 +08:00
cfg --> plugin_dsh_base_session_title_llm
2026-08-13 00:36:22 +08:00
plugin_dsh_base_user_questions["user-questions< br /> @deepseek -ai/dsh-user-questions"]
cfg --> plugin_dsh_base_user_questions
2026-08-04 10:07:17 +08:00
plugin_dsh_base_agent["agent< br /> @deepseek -ai/dsh-agent"]
cfg --> plugin_dsh_base_agent
2026-08-22 20:03:23 +08:00
plugin_dsh_base_plugin_package_inventory_deepseek["plugin-package-inventory-deepseek< br /> @deepseek -ai/dsh-plugin-package-inventory-deepseek"]
cfg --> plugin_dsh_base_plugin_package_inventory_deepseek
2026-08-09 12:13:58 +08:00
plugin_dsh_base_agent_default_model["agent-default-model< br /> @deepseek -ai/dsh-agent-default-model"]
cfg --> plugin_dsh_base_agent_default_model
2026-08-13 00:36:22 +08:00
plugin_dsh_base_jobs["jobs< br /> @deepseek -ai/dsh-jobs-local"]
cfg --> plugin_dsh_base_jobs
2026-08-04 10:07:17 +08:00
plugin_dsh_base_llm_retry["llm-retry< br /> @deepseek -ai/dsh-llm-retry"]
cfg --> plugin_dsh_base_llm_retry
2026-08-13 00:36:22 +08:00
plugin_dsh_base_settings["settings< br /> @deepseek -ai/dsh-settings-file"]
2026-08-04 10:07:17 +08:00
cfg --> plugin_dsh_base_settings
plugin_dsh_base_credentials["credentials< br /> @deepseek -ai/dsh-credentials-local"]
cfg --> plugin_dsh_base_credentials
plugin_dsh_base_llm_pi_ai["llm-pi-ai< br /> @deepseek -ai/dsh-llm-pi-ai"]
cfg --> plugin_dsh_base_llm_pi_ai
plugin_dsh_base_session_persistence_jsonl["session-persistence-jsonl< br /> @deepseek -ai/dsh-session-persistence-jsonl"]
cfg --> plugin_dsh_base_session_persistence_jsonl
2026-08-08 01:56:29 +08:00
plugin_dsh_base_attachment_local["attachment-local< br /> @deepseek -ai/dsh-attachment-local"]
cfg --> plugin_dsh_base_attachment_local
2026-08-04 10:07:17 +08:00
plugin_dsh_base_session_query_sqlite["session-query-sqlite< br /> @deepseek -ai/dsh-session-query-sqlite"]
cfg --> plugin_dsh_base_session_query_sqlite
2026-08-06 21:41:50 +08:00
plugin_dsh_base_session_projection["session-projection< br /> @deepseek -ai/dsh-session-projection"]
cfg --> plugin_dsh_base_session_projection
2026-08-20 14:38:39 +08:00
plugin_dsh_base_storage["storage< br /> @deepseek -ai/dsh-storage"]
cfg --> plugin_dsh_base_storage
plugin_dsh_base_storage_json["storage-json< br /> @deepseek -ai/dsh-storage-json"]
cfg --> plugin_dsh_base_storage_json
plugin_dsh_base_storage_domain["storage-domain< br /> @deepseek -ai/dsh-storage-domain"]
cfg --> plugin_dsh_base_storage_domain
plugin_dsh_base_session_projection_cache["session-projection-cache< br /> @deepseek -ai/dsh-session-projection-cache"]
cfg --> plugin_dsh_base_session_projection_cache
2026-08-13 00:36:22 +08:00
plugin_dsh_base_session_telemetry_otel["session-telemetry-otel< br /> @deepseek -ai/dsh-session-telemetry-otel"]
cfg --> plugin_dsh_base_session_telemetry_otel
2026-08-04 10:07:17 +08:00
plugin_dsh_base_subprocess["subprocess< br /> @deepseek -ai/dsh-subprocess-local"]
cfg --> plugin_dsh_base_subprocess
plugin_dsh_base_sandbox["sandbox< br /> @deepseek -ai/dsh-sandbox-local"]
cfg --> plugin_dsh_base_sandbox
plugin_dsh_base_sandbox_policy["sandbox-policy< br /> @deepseek -ai/dsh-sandbox-policy"]
cfg --> plugin_dsh_base_sandbox_policy
plugin_dsh_base_bash_sandbox["bash-sandbox< br /> @deepseek -ai/dsh-bash-sandbox"]
cfg --> plugin_dsh_base_bash_sandbox
2026-08-11 15:11:45 +08:00
plugin_dsh_base_pwsh_sandbox["pwsh-sandbox< br /> @deepseek -ai/dsh-pwsh-sandbox"]
cfg --> plugin_dsh_base_pwsh_sandbox
2026-08-04 10:07:17 +08:00
plugin_dsh_base_approval["approval< br /> @deepseek -ai/dsh-user-approval"]
cfg --> plugin_dsh_base_approval
2026-08-13 00:36:22 +08:00
plugin_dsh_base_permission["permission< br /> @deepseek -ai/dsh-permission-presets"]
2026-08-04 10:07:17 +08:00
cfg --> plugin_dsh_base_permission
2026-08-13 00:36:22 +08:00
plugin_dsh_base_shell_env["shell-env< br /> @deepseek -ai/dsh-shell-env"]
cfg --> plugin_dsh_base_shell_env
2026-08-04 10:07:17 +08:00
plugin_dsh_base_tool_bash["tool-bash< br /> @deepseek -ai/dsh-tool-bash"]
cfg --> plugin_dsh_base_tool_bash
2026-08-11 15:11:45 +08:00
plugin_dsh_base_tool_pwsh["tool-pwsh< br /> @deepseek -ai/dsh-tool-pwsh"]
cfg --> plugin_dsh_base_tool_pwsh
2026-08-13 00:36:22 +08:00
plugin_dsh_base_tool_jobs["tool-jobs< br /> @deepseek -ai/dsh-tool-jobs"]
cfg --> plugin_dsh_base_tool_jobs
plugin_dsh_base_fs_observation_policy["fs-observation-policy< br /> @deepseek -ai/dsh-fs-observation-policy"]
cfg --> plugin_dsh_base_fs_observation_policy
2026-08-04 10:07:17 +08:00
plugin_dsh_base_tool_fs["tool-fs< br /> @deepseek -ai/dsh-tool-fs"]
cfg --> plugin_dsh_base_tool_fs
plugin_dsh_base_tool_fs_search["tool-fs-search< br /> @deepseek -ai/dsh-tool-fs-search"]
cfg --> plugin_dsh_base_tool_fs_search
2026-08-13 00:36:22 +08:00
plugin_dsh_base_agent_instructions["agent-instructions< br /> @deepseek -ai/dsh-agent-instructions"]
cfg --> plugin_dsh_base_agent_instructions
2026-08-04 10:07:17 +08:00
plugin_dsh_base_skill["skill< br /> @deepseek -ai/dsh-skill"]
cfg --> plugin_dsh_base_skill
2026-08-13 00:36:22 +08:00
plugin_dsh_base_skill_filesystem["skill-filesystem< br /> @deepseek -ai/dsh-skill-filesystem"]
cfg --> plugin_dsh_base_skill_filesystem
2026-08-05 21:50:44 +08:00
plugin_dsh_base_skill_badge["skill-badge< br /> @deepseek -ai/dsh-skill-badge"]
cfg --> plugin_dsh_base_skill_badge
2026-08-04 10:07:17 +08:00
plugin_dsh_base_tool_skill["tool-skill< br /> @deepseek -ai/dsh-tool-skill"]
cfg --> plugin_dsh_base_tool_skill
plugin_dsh_base_commands["commands< br /> @deepseek -ai/dsh-commands"]
cfg --> plugin_dsh_base_commands
2026-08-06 16:02:25 +08:00
plugin_dsh_base_command_feedback["command-feedback< br /> @deepseek -ai/dsh-command-feedback"]
cfg --> plugin_dsh_base_command_feedback
2026-08-04 10:07:17 +08:00
plugin_dsh_base_goal["goal< br /> @deepseek -ai/dsh-goal"]
cfg --> plugin_dsh_base_goal
2026-08-13 00:36:22 +08:00
plugin_dsh_base_goal_round_driver["goal-round-driver< br /> @deepseek -ai/dsh-goal-round-driver"]
cfg --> plugin_dsh_base_goal_round_driver
2026-08-04 10:07:17 +08:00
plugin_dsh_base_command_goal["command-goal< br /> @deepseek -ai/dsh-command-goal"]
cfg --> plugin_dsh_base_command_goal
plugin_dsh_base_plan_mode["plan-mode< br /> @deepseek -ai/dsh-plan-mode"]
cfg --> plugin_dsh_base_plan_mode
plugin_dsh_base_token_meter["token-meter< br /> @deepseek -ai/dsh-token-meter"]
cfg --> plugin_dsh_base_token_meter
2026-08-13 00:36:22 +08:00
plugin_dsh_base_compaction_basic["compaction-basic< br /> @deepseek -ai/dsh-compaction-basic"]
cfg --> plugin_dsh_base_compaction_basic
2026-08-04 10:07:17 +08:00
plugin_dsh_base_command_compact["command-compact< br /> @deepseek -ai/dsh-command-compact"]
cfg --> plugin_dsh_base_command_compact
plugin_dsh_base_subagent["subagent< br /> @deepseek -ai/dsh-subagent"]
cfg --> plugin_dsh_base_subagent
2026-08-13 00:36:22 +08:00
plugin_dsh_base_subagent_spawn_in_process["subagent-spawn-in-process< br /> @deepseek -ai/dsh-subagent-spawn-in-process"]
cfg --> plugin_dsh_base_subagent_spawn_in_process
plugin_dsh_base_subagent_fork_in_process["subagent-fork-in-process< br /> @deepseek -ai/dsh-subagent-fork-in-process"]
cfg --> plugin_dsh_base_subagent_fork_in_process
2026-08-04 10:07:17 +08:00
plugin_dsh_base_tool_subagent_control["tool-subagent-control< br /> @deepseek -ai/dsh-tool-subagent-control"]
cfg --> plugin_dsh_base_tool_subagent_control
plugin_dsh_base_tool_subagent_list_agents["tool-subagent-list-agents< br /> @deepseek -ai/dsh-tool-subagent-control/list-agents"]
cfg --> plugin_dsh_base_tool_subagent_list_agents
plugin_dsh_base_tool_subagent["tool-subagent< br /> @deepseek -ai/dsh-tool-subagent"]
cfg --> plugin_dsh_base_tool_subagent
plugin_dsh_base_tool_subagent_fork["tool-subagent-fork< br /> @deepseek -ai/dsh-tool-subagent"]
cfg --> plugin_dsh_base_tool_subagent_fork
plugin_dsh_base_tool_subagent_report["tool-subagent-report< br /> @deepseek -ai/dsh-tool-subagent-report"]
cfg --> plugin_dsh_base_tool_subagent_report
2026-08-13 00:36:22 +08:00
plugin_dsh_base_workflow_worker_thread["workflow-worker-thread< br /> @deepseek -ai/dsh-workflow-worker-thread"]
cfg --> plugin_dsh_base_workflow_worker_thread
2026-08-04 10:07:17 +08:00
plugin_dsh_base_tool_workflow["tool-workflow< br /> @deepseek -ai/dsh-tool-workflow"]
cfg --> plugin_dsh_base_tool_workflow
2026-08-13 00:36:22 +08:00
plugin_dsh_base_timeout_policy["timeout-policy< br /> @deepseek -ai/dsh-tool-call-timeout-policy"]
2026-08-04 10:07:17 +08:00
cfg --> plugin_dsh_base_timeout_policy
plugin_dsh_base_spill_local["spill-local< br /> @deepseek -ai/dsh-spill-local"]
cfg --> plugin_dsh_base_spill_local
plugin_dsh_base_spill_policy["spill-policy< br /> @deepseek -ai/dsh-spill-policy"]
cfg --> plugin_dsh_base_spill_policy
plugin_dsh_base_session_checkpoint_policy["session-checkpoint-policy< br /> @deepseek -ai/dsh-session-checkpoint-policy"]
cfg --> plugin_dsh_base_session_checkpoint_policy
2026-08-13 00:36:22 +08:00
plugin_dsh_base_tool_result_pruner["tool-result-pruner< br /> @deepseek -ai/dsh-compaction-tool-result-pruner"]
cfg --> plugin_dsh_base_tool_result_pruner
2026-08-04 10:07:17 +08:00
plugin_dsh_base_tool_todo["tool-todo< br /> @deepseek -ai/dsh-tool-todo"]
cfg --> plugin_dsh_base_tool_todo
plugin_dsh_base_tool_goal["tool-goal< br /> @deepseek -ai/dsh-tool-goal"]
cfg --> plugin_dsh_base_tool_goal
plugin_dsh_base_tool_ralph["tool-ralph< br /> @deepseek -ai/dsh-tool-ralph"]
cfg --> plugin_dsh_base_tool_ralph
plugin_dsh_base_tool_str_replace_editor["tool-str-replace-editor< br /> @deepseek -ai/dsh-tool-str-replace-editor"]
cfg --> plugin_dsh_base_tool_str_replace_editor
2026-08-13 00:36:22 +08:00
plugin_dsh_base_repeat_tool_reminder["repeat-tool-reminder< br /> @deepseek -ai/dsh-repeat-tool-reminder"]
cfg --> plugin_dsh_base_repeat_tool_reminder
2026-08-04 10:07:17 +08:00
plugin_dsh_base_web["web< br /> @deepseek -ai/dsh-web"]
cfg --> plugin_dsh_base_web
plugin_dsh_base_web_search_deepseek["web-search-deepseek< br /> @deepseek -ai/dsh-web-search-deepseek"]
cfg --> plugin_dsh_base_web_search_deepseek
2026-08-24 13:38:06 +08:00
plugin_dsh_base_web_fetch_http["web-fetch-http< br /> @deepseek -ai/dsh-web-fetch-http"]
cfg --> plugin_dsh_base_web_fetch_http
2026-08-04 10:07:17 +08:00
plugin_dsh_base_tool_web["tool-web< br /> @deepseek -ai/dsh-tool-web"]
cfg --> plugin_dsh_base_tool_web
plugin_dsh_base_tools["tools< br /> @deepseek -ai/dsh-tools"]
cfg --> plugin_dsh_base_tools
plugin_dsh_base_system_prompt["system-prompt< br /> @deepseek -ai/dsh-system-prompt"]
cfg --> plugin_dsh_base_system_prompt
plugin_dsh_base_agent_loop["agent-loop< br /> @deepseek -ai/dsh-agent-loop"]
cfg --> plugin_dsh_base_agent_loop
plugin_dsh_base_fs_sandbox["fs-sandbox< br /> @deepseek -ai/dsh-fs-sandbox"]
cfg --> plugin_dsh_base_fs_sandbox
plugin_dsh_base_llm_deepseek["llm-deepseek< br /> @deepseek -ai/dsh-llm-deepseek"]
cfg --> plugin_dsh_base_llm_deepseek
2026-07-19 01:09:20 +08:00
```
| Plugin id | Package / module |
| --- | --- |
build(vendor): rescope the vendored Cordis packages into @deepseek-ai
Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it
prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`,
`verify-translation-pairing --write` for the touched bilingual pairs,
`gen-doc-graphs`, and one typert snapshot whose ids embed character offsets.
`pnpm run rescope-vendor --check` verifies the result.
Renames nine vendored packages (cordis, cosmokit, schemastery and the six
@cordisjs plugins) and every reference that resolves them: manifest names and
dependency keys, module specifiers including declare-module merges, cordis.yml
plugin names, tsconfig paths, every Markdown fence, and `docs/` prose.
Directory names, upstream versions, and dependency ranges are unchanged, so
vendor/README.md still reads as an upstream snapshot; its manifest table gains
an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed
at each fork's origin.
The tutorial tier follows the rename end to end: its yaml fences named plugins
the Loader can no longer resolve, its `ts ignore-check` fences disagreed with
the compiled fences beside them, and its prose quoted both. The contracts that
told readers to keep upstream names — the root convention and the vendoring
cookbook's tree comment and manifest invariant — now say to rescope instead.
Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle
purity gate now names the vendored libraries a browser bundle inlines, and the
files where a bare `cordis` is an agent-preset id keep that product data.
2026-08-10 22:04:06 +08:00
| `timer` | `@deepseek-ai/cordis-plugin-timer` |
| `hmr` | `@deepseek-ai/cordis-plugin-hmr` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `llm` | `@deepseek-ai/dsh-llm` |
2026-08-22 20:03:23 +08:00
| `deepseek-llm-api-extensions` | `@deepseek-ai/dsh-deepseek-llm-api-extensions` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `session` | `@deepseek-ai/dsh-session` |
2026-08-22 02:02:38 +08:00
| `session-log-deepseek` | `@deepseek-ai/dsh-session-log-deepseek` |
2026-08-05 11:17:47 +08:00
| `typert` | `@deepseek-ai/dsh-typert-registry` |
| `typert-loader` | `@deepseek-ai/dsh-typert-loader` |
2026-08-07 15:48:29 +08:00
| `typert-gateway` | `@deepseek-ai/dsh-api-gateway` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `session-title` | `@deepseek-ai/dsh-session-title` |
2026-08-13 00:36:22 +08:00
| `session-title-llm` | `@deepseek-ai/dsh-session-title-first-prompt-llm` |
| `user-questions` | `@deepseek-ai/dsh-user-questions` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `agent` | `@deepseek-ai/dsh-agent` |
2026-08-22 20:03:23 +08:00
| `plugin-package-inventory-deepseek` | `@deepseek-ai/dsh-plugin-package-inventory-deepseek` |
2026-08-09 12:13:58 +08:00
| `agent-default-model` | `@deepseek-ai/dsh-agent-default-model` |
2026-08-13 00:36:22 +08:00
| `jobs` | `@deepseek-ai/dsh-jobs-local` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `llm-retry` | `@deepseek-ai/dsh-llm-retry` |
2026-08-13 00:36:22 +08:00
| `settings` | `@deepseek-ai/dsh-settings-file` |
docs: bilingual credentials/settings-consumer documentation, catalogs, and gates
New credentials data-structure page (type-equiv manifested), group README,
rewritten llm-deepseek/llm-pi-ai READMEs (dynamic configuration, dict
profiles, credential chain), capability-seams/service-role registration,
Agent Note (bilingual), demo compositions mounting settings-local +
credentials-local with no inline key plumbing, installSettingsSection
consumer helper on the settings seam (deduplicating both adapters' wiring),
jscpd symmetry markers for the provider twins, runtime-closure additions for
python/sdk-runtime, and doc-budget ceilings AGENTS.md 1750→1755 /
packages/README.md 850→865 for the structural one-line group rows.
2026-07-29 14:20:06 +08:00
| `credentials` | `@deepseek-ai/dsh-credentials-local` |
2026-07-29 14:56:09 +08:00
| `llm-pi-ai` | `@deepseek-ai/dsh-llm-pi-ai` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `session-persistence-jsonl` | `@deepseek-ai/dsh-session-persistence-jsonl` |
2026-08-08 01:56:29 +08:00
| `attachment-local` | `@deepseek-ai/dsh-attachment-local` |
2026-07-30 14:56:39 +08:00
| `session-query-sqlite` | `@deepseek-ai/dsh-session-query-sqlite` |
2026-08-06 21:41:50 +08:00
| `session-projection` | `@deepseek-ai/dsh-session-projection` |
2026-08-20 14:38:39 +08:00
| `storage` | `@deepseek-ai/dsh-storage` |
| `storage-json` | `@deepseek-ai/dsh-storage-json` |
| `storage-domain` | `@deepseek-ai/dsh-storage-domain` |
| `session-projection-cache` | `@deepseek-ai/dsh-session-projection-cache` |
2026-08-13 00:36:22 +08:00
| `session-telemetry-otel` | `@deepseek-ai/dsh-session-telemetry-otel` |
refactor(subprocess): rename the process seam to subprocess and address review
Review feedback (tianyicui): 'process' is a poor service name. The family is
now packages/subprocess/ — @deepseek-ai/dsh-subprocess (ctx.subprocess,
abstract SubprocessService, Subprocess* vocabulary) and
@deepseek-ai/dsh-subprocess-local (LocalSubprocessService) — renamed
throughout code, compositions, docs (en+zh, pairs re-recorded), catalogs,
and gates. 'subprocess' is the precise term for managed OS children (the
Python-stdlib sense), avoids colliding with Node's global process object,
and reads as one system beside dsh-subagent-subprocess.
ds-review-bot findings addressed:
- kill() on a settled handle is now a no-op (no signal to a possibly-reused
pgid, no referenced grace timer delaying exit); pinned by a spy test.
- The moved DshEnvironmentKey/DshEnvironment/CollectedOutput types get
drift-checked type-equiv blocks on the new subprocess.md page, restoring
their manifest registration.
- subprocess.md is registered in the core.md sub-page index (en+zh).
2026-07-26 12:43:14 +08:00
| `subprocess` | `@deepseek-ai/dsh-subprocess-local` |
2026-07-31 20:39:53 +08:00
| `sandbox` | `@deepseek-ai/dsh-sandbox-local` |
| `sandbox-policy` | `@deepseek-ai/dsh-sandbox-policy` |
| `bash-sandbox` | `@deepseek-ai/dsh-bash-sandbox` |
2026-08-11 15:11:45 +08:00
| `pwsh-sandbox` | `@deepseek-ai/dsh-pwsh-sandbox` |
2026-07-31 20:39:53 +08:00
| `approval` | `@deepseek-ai/dsh-user-approval` |
2026-08-13 00:36:22 +08:00
| `permission` | `@deepseek-ai/dsh-permission-presets` |
| `shell-env` | `@deepseek-ai/dsh-shell-env` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `tool-bash` | `@deepseek-ai/dsh-tool-bash` |
2026-08-11 15:11:45 +08:00
| `tool-pwsh` | `@deepseek-ai/dsh-tool-pwsh` |
2026-08-13 00:36:22 +08:00
| `tool-jobs` | `@deepseek-ai/dsh-tool-jobs` |
| `fs-observation-policy` | `@deepseek-ai/dsh-fs-observation-policy` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `tool-fs` | `@deepseek-ai/dsh-tool-fs` |
| `tool-fs-search` | `@deepseek-ai/dsh-tool-fs-search` |
2026-08-13 00:36:22 +08:00
| `agent-instructions` | `@deepseek-ai/dsh-agent-instructions` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `skill` | `@deepseek-ai/dsh-skill` |
2026-08-13 00:36:22 +08:00
| `skill-filesystem` | `@deepseek-ai/dsh-skill-filesystem` |
2026-08-05 21:50:44 +08:00
| `skill-badge` | `@deepseek-ai/dsh-skill-badge` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `tool-skill` | `@deepseek-ai/dsh-tool-skill` |
| `commands` | `@deepseek-ai/dsh-commands` |
2026-08-06 16:02:25 +08:00
| `command-feedback` | `@deepseek-ai/dsh-command-feedback` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `goal` | `@deepseek-ai/dsh-goal` |
2026-08-13 00:36:22 +08:00
| `goal-round-driver` | `@deepseek-ai/dsh-goal-round-driver` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `command-goal` | `@deepseek-ai/dsh-command-goal` |
| `plan-mode` | `@deepseek-ai/dsh-plan-mode` |
2026-07-20 19:26:04 +08:00
| `token-meter` | `@deepseek-ai/dsh-token-meter` |
2026-08-13 00:36:22 +08:00
| `compaction-basic` | `@deepseek-ai/dsh-compaction-basic` |
2026-07-30 17:40:25 +08:00
| `command-compact` | `@deepseek-ai/dsh-command-compact` |
2026-07-20 19:26:04 +08:00
| `subagent` | `@deepseek-ai/dsh-subagent` |
2026-08-13 00:36:22 +08:00
| `subagent-spawn-in-process` | `@deepseek-ai/dsh-subagent-spawn-in-process` |
| `subagent-fork-in-process` | `@deepseek-ai/dsh-subagent-fork-in-process` |
2026-07-23 18:14:37 +08:00
| `tool-subagent-control` | `@deepseek-ai/dsh-tool-subagent-control` |
2026-07-30 23:33:07 +08:00
| `tool-subagent-list-agents` | `@deepseek-ai/dsh-tool-subagent-control/list-agents` |
2026-07-20 19:26:04 +08:00
| `tool-subagent` | `@deepseek-ai/dsh-tool-subagent` |
| `tool-subagent-fork` | `@deepseek-ai/dsh-tool-subagent` |
2026-07-31 22:45:21 +08:00
| `tool-subagent-report` | `@deepseek-ai/dsh-tool-subagent-report` |
2026-08-13 00:36:22 +08:00
| `workflow-worker-thread` | `@deepseek-ai/dsh-workflow-worker-thread` |
2026-07-20 19:26:04 +08:00
| `tool-workflow` | `@deepseek-ai/dsh-tool-workflow` |
2026-08-13 00:36:22 +08:00
| `timeout-policy` | `@deepseek-ai/dsh-tool-call-timeout-policy` |
2026-07-20 19:26:04 +08:00
| `spill-local` | `@deepseek-ai/dsh-spill-local` |
| `spill-policy` | `@deepseek-ai/dsh-spill-policy` |
feat(cli): even out the shipped tool rosters across both surfaces
The two shipped surfaces offered different tools for no recorded reason:
session checkpoints, tool-result pruning, the goal tools, and Ralph were in
`tui.cordis.yml`; `tool-todo` and web search were in `web.cordis.yml`. Neither
offered session search, a string-replacement editor, or a repeat-tool guard,
though none of the three is surface-specific.
Move the rows that are not surface-specific into `base.cordis.yml` and add
those three. Web search moves there too — the TUI decision the change that
made it a Web default deferred. Both surfaces now assemble the same 27 tools.
This adds only. No row is removed from either surface and no existing row's
configuration is edited: executors, sandbox composition, access defaults,
`tools.mode`, and the workflow tool are exactly what they were. Two rows stay
surface-specific: `tmux-context` (no terminal multiplexer in a browser) and
`session-reference` (its index has one writer owner).
Ship `dsh-mcp-client` as a dependency without a row: the plugin mounts one
server per instance and `command` is required, so a default would name a
third-party server and spawn it outside `ctx.bash` on every launch. The CLI
README carries the YAML for mounting one from a personal config.
2026-07-31 13:42:51 +08:00
| `session-checkpoint-policy` | `@deepseek-ai/dsh-session-checkpoint-policy` |
2026-08-13 00:36:22 +08:00
| `tool-result-pruner` | `@deepseek-ai/dsh-compaction-tool-result-pruner` |
feat(cli): even out the shipped tool rosters across both surfaces
The two shipped surfaces offered different tools for no recorded reason:
session checkpoints, tool-result pruning, the goal tools, and Ralph were in
`tui.cordis.yml`; `tool-todo` and web search were in `web.cordis.yml`. Neither
offered session search, a string-replacement editor, or a repeat-tool guard,
though none of the three is surface-specific.
Move the rows that are not surface-specific into `base.cordis.yml` and add
those three. Web search moves there too — the TUI decision the change that
made it a Web default deferred. Both surfaces now assemble the same 27 tools.
This adds only. No row is removed from either surface and no existing row's
configuration is edited: executors, sandbox composition, access defaults,
`tools.mode`, and the workflow tool are exactly what they were. Two rows stay
surface-specific: `tmux-context` (no terminal multiplexer in a browser) and
`session-reference` (its index has one writer owner).
Ship `dsh-mcp-client` as a dependency without a row: the plugin mounts one
server per instance and `command` is required, so a default would name a
third-party server and spawn it outside `ctx.bash` on every launch. The CLI
README carries the YAML for mounting one from a personal config.
2026-07-31 13:42:51 +08:00
| `tool-todo` | `@deepseek-ai/dsh-tool-todo` |
| `tool-goal` | `@deepseek-ai/dsh-tool-goal` |
| `tool-ralph` | `@deepseek-ai/dsh-tool-ralph` |
| `tool-str-replace-editor` | `@deepseek-ai/dsh-tool-str-replace-editor` |
2026-08-13 00:36:22 +08:00
| `repeat-tool-reminder` | `@deepseek-ai/dsh-repeat-tool-reminder` |
feat(cli): even out the shipped tool rosters across both surfaces
The two shipped surfaces offered different tools for no recorded reason:
session checkpoints, tool-result pruning, the goal tools, and Ralph were in
`tui.cordis.yml`; `tool-todo` and web search were in `web.cordis.yml`. Neither
offered session search, a string-replacement editor, or a repeat-tool guard,
though none of the three is surface-specific.
Move the rows that are not surface-specific into `base.cordis.yml` and add
those three. Web search moves there too — the TUI decision the change that
made it a Web default deferred. Both surfaces now assemble the same 27 tools.
This adds only. No row is removed from either surface and no existing row's
configuration is edited: executors, sandbox composition, access defaults,
`tools.mode`, and the workflow tool are exactly what they were. Two rows stay
surface-specific: `tmux-context` (no terminal multiplexer in a browser) and
`session-reference` (its index has one writer owner).
Ship `dsh-mcp-client` as a dependency without a row: the plugin mounts one
server per instance and `command` is required, so a default would name a
third-party server and spawn it outside `ctx.bash` on every launch. The CLI
README carries the YAML for mounting one from a personal config.
2026-07-31 13:42:51 +08:00
| `web` | `@deepseek-ai/dsh-web` |
| `web-search-deepseek` | `@deepseek-ai/dsh-web-search-deepseek` |
2026-08-24 13:38:06 +08:00
| `web-fetch-http` | `@deepseek-ai/dsh-web-fetch-http` |
feat(cli): even out the shipped tool rosters across both surfaces
The two shipped surfaces offered different tools for no recorded reason:
session checkpoints, tool-result pruning, the goal tools, and Ralph were in
`tui.cordis.yml`; `tool-todo` and web search were in `web.cordis.yml`. Neither
offered session search, a string-replacement editor, or a repeat-tool guard,
though none of the three is surface-specific.
Move the rows that are not surface-specific into `base.cordis.yml` and add
those three. Web search moves there too — the TUI decision the change that
made it a Web default deferred. Both surfaces now assemble the same 27 tools.
This adds only. No row is removed from either surface and no existing row's
configuration is edited: executors, sandbox composition, access defaults,
`tools.mode`, and the workflow tool are exactly what they were. Two rows stay
surface-specific: `tmux-context` (no terminal multiplexer in a browser) and
`session-reference` (its index has one writer owner).
Ship `dsh-mcp-client` as a dependency without a row: the plugin mounts one
server per instance and `command` is required, so a default would name a
third-party server and spawn it outside `ctx.bash` on every launch. The CLI
README carries the YAML for mounting one from a personal config.
2026-07-31 13:42:51 +08:00
| `tool-web` | `@deepseek-ai/dsh-tool-web` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `tools` | `@deepseek-ai/dsh-tools` |
| `system-prompt` | `@deepseek-ai/dsh-system-prompt` |
| `agent-loop` | `@deepseek-ai/dsh-agent-loop` |
2026-07-31 20:39:53 +08:00
| `fs-sandbox` | `@deepseek-ai/dsh-fs-sandbox` |
refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.
- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
patches never cross an include boundary. Precedence: base < surface <
(--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
test tree never inherits the user's route; new `--config-replace` boots a file
as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
configure or disable it. Upstream built the id index once before the patch
loop, leaving every surface-only row — the whole TUI front door — silently
unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay
Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.
Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 13:58:21 +08:00
| `llm-deepseek` | `@deepseek-ai/dsh-llm-deepseek` |
2026-07-19 01:09:20 +08:00
2026-08-06 04:40:32 +08:00
Source config: [`packages/bundle/base/cordis.patch.yml` ](../../packages/bundle/base/cordis.patch.yml ).
2026-07-19 01:09:20 +08:00
2026-08-24 10:00:15 +08:00
Maintenance mode: hybrid: the patch row list is parsed from its `cordis.yml` ; app package expansion is curated from package source.