From b48384223ac250512fccf25967750613bb7eeb54 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Mon, 5 Oct 2026 22:08:09 +0800 Subject: [PATCH] refactor(experimental)!: classify optional packages and move prototypes --- ...26-07-16-persistent-pty-sessions.i18n.yaml | 12 +- .../2026-07-16-persistent-pty-sessions.md | 10 +- .../2026-07-16-persistent-pty-sessions.zh.md | 10 +- ...5-product-package-classification.i18n.yaml | 19 ++ ...26-10-05-product-package-classification.md | 29 ++ ...10-05-product-package-classification.zh.md | 29 ++ .../2026-10-03-pi-extensions-bridge.i18n.yaml | 4 +- .../2026-10-03-pi-extensions-bridge.md | 2 +- .../2026-10-03-pi-extensions-bridge.zh.md | 2 +- .github/workflows/ci.yml | 2 +- AGENTS.md | 6 +- apps/cli/composition.md | 6 - apps/cli/package.json | 11 +- apps/cli/tests/dsh-badge.expected.e2e.ts | 2 +- apps/cli/tests/fixtures/dsh-badge/cordis.yml | 5 +- apps/cli/tests/fixtures/dsh-badge/snapshot.ts | 9 +- .../tests/fixtures/github-webhook/cordis.yml | 4 +- .../github-webhook/github-webhook-rule.mjs | 2 +- apps/cli/tests/profiles/webhook-packed.e2e.ts | 253 ++++++++++++++ apps/cli/tests/web-agent-presets.e2e.ts | 2 +- apps/web/tests/github-ready-review.e2e.ts | 4 +- docs/architecture.i18n.yaml | 8 +- docs/architecture.md | 3 +- docs/architecture.zh.md | 3 +- docs/cookbook/extension-cookbook.i18n.yaml | 4 +- docs/cookbook/extension-cookbook.md | 2 +- docs/cookbook/extension-cookbook.zh.md | 2 +- .../reviewing-persistence-type-changes.md | 4 +- .../reviewing-persistence-type-changes.zh.md | 4 +- docs/persistence-catalog.i18n.yaml | 36 +- docs/persistence-catalog.md | 28 +- docs/persistence-catalog.zh.md | 28 +- docs/persistence-schema.json | 22 +- docs/subsystems/claude-code-mods.i18n.yaml | 4 +- docs/subsystems/claude-code-mods.md | 2 +- docs/subsystems/claude-code-mods.zh.md | 2 +- docs/subsystems/session.i18n.yaml | 8 +- docs/subsystems/session.md | 4 +- docs/subsystems/session.zh.md | 4 +- docs/subsystems/skills.i18n.yaml | 8 +- docs/subsystems/skills.md | 6 +- docs/subsystems/skills.zh.md | 6 +- docs/subsystems/webhook.i18n.yaml | 4 +- docs/subsystems/webhook.md | 4 +- docs/subsystems/webhook.zh.md | 4 +- docs/subsystems/workflow.i18n.yaml | 4 +- docs/subsystems/workflow.md | 2 +- docs/subsystems/workflow.zh.md | 2 +- docs/tool-catalog.md | 26 +- docs/tool-catalog.zh.md | 26 +- .../guide.i18n.yaml | 16 + .../experimental-package-renames/guide.md | 41 +++ .../experimental-package-renames/guide.zh.md | 41 +++ docs/user/guide/github-review.i18n.yaml | 4 +- docs/user/guide/github-review.md | 13 +- docs/user/guide/github-review.zh.md | 13 +- package.json | 7 +- packages/README.i18n.yaml | 8 +- packages/README.md | 4 +- packages/README.zh.md | 4 +- packages/bundle/base/cordis.patch.yml | 18 - packages/bundle/base/package.json | 2 - packages/bundle/web-app/cordis.patch.yml | 6 - packages/bundle/web-app/package.json | 1 - .../bundle/web-app/presets/cordis.patch.yml | 6 - packages/bundle/web-app/presets/ptc.patch.yml | 6 - .../bundle/web-app/presets/standard.patch.yml | 6 - packages/client/ui-tool/package.json | 2 +- .../tests/details-models.client.spec.ts | 2 +- .../agent-loop/tests/interception.spec.ts | 2 +- packages/experimental/AGENTS.md | 2 +- packages/experimental/README.i18n.yaml | 15 +- packages/experimental/README.md | 23 +- packages/experimental/README.zh.md | 23 +- .../claude-code-mods/README.i18n.yaml | 8 +- .../experimental/claude-code-mods/README.md | 4 +- .../claude-code-mods/README.zh.md | 4 +- .../hook-protocol/README.i18n.yaml | 61 ++++ .../hook-protocol/README.md | 10 +- .../hook-protocol/README.zh.md | 10 +- .../hook-protocol/package.json | 4 +- .../hook-protocol/src/codec.ts | 2 +- .../hook-protocol/src/detached.ts | 2 +- .../hook-protocol/src/events.ts | 2 +- .../hook-protocol/src/index.ts | 2 +- .../hook-protocol/src/matcher.ts | 2 +- .../hook-protocol/src/merge.ts | 2 +- .../hook-protocol/src/runner.ts | 2 +- .../hook-protocol/src/types.ts | 2 +- .../hook-protocol/tests/codec.spec.ts | 2 +- .../hook-protocol/tests/detached.spec.ts | 2 +- .../hook-protocol/tests/events.spec.ts | 2 +- .../hook-protocol/tests/matcher.spec.ts | 2 +- .../hook-protocol/tests/merge.spec.ts | 4 +- .../hook-protocol/tests/runner.spec.ts | 4 +- .../hook-protocol/tsconfig.json | 0 .../hooks-claude-code/README.i18n.yaml | 88 +++++ .../hooks-claude-code/README.md | 12 +- .../hooks-claude-code/README.zh.md | 12 +- .../hooks-claude-code/package.json | 8 +- .../hooks-claude-code/src/config.ts | 4 +- .../hooks-claude-code/src/index.ts | 6 +- .../hooks-claude-code/tests/bridge.spec.ts | 4 +- .../hooks-claude-code/tests/config.spec.ts | 2 +- .../hooks-claude-code/tests/coverage-cases.ts | 2 +- .../tests/coverage-config.spec.ts | 0 .../tests/coverage-context.spec.ts | 0 .../tests/coverage-edge-paths.spec.ts | 0 .../tests/coverage-stop.spec.ts | 0 .../hooks-claude-code/tsconfig.json | 0 .../experimental/hooks-codex/README.i18n.yaml | 88 +++++ .../hooks-codex/README.md | 12 +- .../hooks-codex/README.zh.md | 12 +- .../hooks-codex/package.json | 8 +- .../hooks-codex/src/config.ts | 4 +- .../hooks-codex/src/index.ts | 6 +- .../hooks-codex/tests/bridge.spec.ts | 2 +- .../hooks-codex/tests/config.spec.ts | 2 +- .../hooks-codex/tests/coverage-cases.ts | 2 +- .../tests/coverage-post-tool.spec.ts | 0 .../hooks-codex/tests/coverage-prompt.spec.ts | 0 .../tests/coverage-result-shape.spec.ts | 0 .../hooks-codex/tsconfig.json | 0 .../README.i18n.yaml | 64 ++++ .../session-title-all-prompts-llm/README.md | 18 +- .../README.zh.md | 18 +- .../package.json | 4 +- .../src/index.ts | 0 .../tests/provider.spec.ts | 2 +- .../tsconfig.json | 4 +- .../experimental/skill-badge/README.i18n.yaml | 55 +++ .../skill-badge/README.md | 14 +- .../skill-badge/README.zh.md | 14 +- .../skill-badge/assets/dsh-badge.md | 0 .../skill-badge/assets/dsh-badge.png | Bin .../skill-badge/package.json | 4 +- .../skill-badge/src/index.ts | 2 +- .../skill-badge/tests/skill-badge.spec.ts | 4 +- .../skill-badge/tsconfig.json | 2 +- .../experimental/tool-ralph/README.i18n.yaml | 100 ++++++ .../tool-ralph/README.md | 10 +- .../tool-ralph/README.zh.md | 10 +- .../tool-ralph/package.json | 4 +- .../tool-ralph/src/index.ts | 2 +- .../tool-ralph/tests/integration.spec.ts | 4 +- .../tool-ralph/tests/tool-ralph.spec.ts | 2 +- .../tool-ralph/tsconfig.json | 2 +- .../tool-terminal/README.i18n.yaml | 100 ++++++ .../tool-terminal/README.md | 16 +- .../tool-terminal/README.zh.md | 16 +- .../tool-terminal/package.json | 4 +- .../tool-terminal/src/background.ts | 2 +- .../tool-terminal/src/index.ts | 2 +- .../tool-terminal/src/render.ts | 0 .../tests/loader-composition.spec.ts | 6 +- .../tool-terminal/tests/render.spec.ts | 2 +- .../tool-terminal/tests/tools.spec.ts | 2 +- .../tool-terminal/tsconfig.json | 2 +- .../webhook-github/README.i18n.yaml | 37 +++ .../webhook-github/README.md | 8 +- .../webhook-github/README.zh.md | 8 +- .../examples/github-review/cordis.yml | 6 +- .../github-ready-review-rule.mjs | 2 +- .../webhook-github/package.json | 13 +- .../webhook-github/src/body.ts | 0 .../webhook-github/src/handler.ts | 2 +- .../webhook-github/src/index.ts | 0 .../webhook-github/src/types.ts | 2 +- .../webhook-github/tests/body.spec.ts | 0 .../webhook-github/tests/config.spec.ts | 0 .../webhook-github/tests/handler.spec.ts | 0 .../tests/loader-composition.spec.ts | 4 +- .../webhook-github/tsconfig.json | 0 .../experimental/webhook/README.i18n.yaml | 46 +++ .../webhook/README.md | 4 +- .../webhook/README.zh.md | 4 +- .../webhook/package.json | 4 +- .../webhook/src/brand.ts | 0 .../webhook/src/index.ts | 0 .../webhook/src/session.ts | 0 .../webhook/src/types.ts | 0 .../webhook/tests/loader-composition.spec.ts | 4 +- .../webhook/tests/runtime.spec.ts | 0 .../webhook/tests/session.spec.ts | 0 .../webhook/tsconfig.json | 0 packages/hooks/README.i18n.yaml | 25 -- packages/hooks/README.md | 50 --- packages/hooks/README.zh.md | 50 --- packages/hooks/hook-protocol/README.i18n.yaml | 61 ---- .../hooks/hooks-claude-code/README.i18n.yaml | 88 ----- packages/hooks/hooks-codex/README.i18n.yaml | 88 ----- packages/session/README.i18n.yaml | 8 +- packages/session/README.md | 3 +- packages/session/README.zh.md | 3 +- .../README.i18n.yaml | 64 ---- .../README.i18n.yaml | 4 +- .../session-title-first-prompt-llm/README.md | 2 +- .../README.zh.md | 2 +- .../session-title-llm/README.i18n.yaml | 8 +- packages/session/session-title-llm/README.md | 4 +- .../session/session-title-llm/README.zh.md | 4 +- .../session/session-title/README.i18n.yaml | 8 +- packages/session/session-title/README.md | 4 +- packages/session/session-title/README.zh.md | 4 +- .../tool-bash-persistent/README.i18n.yaml | 4 +- packages/shell/tool-bash-persistent/README.md | 2 +- .../shell/tool-bash-persistent/README.zh.md | 2 +- packages/skill/README.i18n.yaml | 12 +- packages/skill/README.md | 5 +- packages/skill/README.zh.md | 5 +- packages/skill/skill-badge/README.i18n.yaml | 55 --- packages/terminal/README.i18n.yaml | 12 +- packages/terminal/README.md | 5 +- packages/terminal/README.zh.md | 5 +- .../terminal/terminal-bash/README.i18n.yaml | 8 +- packages/terminal/terminal-bash/README.md | 6 +- packages/terminal/terminal-bash/README.zh.md | 6 +- packages/terminal/terminal/README.i18n.yaml | 20 +- packages/terminal/terminal/README.md | 12 +- packages/terminal/terminal/README.zh.md | 12 +- .../terminal/tool-terminal/README.i18n.yaml | 100 ------ packages/webhook/README.i18n.yaml | 25 -- packages/webhook/README.md | 38 --- packages/webhook/README.zh.md | 38 --- .../webhook/webhook-github/README.i18n.yaml | 37 --- packages/webhook/webhook/README.i18n.yaml | 46 --- packages/workflow/README.i18n.yaml | 8 +- packages/workflow/README.md | 5 +- packages/workflow/README.zh.md | 5 +- packages/workflow/tool-ralph/README.i18n.yaml | 100 ------ .../workflow/workflow-ptc/README.i18n.yaml | 8 +- packages/workflow/workflow-ptc/README.md | 4 +- packages/workflow/workflow-ptc/README.zh.md | 4 +- python/sdk-runtime/package.json | 4 - .../build-exe-for-python-sdk-assets.spec.ts | 2 +- scripts/build-exe-for-python-sdk.ts | 4 +- scripts/check-workspace-constraints.ts | 3 +- scripts/doc-standard.spec.ts | 2 +- scripts/gen-doc-graphs.ts | 24 +- scripts/gen-tool-catalog.ts | 12 +- scripts/no-unknown-casts.baseline.json | 24 +- scripts/product-package-policy.ts | 50 +++ scripts/run-gates.spec.ts | 2 +- scripts/run-gates.ts | 2 + scripts/smoke-python-runtime.py | 1 - .../verify-package-readme-model-experience.ts | 6 +- scripts/verify-product-use.spec.ts | 288 ++++++++++++++++ scripts/verify-product-use.ts | 312 ++++++++++++++++++ scripts/verify-subsystem-pages.ts | 1 - snapshots/acp/escalation-approved/cordis.yml | 4 +- snapshots/sdk/persistent-tools/cordis.yml | 4 - snapshots/session/headless.snapshot.ts | 8 +- .../cordis.snapshot.yml | 2 +- .../pty-tools-sandbox-backend/cordis.yml | 2 +- .../session/ralph-loop/cordis.snapshot.yml | 8 +- snapshots/session/ralph-loop/cordis.yml | 13 +- snapshots/session/text-turn/cordis.yml | 4 +- tsconfig.base.json | 19 +- tsconfig.host.json | 18 +- 259 files changed, 2366 insertions(+), 1512 deletions(-) create mode 100644 .agents/notes/implemented/process/2026-10-05-product-package-classification.i18n.yaml create mode 100644 .agents/notes/implemented/process/2026-10-05-product-package-classification.md create mode 100644 .agents/notes/implemented/process/2026-10-05-product-package-classification.zh.md create mode 100644 apps/cli/tests/profiles/webhook-packed.e2e.ts create mode 100644 docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.i18n.yaml create mode 100644 docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.md create mode 100644 docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.zh.md create mode 100644 packages/experimental/hook-protocol/README.i18n.yaml rename packages/{hooks => experimental}/hook-protocol/README.md (86%) rename packages/{hooks => experimental}/hook-protocol/README.zh.md (86%) rename packages/{hooks => experimental}/hook-protocol/package.json (90%) rename packages/{hooks => experimental}/hook-protocol/src/codec.ts (99%) rename packages/{hooks => experimental}/hook-protocol/src/detached.ts (97%) rename packages/{hooks => experimental}/hook-protocol/src/events.ts (98%) rename packages/{hooks => experimental}/hook-protocol/src/index.ts (95%) rename packages/{hooks => experimental}/hook-protocol/src/matcher.ts (98%) rename packages/{hooks => experimental}/hook-protocol/src/merge.ts (98%) rename packages/{hooks => experimental}/hook-protocol/src/runner.ts (98%) rename packages/{hooks => experimental}/hook-protocol/src/types.ts (98%) rename packages/{hooks => experimental}/hook-protocol/tests/codec.spec.ts (99%) rename packages/{hooks => experimental}/hook-protocol/tests/detached.spec.ts (97%) rename packages/{hooks => experimental}/hook-protocol/tests/events.spec.ts (98%) rename packages/{hooks => experimental}/hook-protocol/tests/matcher.spec.ts (98%) rename packages/{hooks => experimental}/hook-protocol/tests/merge.spec.ts (96%) rename packages/{hooks => experimental}/hook-protocol/tests/runner.spec.ts (98%) rename packages/{hooks => experimental}/hook-protocol/tsconfig.json (100%) create mode 100644 packages/experimental/hooks-claude-code/README.i18n.yaml rename packages/{hooks => experimental}/hooks-claude-code/README.md (94%) rename packages/{hooks => experimental}/hooks-claude-code/README.zh.md (94%) rename packages/{hooks => experimental}/hooks-claude-code/package.json (88%) rename packages/{hooks => experimental}/hooks-claude-code/src/config.ts (97%) rename packages/{hooks => experimental}/hooks-claude-code/src/index.ts (98%) rename packages/{hooks => experimental}/hooks-claude-code/tests/bridge.spec.ts (99%) rename packages/{hooks => experimental}/hooks-claude-code/tests/config.spec.ts (98%) rename packages/{hooks => experimental}/hooks-claude-code/tests/coverage-cases.ts (99%) rename packages/{hooks => experimental}/hooks-claude-code/tests/coverage-config.spec.ts (100%) rename packages/{hooks => experimental}/hooks-claude-code/tests/coverage-context.spec.ts (100%) rename packages/{hooks => experimental}/hooks-claude-code/tests/coverage-edge-paths.spec.ts (100%) rename packages/{hooks => experimental}/hooks-claude-code/tests/coverage-stop.spec.ts (100%) rename packages/{hooks => experimental}/hooks-claude-code/tsconfig.json (100%) create mode 100644 packages/experimental/hooks-codex/README.i18n.yaml rename packages/{hooks => experimental}/hooks-codex/README.md (93%) rename packages/{hooks => experimental}/hooks-codex/README.zh.md (93%) rename packages/{hooks => experimental}/hooks-codex/package.json (88%) rename packages/{hooks => experimental}/hooks-codex/src/config.ts (97%) rename packages/{hooks => experimental}/hooks-codex/src/index.ts (99%) rename packages/{hooks => experimental}/hooks-codex/tests/bridge.spec.ts (99%) rename packages/{hooks => experimental}/hooks-codex/tests/config.spec.ts (99%) rename packages/{hooks => experimental}/hooks-codex/tests/coverage-cases.ts (99%) rename packages/{hooks => experimental}/hooks-codex/tests/coverage-post-tool.spec.ts (100%) rename packages/{hooks => experimental}/hooks-codex/tests/coverage-prompt.spec.ts (100%) rename packages/{hooks => experimental}/hooks-codex/tests/coverage-result-shape.spec.ts (100%) rename packages/{hooks => experimental}/hooks-codex/tsconfig.json (100%) create mode 100644 packages/experimental/session-title-all-prompts-llm/README.i18n.yaml rename packages/{session => experimental}/session-title-all-prompts-llm/README.md (68%) rename packages/{session => experimental}/session-title-all-prompts-llm/README.zh.md (66%) rename packages/{session => experimental}/session-title-all-prompts-llm/package.json (90%) rename packages/{session => experimental}/session-title-all-prompts-llm/src/index.ts (100%) rename packages/{session => experimental}/session-title-all-prompts-llm/tests/provider.spec.ts (97%) rename packages/{session => experimental}/session-title-all-prompts-llm/tsconfig.json (76%) create mode 100644 packages/experimental/skill-badge/README.i18n.yaml rename packages/{skill => experimental}/skill-badge/README.md (85%) rename packages/{skill => experimental}/skill-badge/README.zh.md (85%) rename packages/{skill => experimental}/skill-badge/assets/dsh-badge.md (100%) rename packages/{skill => experimental}/skill-badge/assets/dsh-badge.png (100%) rename packages/{skill => experimental}/skill-badge/package.json (88%) rename packages/{skill => experimental}/skill-badge/src/index.ts (97%) rename packages/{skill => experimental}/skill-badge/tests/skill-badge.spec.ts (93%) rename packages/{skill => experimental}/skill-badge/tsconfig.json (87%) create mode 100644 packages/experimental/tool-ralph/README.i18n.yaml rename packages/{workflow => experimental}/tool-ralph/README.md (93%) rename packages/{workflow => experimental}/tool-ralph/README.zh.md (92%) rename packages/{workflow => experimental}/tool-ralph/package.json (94%) rename packages/{workflow => experimental}/tool-ralph/src/index.ts (99%) rename packages/{workflow => experimental}/tool-ralph/tests/integration.spec.ts (98%) rename packages/{workflow => experimental}/tool-ralph/tests/tool-ralph.spec.ts (99%) rename packages/{workflow => experimental}/tool-ralph/tsconfig.json (93%) create mode 100644 packages/experimental/tool-terminal/README.i18n.yaml rename packages/{terminal => experimental}/tool-terminal/README.md (84%) rename packages/{terminal => experimental}/tool-terminal/README.zh.md (84%) rename packages/{terminal => experimental}/tool-terminal/package.json (95%) rename packages/{terminal => experimental}/tool-terminal/src/background.ts (95%) rename packages/{terminal => experimental}/tool-terminal/src/index.ts (99%) rename packages/{terminal => experimental}/tool-terminal/src/render.ts (100%) rename packages/{terminal => experimental}/tool-terminal/tests/loader-composition.spec.ts (96%) rename packages/{terminal => experimental}/tool-terminal/tests/render.spec.ts (97%) rename packages/{terminal => experimental}/tool-terminal/tests/tools.spec.ts (99%) rename packages/{terminal => experimental}/tool-terminal/tsconfig.json (94%) create mode 100644 packages/experimental/webhook-github/README.i18n.yaml rename packages/{webhook => experimental}/webhook-github/README.md (79%) rename packages/{webhook => experimental}/webhook-github/README.zh.md (78%) rename {apps/cli/config => packages/experimental/webhook-github}/examples/github-review/cordis.yml (85%) rename {apps/cli/config => packages/experimental/webhook-github}/examples/github-review/github-ready-review-rule.mjs (97%) rename packages/{webhook => experimental}/webhook-github/package.json (77%) rename packages/{webhook => experimental}/webhook-github/src/body.ts (100%) rename packages/{webhook => experimental}/webhook-github/src/handler.ts (99%) rename packages/{webhook => experimental}/webhook-github/src/index.ts (100%) rename packages/{webhook => experimental}/webhook-github/src/types.ts (92%) rename packages/{webhook => experimental}/webhook-github/tests/body.spec.ts (100%) rename packages/{webhook => experimental}/webhook-github/tests/config.spec.ts (100%) rename packages/{webhook => experimental}/webhook-github/tests/handler.spec.ts (100%) rename packages/{webhook => experimental}/webhook-github/tests/loader-composition.spec.ts (95%) rename packages/{webhook => experimental}/webhook-github/tsconfig.json (100%) create mode 100644 packages/experimental/webhook/README.i18n.yaml rename packages/{webhook => experimental}/webhook/README.md (91%) rename packages/{webhook => experimental}/webhook/README.zh.md (90%) rename packages/{webhook => experimental}/webhook/package.json (95%) rename packages/{webhook => experimental}/webhook/src/brand.ts (100%) rename packages/{webhook => experimental}/webhook/src/index.ts (100%) rename packages/{webhook => experimental}/webhook/src/session.ts (100%) rename packages/{webhook => experimental}/webhook/src/types.ts (100%) rename packages/{webhook => experimental}/webhook/tests/loader-composition.spec.ts (96%) rename packages/{webhook => experimental}/webhook/tests/runtime.spec.ts (100%) rename packages/{webhook => experimental}/webhook/tests/session.spec.ts (100%) rename packages/{webhook => experimental}/webhook/tsconfig.json (100%) delete mode 100644 packages/hooks/README.i18n.yaml delete mode 100644 packages/hooks/README.md delete mode 100644 packages/hooks/README.zh.md delete mode 100644 packages/hooks/hook-protocol/README.i18n.yaml delete mode 100644 packages/hooks/hooks-claude-code/README.i18n.yaml delete mode 100644 packages/hooks/hooks-codex/README.i18n.yaml delete mode 100644 packages/session/session-title-all-prompts-llm/README.i18n.yaml delete mode 100644 packages/skill/skill-badge/README.i18n.yaml delete mode 100644 packages/terminal/tool-terminal/README.i18n.yaml delete mode 100644 packages/webhook/README.i18n.yaml delete mode 100644 packages/webhook/README.md delete mode 100644 packages/webhook/README.zh.md delete mode 100644 packages/webhook/webhook-github/README.i18n.yaml delete mode 100644 packages/webhook/webhook/README.i18n.yaml delete mode 100644 packages/workflow/tool-ralph/README.i18n.yaml create mode 100644 scripts/product-package-policy.ts create mode 100644 scripts/verify-product-use.spec.ts create mode 100644 scripts/verify-product-use.ts diff --git a/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml b/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml index e56fd4028e..87b1ee3a4b 100644 --- a/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml @@ -12,8 +12,8 @@ en: 5656c117648160c8 zh: 7f7c3de8e2ea6d9a /agent-note-persistent-pty-sessions/decision/package-topology: - en: 0187ac573d06a360 - zh: 13e08f4f22bacfff + en: 98d7a77fa6cb717e + zh: b2364ffe4827ac11 /agent-note-persistent-pty-sessions/decision/agent-ownership-and-identity: en: 9bf79081f102eb51 zh: 34855888f0614b47 @@ -21,8 +21,8 @@ en: 882bbfd3f0dc6e09 zh: a547d6ff5e6ef7a1 /agent-note-persistent-pty-sessions/decision/six-model-facing-tools: - en: b92715f36550c728 - zh: e18d7e0e2363347a + en: e124f17351795dba + zh: 9f91f729ca384bb2 /agent-note-persistent-pty-sessions/decision/local-readiness-detection: en: 8f36f06869bd5367 zh: f3560477a8965cbe @@ -33,8 +33,8 @@ en: e96a972845bc3513 zh: d76d7dfb80985e9d /agent-note-persistent-pty-sessions/decision/composition-and-rollout: - en: db49b6dff73d8772 - zh: 1f2182fd2c7dc3af + en: 9473f6670c12c8e7 + zh: 882f8302007e6026 /agent-note-persistent-pty-sessions/decision/deferred-work: en: c0ae6d86dd5c0635 zh: 737bd3fda903d5e3 diff --git a/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md b/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md index 43a707e661..5ba80a1667 100644 --- a/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md +++ b/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md @@ -24,7 +24,7 @@ The implementation supports interactive shells and line-oriented REPLs on Linux |---|---|---| | `dsh-terminal` | `TerminalSessionService`, branded `TerminalSessionId`, backend registry, owner-scoped session contract, and result types | `ctx.terminals` | | `dsh-terminal-bash` | Persistent-shell backend over `ctx.subprocess.spawnTerminal()`: readiness, bounded terminal buffers, sandbox resolution, and owner-aware session lifecycle | registers a backend on `ctx.terminals` | -| `dsh-tool-terminal` | Six model-facing tools, task-runtime integration for background sends, guidance, and UI render intents | registers on `ctx.tools` | +| `dsh-experimental-tool-terminal` | Six model-facing tools, task-runtime integration for background sends, guidance, and UI render intents | registers on `ctx.tools` | Readiness remains PTY-backend behavior, not a second public contract. The terminal-process provider supplies only substrate facts such as the foreground process group and whether it can prove that group is waiting on input; `dsh-terminal-bash` combines those facts with prompt and silence evidence into the common send result. @@ -62,9 +62,9 @@ The UI render contract is exact and location-free. `terminal_send` uses terminal `terminal_send({ sessionId, text, submit?, run_in_background? })` treats `text` as UTF-8 bytes and resolves `submit` to `true` in the tool implementation. When `submit` is true it writes the platform Enter sequence after the text; when false it writes only the text, allowing control characters and REPL fragments without hidden content heuristics. Cancellation marks queued input before signaling the real foreground group, so input cannot execute if an asynchronous pre-write inspection settles afterward. The canceled send retains its reservation until asynchronous foreground signalling settles, so a successor cannot become that signal's target. `enableRunInBackground` defaults to true; false removes `run_in_background` from the schema and rejects the same undeclared argument if a caller forces it through execution. -Foreground sends return a bounded rendered delta and two independent facts: `waitReason` (`stdin_read | inferred_idle | timeout | session_exit`) and `sessionStatus` (`running` or `exited` with exit code or signal). `session_exit` refers to the PTY's top-level shell process, not an arbitrary foreground command whose status the shell consumes. A timeout never implies process exit. `dsh-tool-terminal.maxResultBytes` defaults to 262144, rejects values below 64 so creation acknowledgements retain registry-issued ids, and caps each single-text UTF-8 result after normalized tool or pipeline errors, wait, session, pagination, truncation, generic task-status wrappers, policy denials or short-circuits, and post-execute replacements or blocks; the terminal definitions' last-mile `finalizeContent` callback leaves deliberately structured multi-block policy content unchanged. The renderer reserves suffix space and preserves code-point boundaries instead of treating the backend payload cap as the final model bound. +Foreground sends return a bounded rendered delta and two independent facts: `waitReason` (`stdin_read | inferred_idle | timeout | session_exit`) and `sessionStatus` (`running` or `exited` with exit code or signal). `session_exit` refers to the PTY's top-level shell process, not an arbitrary foreground command whose status the shell consumes. A timeout never implies process exit. `dsh-experimental-tool-terminal.maxResultBytes` defaults to 262144, rejects values below 64 so creation acknowledgements retain registry-issued ids, and caps each single-text UTF-8 result after normalized tool or pipeline errors, wait, session, pagination, truncation, generic task-status wrappers, policy denials or short-circuits, and post-execute replacements or blocks; the terminal definitions' last-mile `finalizeContent` callback leaves deliberately structured multi-block policy content unchanged. The renderer reserves suffix space and preserves code-point boundaries instead of treating the backend payload cap as the final model bound. -With `run_in_background: true`, `dsh-tool-terminal` registers the in-flight send on `ctx.jobs` and returns immediately with `jobId`. The producer places `maxResultBytes` on the task snapshot so `job_output`, terminal kill status, and completion notices enforce the same complete-result cap after generic metadata. `job_output(wait: true)` waits, reads incremental output, and records the final result; `job_kill` resolves the current foreground PGID and delivers a real `SIGINT`, including when the application has disabled terminal `ISIG`, and escalates only through the PTY backend's owned teardown path. If the task surface is absent, background mode fails before writing input. No PTY-specific `sleep` tool or general wake-up API is added. +With `run_in_background: true`, `dsh-experimental-tool-terminal` registers the in-flight send on `ctx.jobs` and returns immediately with `jobId`. The producer places `maxResultBytes` on the task snapshot so `job_output`, terminal kill status, and completion notices enforce the same complete-result cap after generic metadata. `job_output(wait: true)` waits, reads incremental output, and records the final result; `job_kill` resolves the current foreground PGID and delivers a real `SIGINT`, including when the application has disabled terminal `ISIG`, and escalates only through the PTY backend's owned teardown path. If the task surface is absent, background mode fails before writing input. No PTY-specific `sleep` tool or general wake-up API is added. `terminal_read` pages backward from the newest retained line. The backend enforces both line and UTF-8 byte caps on retained scrollback and the returned page payload, so one oversized line cannot bypass the backend bound; the tool then caps the fully rendered page including pagination and truncation metadata. `truncated` distinguishes retention loss from an ordinary viewport delta. @@ -122,13 +122,13 @@ plugins: handoffGraceMs: 500 timeoutMs: 30000 disposeGraceMs: 3000 - '@deepseek-ai/dsh-tool-terminal': + '@deepseek-ai/dsh-experimental-tool-terminal': config: enableRunInBackground: true maxResultBytes: 262144 ``` -The package ships concise tool guidance explaining persistent state, owner isolation, uncertain idle results, cleanup, and the preference for existing one-shot tools when interaction is unnecessary. It does not mount PTY in the base shipped examples: PTY is opt-in through the dedicated composition, while ACP and headless snapshot overlays exercise it. Within an enabled `dsh-tool-terminal` instance, the six tools and `run_in_background` are enabled by default; deployments may disable only the background argument with config. +The package ships concise tool guidance explaining persistent state, owner isolation, uncertain idle results, cleanup, and the preference for existing one-shot tools when interaction is unnecessary. It does not mount PTY in the base shipped examples: PTY is opt-in through the dedicated composition, while ACP and headless snapshot overlays exercise it. Within an enabled `dsh-experimental-tool-terminal` instance, the six tools and `run_in_background` are enabled by default; deployments may disable only the background argument with config. ### Deferred work diff --git a/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md b/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md index 04891dc106..8527df120e 100644 --- a/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md +++ b/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md @@ -24,7 +24,7 @@ harness 可以运行前台与后台命令、编辑文件和委派工作,但无 |---|---|---| | `dsh-terminal` | `TerminalSessionService`、branded `TerminalSessionId`、后端注册表、按 owner 隔离的会话约定和结果类型 | `ctx.terminals` | | `dsh-terminal-bash` | 基于 `ctx.subprocess.spawnTerminal()` 的持久 shell 后端:就绪状态、有界终端缓冲、沙箱解析和感知 owner 的会话生命周期 | 在 `ctx.terminals` 上注册后端 | -| `dsh-tool-terminal` | 6 个面向模型的工具、后台发送的 task 运行时集成、使用指引和 UI 渲染意图 | 注册到 `ctx.tools` | +| `dsh-experimental-tool-terminal` | 6 个面向模型的工具、后台发送的 task 运行时集成、使用指引和 UI 渲染意图 | 注册到 `ctx.tools` | 就绪判定仍属于 PTY 后端行为,不是第二条公共约定。终端进程提供方只提供基底事实,例如前台进程组,以及能否证明该组正在等待输入;`dsh-terminal-bash` 将这些事实与提示符和静默证据组合成统一的发送结果。 @@ -62,9 +62,9 @@ UI 渲染约定精确且不携带位置信息。`terminal_send` 只为前台发 `terminal_send({ sessionId, text, submit?, run_in_background? })` 将 `text` 视为 UTF-8 字节,并由工具实现在解析阶段把 `submit` 默认成 `true`。`submit` 为 true 时先写入文本,再写入平台 Enter 序列;为 false 时只写文本,使控制字符和 REPL 片段无需隐藏的内容启发式即可发送。取消会在向真实前台进程组发送信号前将排队输入标记为已取消,因此即使异步的写入前检查随后才结算,该输入也无法执行。被取消的发送会保留其预留,直至异步前台信号发送结算,因此后续发送不会成为该信号的目标。`enableRunInBackground` 默认为 true;设为 false 时,schema 中会移除 `run_in_background`,调用方即使强行把这个未声明参数传入执行流程,也会被拒绝。 -前台发送返回有界的渲染增量和两个独立事实:`waitReason`(`stdin_read | inferred_idle | timeout | session_exit`)与 `sessionStatus`(`running`,或携带退出码或信号的 `exited`)。`session_exit` 指 PTY 顶层 shell 进程退出,不指由 shell 消费状态的任意前台命令。timeout 从不意味着进程已经退出。`dsh-tool-terminal.maxResultBytes` 默认为 262144;低于 64 的值会被拒绝,以确保创建确认保留注册表签发的 id;每个单文本 UTF-8 结果在加入规范化的工具或流水线错误、等待、会话、分页、截断、通用 task 状态包装、策略拒绝或短路以及 post-execute 替换或阻断后,仍受该值限制;终端定义自有的末端 `finalizeContent` callback 会原样保留策略刻意返回的结构化多块内容。渲染器会为后缀预留空间并保持代码点边界,而不会把后端载荷上限当作面向模型结果的最终上限。 +前台发送返回有界的渲染增量和两个独立事实:`waitReason`(`stdin_read | inferred_idle | timeout | session_exit`)与 `sessionStatus`(`running`,或携带退出码或信号的 `exited`)。`session_exit` 指 PTY 顶层 shell 进程退出,不指由 shell 消费状态的任意前台命令。timeout 从不意味着进程已经退出。`dsh-experimental-tool-terminal.maxResultBytes` 默认为 262144;低于 64 的值会被拒绝,以确保创建确认保留注册表签发的 id;每个单文本 UTF-8 结果在加入规范化的工具或流水线错误、等待、会话、分页、截断、通用 task 状态包装、策略拒绝或短路以及 post-execute 替换或阻断后,仍受该值限制;终端定义自有的末端 `finalizeContent` callback 会原样保留策略刻意返回的结构化多块内容。渲染器会为后缀预留空间并保持代码点边界,而不会把后端载荷上限当作面向模型结果的最终上限。 -当 `run_in_background: true` 时,`dsh-tool-terminal` 在 `ctx.jobs` 上注册进行中的发送,并立即返回 `jobId`。生产方把 `maxResultBytes` 写入 task 快照,使 `job_output`、kill 返回的终态状态和完成通知在加上通用元数据后,仍对完整结果执行同一上限。`job_output(wait: true)` 负责等待、读取增量输出并记录最终结果;`job_kill` 会解析当前前台 PGID 并发送真正的 `SIGINT`,即使应用已禁用终端 `ISIG` 也同样如此,且后续升级仍只通过 PTY 后端拥有的 teardown 路径进行。若 task 对外接口不存在,后台模式必须在写入输入前失败。设计不新增 PTY 专用的 `sleep` 工具或通用唤醒 API。 +当 `run_in_background: true` 时,`dsh-experimental-tool-terminal` 在 `ctx.jobs` 上注册进行中的发送,并立即返回 `jobId`。生产方把 `maxResultBytes` 写入 task 快照,使 `job_output`、kill 返回的终态状态和完成通知在加上通用元数据后,仍对完整结果执行同一上限。`job_output(wait: true)` 负责等待、读取增量输出并记录最终结果;`job_kill` 会解析当前前台 PGID 并发送真正的 `SIGINT`,即使应用已禁用终端 `ISIG` 也同样如此,且后续升级仍只通过 PTY 后端拥有的 teardown 路径进行。若 task 对外接口不存在,后台模式必须在写入输入前失败。设计不新增 PTY 专用的 `sleep` 工具或通用唤醒 API。 `terminal_read` 从最新保留行向后分页。后端同时对保留的 scrollback 和返回页载荷执行行数与 UTF-8 字节上限,因此单个超长行无法绕过后端上限;工具随后再限制包含分页与截断元数据的完整渲染页。`truncated` 用于区分保留数据丢失与普通 viewport 增量。 @@ -122,13 +122,13 @@ plugins: handoffGraceMs: 500 timeoutMs: 30000 disposeGraceMs: 3000 - '@deepseek-ai/dsh-tool-terminal': + '@deepseek-ai/dsh-experimental-tool-terminal': config: enableRunInBackground: true maxResultBytes: 262144 ``` -包提供简洁的工具指引,说明持久状态、owner 隔离、不确定的 idle 结果、清理,以及无需交互时优先使用现有一次性工具。已发布的基础示例不挂载 PTY:PTY 仅通过专用组合 opt-in,而 ACP(Agent Client Protocol)与 headless 快照 overlay 会对其进行验证。`dsh-tool-terminal` 实例一旦启用,6 个工具和 `run_in_background` 就会默认启用;部署可通过配置仅禁用后台参数。 +包提供简洁的工具指引,说明持久状态、owner 隔离、不确定的 idle 结果、清理,以及无需交互时优先使用现有一次性工具。已发布的基础示例不挂载 PTY:PTY 仅通过专用组合 opt-in,而 ACP(Agent Client Protocol)与 headless 快照 overlay 会对其进行验证。`dsh-experimental-tool-terminal` 实例一旦启用,6 个工具和 `run_in_background` 就会默认启用;部署可通过配置仅禁用后台参数。 ### 推迟的工作 diff --git a/.agents/notes/implemented/process/2026-10-05-product-package-classification.i18n.yaml b/.agents/notes/implemented/process/2026-10-05-product-package-classification.i18n.yaml new file mode 100644 index 0000000000..7673f38075 --- /dev/null +++ b/.agents/notes/implemented/process/2026-10-05-product-package-classification.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-10-05-product-package-classification.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-10-05-product-package-classification.md +/agent-note-require-product-use-or-an-explicit-package-classification: + en: 8caa2edff065f7db + zh: 163ee0f31c7adc6a +/agent-note-require-product-use-or-an-explicit-package-classification/problem: + en: 748eb2bf5f645911 + zh: b123aec22395193a +/agent-note-require-product-use-or-an-explicit-package-classification/decision: + en: 8678a01d48195e8f + zh: 9052cc7f64ed452f +/agent-note-require-product-use-or-an-explicit-package-classification/alternatives-considered: + en: 67177e349ecb70de + zh: e8263b9445f46ded +/agent-note-require-product-use-or-an-explicit-package-classification/consequences: + en: 449278a2bccea70e + zh: 5eb28c22783ac6cf diff --git a/.agents/notes/implemented/process/2026-10-05-product-package-classification.md b/.agents/notes/implemented/process/2026-10-05-product-package-classification.md new file mode 100644 index 0000000000..2f3a76ae85 --- /dev/null +++ b/.agents/notes/implemented/process/2026-10-05-product-package-classification.md @@ -0,0 +1,29 @@ +# Agent Note: Require product use or an explicit package classification + +Status: implemented + +English | [中文](2026-10-05-product-package-classification.zh.md) + +## Problem + +An installation dependency can remain dormant indefinitely. Its presence in the dependency graph does not establish that a shipped profile, runtime import, or optional capability uses it. Conversely, an embedding SDK or a deployment-configured provider can have a maintained product role without appearing in the default GUI. + +## Decision + +Nonexperimental packages have effective product use or an explicit entry in the [package policy](../../../../scripts/product-package-policy.ts). The policy distinguishes optional integrations, SDKs, build tools, test tools, Web distribution packages, and declaration-only infrastructure. Each exception records its maintained role. [Experimental status](../../../../packages/experimental/README.md#status) describes maturity and support, independently of installation, optional selection, and Official discovery. + +The [product-use check](../../../../scripts/verify-product-use.ts) follows effective shipped profiles, preset children, runtime source imports, and explicit dynamic mounts. It preserves disabled state through groups and Includes and applies patches before counting use. Manifest dependencies and type-only references do not create runtime use. Optional-bundle reachability remains separate from default reachability. Unknown packages and invalid or stale policy entries fail static CI and package hygiene. + +The [default-product isolation rule](2026-09-12-default-product-experimental-isolation.md) remains independent: its conservative installation and declaration traversal rejects unintended experimental dependencies even when they are disabled. That traversal cannot establish active product use. + +## Alternatives considered + +**Treat every installed package as used.** A redundant dependency would satisfy its own classification requirement and conceal dormant code. + +**Classify every nondefault capability as experimental.** Deployment prerequisites and installation cost do not establish immaturity; supported optional providers and SDKs need separate categories. + +**Count every declared patch row.** A disabled Include, missing target, or later replacement can prevent that row from mounting. Only the effective composition establishes use. + +## Consequences + +Adding a nonexperimental package requires a product consumer or a reviewed classification. Renames and reduced in-box availability require upgrade instructions, while recorded events and released data keep their existing obligations. Regression fixtures reject manifest-only dependencies, disabled subtrees, ineffective patches, and stale classifications. SDK, test, build, and declaration packages remain independently installable without acquiring a runtime mount requirement. diff --git a/.agents/notes/implemented/process/2026-10-05-product-package-classification.zh.md b/.agents/notes/implemented/process/2026-10-05-product-package-classification.zh.md new file mode 100644 index 0000000000..e53da65c0e --- /dev/null +++ b/.agents/notes/implemented/process/2026-10-05-product-package-classification.zh.md @@ -0,0 +1,29 @@ +# Agent Note: Require product use or an explicit package classification + +Status: implemented + +[English](2026-10-05-product-package-classification.md) | 中文 + +## 问题 + +安装依赖可能长期处于休眠状态。出现在依赖图中,并不表明随附 profile、运行时导入或可选能力使用了它。反过来,嵌入式 SDK 或需要部署配置的提供方即使不出现在默认 GUI 中,也可以承担维护中的产品职责。 + +## 决策 + +非实验包必须具有有效产品用途,或在[包策略](../../../../scripts/product-package-policy.ts)中显式列出。策略区分可选集成、SDK、构建工具、测试工具、Web 分发包和纯声明基础设施,每个例外记录其维护职责。[实验性状态](../../../../packages/experimental/README.zh.md#status)描述成熟度与支持承诺,独立于安装、可选启用与官方发现。 + +[产品用途检查](../../../../scripts/verify-product-use.ts)跟踪有效的随附 profile、预设子行、运行时源码导入与显式动态挂载。检查在组与 Include 中保留禁用状态,并先应用 patch 再统计用途。Manifest 依赖和纯类型引用不产生运行时用途。可选组合包的可达关系与默认可达关系分别计算。未知包及无效或过时的策略条目会使静态 CI 和包卫生检查失败。 + +[默认产品隔离规则](2026-09-12-default-product-experimental-isolation.zh.md)保持独立:其保守的安装与声明遍历即使对已禁用行,也会拒绝意外实验依赖。该遍历不能证明活动产品用途。 + +## 考虑过的替代方案 + +**将所有已安装包视为已使用。** 冗余依赖本身就能满足分类要求,从而掩盖休眠代码。 + +**将所有非默认能力归为实验性。** 部署前提与安装成本不能证明不成熟;受支持的可选提供方与 SDK 需要独立分类。 + +**统计所有声明的 patch 行。** 禁用的 Include、缺失目标或后续替换都可能阻止该行挂载。只有有效组合才能证明用途。 + +## 影响 + +新增非实验包需要产品消费者或经过审查的分类。改名和减少随附可用性需要升级说明,已记录事件和已发布数据继续遵守既有义务。回归 fixture 拒绝只有 manifest 依赖、禁用子树、无效 patch 和过时分类的情况。SDK、测试、构建与声明包仍可独立安装,无需新增运行时挂载。 diff --git a/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.i18n.yaml b/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.i18n.yaml index 56e07b0a83..6a09cae1de 100644 --- a/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.i18n.yaml @@ -6,8 +6,8 @@ en: cd9f68956ba34672 zh: 1fc649c5eb0d3cf4 /agent-note-pi-extensions-bridge/problem: - en: 9bfc5f0c9ff223a6 - zh: 7c5f026c94677dd8 + en: eb4d3f10c3feedb4 + zh: a1a1a75a724c9a8b /agent-note-pi-extensions-bridge/proposal: en: 56b36193ca6f829d zh: a31e226794c1ca90 diff --git a/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.md b/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.md index 214fcd66dd..28faf5911a 100644 --- a/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.md +++ b/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.md @@ -8,7 +8,7 @@ English | [中文](2026-10-03-pi-extensions-bridge.zh.md) Pi 1.0.0 extensions are in-process TypeScript factories `(pi: ExtensionAPI) => void`. A factory subscribes to about forty lifecycle, context, tool, and provider events, registers model tools, slash commands, model providers, and MCP servers, and talks to the user through `ctx.ui` ([extensions guide](https://github.com/earendil-works/pi/blob/v1.0.0/packages/coding-agent/docs/extensions.md), [API types](https://github.com/earendil-works/pi/blob/v1.0.0/packages/coding-agent/src/core/extensions/types.ts)). The API is published and widely used: about 11,000 npm packages carried the `pi-package` keyword in October 2026. -DSH has bridges for two other ecosystems: shell hooks written for Claude Code and Codex ([hooks group](../../../../packages/hooks/README.md)) and Claude Code mods ([compatibility page](../../../../docs/subsystems/claude-code-mods.md)). Pi's extension API is broader than either. It lets one in-process module rewrite the messages of a single request, edit tool arguments, append its own durable records, and continue a finished run. Serving that API from DSH extension points answers two questions: how much of an extension written for another harness runs unchanged, and which DSH core mechanisms are narrower than Pi's. +DSH has bridges for two other ecosystems: shell hooks written for Claude Code and Codex ([hooks group](../../../../packages/experimental/README.md)) and Claude Code mods ([compatibility page](../../../../docs/subsystems/claude-code-mods.md)). Pi's extension API is broader than either. It lets one in-process module rewrite the messages of a single request, edit tool arguments, append its own durable records, and continue a finished run. Serving that API from DSH extension points answers two questions: how much of an extension written for another harness runs unchanged, and which DSH core mechanisms are narrower than Pi's. ## Proposal diff --git a/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.zh.md b/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.zh.md index 0d3475d439..855f7b160c 100644 --- a/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.zh.md +++ b/.agents/notes/proposed/feature/2026-10-03-pi-extensions-bridge.zh.md @@ -8,7 +8,7 @@ Status: proposed Pi 1.0.0 的扩展是进程内的 TypeScript 工厂函数 `(pi: ExtensionAPI) => void`。工厂函数订阅约四十个生命周期、上下文、工具与提供方事件,注册模型工具、斜杠命令、模型提供商与 MCP server,并通过 `ctx.ui` 与用户交互([扩展指南](https://github.com/earendil-works/pi/blob/v1.0.0/packages/coding-agent/docs/extensions.md)、[API 类型](https://github.com/earendil-works/pi/blob/v1.0.0/packages/coding-agent/src/core/extensions/types.ts))。该 API 已发布并被广泛使用:截至 2026 年 10 月,npm 上约有 11,000 个包带有 `pi-package` 关键字。 -DSH 已为另外两个生态提供桥接:为 Claude Code 与 Codex 编写的 shell 钩子([hooks 组](../../../../packages/hooks/README.zh.md)),以及 Claude Code mods([兼容性页面](../../../../docs/subsystems/claude-code-mods.zh.md))。Pi 的扩展 API 比两者都宽。它允许一个进程内模块改写单次请求的消息、编辑工具参数、追加自己的持久记录,并让已经结束的运行继续。用 DSH 扩展点提供这套 API 可以回答两个问题:为另一个 harness 编写的扩展有多少能原样运行,以及 DSH 的哪些核心机制比 Pi 窄。 +DSH 已为另外两个生态提供桥接:为 Claude Code 与 Codex 编写的 shell 钩子([hooks 组](../../../../packages/experimental/README.zh.md)),以及 Claude Code mods([兼容性页面](../../../../docs/subsystems/claude-code-mods.zh.md))。Pi 的扩展 API 比两者都宽。它允许一个进程内模块改写单次请求的消息、编辑工具参数、追加自己的持久记录,并让已经结束的运行继续。用 DSH 扩展点提供这套 API 可以回答两个问题:为另一个 harness 编写的扩展有多少能原样运行,以及 DSH 的哪些核心机制比 Pi 窄。 ## 提案 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61b65fd893..f2973a365b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -700,7 +700,7 @@ jobs: --testTimeout 90000 packages/shell/tool-pwsh/tests/loader.spec.ts packages/workflow/workflow-ptc/tests/workflow-ptc.spec.ts - packages/workflow/tool-ralph/tests/integration.spec.ts + packages/experimental/tool-ralph/tests/integration.spec.ts packages/subprocess/subprocess-local/tests/process-exit.spec.ts # Single stable required check for branch protection: require "all checks diff --git a/AGENTS.md b/AGENTS.md index 4940e9b484..38e5ae46cf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,7 +40,6 @@ packages/ @deepseek-ai/dsh- workspaces at packages/// jobs/ background jobs bundle/ profile bundles workflow/ workflow execution - webhook/ webhook ingress todo/ todo_write tool plan/ logged planning goal/ session goals @@ -48,7 +47,6 @@ packages/ @deepseek-ai/dsh- workspaces at packages/// preset/ agent composition guard/ loop/tool guards extensions/ runtime self-modification - hooks/ Claude Code/Codex bridges session/ durable sessions session-query/ browsing/search/export attachment/ binary attachments @@ -66,7 +64,7 @@ packages/ @deepseek-ai/dsh- workspaces at packages/// host/ GUI host client/ GUI client mcp/ external tools - experimental/ pre-stable prototypes; public by default with explicit private exceptions + experimental/ evaluated capabilities without a product-support commitment test-support/ test infrastructure util/ zero-dependency utilities python/ Python SDK/runtime (python/README.md) @@ -78,7 +76,7 @@ scripts/ gates and generators website/ VitePress documentation projection ``` -Package groups: [packages/README.md](packages/README.md). +Package groups: [packages/README.md](packages/README.md). [Experimental status](packages/experimental/README.md#status) is independent of optional delivery; nonexperimental packages need product use or an explicit [classification](scripts/product-package-policy.ts). ## Commands diff --git a/apps/cli/composition.md b/apps/cli/composition.md index b8f54e32f7..9888602296 100644 --- a/apps/cli/composition.md +++ b/apps/cli/composition.md @@ -116,8 +116,6 @@ flowchart LR cfg --> plugin_dsh_base_skill plugin_dsh_base_skill_filesystem["skill-filesystem
@deepseek-ai/dsh-skill-filesystem"] cfg --> plugin_dsh_base_skill_filesystem - plugin_dsh_base_skill_badge["skill-badge
@deepseek-ai/dsh-skill-badge"] - cfg --> plugin_dsh_base_skill_badge plugin_dsh_base_tool_skill["tool-skill
@deepseek-ai/dsh-tool-skill"] cfg --> plugin_dsh_base_tool_skill plugin_dsh_base_commands["commands
@deepseek-ai/dsh-commands"] @@ -174,8 +172,6 @@ flowchart LR cfg --> plugin_dsh_base_tool_todo plugin_dsh_base_tool_goal["tool-goal
@deepseek-ai/dsh-tool-goal"] cfg --> plugin_dsh_base_tool_goal - plugin_dsh_base_tool_ralph["tool-ralph
@deepseek-ai/dsh-tool-ralph"] - cfg --> plugin_dsh_base_tool_ralph plugin_dsh_base_repeat_tool_reminder["repeat-tool-reminder
@deepseek-ai/dsh-repeat-tool-reminder"] cfg --> plugin_dsh_base_repeat_tool_reminder plugin_dsh_base_web["web
@deepseek-ai/dsh-web"] @@ -258,7 +254,6 @@ flowchart LR | `agent-instructions` | `@deepseek-ai/dsh-agent-instructions` | | `skill` | `@deepseek-ai/dsh-skill` | | `skill-filesystem` | `@deepseek-ai/dsh-skill-filesystem` | -| `skill-badge` | `@deepseek-ai/dsh-skill-badge` | | `tool-skill` | `@deepseek-ai/dsh-tool-skill` | | `commands` | `@deepseek-ai/dsh-commands` | | `command-feedback` | `@deepseek-ai/dsh-command-feedback` | @@ -287,7 +282,6 @@ flowchart LR | `image-offload` | `@deepseek-ai/dsh-compaction-image-offload` | | `tool-todo` | `@deepseek-ai/dsh-tool-todo` | | `tool-goal` | `@deepseek-ai/dsh-tool-goal` | -| `tool-ralph` | `@deepseek-ai/dsh-tool-ralph` | | `repeat-tool-reminder` | `@deepseek-ai/dsh-repeat-tool-reminder` | | `web` | `@deepseek-ai/dsh-web` | | `web-search-deepseek` | `@deepseek-ai/dsh-web-search-deepseek` | diff --git a/apps/cli/package.json b/apps/cli/package.json index 44f5366fc7..b8e34aa527 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -45,8 +45,6 @@ "@deepseek-ai/dsh-goal-round-driver": "workspace:*", "@deepseek-ai/dsh-headless": "workspace:*", "@deepseek-ai/dsh-home-paths": "workspace:*", - "@deepseek-ai/dsh-hooks-claude-code": "workspace:*", - "@deepseek-ai/dsh-hooks-codex": "workspace:*", "@deepseek-ai/dsh-jobs-local": "workspace:*", "@deepseek-ai/dsh-launch-environment": "workspace:*", "@deepseek-ai/dsh-mcp-client": "workspace:*", @@ -79,7 +77,6 @@ "@deepseek-ai/dsh-tool-jobs": "workspace:*", "@deepseek-ai/dsh-tool-pwsh": "workspace:*", "@deepseek-ai/dsh-tool-pwsh-persistent": "workspace:*", - "@deepseek-ai/dsh-tool-ralph": "workspace:*", "@deepseek-ai/dsh-tool-schedule": "workspace:*", "@deepseek-ai/dsh-tool-skill": "workspace:*", "@deepseek-ai/dsh-tool-str-replace-editor": "workspace:*", @@ -89,8 +86,6 @@ "@deepseek-ai/dsh-tool-web": "workspace:*", "@deepseek-ai/dsh-tool-workflow": "workspace:*", "@deepseek-ai/dsh-web-app": "workspace:*", - "@deepseek-ai/dsh-webhook": "workspace:*", - "@deepseek-ai/dsh-webhook-github": "workspace:*", "@deepseek-ai/dsh-workflow-ptc": "workspace:*", "@deepseek-ai/schemastery": "workspace:~", "commander": "^15.0.0", @@ -107,6 +102,12 @@ "@deepseek-ai/dsh-experimental-tool-worktree": "workspace:*" }, "devDependencies": { + "@deepseek-ai/dsh-experimental-skill-badge": "workspace:*", + "@deepseek-ai/dsh-experimental-webhook-github": "workspace:*", + "@deepseek-ai/dsh-experimental-webhook": "workspace:*", + "@deepseek-ai/dsh-experimental-tool-ralph": "workspace:*", + "@deepseek-ai/dsh-experimental-hooks-codex": "workspace:*", + "@deepseek-ai/dsh-experimental-hooks-claude-code": "workspace:*", "@agentclientprotocol/sdk": "1.4.0", "@deepseek-ai/dsh-acp": "workspace:*", "@deepseek-ai/dsh-agent": "workspace:*", diff --git a/apps/cli/tests/dsh-badge.expected.e2e.ts b/apps/cli/tests/dsh-badge.expected.e2e.ts index ca70622be2..a1f456c5b5 100644 --- a/apps/cli/tests/dsh-badge.expected.e2e.ts +++ b/apps/cli/tests/dsh-badge.expected.e2e.ts @@ -5,7 +5,7 @@ const binScript = fileURLToPath(new URL('./fixtures/dsh-badge/snapshot.ts', impo const configPath = fileURLToPath(new URL('./fixtures/dsh-badge/cordis.yml', import.meta.url)) const defaultConfigPath = fileURLToPath(new URL('./fixtures/dsh-badge/default.cordis.yml', import.meta.url)) const tsconfigPath = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url)) -const badgeAssetsPath = fileURLToPath(new URL('../../../packages/skill/skill-badge/assets/', import.meta.url)) +const badgeAssetsPath = fileURLToPath(new URL('../../../packages/experimental/skill-badge/assets/', import.meta.url)) describe('dsh badge assembled snapshot', () => { it('advertises and loads the opt-in bundled skill through the shipped app', async () => { diff --git a/apps/cli/tests/fixtures/dsh-badge/cordis.yml b/apps/cli/tests/fixtures/dsh-badge/cordis.yml index dd419b684f..bfbbc7c5a7 100644 --- a/apps/cli/tests/fixtures/dsh-badge/cordis.yml +++ b/apps/cli/tests/fixtures/dsh-badge/cordis.yml @@ -1,5 +1,6 @@ -- id: skill-badge - disabled: false +- insert: + - id: skill-badge + name: '@deepseek-ai/dsh-experimental-skill-badge' - id: skill-filesystem config: diff --git a/apps/cli/tests/fixtures/dsh-badge/snapshot.ts b/apps/cli/tests/fixtures/dsh-badge/snapshot.ts index 4c2331ed0b..3a83a4b3b5 100644 --- a/apps/cli/tests/fixtures/dsh-badge/snapshot.ts +++ b/apps/cli/tests/fixtures/dsh-badge/snapshot.ts @@ -11,9 +11,16 @@ const overlayPath = process.argv[2] if (overlayPath === undefined) throw new Error('dsh-badge snapshot requires an overlay path') const rootConfigPath = fileURLToPath(new URL('../../../../../packages/bundle/base/tests/fixtures/root.cordis.yml', import.meta.url)) const basePatchPath = fileURLToPath(new URL('../../../../../packages/bundle/base/cordis.patch.yml', import.meta.url)) +// The fixture owns the optional provider; the base bundle has no dependency on it. +const overlays = loadOverlayPatches('dsh-badge-snapshot', overlayPath).map(patch => patch.insert === undefined ? patch : { + ...patch, + insert: patch.insert.map(row => row.name === '@deepseek-ai/dsh-experimental-skill-badge' + ? { ...row, name: import.meta.resolve('@deepseek-ai/dsh-experimental-skill-badge') } + : row), +}) const ctx = await boot('dsh-badge-snapshot', rootConfigPath, [ ...loadOverlayPatches('dsh-badge-snapshot', basePatchPath), - ...loadOverlayPatches('dsh-badge-snapshot', overlayPath), + ...overlays, ]) try { diff --git a/apps/cli/tests/fixtures/github-webhook/cordis.yml b/apps/cli/tests/fixtures/github-webhook/cordis.yml index 06a90c5e79..2f1efe7115 100644 --- a/apps/cli/tests/fixtures/github-webhook/cordis.yml +++ b/apps/cli/tests/fixtures/github-webhook/cordis.yml @@ -3,7 +3,7 @@ - insert: - id: webhook-runtime - name: '@deepseek-ai/dsh-webhook' + name: '@deepseek-ai/dsh-experimental-webhook' - id: github-webhook-real-e2e-rule name: './github-webhook-rule.mjs' @@ -28,7 +28,7 @@ port: !!js Number(process.env.DSH_GITHUB_WEBHOOK_PORT) - id: github-webhook-real-e2e-adapter - name: '@deepseek-ai/dsh-webhook-github' + name: '@deepseek-ai/dsh-experimental-webhook-github' config: source: github-real-e2e path: /github diff --git a/apps/cli/tests/fixtures/github-webhook/github-webhook-rule.mjs b/apps/cli/tests/fixtures/github-webhook/github-webhook-rule.mjs index 2ae7c8123b..b3d9287801 100644 --- a/apps/cli/tests/fixtures/github-webhook/github-webhook-rule.mjs +++ b/apps/cli/tests/fixtures/github-webhook/github-webhook-rule.mjs @@ -1,5 +1,5 @@ import z from '@deepseek-ai/schemastery' -import { WebhookRuleId } from '@deepseek-ai/dsh-webhook' +import { WebhookRuleId } from '@deepseek-ai/dsh-experimental-webhook' export const name = 'github-webhook-real-e2e-rule' export const inject = ['webhookRuntime'] diff --git a/apps/cli/tests/profiles/webhook-packed.e2e.ts b/apps/cli/tests/profiles/webhook-packed.e2e.ts new file mode 100644 index 0000000000..a68769a7c5 --- /dev/null +++ b/apps/cli/tests/profiles/webhook-packed.e2e.ts @@ -0,0 +1,253 @@ +/** Exercise the published webhook example from an isolated installed Web profile. */ +import { createHmac } from 'node:crypto' +import { createRequire } from 'node:module' +import { existsSync, globSync } from 'node:fs' +import { lstat, mkdir, mkdtemp, readFile, readdir, readlink, realpath, rm, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { dirname, join, relative, sep } from 'node:path' +import { fileURLToPath } from 'node:url' +import { execa } from 'execa' +import yaml from 'js-yaml' +import { expect, it, onTestFinished } from 'vitest' +import { pnpmCommand } from '../../../../scripts/release/process.ts' +import { packedWorkspaceClosure, type WorkspacePackage } from '../../../../packages/sandbox/sandbox-local/tests/packed-workspace-closure.ts' + +const root = fileURLToPath(new URL('../../../..', import.meta.url)) +const adapter = '@deepseek-ai/dsh-experimental-webhook-github' +const runtime = '@deepseek-ai/dsh-experimental-webhook' +const built = existsSync(join(root, 'apps/cli/lib/bin.js')) + && existsSync(join(root, 'packages/experimental/webhook-github/lib/index.js')) +const secret = 'packed-webhook-test-secret' + +/** Capture workspace dependency links without following their targets. */ +async function workspaceLinks(directories: string[]): Promise> { + const links: Record = {} + for (const directory of directories) { + const modules = join(directory, 'node_modules') + links[modules] = existsSync(modules) ? 'directory' : 'absent' + if (!existsSync(modules)) continue + for (const entry of await readdir(modules, { withFileTypes: true })) { + const path = join(modules, entry.name) + const paths = entry.name.startsWith('@') && entry.isDirectory() + ? (await readdir(path)).map(name => join(path, name)) : [path] + for (const dependency of paths) { + const stat = await lstat(dependency) + links[dependency] = stat.isSymbolicLink() ? await readlink(dependency) : stat.isDirectory() ? 'directory' : 'file' + } + } + } + return links +} + +/** Reject workspace links throughout the installed dependency tree. */ +async function assertInstalledTree(directory: string): Promise { + const installedRoot = await realpath(directory) + const visited = new Set() + const visit = async (path: string): Promise => { + const resolved = await realpath(path) + expect(resolved === installedRoot || resolved.startsWith(installedRoot + sep), `${path} escapes its installation`).toBe(true) + if (visited.has(resolved)) return + visited.add(resolved) + for (const entry of await readdir(path, { withFileTypes: true })) { + const child = join(path, entry.name) + if (entry.isSymbolicLink()) { + const target = await realpath(child) + expect(target.startsWith(installedRoot + sep), `${child} escapes its installation`).toBe(true) + } else if (entry.isDirectory()) await visit(child) + } + } + await visit(directory) +} + +it.skipIf(!built)('loads the packed GitHub example with its explicitly installed runtime peer', { + // Packing and installing the complete product closure owns this budget; no model request runs. + timeout: 360_000, + retry: 0, +}, async () => { + const temporary = await realpath(await mkdtemp(join(tmpdir(), 'dsh-webhook-packed-'))) + onTestFinished(() => rm(temporary, { recursive: true, force: true })) + const installation = join(temporary, 'installation') + const home = join(temporary, 'home') + const profile = join(home, 'profiles', 'web') + const archives = join(temporary, 'archives') + await mkdir(profile, { recursive: true }) + await mkdir(archives) + const environment: NodeJS.ProcessEnv = Object.fromEntries(Object.entries(process.env).filter(([key]) => ( + !/KEY|SECRET|TOKEN|PASSWORD/.test(key) && key !== 'NODE_OPTIONS' && key !== 'NODE_PATH' + ))) + Object.assign(environment, { + DSH_HOME: home, + DSH_AGENTS_HOME: join(temporary, 'agents'), + DSH_TELEMETRY_DISABLED: '1', + DSH_GITHUB_WEBHOOK_SECRET: secret, + DSH_GITHUB_WEBHOOK_PORT: '0', + CI: 'true', + }) + const [pnpm, ...prefix] = pnpmCommand() + const packageCommand = async (args: string[], cwd: string) => { + const result = await execa(pnpm, [...prefix, ...args], { + cwd, env: environment, extendEnv: false, timeout: 180_000, reject: false, + }) + expect(result.timedOut, `${result.stdout}\n${result.stderr}`).toBe(false) + expect(result.signal, result.stderr).toBeUndefined() + expect(result.exitCode, `${result.stdout}\n${result.stderr}`).toBe(0) + return result + } + const packages = new Map() + for (const path of globSync([ + 'apps/*/package.json', 'packages/*/*/package.json', 'vendor/*/package.json', 'native/system/packages/*/package.json', + ], { cwd: root })) { + const manifest = JSON.parse(await readFile(join(root, path), 'utf8')) as Record + if (typeof manifest.name !== 'string') throw new Error(`${path} has no package name`) + packages.set(manifest.name, { name: manifest.name, manifest, directory: dirname(join(root, path)) }) + } + const sourceDirectories = [root, ...[...packages.values()].map(member => member.directory)] + const initialLinks = await workspaceLinks(sourceDirectories) + onTestFinished(async () => { expect(await workspaceLinks(sourceDirectories)).toEqual(initialLinks) }) + const closure = packedWorkspaceClosure('@deepseek-ai/dsh', packages) + const runtimeMembers = closure.filter(member => ( + (!Array.isArray(member.manifest.os) || member.manifest.os.includes(process.platform)) + && (!Array.isArray(member.manifest.cpu) || member.manifest.cpu.includes(process.arch)) + )) + const members = new Map(runtimeMembers.map(member => [member.name, member])) + for (const name of [runtime, adapter]) { + const member = packages.get(name) + if (member === undefined) throw new Error(`missing workspace package ${name}`) + members.set(name, member) + } + // Packing reads package-owned files; installation never runs in the workspace. + await packageCommand([ + 'pack', '--recursive', '--workspace-concurrency=4', + ...[...members.keys()].map(name => `--filter=${name}`), '--pack-destination', archives, + ], root) + const tarballs = new Map([...members.values()].map((member) => { + if (typeof member.manifest.version !== 'string') throw new Error(`${member.name} has no version`) + const name = member.name.replaceAll('/', '-').replace('@', '') + const archive = join(archives, `${name}-${member.manifest.version}.tgz`) + expect(existsSync(archive), `missing packed payload for ${member.name}`).toBe(true) + return [member.name, archive] + })) + const workspaceSettings = yaml.load(await readFile(join(root, 'pnpm-workspace.yaml'), 'utf8')) as { + allowBuilds: Record + patchedDependencies: Record + minimumReleaseAgeExclude: string[] + overrides: Record + } + const externalVersions: Record = {} + for (const member of members.values()) { + const require = createRequire(join(member.directory, 'package.json')) + for (const section of ['dependencies', 'optionalDependencies', 'peerDependencies']) { + const dependencies = member.manifest[section] as Record | undefined + for (const [name, range] of Object.entries(dependencies ?? {})) { + if (range.startsWith('workspace:')) continue + const manifest = require.resolve.paths(name)?.map(path => join(path, name, 'package.json')).find(path => existsSync(path)) + if (manifest === undefined) continue + const installed = JSON.parse(await readFile(manifest, 'utf8')) as { version: string } + externalVersions[`${name}@${range}`] = installed.version + } + } + } + await mkdir(installation) + for (const path of Object.values(workspaceSettings.patchedDependencies)) { + await mkdir(dirname(join(installation, path)), { recursive: true }) + await writeFile(join(installation, path), await readFile(join(root, path))) + } + await writeFile(join(installation, 'package.json'), JSON.stringify({ + name: 'packed-webhook-installation', private: true, + dependencies: Object.fromEntries(runtimeMembers.map(member => [member.name, `file:${tarballs.get(member.name)!}`])), + })) + await writeFile(join(installation, 'pnpm-workspace.yaml'), yaml.dump({ + packages: ['.'], nodeLinker: 'hoisted', autoInstallPeers: false, allowUnusedPatches: true, + ignoredOptionalDependencies: closure.filter(member => !members.has(member.name)).map(member => member.name), + allowBuilds: { + ...workspaceSettings.allowBuilds, + [`@deepseek-ai/dsh-subprocess-local@file:${relative(installation, tarballs.get('@deepseek-ai/dsh-subprocess-local')!).split(sep).join('/')}`]: true, + }, + patchedDependencies: workspaceSettings.patchedDependencies, + minimumReleaseAgeExclude: workspaceSettings.minimumReleaseAgeExclude, + overrides: { + ...workspaceSettings.overrides, + ...externalVersions, + ...Object.fromEntries(runtimeMembers.map(member => [member.name, `file:${tarballs.get(member.name)!}`])), + }, + })) + await packageCommand(['install', '--offline', '--no-frozen-lockfile'], installation) + await assertInstalledTree(installation) + expect(existsSync(join(installation, 'node_modules', runtime))).toBe(false) + expect(existsSync(join(installation, 'node_modules', adapter))).toBe(false) + await writeFile(join(profile, 'package.json'), JSON.stringify({ + name: 'packed-webhook-profile', private: true, dependencies: {}, + dsh: { profile: { bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'] } }, + })) + const profileDependencies = new Set([runtime, adapter]) + for (const name of profileDependencies) { + const member = members.get(name) + if (member === undefined) throw new Error(`missing packed dependency ${name}`) + for (const [dependency, range] of Object.entries(member.manifest.dependencies as Record | undefined ?? {})) { + if (range.startsWith('workspace:')) profileDependencies.add(dependency) + } + } + await writeFile(join(profile, 'pnpm-workspace.yaml'), yaml.dump({ + packages: ['.'], nodeLinker: 'hoisted', autoInstallPeers: false, + overrides: { + ...externalVersions, + ...Object.fromEntries([...profileDependencies].map(name => [name, `file:${tarballs.get(name)!}`])), + }, + })) + const adapterArchive = tarballs.get(adapter) + const runtimeArchive = tarballs.get(runtime) + if (adapterArchive === undefined || runtimeArchive === undefined) throw new Error('webhook tarballs were not packed') + await packageCommand(['add', runtimeArchive, adapterArchive, '--offline', '--ignore-scripts'], profile) + const manifest = JSON.parse(await readFile(join(profile, 'package.json'), 'utf8')) as { dependencies: Record } + expect(Object.keys(manifest.dependencies).sort()).toEqual([runtime, adapter].sort()) + await assertInstalledTree(profile) + + const example = join(profile, 'node_modules', adapter, 'examples/github-review/cordis.yml') + expect(existsSync(example)).toBe(true) + expect(existsSync(join(dirname(example), 'github-ready-review-rule.mjs'))).toBe(true) + const observer = join(temporary, 'observe-ingress.mjs') + await writeFile(observer, `export const name = 'observe-packed-ingress' +export const inject = ['webServer', 'webhookRuntime'] +export function apply(ctx) { + process.stdout.write('PACKED_WEBHOOK_READY=http://127.0.0.1:' + ctx.webServer.port + '\\n') +} +`) + const patch = join(temporary, 'test.patch.yml') + await writeFile(patch, yaml.dump([ + { id: 'session-telemetry-otel', disabled: true }, + { id: 'github-webhook-ingress', insert: [{ id: 'observe-packed-ingress', name: observer }] }, + ])) + const child = execa(process.execPath, [ + join(installation, 'node_modules/@deepseek-ai/dsh/lib/bin.js'), 'web', '--patch', example, '--patch', patch, '--no-open', '--port', '0', + ], { cwd: temporary, env: environment, extendEnv: false, reject: false, timeout: 90_000 }) + try { + const ready = new Promise((resolveReady, rejectReady) => { + let output = '' + child.stdout?.on('data', (chunk: Buffer) => { + output += chunk.toString() + const origin = /PACKED_WEBHOOK_READY=(http:\/\/127\.0\.0\.1:\d+)/.exec(output)?.[1] + if (origin !== undefined && output.includes('dsh web: ')) resolveReady(origin) + }) + void child.then((result) => { + rejectReady(new Error(`Web profile exited before readiness:\n${result.stdout}\n${result.stderr}`)) + }) + }) + const origin = await ready + expect((await fetch(`${origin}/api`, { signal: AbortSignal.timeout(10_000) })).status).toBe(404) + const body = JSON.stringify({ zen: 'A signed ping does not start an Agent.' }) + const response = await fetch(`${origin}/github`, { + method: 'POST', body, signal: AbortSignal.timeout(10_000), + headers: { + 'content-type': 'application/json', 'x-github-event': 'ping', 'x-github-delivery': 'packed-ping', + 'x-hub-signature-256': `sha256=${createHmac('sha256', secret).update(body).digest('hex')}`, + }, + }) + expect(response.status, await response.text()).toBe(202) + } finally { + child.kill('SIGTERM') + const result = await child + expect(result.timedOut, `${result.stdout}\n${result.stderr}`).toBe(false) + expect(result.exitCode === 0 || result.signal === 'SIGTERM', result.stderr).toBe(true) + } + expect(globSync('sessions/**/*.jsonl*', { cwd: home })).toEqual([]) +}) diff --git a/apps/cli/tests/web-agent-presets.e2e.ts b/apps/cli/tests/web-agent-presets.e2e.ts index 58c77f4a2f..04246877e3 100644 --- a/apps/cli/tests/web-agent-presets.e2e.ts +++ b/apps/cli/tests/web-agent-presets.e2e.ts @@ -93,7 +93,7 @@ async function bootWeb( // A deployment-level skill on the host registry's GLOBAL layer — the same // registration shape a repository plugin's skill root uses. The layered // skills test below proves it reaches preset-composed agents. - { id: 'skill-badge', disabled: false }, + { insert: [{ id: 'skill-badge', name: '@deepseek-ai/dsh-experimental-skill-badge' }] }, { id: 'modules', disabled: true }, // The physical Connection row owns the disabled HTTP server. bootWeb // supplies only its in-process registries so Host services still prove diff --git a/apps/web/tests/github-ready-review.e2e.ts b/apps/web/tests/github-ready-review.e2e.ts index 8bca2a746a..3527f067dd 100644 --- a/apps/web/tests/github-ready-review.e2e.ts +++ b/apps/web/tests/github-ready-review.e2e.ts @@ -9,7 +9,7 @@ import { chromium } from 'playwright' import { afterAll, beforeAll, describe, expect, it, onTestFailed, onTestFinished, vi } from 'vitest' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' import { LlmAdapter } from '@deepseek-ai/dsh-llm' -import type {} from '@deepseek-ai/dsh-webhook' +import type {} from '@deepseek-ai/dsh-experimental-webhook' import { captureExpandedTurnProcessAria, captureStableAria, @@ -22,7 +22,7 @@ import { import { saveFailureShot } from './support.ts' const MODE = webSnapshotMode() -const OVERLAY = fileURLToPath(new URL('../../cli/config/examples/github-review/cordis.yml', import.meta.url)) +const OVERLAY = fileURLToPath(new URL('../../../packages/experimental/webhook-github/examples/github-review/cordis.yml', import.meta.url)) const EXPECTED = fileURLToPath(new URL('./expected/github-ready-review/conversation.expected.md', import.meta.url)) const EXPANDED_EXPECTED = fileURLToPath( new URL('./expected/github-ready-review/conversation-expanded.expected.md', import.meta.url), diff --git a/docs/architecture.i18n.yaml b/docs/architecture.i18n.yaml index fdce5d96e6..6415e32582 100644 --- a/docs/architecture.i18n.yaml +++ b/docs/architecture.i18n.yaml @@ -18,8 +18,8 @@ en: b9eeb18645121a8b zh: 70d87a12c43e042a /deepseek-harness-architecture/core-packages: - en: 651ad3fefe270b64 - zh: 85b82b5d327dcbca + en: 20ef882e44b06a10 + zh: c10c3934ed5570e9 /deepseek-harness-architecture/events: en: 214c3c81c21df6f9 zh: 75d2cdc3c9fc9930 @@ -33,5 +33,5 @@ en: 93d1dc2eeda4aec2 zh: ee7a9da89151ea17 /deepseek-harness-architecture/where-new-behavior-goes: - en: 9b2eb0539a9cd0d6 - zh: 4f575277b91d4e5c + en: 3cbf3d7d6094fa44 + zh: 015a848652d90f54 diff --git a/docs/architecture.md b/docs/architecture.md index ddcf6e4d39..2b4ba34c38 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -63,7 +63,6 @@ Electron starts the private Desktop Host in Electron Node mode. The Host invokes | [`core/agent-loop`](subsystems/core.md) | The default driver implementing that interface | `ctx.agentLoop` | | [`core/scope`](subsystems/scope.md) | The per-agent scoped-registration primitive | library, no key | | [`llm/llm`](subsystems/llm-streaming.md) | Message and stream vocabulary plus the adapter seam | `ctx.llm` | -| [`webhook/webhook`](subsystems/webhook.md) | Authenticated-delivery dispatch and Workspace Session creation | `ctx.webhookRuntime` | ## Events @@ -146,7 +145,7 @@ New behavior attaches to a documented extension point. Changing the loop itself | Add a model-facing capability | register on `ctx.tools`; its schema joins prompt assembly | | Give one session a different capability set | compose an agent preset; a service row there needs an `isolate` realm | | Add shell execution | register a `ctx.shell` backend; the local one spawns through `ctx.subprocess` | -| Add persistent terminal execution | register a `ctx.terminals` backend plus `dsh-tool-terminal` | +| Add persistent terminal execution | register a `ctx.terminals` backend plus `dsh-experimental-tool-terminal` | | Add a human command | register on `ctx.commands`; it dispatches without a model turn | | Manage background jobs | register on `ctx.jobs`; `job_*` tools read or stop jobs | | Start a Session from an external webhook | register a trusted rule on `ctx.webhookRuntime` and mount a provider adapter | diff --git a/docs/architecture.zh.md b/docs/architecture.zh.md index 37a41e1c7a..dd9fe233a2 100644 --- a/docs/architecture.zh.md +++ b/docs/architecture.zh.md @@ -63,7 +63,6 @@ Electron 使用 Electron Node 模式启动私有 Desktop Host。Host 调用共 | [`core/agent-loop`](subsystems/core.zh.md) | 实现该接口的默认驱动器 | `ctx.agentLoop` | | [`core/scope`](subsystems/scope.zh.md) | 按 agent 划分作用域的注册原语 | 库,无 ctx 键 | | [`llm/llm`](subsystems/llm-streaming.zh.md) | 消息与流式词汇表,以及适配器 seam | `ctx.llm` | -| [`webhook/webhook`](subsystems/webhook.zh.md) | 已认证 delivery 的分派和 Workspace Session 创建 | `ctx.webhookRuntime` | @@ -150,7 +149,7 @@ seam 正是替换一个提供方就能改变整个产品的原因。文件系统 | 添加面向模型的能力 | 在 `ctx.tools` 上注册;其 schema 加入提示词组装 | | 让某个会话拥有不同的能力集合 | 组装一个 agent preset;其中的服务行需要 `isolate` realm | | 添加 shell 执行 | 注册 `ctx.shell` 后端;本地后端通过 `ctx.subprocess` spawn 进程 | -| 添加持久化终端执行 | 注册 `ctx.terminals` 后端和 `dsh-tool-terminal` | +| 添加持久化终端执行 | 注册 `ctx.terminals` 后端和 `dsh-experimental-tool-terminal` | | 添加用户命令 | 在 `ctx.commands` 上注册;它无需模型轮次即可分派 | | 管理后台任务 | 在 `ctx.jobs` 上注册;`job_*` 工具读取或停止任务 | | 从外部 webhook 启动 Session | 在 `ctx.webhookRuntime` 上注册可信规则,并挂载提供方适配器 | diff --git a/docs/cookbook/extension-cookbook.i18n.yaml b/docs/cookbook/extension-cookbook.i18n.yaml index e841296f69..1bceacde0d 100644 --- a/docs/cookbook/extension-cookbook.i18n.yaml +++ b/docs/cookbook/extension-cookbook.i18n.yaml @@ -21,5 +21,5 @@ en: f0a28d07c0bb4d1b zh: 840962f512cb4031 /cookbook-extension-plugin-shapes/the-feature-mechanism-map: - en: fa917d46c071fad2 - zh: 4062805237e2c847 + en: abe512b526ffbefd + zh: 6bae5440248441f3 diff --git a/docs/cookbook/extension-cookbook.md b/docs/cookbook/extension-cookbook.md index 006b6b7092..272fc41b8f 100644 --- a/docs/cookbook/extension-cookbook.md +++ b/docs/cookbook/extension-cookbook.md @@ -103,7 +103,7 @@ Every product feature maps to a listener on a documented extension point — the | Product feature | Plugin mechanism | |---|---| -| Hook system (user + project level) | listeners on `agent/created`, `agent/pre-step`, `agent/request`, `tools/pre-execute`, `tools/post-execute`, and `agent/turn-stopping`; the waterfalls return typed decisions, while `agent/turn-stopping` may steer another step; the `dsh-hooks-claude-code` / `dsh-hooks-codex` bridges map hook config files onto these extension points | +| Hook system (user + project level) | listeners on `agent/created`, `agent/pre-step`, `agent/request`, `tools/pre-execute`, `tools/post-execute`, and `agent/turn-stopping`; the waterfalls return typed decisions, while `agent/turn-stopping` may steer another step; the `dsh-experimental-hooks-claude-code` / `dsh-experimental-hooks-codex` bridges map hook config files onto these extension points | | `/goal` | `ctx.goals` owns durable state, `dsh-goal-round-driver` schedules same-session rounds through the public `Agent`, and separate command/tool producers expose human/model control | | `/loop` | on the `turn/end` session event, `followup()` the next iteration; or force-continue | | Dynamic workflow | `ctx.workflowEngine` + the PTC workflow engine + the `workflow` tool; structured in-process children enforce output with scoped prompt/tool registrations, a monotonic tool guard, final `tools/result` commit (including enclosing `run_code`), and the structured-output execution's monotonic `concludeTurn()` marker | diff --git a/docs/cookbook/extension-cookbook.zh.md b/docs/cookbook/extension-cookbook.zh.md index 826510f6a5..c2b9d75424 100644 --- a/docs/cookbook/extension-cookbook.zh.md +++ b/docs/cookbook/extension-cookbook.zh.md @@ -107,7 +107,7 @@ export function apply(ctx: Context) { | 产品功能 | 插件机制 | |---|---| -| 钩子系统(用户级 + 项目级) | `agent/created`、`agent/pre-step`、`agent/request`、`tools/pre-execute`、`tools/post-execute` 和 `agent/turn-stopping` 上的监听器;waterfall 返回类型化决策,`agent/turn-stopping` 则可通过 steering(中途引导)触发下一步;`dsh-hooks-claude-code` / `dsh-hooks-codex` 桥接器将钩子配置文件映射到这些扩展点上 | +| 钩子系统(用户级 + 项目级) | `agent/created`、`agent/pre-step`、`agent/request`、`tools/pre-execute`、`tools/post-execute` 和 `agent/turn-stopping` 上的监听器;waterfall 返回类型化决策,`agent/turn-stopping` 则可通过 steering(中途引导)触发下一步;`dsh-experimental-hooks-claude-code` / `dsh-experimental-hooks-codex` 桥接器将钩子配置文件映射到这些扩展点上 | | `/goal` | `ctx.goals` 管理持久状态,`dsh-goal-round-driver` 通过公共 `Agent` 调度同会话 Round,独立的命令/工具生产方分别提供人类/模型控制 | | `/loop` | 在 `turn/end` 会话事件上 `followup()` 下一次迭代;或强制继续 | | 动态工作流 | `ctx.workflowEngine` + PTC 工作流引擎 + `workflow` 工具;结构化的进程内子任务通过作用域化的提示词/工具注册、单调工具守卫、最终 `tools/result` 提交(包括外层 `run_code`)和结构化输出执行的单调 `concludeTurn()` 标记来强制输出 | diff --git a/docs/cookbook/reviewing-persistence-type-changes.md b/docs/cookbook/reviewing-persistence-type-changes.md index bf3810453c..15b6c9fab9 100644 --- a/docs/cookbook/reviewing-persistence-type-changes.md +++ b/docs/cookbook/reviewing-persistence-type-changes.md @@ -57,12 +57,12 @@ Save the input as `.artifacts/persistence-change.prose.json`, creating the ignor "en": { "summary": "Makes the persisted hook audit decision optional.", "compatibility": "Existing records remain valid. Hook execution consumes HookOutput instead of replaying this audit field. Producers still write decisions, and absence does not imply pass.", - "verification": "pnpm exec vitest run packages/hooks/hook-protocol/tests/events.spec.ts: 10 tests passed." + "verification": "pnpm exec vitest run packages/experimental/hook-protocol/tests/events.spec.ts: 10 tests passed." }, "zh": { "summary": "将持久化的钩子审计决策改为可选。", "compatibility": "已有记录仍然有效。钩子执行消费 HookOutput,不回放此审计字段。写入方仍然记录决策,缺失不代表 pass。", - "verification": "pnpm exec vitest run packages/hooks/hook-protocol/tests/events.spec.ts:10 个测试通过。" + "verification": "pnpm exec vitest run packages/experimental/hook-protocol/tests/events.spec.ts:10 个测试通过。" } } ``` diff --git a/docs/cookbook/reviewing-persistence-type-changes.zh.md b/docs/cookbook/reviewing-persistence-type-changes.zh.md index 4e31658b6b..ed82decae9 100644 --- a/docs/cookbook/reviewing-persistence-type-changes.zh.md +++ b/docs/cookbook/reviewing-persistence-type-changes.zh.md @@ -57,12 +57,12 @@ pnpm --silent run persistence-review --before .artifacts/base.schema.json --afte "en": { "summary": "Makes the persisted hook audit decision optional.", "compatibility": "Existing records remain valid. Hook execution consumes HookOutput instead of replaying this audit field. Producers still write decisions, and absence does not imply pass.", - "verification": "pnpm exec vitest run packages/hooks/hook-protocol/tests/events.spec.ts: 10 tests passed." + "verification": "pnpm exec vitest run packages/experimental/hook-protocol/tests/events.spec.ts: 10 tests passed." }, "zh": { "summary": "将持久化的钩子审计决策改为可选。", "compatibility": "已有记录仍然有效。钩子执行消费 HookOutput,不回放此审计字段。写入方仍然记录决策,缺失不代表 pass。", - "verification": "pnpm exec vitest run packages/hooks/hook-protocol/tests/events.spec.ts:10 个测试通过。" + "verification": "pnpm exec vitest run packages/experimental/hook-protocol/tests/events.spec.ts:10 个测试通过。" } } ``` diff --git a/docs/persistence-catalog.i18n.yaml b/docs/persistence-catalog.i18n.yaml index b286aae4c2..40f318eb60 100644 --- a/docs/persistence-catalog.i18n.yaml +++ b/docs/persistence-catalog.i18n.yaml @@ -108,11 +108,11 @@ en: 8d6fa78d450a0e56 zh: 8d6fa78d450a0e56 /session-persistence-event-catalog/events/hook/hook-invoked-log-only: - en: 7e87780c1e9328b7 - zh: 79b535ed8a26bc4f + en: 705ffb04951178a1 + zh: 6031b9e7b48f5549 /session-persistence-event-catalog/events/hook/hook-result-log-only: - en: 5479d86486adbc40 - zh: b9df61258535c7da + en: b84c2cbfca534935 + zh: ee1d71fad6dfb896 /session-persistence-event-catalog/events/image: en: 4378f94cd30a2ba8 zh: 4378f94cd30a2ba8 @@ -1020,11 +1020,11 @@ en: d13de5c951afd4e5 zh: 44069b6d0f3b8303 /session-persistence-event-catalog/resolved-persistence-types/headerline: - en: 0228dc7dcff3ff5a - zh: bfab168767453f00 + en: d0e4b453af58af7f + zh: 8209d2206840b137 /session-persistence-event-catalog/resolved-persistence-types/hookdialect: - en: c8420c48f6167ad9 - zh: a6dc3dc1ee50ea81 + en: c5418d1e906e9114 + zh: 0bc528427386d8a4 /session-persistence-event-catalog/resolved-persistence-types/imageattachmentref: en: 76ee1e266cd651da zh: 55c7c95a223ccbed @@ -1296,11 +1296,11 @@ en: 5e7d82a493a1d4d8 zh: d2d785891dd766fc /session-persistence-event-catalog/resolved-persistence-types/number~2: - en: 38211d71372021e4 - zh: c0305af81a67e285 + en: 386989934d1bb62e + zh: 69b8bc182a5acbd3 /session-persistence-event-catalog/resolved-persistence-types/string: - en: 052f9ce1988e44f2 - zh: 5adaad6c9bca43e2 + en: 21a0bfa3d2e4d775 + zh: e1d212b7cbc37c35 /session-persistence-event-catalog/resolved-persistence-types/string~2: en: 0089620bf4638263 zh: 1922bef1713094bb @@ -1413,8 +1413,8 @@ en: 1bc55be85a68f0a3 zh: 9e84a55ed11bba5d /session-persistence-event-catalog/resolved-persistence-types/decision-durationms-exitcode-handlerid: - en: ed8ca43bb7622393 - zh: 697e1ccbe9439aa9 + en: a99ac57bbec0370f + zh: 9073329e324a66e0 /session-persistence-event-catalog/resolved-persistence-types/delayms-failure-maxretries-mode: en: 27987dc154def5d8 zh: 7dd493f04daa654f @@ -1428,8 +1428,8 @@ en: a07969828eed2e6f zh: e06893743af544b5 /session-persistence-event-catalog/resolved-persistence-types/dialect-handlerid-matcher-point: - en: afb33a900f77ddf6 - zh: 90edc32643550430 + en: eeba88520aacd126 + zh: 8e2ca4e2bd2c1e3a /session-persistence-event-catalog/resolved-persistence-types/end-start: en: 4b7a8793663d3fef zh: 249459c825d330c3 @@ -1809,8 +1809,8 @@ en: 77a8fc6a2f3a9319 zh: 4dc1de1358b51a8d /session-persistence-event-catalog/resolved-persistence-types/kind-webhook-form-notice: - en: ebced4ba6c43c34b - zh: 627c660edbf5030c + en: 0b74295f7c5c8f11 + zh: 5f1213cec87f6be0 /session-persistence-event-catalog/resolved-persistence-types/kind-working-directory: en: 9848d783b7b5af16 zh: f161eaf1a841cd55 diff --git a/docs/persistence-catalog.md b/docs/persistence-catalog.md index e7335c2e14..571a4b49f6 100644 --- a/docs/persistence-catalog.md +++ b/docs/persistence-catalog.md @@ -583,7 +583,7 @@ Source: [`packages/goal/goal/src/domain.ts:66`](../packages/goal/goal/src/domain } ``` -Source: [`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook-protocol/src/types.ts) +Source: [`packages/experimental/hook-protocol/src/types.ts:19`](../packages/experimental/hook-protocol/src/types.ts) @@ -606,7 +606,7 @@ Source: [`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook- } ``` -Source: [`packages/hooks/hook-protocol/src/types.ts:31`](../packages/hooks/hook-protocol/src/types.ts) +Source: [`packages/experimental/hook-protocol/src/types.ts:31`](../packages/experimental/hook-protocol/src/types.ts) ### `image/*` @@ -3582,13 +3582,13 @@ Sources: [`packages/session/session-persistence-jsonl/src/format.ts:83`](../pack - + ### `HookDialect` SHA-256: `a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb` -Sources: [`packages/hooks/hook-protocol/src/types.ts:48`](../packages/hooks/hook-protocol/src/types.ts) +Sources: [`packages/experimental/hook-protocol/src/types.ts:48`](../packages/experimental/hook-protocol/src/types.ts) One of: @@ -5315,6 +5315,12 @@ Array of `number`. + + + + + + @@ -5339,12 +5345,6 @@ Array of `number`. - - - - - - @@ -5381,7 +5381,7 @@ Array of `number`. SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b` -Sources: [`packages/api/session-controller/src/types.ts:398`](../packages/api/session-controller/src/types.ts) · [`packages/attachment/attachment/src/brand.ts:6`](../packages/attachment/attachment/src/brand.ts) · [`packages/compaction/compaction/src/brand.ts:4`](../packages/compaction/compaction/src/brand.ts) · [`packages/core/session/src/types.ts:20`](../packages/core/session/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:20`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:32`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:8`](../packages/experimental/agent-team/src/types.ts) · [`packages/feedback/message-feedback/src/types.ts:14`](../packages/feedback/message-feedback/src/types.ts) · [`packages/goal/goal/src/types.ts:17`](../packages/goal/goal/src/types.ts) · [`packages/interaction/commands/src/brand.ts:31`](../packages/interaction/commands/src/brand.ts) · [`packages/interaction/user-approval/src/types.ts:17`](../packages/interaction/user-approval/src/types.ts) · [`packages/llm/llm-retry/src/brand.ts:4`](../packages/llm/llm-retry/src/brand.ts) · [`packages/llm/llm/src/brand.ts:16`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:31`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:43`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:67`](../packages/llm/llm/src/brand.ts) · [`packages/schedule/schedule/src/types.ts:14`](../packages/schedule/schedule/src/types.ts) · [`packages/session/session-title/src/index.ts:42`](../packages/session/session-title/src/index.ts) · [`packages/session/session-title/src/types.ts:17`](../packages/session/session-title/src/types.ts) · [`packages/webhook/webhook/src/brand.ts:12`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:6`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:9`](../packages/webhook/webhook/src/brand.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts) +Sources: [`packages/api/session-controller/src/types.ts:398`](../packages/api/session-controller/src/types.ts) · [`packages/attachment/attachment/src/brand.ts:6`](../packages/attachment/attachment/src/brand.ts) · [`packages/compaction/compaction/src/brand.ts:4`](../packages/compaction/compaction/src/brand.ts) · [`packages/core/session/src/types.ts:20`](../packages/core/session/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:20`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:32`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:8`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/webhook/src/brand.ts:12`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:6`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:9`](../packages/experimental/webhook/src/brand.ts) · [`packages/feedback/message-feedback/src/types.ts:14`](../packages/feedback/message-feedback/src/types.ts) · [`packages/goal/goal/src/types.ts:17`](../packages/goal/goal/src/types.ts) · [`packages/interaction/commands/src/brand.ts:31`](../packages/interaction/commands/src/brand.ts) · [`packages/interaction/user-approval/src/types.ts:17`](../packages/interaction/user-approval/src/types.ts) · [`packages/llm/llm-retry/src/brand.ts:4`](../packages/llm/llm-retry/src/brand.ts) · [`packages/llm/llm/src/brand.ts:16`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:31`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:43`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:67`](../packages/llm/llm/src/brand.ts) · [`packages/schedule/schedule/src/types.ts:14`](../packages/schedule/schedule/src/types.ts) · [`packages/session/session-title/src/index.ts:42`](../packages/session/session-title/src/index.ts) · [`packages/session/session-title/src/types.ts:17`](../packages/session/session-title/src/types.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts) `string` @@ -5876,7 +5876,7 @@ Sources: [`packages/session/working-directory/src/index.ts:36`](../packages/sess SHA-256: `8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141` -Sources: [`packages/hooks/hook-protocol/src/types.ts:31`](../packages/hooks/hook-protocol/src/types.ts) +Sources: [`packages/experimental/hook-protocol/src/types.ts:31`](../packages/experimental/hook-protocol/src/types.ts) | Property | Presence | Type | |---|---|---| @@ -5956,7 +5956,7 @@ Array of [`{ description, name }`](#persistence-type-sha256-83079c8a3f733ac3fa60 SHA-256: `119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25` -Sources: [`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook-protocol/src/types.ts) +Sources: [`packages/experimental/hook-protocol/src/types.ts:19`](../packages/experimental/hook-protocol/src/types.ts) | Property | Presence | Type | |---|---|---| @@ -7446,7 +7446,7 @@ Sources: [`packages/interaction/user-questions/src/types.ts:117`](../packages/in SHA-256: `9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94` -Sources: [`packages/webhook/webhook/src/types.ts:74`](../packages/webhook/webhook/src/types.ts) +Sources: [`packages/experimental/webhook/src/types.ts:74`](../packages/experimental/webhook/src/types.ts) | Property | Presence | Type | |---|---|---| diff --git a/docs/persistence-catalog.zh.md b/docs/persistence-catalog.zh.md index b0c7414222..2c965d7674 100644 --- a/docs/persistence-catalog.zh.md +++ b/docs/persistence-catalog.zh.md @@ -585,7 +585,7 @@ export type SessionEvent = { } ``` -来源:[`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook-protocol/src/types.ts) +来源:[`packages/experimental/hook-protocol/src/types.ts:19`](../packages/experimental/hook-protocol/src/types.ts) @@ -608,7 +608,7 @@ export type SessionEvent = { } ``` -来源:[`packages/hooks/hook-protocol/src/types.ts:31`](../packages/hooks/hook-protocol/src/types.ts) +来源:[`packages/experimental/hook-protocol/src/types.ts:31`](../packages/experimental/hook-protocol/src/types.ts) ### `image/*` @@ -3584,13 +3584,13 @@ SHA-256: `18ee62b8900a4c3d046700f05d7a4d49d6cab2a660a020c87481d1603dd8bd4f` - + ### `HookDialect` SHA-256: `a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb` -来源:[`packages/hooks/hook-protocol/src/types.ts:48`](../packages/hooks/hook-protocol/src/types.ts) +来源:[`packages/experimental/hook-protocol/src/types.ts:48`](../packages/experimental/hook-protocol/src/types.ts) 以下类型之一: @@ -5317,6 +5317,12 @@ SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` + + + + + + @@ -5341,12 +5347,6 @@ SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` - - - - - - @@ -5383,7 +5383,7 @@ SHA-256: `5d03ba38734809bcbd2a55221bd938b3b3fc34b49bb686c6113e9e4931e3aa78` SHA-256: `4cd48f3e5108bd6ebedf7301c3638839b8b2b9db8dbd493974177fbdeb91a01b` -来源:[`packages/api/session-controller/src/types.ts:398`](../packages/api/session-controller/src/types.ts) · [`packages/attachment/attachment/src/brand.ts:6`](../packages/attachment/attachment/src/brand.ts) · [`packages/compaction/compaction/src/brand.ts:4`](../packages/compaction/compaction/src/brand.ts) · [`packages/core/session/src/types.ts:20`](../packages/core/session/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:20`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:32`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:8`](../packages/experimental/agent-team/src/types.ts) · [`packages/feedback/message-feedback/src/types.ts:14`](../packages/feedback/message-feedback/src/types.ts) · [`packages/goal/goal/src/types.ts:17`](../packages/goal/goal/src/types.ts) · [`packages/interaction/commands/src/brand.ts:31`](../packages/interaction/commands/src/brand.ts) · [`packages/interaction/user-approval/src/types.ts:17`](../packages/interaction/user-approval/src/types.ts) · [`packages/llm/llm-retry/src/brand.ts:4`](../packages/llm/llm-retry/src/brand.ts) · [`packages/llm/llm/src/brand.ts:16`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:31`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:43`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:67`](../packages/llm/llm/src/brand.ts) · [`packages/schedule/schedule/src/types.ts:14`](../packages/schedule/schedule/src/types.ts) · [`packages/session/session-title/src/index.ts:42`](../packages/session/session-title/src/index.ts) · [`packages/session/session-title/src/types.ts:17`](../packages/session/session-title/src/types.ts) · [`packages/webhook/webhook/src/brand.ts:12`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:6`](../packages/webhook/webhook/src/brand.ts) · [`packages/webhook/webhook/src/brand.ts:9`](../packages/webhook/webhook/src/brand.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts) +来源:[`packages/api/session-controller/src/types.ts:398`](../packages/api/session-controller/src/types.ts) · [`packages/attachment/attachment/src/brand.ts:6`](../packages/attachment/attachment/src/brand.ts) · [`packages/compaction/compaction/src/brand.ts:4`](../packages/compaction/compaction/src/brand.ts) · [`packages/core/session/src/types.ts:20`](../packages/core/session/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:20`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:32`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/agent-team/src/types.ts:8`](../packages/experimental/agent-team/src/types.ts) · [`packages/experimental/webhook/src/brand.ts:12`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:6`](../packages/experimental/webhook/src/brand.ts) · [`packages/experimental/webhook/src/brand.ts:9`](../packages/experimental/webhook/src/brand.ts) · [`packages/feedback/message-feedback/src/types.ts:14`](../packages/feedback/message-feedback/src/types.ts) · [`packages/goal/goal/src/types.ts:17`](../packages/goal/goal/src/types.ts) · [`packages/interaction/commands/src/brand.ts:31`](../packages/interaction/commands/src/brand.ts) · [`packages/interaction/user-approval/src/types.ts:17`](../packages/interaction/user-approval/src/types.ts) · [`packages/llm/llm-retry/src/brand.ts:4`](../packages/llm/llm-retry/src/brand.ts) · [`packages/llm/llm/src/brand.ts:16`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:31`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:43`](../packages/llm/llm/src/brand.ts) · [`packages/llm/llm/src/brand.ts:67`](../packages/llm/llm/src/brand.ts) · [`packages/schedule/schedule/src/types.ts:14`](../packages/schedule/schedule/src/types.ts) · [`packages/session/session-title/src/index.ts:42`](../packages/session/session-title/src/index.ts) · [`packages/session/session-title/src/types.ts:17`](../packages/session/session-title/src/types.ts) · [`packages/workflow/workflow/src/types.ts:13`](../packages/workflow/workflow/src/types.ts) `string` @@ -5878,7 +5878,7 @@ SHA-256: `da60ed58a8fa23d7aa4920ab5c1f4e3d28109cb0797ef9e5c8b125721b847582` SHA-256: `8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141` -来源:[`packages/hooks/hook-protocol/src/types.ts:31`](../packages/hooks/hook-protocol/src/types.ts) +来源:[`packages/experimental/hook-protocol/src/types.ts:31`](../packages/experimental/hook-protocol/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| @@ -5958,7 +5958,7 @@ SHA-256: `aba175fb20ffc71112c55efe70458ff5d7dbfb83501892b4ba8d077f0ea5d7ba` SHA-256: `119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25` -来源:[`packages/hooks/hook-protocol/src/types.ts:19`](../packages/hooks/hook-protocol/src/types.ts) +来源:[`packages/experimental/hook-protocol/src/types.ts:19`](../packages/experimental/hook-protocol/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| @@ -7448,7 +7448,7 @@ SHA-256: `c55827fba7018198772c50e37cb7d3f60a3d8bb6e94b07de72dee0d9f8968005` SHA-256: `9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94` -来源:[`packages/webhook/webhook/src/types.ts:74`](../packages/webhook/webhook/src/types.ts) +来源:[`packages/experimental/webhook/src/types.ts:74`](../packages/experimental/webhook/src/types.ts) | 属性 | 存在性 | 类型 | |---|---|---| diff --git a/docs/persistence-schema.json b/docs/persistence-schema.json index d7d9328556..7122e8ecd8 100644 --- a/docs/persistence-schema.json +++ b/docs/persistence-schema.json @@ -22223,7 +22223,7 @@ "digest": "119abe2b9c0b2f46ecb31d82b9acba4d4b30e049f655e2475e8b4ae12d5a9e25", "names": [], "sources": [ - "packages/hooks/hook-protocol/src/types.ts:19" + "packages/experimental/hook-protocol/src/types.ts:19" ] }, { @@ -23110,6 +23110,9 @@ "packages/experimental/agent-team/src/types.ts#TeamId", "packages/experimental/agent-team/src/types.ts#TeamMessageId", "packages/experimental/agent-team/src/types.ts#TeamTaskId", + "packages/experimental/webhook/src/brand.ts#WebhookDeliveryId", + "packages/experimental/webhook/src/brand.ts#WebhookRuleId", + "packages/experimental/webhook/src/brand.ts#WebhookSourceId", "packages/feedback/message-feedback/src/types.ts#MessageFeedbackVersion", "packages/goal/goal/src/types.ts#GoalId", "packages/interaction/commands/src/brand.ts#CommandId", @@ -23122,9 +23125,6 @@ "packages/schedule/schedule/src/types.ts#ScheduleId", "packages/session/session-title/src/index.ts#SessionTitleProviderId", "packages/session/session-title/src/types.ts#SessionTitleProviderId", - "packages/webhook/webhook/src/brand.ts#WebhookDeliveryId", - "packages/webhook/webhook/src/brand.ts#WebhookRuleId", - "packages/webhook/webhook/src/brand.ts#WebhookSourceId", "packages/workflow/workflow/src/types.ts#WorkflowRunId" ], "sources": [ @@ -23135,6 +23135,9 @@ "packages/experimental/agent-team/src/types.ts:20", "packages/experimental/agent-team/src/types.ts:32", "packages/experimental/agent-team/src/types.ts:8", + "packages/experimental/webhook/src/brand.ts:12", + "packages/experimental/webhook/src/brand.ts:6", + "packages/experimental/webhook/src/brand.ts:9", "packages/feedback/message-feedback/src/types.ts:14", "packages/goal/goal/src/types.ts:17", "packages/interaction/commands/src/brand.ts:31", @@ -23147,9 +23150,6 @@ "packages/schedule/schedule/src/types.ts:14", "packages/session/session-title/src/index.ts:42", "packages/session/session-title/src/types.ts:17", - "packages/webhook/webhook/src/brand.ts:12", - "packages/webhook/webhook/src/brand.ts:6", - "packages/webhook/webhook/src/brand.ts:9", "packages/workflow/workflow/src/types.ts:13" ] }, @@ -24068,7 +24068,7 @@ "digest": "8ad45ad053b4d89f8865c17cc9ff3b8748e86045f3f0fb816269a34af2619141", "names": [], "sources": [ - "packages/hooks/hook-protocol/src/types.ts:31" + "packages/experimental/hook-protocol/src/types.ts:31" ] }, { @@ -24333,7 +24333,7 @@ "digest": "9edc162949abf93bd5ff049191b345454ba104f583937ce5580fb50f067d2b94", "names": [], "sources": [ - "packages/webhook/webhook/src/types.ts:74" + "packages/experimental/webhook/src/types.ts:74" ] }, { @@ -24428,10 +24428,10 @@ { "digest": "a6b41f5bede8094d7bf635be5d69b1bd7a25e006ca9cf9415bceb9322f1a7feb", "names": [ - "packages/hooks/hook-protocol/src/types.ts#HookDialect" + "packages/experimental/hook-protocol/src/types.ts#HookDialect" ], "sources": [ - "packages/hooks/hook-protocol/src/types.ts:48" + "packages/experimental/hook-protocol/src/types.ts:48" ] }, { diff --git a/docs/subsystems/claude-code-mods.i18n.yaml b/docs/subsystems/claude-code-mods.i18n.yaml index 67dce12eae..f85d0a1549 100644 --- a/docs/subsystems/claude-code-mods.i18n.yaml +++ b/docs/subsystems/claude-code-mods.i18n.yaml @@ -6,8 +6,8 @@ en: e520df3bf44e1160 zh: 557956eaf6faf4a7 /claude-code-mods-compatibility/packaging-and-loading: - en: 75cf021ce8babaab - zh: caa20540f8bce11a + en: 169ef86a77b15f0a + zh: a3425924fc771856 /claude-code-mods-compatibility/events: en: cea776ec0063c311 zh: 6b8c8b32f2f7ede9 diff --git a/docs/subsystems/claude-code-mods.md b/docs/subsystems/claude-code-mods.md index 1d125affae..f5d63e5183 100644 --- a/docs/subsystems/claude-code-mods.md +++ b/docs/subsystems/claude-code-mods.md @@ -15,7 +15,7 @@ Every way a mod behaves differently through this bridge than under Claude Code, | A hooks module may be TypeScript | A `.ts` hooks module loads only where the launcher transpiles (the source launch does; a built install does not) | DSH ships plain Node | | Mods run in-process with `$` as their only access to the host | The hooks module runs in-process with Node's globals, no access rule, and the process's full authority: `$.env` reads and writes the harness environment, `$.http.fetch` reaches any URL, `$.fs` and `$.tool.call` act as the session | No sandbox is applied to mods; mount only mods you would run as a plugin | | `import type { … } from 'claude-code'`, `declare module 'claude-code' { interface PluginState }` | The `claude-code` module name resolves only inside this repository's test setup, to the bridge's types; a mod outside it imports `@deepseek-ai/dsh-experimental-claude-code-mods` | The type names are the bridge's own | -| `settings hooks` in `hooks.json` run beside mod hooks | Not run; mount `@deepseek-ai/dsh-hooks-claude-code` for them | Different bridge | +| `settings hooks` in `hooks.json` run beside mod hooks | Not run; mount `@deepseek-ai/dsh-experimental-hooks-claude-code` for them | Different bridge | ## Events diff --git a/docs/subsystems/claude-code-mods.zh.md b/docs/subsystems/claude-code-mods.zh.md index 696b6af1e7..0bf67fd561 100644 --- a/docs/subsystems/claude-code-mods.zh.md +++ b/docs/subsystems/claude-code-mods.zh.md @@ -15,7 +15,7 @@ | 钩子模块可以是 TypeScript | `.ts` 钩子模块只在启动器转译时可加载(源码启动可以;构建后的安装不行) | DSH 交付的是纯 Node | | 模组在进程内运行,`$` 是其访问宿主的唯一途径 | 钩子模块以 Node 全局对象在进程内运行,没有访问规则,并拥有进程的全部权限:`$.env` 读写 harness 环境变量,`$.http.fetch` 可访问任意 URL,`$.fs` 与 `$.tool.call` 以会话的身份行动 | 不对模组施加沙箱;只挂载你愿意作为插件运行的模组 | | `import type { … } from 'claude-code'`、`declare module 'claude-code' { interface PluginState }` | `claude-code` 模块名只在本仓库的测试设置中解析到桥接的类型;仓库外的模组导入 `@deepseek-ai/dsh-experimental-claude-code-mods` | 类型名是桥接自己的 | -| `hooks.json` 中的设置钩子与模组钩子并行运行 | 不运行;为它们挂载 `@deepseek-ai/dsh-hooks-claude-code` | 不同的桥接 | +| `hooks.json` 中的设置钩子与模组钩子并行运行 | 不运行;为它们挂载 `@deepseek-ai/dsh-experimental-hooks-claude-code` | 不同的桥接 | ## 事件 diff --git a/docs/subsystems/session.i18n.yaml b/docs/subsystems/session.i18n.yaml index 1a778923dc..6b344f0f33 100644 --- a/docs/subsystems/session.i18n.yaml +++ b/docs/subsystems/session.i18n.yaml @@ -6,8 +6,8 @@ en: 28fb7eb8f758fdf0 zh: a36d6f03e331ad86 /sessions/sessioneventmap-the-event-vocabulary: - en: 541354f6468e117d - zh: 2d7a665bad828a02 + en: e1d52db578c6cb8a + zh: ddc12916f6e60b81 /sessions/sessioneventmap-the-event-vocabulary/the-request-header-event-request-header: en: 6eb931fcb2f4ab8d zh: d822a83384cc1fee @@ -57,8 +57,8 @@ en: 63b4059793255ca3 zh: 6bc7891c320249f4 /sessions/plugin-contributed-log-only-events: - en: 0a014a755b75449f - zh: 9d59d74490a1bcb2 + en: a176d23454f6f6e3 + zh: 1b6af3e8fd8e9d6e /sessions/plugin-contributed-log-only-events/plugin-records: en: 15102fd0b937fbf3 zh: 37ebf1d715db097c diff --git a/docs/subsystems/session.md b/docs/subsystems/session.md index 1dd08630bb..bb26c8e9cd 100644 --- a/docs/subsystems/session.md +++ b/docs/subsystems/session.md @@ -8,7 +8,7 @@ Source: [`packages/core/session/src/types.ts`](../../packages/core/session/src/t ## `SessionEventMap` — the event vocabulary -The append-only event types. Merge-extensible: a plugin declares extra event types via declaration merging — e.g. the [compaction seam](compaction.md) adds `compaction/start` / `compaction/summary` / `compaction/end`, and `@deepseek-ai/dsh-hook-protocol` adds log-only `hook/invoked` / `hook/result` records for a hook bridge. Like `compaction/*`, these are NOT `SurfaceEventType`s (no `surfaceOp`). The generated [persistence log event catalog](../persistence-catalog.md) enumerates every member — core and merged — with its payload, surface badge, and declaration site. +The append-only event types. Merge-extensible: a plugin declares extra event types via declaration merging — e.g. the [compaction seam](compaction.md) adds `compaction/start` / `compaction/summary` / `compaction/end`, and `@deepseek-ai/dsh-experimental-hook-protocol` adds log-only `hook/invoked` / `hook/result` records for a hook bridge. Like `compaction/*`, these are NOT `SurfaceEventType`s (no `surfaceOp`). The generated [persistence log event catalog](../persistence-catalog.md) enumerates every member — core and merged — with its payload, surface badge, and declaration site. ```ts type-equiv /** A user-role specialization of the shared message representation. */ @@ -750,7 +750,7 @@ A plugin may declaration-merge extra `SessionEventMap` types. These are **log-on When several events in one plugin-owned family assemble into one Web Client Conversation Node, every start, update, result, resource, or interruption event in that family carries or independently derives the same stable business id. This requirement applies to correlated Node families, not to every Session event; it lets the client group each event without guessing from adjacency or scanning history. See the [Conversation subsystem](conversation.md). -The hook bridges' `hook/invoked` / `hook/result` pairs (from `@deepseek-ai/dsh-hook-protocol`) correlate by `handlerId`. `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, and `Stop` fire inside the loop's open turn, so their `hook/*` records are turn-enclosed by construction. `SessionStart` gets no `hook/*` record because it runs before turn 1; its context remains pending in the inbox until a waking delivery opens a turn. +The hook bridges' `hook/invoked` / `hook/result` pairs (from `@deepseek-ai/dsh-experimental-hook-protocol`) correlate by `handlerId`. `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, and `Stop` fire inside the loop's open turn, so their `hook/*` records are turn-enclosed by construction. `SessionStart` gets no `hook/*` record because it runs before turn 1; its context remains pending in the inbox until a waking delivery opens a turn. ### Plugin records diff --git a/docs/subsystems/session.zh.md b/docs/subsystems/session.zh.md index 8085cb8067..d63d691a10 100644 --- a/docs/subsystems/session.zh.md +++ b/docs/subsystems/session.zh.md @@ -8,7 +8,7 @@ ## `SessionEventMap`:事件词汇 -仅追加的事件类型。可通过声明合并扩展:插件通过 declaration merging 声明额外的事件类型。例如[压缩(compaction) seam](compaction.zh.md) 添加了 `compaction/start` / `compaction/summary` / `compaction/end`,`@deepseek-ai/dsh-hook-protocol` 为钩子桥接添加了仅记录日志的 `hook/invoked` / `hook/result` 记录。与 `compaction/*` 一样,这些都不是 `SurfaceEventType`(没有 `surfaceOp`)。生成的[持久化日志事件目录](../persistence-catalog.zh.md)列举了所有成员(核心与合并扩展的),包含其 payload、surface 标记与声明位置。 +仅追加的事件类型。可通过声明合并扩展:插件通过 declaration merging 声明额外的事件类型。例如[压缩(compaction) seam](compaction.zh.md) 添加了 `compaction/start` / `compaction/summary` / `compaction/end`,`@deepseek-ai/dsh-experimental-hook-protocol` 为钩子桥接添加了仅记录日志的 `hook/invoked` / `hook/result` 记录。与 `compaction/*` 一样,这些都不是 `SurfaceEventType`(没有 `surfaceOp`)。生成的[持久化日志事件目录](../persistence-catalog.zh.md)列举了所有成员(核心与合并扩展的),包含其 payload、surface 标记与声明位置。 ```ts type-equiv /** A user-role specialization of the shared message representation. */ @@ -754,7 +754,7 @@ interface TurnEndReasonMap { 如果同一个插件事件族中的多条事件要组装成一个 Web Client Conversation Node,该事件族中的每条 start、update、result、resource 或 interruption 事件都必须携带或独立推导出同一个稳定业务 id。此要求只约束需要关联的 Node 事件族,并不要求每条 Session 事件都有业务 id;Client 因此无须根据相邻关系猜测归属,也无须扫描历史。参见 [Conversation 子系统](conversation.zh.md)。 -钩子桥接层的 `hook/invoked` / `hook/result` 对(来自 `@deepseek-ai/dsh-hook-protocol`)通过 `handlerId` 关联。`UserPromptSubmit`、`PreToolUse`、`PostToolUse` 与 `Stop` 在 loop 已打开的轮次内触发,因此其 `hook/*` 记录天然位于轮次之内。`SessionStart` 不生成 `hook/*` 记录,因为它在轮次 1 之前运行;其上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次。 +钩子桥接层的 `hook/invoked` / `hook/result` 对(来自 `@deepseek-ai/dsh-experimental-hook-protocol`)通过 `handlerId` 关联。`UserPromptSubmit`、`PreToolUse`、`PostToolUse` 与 `Stop` 在 loop 已打开的轮次内触发,因此其 `hook/*` 记录天然位于轮次之内。`SessionStart` 不生成 `hook/*` 记录,因为它在轮次 1 之前运行;其上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次。 ### 插件记录 diff --git a/docs/subsystems/skills.i18n.yaml b/docs/subsystems/skills.i18n.yaml index d95e69dd63..c65da46c7a 100644 --- a/docs/subsystems/skills.i18n.yaml +++ b/docs/subsystems/skills.i18n.yaml @@ -3,14 +3,14 @@ # After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/skills.md /skills: - en: 047c73a023dcdcd1 - zh: 052f42fbfd202f32 + en: 8e9b47984ad1b59e + zh: 2dbe82fe2ef13618 /skills/provider-registry: en: abe338b6c6d1ebd1 zh: c604db2de10a23c4 /skills/local-discovery-priority: - en: accf8ad4c73c41ad - zh: 141294fe8dab8ecf + en: 13233cb0f2d37f66 + zh: d13b16ae7a444649 /skills/skill-identity: en: 61295a9cf1c51588 zh: 1c4c1582688d2310 diff --git a/docs/subsystems/skills.md b/docs/subsystems/skills.md index e330edd2c5..31fdd4fcee 100644 --- a/docs/subsystems/skills.md +++ b/docs/subsystems/skills.md @@ -2,9 +2,9 @@ English | [中文](skills.zh.md) -The [skill capability family](../../packages/skill) includes the Service Definition ([dsh-skill](../../packages/skill/skill), `ctx.skills`), the local Service Provider ([dsh-skill-filesystem](../../packages/skill/skill-filesystem)), optional packaged providers ([dsh-skill-badge](../../packages/skill/skill-badge), [dsh-skill-office](../../packages/skill/skill-office), and the Windows ACL diagnosis provider in [dsh-sandbox-windows-acl](../../packages/sandbox/sandbox-windows-acl)), and the Consumer ([dsh-tool-skill](../../packages/skill/tool-skill)). The registry merges provider catalogs across its host and per-scope layers; providers contribute local or packaged skills; the Consumer owns the initial and replacement catalogs plus the model-facing `skill` tool. Skills are optional instructions, not session events, so their vocabulary lives here rather than in [core.md](core.md). +The [skill capability family](../../packages/skill) includes the Service Definition ([dsh-skill](../../packages/skill/skill), `ctx.skills`), the local Service Provider ([dsh-skill-filesystem](../../packages/skill/skill-filesystem)), optional packaged providers ([dsh-experimental-skill-badge](../../packages/experimental/skill-badge), [dsh-skill-office](../../packages/skill/skill-office), and the Windows ACL diagnosis provider in [dsh-sandbox-windows-acl](../../packages/sandbox/sandbox-windows-acl)), and the Consumer ([dsh-tool-skill](../../packages/skill/tool-skill)). The registry merges provider catalogs across its host and per-scope layers; providers contribute local or packaged skills; the Consumer owns the initial and replacement catalogs plus the model-facing `skill` tool. Skills are optional instructions, not session events, so their vocabulary lives here rather than in [core.md](core.md). -Source: [`packages/skill/skill/src/index.ts`](../../packages/skill/skill/src/index.ts), [`packages/skill/skill-filesystem/src/index.ts`](../../packages/skill/skill-filesystem/src/index.ts), [`packages/skill/skill-badge/src/index.ts`](../../packages/skill/skill-badge/src/index.ts), [`packages/skill/skill-office/src/index.ts`](../../packages/skill/skill-office/src/index.ts), [`packages/sandbox/sandbox-windows-acl/src/acl-skill.ts`](../../packages/sandbox/sandbox-windows-acl/src/acl-skill.ts), and [`packages/skill/tool-skill/src/index.ts`](../../packages/skill/tool-skill/src/index.ts). +Source: [`packages/skill/skill/src/index.ts`](../../packages/skill/skill/src/index.ts), [`packages/skill/skill-filesystem/src/index.ts`](../../packages/skill/skill-filesystem/src/index.ts), [`packages/experimental/skill-badge/src/index.ts`](../../packages/experimental/skill-badge/src/index.ts), [`packages/skill/skill-office/src/index.ts`](../../packages/skill/skill-office/src/index.ts), [`packages/sandbox/sandbox-windows-acl/src/acl-skill.ts`](../../packages/sandbox/sandbox-windows-acl/src/acl-skill.ts), and [`packages/skill/tool-skill/src/index.ts`](../../packages/skill/tool-skill/src/index.ts). ## Provider registry @@ -76,7 +76,7 @@ The shipped local provider scans roots in rank order: The project root is the nearest ancestor containing `.git`; without one, the current cwd is used. When `ctx.fs` is available, the git-root walk probes `.git` through the filesystem service so remote or sandboxed workspaces do not fall back to the host filesystem boundary. The user DSH root skips its `.system` child. The local provider does not synthesize built-in system skills; deployments supply packaged skills through configured bundled roots or dedicated providers. -`dsh-skill-badge` registers one immutable `bundled` candidate at `BUNDLED_SKILL_RANK` and exposes its packaged asset directory through `resourceBase`. The shipped CLI declares the plugin disabled, so enabling its composition row is an explicit opt-in. +`dsh-experimental-skill-badge` registers one immutable `bundled` candidate at `BUNDLED_SKILL_RANK` and exposes its packaged asset directory through `resourceBase`. The shipped CLI declares the plugin disabled, so enabling its composition row is an explicit opt-in. Chokidar watches existing roots for direct bundle/flat-entry additions and removals plus direct skill-entry changes. A missing root is followed one absent path segment at a time from its nearest existing ancestor until Chokidar can attach. Resource files below a bundle are not catalog changes. Model-facing `write` and `edit` observations synchronously invalidate the provider when their target is catalog-relevant, while the host watcher covers IDE, Git, shell, and external-process mutations. Watcher failures make the current observation incomplete without hiding readable candidates from direct loads; project-scoped watchers use a configured bounded LRU. diff --git a/docs/subsystems/skills.zh.md b/docs/subsystems/skills.zh.md index 03a6a06f4e..07634870c1 100644 --- a/docs/subsystems/skills.zh.md +++ b/docs/subsystems/skills.zh.md @@ -2,9 +2,9 @@ [English](skills.md) | 中文 -[skill(技能)能力族](../../packages/skill) 包含 Service Definition([dsh-skill](../../packages/skill/skill),`ctx.skills`)、本地 Service Provider([dsh-skill-filesystem](../../packages/skill/skill-filesystem))、可选的随包提供方([dsh-skill-badge](../../packages/skill/skill-badge)、[dsh-skill-office](../../packages/skill/skill-office) 及 [dsh-sandbox-windows-acl](../../packages/sandbox/sandbox-windows-acl) 中的 Windows ACL 诊断提供方)和 Consumer([dsh-tool-skill](../../packages/skill/tool-skill))。注册表在其宿主层与各 scope 层之间合并各提供方的目录;提供方贡献本地或随包 skill;Consumer 拥有初始目录和替换目录,以及面向模型的 `skill` 工具。skill 是可选的指令而非会话事件,因此其词汇定义在此处而非 [core.md](core.zh.md)。 +[skill(技能)能力族](../../packages/skill) 包含 Service Definition([dsh-skill](../../packages/skill/skill),`ctx.skills`)、本地 Service Provider([dsh-skill-filesystem](../../packages/skill/skill-filesystem))、可选的随包提供方([dsh-experimental-skill-badge](../../packages/experimental/skill-badge)、[dsh-skill-office](../../packages/skill/skill-office) 及 [dsh-sandbox-windows-acl](../../packages/sandbox/sandbox-windows-acl) 中的 Windows ACL 诊断提供方)和 Consumer([dsh-tool-skill](../../packages/skill/tool-skill))。注册表在其宿主层与各 scope 层之间合并各提供方的目录;提供方贡献本地或随包 skill;Consumer 拥有初始目录和替换目录,以及面向模型的 `skill` 工具。skill 是可选的指令而非会话事件,因此其词汇定义在此处而非 [core.md](core.zh.md)。 -源码:[`packages/skill/skill/src/index.ts`](../../packages/skill/skill/src/index.ts)、[`packages/skill/skill-filesystem/src/index.ts`](../../packages/skill/skill-filesystem/src/index.ts)、[`packages/skill/skill-badge/src/index.ts`](../../packages/skill/skill-badge/src/index.ts)、[`packages/skill/skill-office/src/index.ts`](../../packages/skill/skill-office/src/index.ts)、[`packages/sandbox/sandbox-windows-acl/src/acl-skill.ts`](../../packages/sandbox/sandbox-windows-acl/src/acl-skill.ts) 与 [`packages/skill/tool-skill/src/index.ts`](../../packages/skill/tool-skill/src/index.ts)。 +源码:[`packages/skill/skill/src/index.ts`](../../packages/skill/skill/src/index.ts)、[`packages/skill/skill-filesystem/src/index.ts`](../../packages/skill/skill-filesystem/src/index.ts)、[`packages/experimental/skill-badge/src/index.ts`](../../packages/experimental/skill-badge/src/index.ts)、[`packages/skill/skill-office/src/index.ts`](../../packages/skill/skill-office/src/index.ts)、[`packages/sandbox/sandbox-windows-acl/src/acl-skill.ts`](../../packages/sandbox/sandbox-windows-acl/src/acl-skill.ts) 与 [`packages/skill/tool-skill/src/index.ts`](../../packages/skill/tool-skill/src/index.ts)。 ## 提供方注册表 @@ -76,7 +76,7 @@ interface SkillProviderControl { 项目根目录为包含 `.git` 的最近祖先目录;找不到时使用当前 cwd。当 `ctx.fs` 可用时,git-root 向上查找通过文件系统服务探测 `.git`,使远程或沙箱工作区不会回退到宿主文件系统边界。用户 DSH 根目录会跳过其 `.system` 子目录。本地提供方不会合成内置系统 skill;部署方通过已配置的 bundled 根目录或专用提供方提供随包 skill。 -`dsh-skill-badge` 在 `BUNDLED_SKILL_RANK` 注册一个不可变的 `bundled` 候选项,并通过 `resourceBase` 公开其随包资产目录。交付的 CLI(命令行界面)将该插件声明为禁用,因此启用其组合配置行即为显式选择加入。 +`dsh-experimental-skill-badge` 在 `BUNDLED_SKILL_RANK` 注册一个不可变的 `bundled` 候选项,并通过 `resourceBase` 公开其随包资产目录。交付的 CLI(命令行界面)将该插件声明为禁用,因此启用其组合配置行即为显式选择加入。 Chokidar 会监视现有根目录中直属 bundle 和平铺条目的添加与移除,以及直属 skill 条目的变更。缺失的根目录会从最近的现有祖先开始,逐个跟踪缺失路径段,直至 Chokidar 可以附加。bundle 下的资源文件变更不属于目录变更。面向模型的 `write` 和 `edit` 观测会在目标路径与目录相关时同步使提供方目录失效,而宿主 watcher 覆盖 IDE、Git、shell 和外部进程产生的变更。watcher 失败会使当前观测不完整,但不会在直接加载时隐藏可读候选项;项目作用域 watcher 使用按配置设限的 LRU。 diff --git a/docs/subsystems/webhook.i18n.yaml b/docs/subsystems/webhook.i18n.yaml index bb5cff569f..fadaacdfe9 100644 --- a/docs/subsystems/webhook.i18n.yaml +++ b/docs/subsystems/webhook.i18n.yaml @@ -15,5 +15,5 @@ en: 2ccdbc45140f9c41 zh: af509a7fb0f84e18 /webhook-runtime/github-adapter: - en: ddb0522ef321a8c5 - zh: 6f08a99848facaf3 + en: 4f99db873df49da3 + zh: 7bb93fd67b1e6e2d diff --git a/docs/subsystems/webhook.md b/docs/subsystems/webhook.md index d84853fc82..97c5959d75 100644 --- a/docs/subsystems/webhook.md +++ b/docs/subsystems/webhook.md @@ -32,7 +32,7 @@ Failed attachment disposes the new Agent before a prompt exists. A failure betwe ## GitHub adapter -`@deepseek-ai/dsh-webhook-github` registers an exact route on an injected WebServer, resolves its credential reference for each request, verifies the untouched `application/json` body before parsing, and returns `202` immediately after in-memory dispatch. Its normalized event guarantees a signed lossless-JSON object; rules validate the event-specific fields they consume. +`@deepseek-ai/dsh-experimental-webhook-github` registers an exact route on an injected WebServer, resolves its credential reference for each request, verifies the untouched `application/json` body before parsing, and returns `202` immediately after in-memory dispatch. Its normalized event guarantees a signed lossless-JSON object; rules validate the event-specific fields they consume. The [GitHub review guide](../user/guide/github-review.md) mounts this route on an isolated second WebServer so exposing webhook ingress does not expose the browser API. @@ -66,5 +66,5 @@ register(rule: WebhookRule): () => Promise dispatch(delivery: VerifiedWebhookDelivery): void ``` -Source: [`packages/webhook/webhook/src/index.ts`](../../packages/webhook/webhook/src/index.ts) +Source: [`packages/experimental/webhook/src/index.ts`](../../packages/experimental/webhook/src/index.ts) diff --git a/docs/subsystems/webhook.zh.md b/docs/subsystems/webhook.zh.md index 9a76c81cb4..0f427302fe 100644 --- a/docs/subsystems/webhook.zh.md +++ b/docs/subsystems/webhook.zh.md @@ -32,7 +32,7 @@ follow-up 是普通持久 user-role 消息,使用 `source.kind: "webhook"`, ## GitHub 适配器 -`@deepseek-ai/dsh-webhook-github` 在注入的 WebServer 上注册精确路由,为每次请求解析凭据引用,在解析前验证未改动的 `application/json` body,并在内存分发后立即返回 `202`。它的规范化事件保证为已签名的无损 JSON 对象;规则负责验证自己消费的事件特定字段。 +`@deepseek-ai/dsh-experimental-webhook-github` 在注入的 WebServer 上注册精确路由,为每次请求解析凭据引用,在解析前验证未改动的 `application/json` body,并在内存分发后立即返回 `202`。它的规范化事件保证为已签名的无损 JSON 对象;规则负责验证自己消费的事件特定字段。 [GitHub 评审指南](../user/guide/github-review.zh.md)把该路由挂载在隔离的第二个 WebServer 上,因此暴露 webhook 入口不会暴露浏览器 API。 @@ -66,5 +66,5 @@ register(rule: WebhookRule): () => Promise dispatch(delivery: VerifiedWebhookDelivery): void ``` -Source: [`packages/webhook/webhook/src/index.ts`](../../packages/webhook/webhook/src/index.ts) +Source: [`packages/experimental/webhook/src/index.ts`](../../packages/experimental/webhook/src/index.ts) diff --git a/docs/subsystems/workflow.i18n.yaml b/docs/subsystems/workflow.i18n.yaml index 6a7a76733e..1a1fba991f 100644 --- a/docs/subsystems/workflow.i18n.yaml +++ b/docs/subsystems/workflow.i18n.yaml @@ -3,8 +3,8 @@ # After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/workflow.md /workflow: - en: eaf02eb7b85ec696 - zh: 648807dce7860e2d + en: 5b0844dea8f31ba6 + zh: 7422bb6b5d87bad7 /workflow/the-start-request: en: 6c8755833293a36c zh: a0f061387fe0d3a6 diff --git a/docs/subsystems/workflow.md b/docs/subsystems/workflow.md index 588c6430f3..b436a50556 100644 --- a/docs/subsystems/workflow.md +++ b/docs/subsystems/workflow.md @@ -4,7 +4,7 @@ English | [中文](workflow.zh.md) The workflow seam lets an agent run a model-written orchestration SCRIPT that starts subagents. Like [subagent](subagent.md) it is **one optional capability**, not part of the agent loop, so its types and operations live here rather than in [core.md](core.md). Like bash, it permits ONE engine implementation per context to provide `ctx.workflowEngine`; there is no named-provider registry (a second engine replaces the first through plugin configuration rather than running beside it). -Service Definition: [dsh-workflow](../../packages/workflow/workflow) (`ctx.workflowEngine` and the vocabulary below). [dsh-workflow-ptc](../../packages/workflow/workflow-ptc) executes the VM and helpers through the shared Node PTC process runtime under the calling Session's file policy. The consumers are [dsh-tool-workflow](../../packages/workflow/tool-workflow) and the opt-in [dsh-tool-ralph](../../packages/workflow/tool-ralph). [Workflow sandbox reuse](../../.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.md) owns execution choices; the [dynamic-workflows reference](../../packages/workflow/workflow/README.md) owns script semantics. +Service Definition: [dsh-workflow](../../packages/workflow/workflow) (`ctx.workflowEngine` and the vocabulary below). [dsh-workflow-ptc](../../packages/workflow/workflow-ptc) executes the VM and helpers through the shared Node PTC process runtime under the calling Session's file policy. The consumers are [dsh-tool-workflow](../../packages/workflow/tool-workflow) and the opt-in [dsh-experimental-tool-ralph](../../packages/experimental/tool-ralph). [Workflow sandbox reuse](../../.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.md) owns execution choices; the [dynamic-workflows reference](../../packages/workflow/workflow/README.md) owns script semantics. Sources: browser-safe vocabulary in [`packages/workflow/workflow/src/types.ts`](../../packages/workflow/workflow/src/types.ts), Host request and live-run handles in [`runtime-types.ts`](../../packages/workflow/workflow/src/runtime-types.ts). diff --git a/docs/subsystems/workflow.zh.md b/docs/subsystems/workflow.zh.md index 1e04710326..25d4729691 100644 --- a/docs/subsystems/workflow.zh.md +++ b/docs/subsystems/workflow.zh.md @@ -4,7 +4,7 @@ 工作流 seam 允许 agent(智能体)运行由模型编写、会启动 subagent 的编排脚本。与 [subagent](subagent.zh.md) 一样,它是**一项可选能力**,不属于 agent loop,因此其类型和操作记录在此处,而非 [core.md](core.zh.md)。与 bash 一样,每个上下文只允许一个引擎实现提供 `ctx.workflowEngine`;没有命名提供方注册表(第二个引擎通过插件配置替换第一个,而不与它同时运行)。 -Service Definition:[dsh-workflow](../../packages/workflow/workflow)(`ctx.workflowEngine` 和下文词汇)。[dsh-workflow-ptc](../../packages/workflow/workflow-ptc)通过共享 Node PTC 进程运行时按调用 Session 的文件策略执行 VM 与辅助函数。消费方为 [dsh-tool-workflow](../../packages/workflow/tool-workflow) 和需显式启用的 [dsh-tool-ralph](../../packages/workflow/tool-ralph)。[工作流沙箱复用](../../.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.zh.md)负责执行选择;[动态工作流参考](../../packages/workflow/workflow/README.zh.md)负责脚本语义。 +Service Definition:[dsh-workflow](../../packages/workflow/workflow)(`ctx.workflowEngine` 和下文词汇)。[dsh-workflow-ptc](../../packages/workflow/workflow-ptc)通过共享 Node PTC 进程运行时按调用 Session 的文件策略执行 VM 与辅助函数。消费方为 [dsh-tool-workflow](../../packages/workflow/tool-workflow) 和需显式启用的 [dsh-experimental-tool-ralph](../../packages/experimental/tool-ralph)。[工作流沙箱复用](../../.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.zh.md)负责执行选择;[动态工作流参考](../../packages/workflow/workflow/README.zh.md)负责脚本语义。 源码:浏览器安全词汇位于 [`packages/workflow/workflow/src/types.ts`](../../packages/workflow/workflow/src/types.ts),Host 请求与活跃运行句柄位于 [`runtime-types.ts`](../../packages/workflow/workflow/src/runtime-types.ts)。 diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index c31a58f93f..8090050b50 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -30,11 +30,11 @@ This table connects model-visible tool names to the plugin package and service s | `@deepseek-ai/dsh-tool-str-replace-editor` | `str_replace_editor` | `ctx.tools`, `ctx.fs` | `tool/call`, `fs/observed after view presence/absence, edit absence, or successful mutation`, `tool/result` | - | Standalone view/create/unique literal replace/line insert tool over the filesystem seam; it composes with any shell or terminal API. | | `@deepseek-ai/dsh-tool-fs` | `edit`, `read`, `read_image`, `write` | `ctx.workingDirectory`, `ctx.tools`, `ctx.fs`, `ctx.systemPrompt`, `ctx.attachments (image-tool registration)`, `ctx.llm + an image-capable route (image-tool execution)` | `tool/call`, `fs/write-intent or fs/edit-intent for mutations`, `fs/observed after read presence/absence or successful file operation`, `durable attachment (read_image)`, `tool/result` | - | The read-before-write/edit policy is added by `@deepseek-ai/dsh-fs-observation-policy` (an `fs/*` event-gate plugin, no schema change); a deployment that loads these tools is expected to also load it. The image tool is not registered without `ctx.attachments`; its schema is route-independent, and execution refuses unless the exact routed model declares image input. | | `@deepseek-ai/dsh-tool-fs-search` | `glob`, `grep` | `ctx.workingDirectory`, `ctx.tools`, `ctx.subprocess`, `ctx.systemPrompt` | `tool/call`, `tool/result` | - | glob and grep are unconditional discovery tools that spawn the packaged ripgrep binary (`@vscode/ripgrep`) through ctx.subprocess as ordinary foreground calls (never background jobs) — no host `rg` install and no shell layer. The catalog uses `sampleOverCapGlobResults: true`; deployments must choose that behavior explicitly. Capped results save the complete formatted list through the optional ctx.spillStore backend; returned locators are follow-up-readable/searchable when the backend exposes local paths in co-located deployments. | -| `@deepseek-ai/dsh-tool-terminal` | `terminal_close`, `terminal_list`, `terminal_open`, `terminal_read`, `terminal_send`, `terminal_signal` | `ctx.workingDirectory`, `ctx.tools`, `ctx.terminals`, `ctx.systemPrompt`, `ctx.jobs at call time for run_in_background` | `tool/call`, `tool/result` | - | The six terminal tools are opt-in and complement one-shot shell/filesystem tools. `terminal_send(run_in_background: true)` registers with `ctx.jobs`; TUI, named key sequences, BEL, resize, auto-start, and cross-agent sharing are absent from the schema. | +| `@deepseek-ai/dsh-experimental-tool-terminal` | `terminal_close`, `terminal_list`, `terminal_open`, `terminal_read`, `terminal_send`, `terminal_signal` | `ctx.workingDirectory`, `ctx.tools`, `ctx.terminals`, `ctx.systemPrompt`, `ctx.jobs at call time for run_in_background` | `tool/call`, `tool/result` | - | The six terminal tools are opt-in and complement one-shot shell/filesystem tools. `terminal_send(run_in_background: true)` registers with `ctx.jobs`; TUI, named key sequences, BEL, resize, auto-start, and cross-agent sharing are absent from the schema. | | `@deepseek-ai/dsh-tool-goal` | `create_goal`, `get_goal`, `update_goal` | `ctx.tools`, `ctx.agents`, `ctx.goals`, `ctx.systemPrompt`, `a calling Agent in an authorized open turn` | `tool/call`, `goal/change for mutations`, `tool/result` | - | create, edit, pause, and resume require direct-human root authority; complete and blocked also accept the exact current goal round. The default blocked lower bound is three admitted rounds. | | `@deepseek-ai/dsh-tool-schedule` | `schedule_create`, `schedule_delete`, `schedule_list`, `schedule_update` | `ctx.tools`, `ctx.schedule` | `tool/call`, `Schedule storage domain create, update, or delete`, `tool/result` | - | A preset or Agent scope mounts this package; the preset decides which agents receive the four management tools. Each call acts on the calling Agent's Session. Accepts after_seconds, explicit absolute at, bounded fixed-rate every_seconds, daily and weekly local times in an explicit IANA zone, and cron as a five-field expression. Management uses the Host storage domain; due messages resume the original Session. | | `@deepseek-ai/dsh-tool-lsp` | `lsp` | `ctx.workingDirectory`, `ctx.tools`, `ctx.lsp`, `ctx.systemPrompt` | `tool/call`, `tool/result` | - | The lsp tool keeps provider selection and language-server subprocesses behind ctx.lsp, so its model-visible schema stays stable across providers. Requires a registered provider (e.g. `@deepseek-ai/dsh-lsp-stdio`) at runtime; without one, a query returns the structured `LSP_UNAVAILABLE` error rather than changing the schema. | -| `@deepseek-ai/dsh-tool-ralph` | `ralph` | `ctx.tools`, `ctx.workflowEngine`, `ctx.subagents`, `ctx.systemPrompt`, `a calling Agent (exec.agent parents every fresh round)` | `tool/call`, `tool/result`, `workflow and child session events during execution` | - | A fixed foreground workflow starts one fresh structured child per round; the model selects only the immutable objective and an optional round cap. | +| `@deepseek-ai/dsh-experimental-tool-ralph` | `ralph` | `ctx.tools`, `ctx.workflowEngine`, `ctx.subagents`, `ctx.systemPrompt`, `a calling Agent (exec.agent parents every fresh round)` | `tool/call`, `tool/result`, `workflow and child session events during execution` | - | A fixed foreground workflow starts one fresh structured child per round; the model selects only the immutable objective and an optional round cap. | | `@deepseek-ai/dsh-tool-skill` | `skill` | `ctx.workingDirectory`, `ctx.tools`, `ctx.agents`, `ctx.skills` | `tool/call`, `tool/result`, `user/message replacement catalogs via agent.inject()` | - | - | | `@deepseek-ai/dsh-tool-session-query` | `session_event_read`, `session_event_search`, `session_event_trace`, `session_search`, `session_trace` | `ctx.tools`, `ctx.systemPrompt`, `ctx.sessionQuery`, `a calling Agent for workspace authority` | `tool/call`, `tool/result` | - | The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. The package is opt-in; compositions that need enforced deadlines or bounded inline output also mount the generic timeout or spill policies. | | `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`, `subagent` | `ctx.tools`, `ctx.subagents`, `ctx.systemPrompt`, `ctx.llm for model discovery and selected-route validation` | `tool/call`, `tool/result`, `child session events through the chosen provider` | `subagent`, `subagent_fork` | The registered delegation name is the load-time `toolName` config (default `subagent`); the default schema above has model selection off, while the discovery schema is shown as the fixed companion available in an enabled Session. Web presets sample the Plugins preference for each new top-level Session and preserve that decision for its child Sessions; `subagent_fork` remains fixed-route. Each instance selects its backend through `provider` and reads model-selection settings through `modelSelectionSettings`. Every delegation returns a child id promptly; local children accept follow-ups, while external backends report their single execution automatically. | @@ -1120,9 +1120,9 @@ Source: [`packages/fs/tool-fs-search/src/index.ts`](../packages/fs/tool-fs-searc glob and grep are unconditional discovery tools that spawn the packaged ripgrep binary (`@vscode/ripgrep`) through ctx.subprocess as ordinary foreground calls (never background jobs) — no host `rg` install and no shell layer. The catalog uses `sampleOverCapGlobResults: true`; deployments must choose that behavior explicitly. Capped results save the complete formatted list through the optional ctx.spillStore backend; returned locators are follow-up-readable/searchable when the backend exposes local paths in co-located deployments. - + -## `@deepseek-ai/dsh-tool-terminal` +## `@deepseek-ai/dsh-experimental-tool-terminal` ### `terminal_close` @@ -1143,7 +1143,7 @@ Close one persistent terminal and wait until its captured owned process tree is } ``` -Source: [`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +Source: [`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_list` @@ -1156,7 +1156,7 @@ List persistent terminal sessions owned by the current agent. } ``` -Source: [`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +Source: [`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_open` @@ -1185,7 +1185,7 @@ Create a persistent, owner-isolated terminal session from a registered backend t } ``` -Source: [`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +Source: [`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_read` @@ -1214,7 +1214,7 @@ Read a bounded page of retained output from a persistent terminal without sendin } ``` -Source: [`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +Source: [`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_send` @@ -1248,7 +1248,7 @@ Send text to a persistent terminal. By default Enter is submitted and the call w } ``` -Source: [`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +Source: [`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_signal` @@ -1281,7 +1281,7 @@ Send an allowed signal to the current foreground process group of a persistent t } ``` -Source: [`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +Source: [`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) The six terminal tools are opt-in and complement one-shot shell/filesystem tools. `terminal_send(run_in_background: true)` registers with `ctx.jobs`; TUI, named key sequences, BEL, resize, auto-start, and cross-agent sharing are absent from the schema. @@ -1720,9 +1720,9 @@ Source: [`packages/lsp/tool-lsp/src/index.ts`](../packages/lsp/tool-lsp/src/inde The lsp tool keeps provider selection and language-server subprocesses behind ctx.lsp, so its model-visible schema stays stable across providers. Requires a registered provider (e.g. `@deepseek-ai/dsh-lsp-stdio`) at runtime; without one, a query returns the structured `LSP_UNAVAILABLE` error rather than changing the schema. - + -## `@deepseek-ai/dsh-tool-ralph` +## `@deepseek-ai/dsh-experimental-tool-ralph` ### `ralph` @@ -1747,7 +1747,7 @@ Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only } ``` -Source: [`packages/workflow/tool-ralph/src/index.ts`](../packages/workflow/tool-ralph/src/index.ts) +Source: [`packages/experimental/tool-ralph/src/index.ts`](../packages/experimental/tool-ralph/src/index.ts) A fixed foreground workflow starts one fresh structured child per round; the model selects only the immutable objective and an optional round cap. diff --git a/docs/tool-catalog.zh.md b/docs/tool-catalog.zh.md index a3190b8c78..68f846b459 100644 --- a/docs/tool-catalog.zh.md +++ b/docs/tool-catalog.zh.md @@ -34,11 +34,11 @@ | `@deepseek-ai/dsh-tool-str-replace-editor` | `str_replace_editor` | `ctx.tools`、`ctx.fs` | `tool/call`、`fs/observed after view presence/absence, edit absence, or successful mutation`、`tool/result` | - | 基于文件系统 seam 的独立查看/创建/唯一字面量替换/按行插入工具;可与任何 shell 或终端接口组合。 | | `@deepseek-ai/dsh-tool-fs` | `edit`、`read`、`read_image`、`write` | `ctx.workingDirectory`、`ctx.tools`、`ctx.fs`、`ctx.systemPrompt`、`ctx.attachments (image-tool registration)`、`ctx.llm + an image-capable route (image-tool execution)` | `tool/call`、`fs/write-intent or fs/edit-intent for mutations`、`fs/observed after read presence/absence or successful file operation`、`durable attachment (read_image)`、`tool/result` | - | 先读后写/编辑策略由 `@deepseek-ai/dsh-fs-observation-policy` 添加;它是一个 `fs/*` 事件门禁插件,不会改变 schema。加载这些工具的部署按预期也应加载该插件。没有 `ctx.attachments` 时图片工具不会注册;其 schema 与路由无关,执行时除非确切路由的模型声明图片输入,否则拒绝。 | | `@deepseek-ai/dsh-tool-fs-search` | `glob`、`grep` | `ctx.workingDirectory`、`ctx.tools`、`ctx.subprocess`、`ctx.systemPrompt` | `tool/call`、`tool/result` | - | glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn 随包提供的 ripgrep 二进制文件(`@vscode/ripgrep`),并作为普通前台调用运行,绝不作为后台任务;无需在宿主机安装 `rg`,也不经过 shell 层。本目录使用 `sampleOverCapGlobResults: true`;部署必须显式选择该行为。结果超过上限时,会通过可选的 ctx.spillStore 后端保存完整的格式化列表;在共置部署中,如果后端公开本地路径,返回的定位信息可供后续读取/搜索。 | -| `@deepseek-ai/dsh-tool-terminal` | `terminal_close`、`terminal_list`、`terminal_open`、`terminal_read`、`terminal_send`、`terminal_signal` | `ctx.workingDirectory`、`ctx.tools`、`ctx.terminals`、`ctx.systemPrompt`、`ctx.jobs at call time for run_in_background` | `tool/call`、`tool/result` | - | 这 6 个终端工具需要选择启用,用于补充一次性 bash/文件系统工具。`terminal_send(run_in_background: true)` 会注册到 `ctx.jobs`;schema 不包含 TUI、具名按键序列、BEL、调整尺寸、自动启动和跨 agent 共享。 | +| `@deepseek-ai/dsh-experimental-tool-terminal` | `terminal_close`、`terminal_list`、`terminal_open`、`terminal_read`、`terminal_send`、`terminal_signal` | `ctx.workingDirectory`、`ctx.tools`、`ctx.terminals`、`ctx.systemPrompt`、`ctx.jobs at call time for run_in_background` | `tool/call`、`tool/result` | - | 这 6 个终端工具需要选择启用,用于补充一次性 bash/文件系统工具。`terminal_send(run_in_background: true)` 会注册到 `ctx.jobs`;schema 不包含 TUI、具名按键序列、BEL、调整尺寸、自动启动和跨 agent 共享。 | | `@deepseek-ai/dsh-tool-goal` | `create_goal`、`get_goal`、`update_goal` | `ctx.tools`、`ctx.agents`、`ctx.goals`、`ctx.systemPrompt`、`a calling Agent in an authorized open turn` | `tool/call`、`goal/change for mutations`、`tool/result` | - | create、edit、pause 和 resume 要求直接来自人类的根权限;complete 和 blocked 也接受确切的当前 Goal Round。blocked 的默认下限是 3 个获准的 Round。 | | `@deepseek-ai/dsh-tool-schedule` | `schedule_create`、`schedule_delete`、`schedule_list`、`schedule_update` | `ctx.tools`、`ctx.schedule` | `tool/call`、Schedule storage domain 创建、更新或删除、`tool/result` | - | preset 或 Agent scope 挂载本包;由 preset 决定哪些 agent 获得这四个管理工具。每次调用都作用于调用方 Agent 的 Session。接受 after_seconds、显式绝对 at、有界固定速率 every_seconds、带显式 IANA 时区的每日与每周本地时间,以及作为五字段表达式的 cron。管理使用宿主 storage domain;到期消息会恢复原 Session。 | | `@deepseek-ai/dsh-tool-lsp` | `lsp` | `ctx.workingDirectory`、`ctx.tools`、`ctx.lsp`、`ctx.systemPrompt` | `tool/call`、`tool/result` | - | lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,因此其模型可见 schema 在更换提供方时保持稳定。运行时要求已注册提供方,例如 `@deepseek-ai/dsh-lsp-stdio`;如果没有提供方,查询会返回结构化 `LSP_UNAVAILABLE` 错误,而不会改变 schema。 | -| `@deepseek-ai/dsh-tool-ralph` | `ralph` | `ctx.tools`、`ctx.workflowEngine`、`ctx.subagents`、`ctx.systemPrompt`、`a calling Agent (exec.agent parents every fresh round)` | `tool/call`、`tool/result`、`workflow and child session events during execution` | - | 固定的前台工作流会在每个 Round 启动一个全新的结构化子级;模型只能选择不可变目标和可选的 Round 上限。 | +| `@deepseek-ai/dsh-experimental-tool-ralph` | `ralph` | `ctx.tools`、`ctx.workflowEngine`、`ctx.subagents`、`ctx.systemPrompt`、`a calling Agent (exec.agent parents every fresh round)` | `tool/call`、`tool/result`、`workflow and child session events during execution` | - | 固定的前台工作流会在每个 Round 启动一个全新的结构化子级;模型只能选择不可变目标和可选的 Round 上限。 | | `@deepseek-ai/dsh-tool-skill` | `skill` | `ctx.workingDirectory`、`ctx.tools`、`ctx.agents`、`ctx.skills` | `tool/call`、`tool/result`、`user/message replacement catalogs via agent.inject()` | - | - | | `@deepseek-ai/dsh-tool-session-query` | `session_event_read`、`session_event_search`、`session_event_trace`、`session_search`、`session_trace` | `ctx.tools`、`ctx.systemPrompt`、`ctx.sessionQuery`、`a calling Agent for workspace authority` | `tool/call`、`tool/result` | - | 这 5 个只读工具会隐藏提供方游标,并根据不可变的调用 agent 会话为每个结果授权。该包需要选择启用;需要强制截止时间或限制行内输出的组合还会挂载通用超时或 spill 策略。 | | `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`、`subagent` | `ctx.tools`、`ctx.subagents`、`ctx.systemPrompt`、`用于模型发现和所选路由校验的 ctx.llm` | `tool/call`、`tool/result`、`child session events through the chosen provider` | `subagent`、`subagent_fork` | 注册的委派工具名称取决于加载时 `toolName` 配置(默认为 `subagent`);上述默认 schema 关闭模型选择,而发现 schema 则展示为已启用 Session 中可用的固定配套工具。Web preset 会在每个新顶层 Session 创建时读取插件页偏好,并为其子 Session 保留该决定;`subagent_fork` 始终使用固定路由。每个实例通过 `provider` 选择后端,通过 `modelSelectionSettings` 读取模型选择设置。每次委派都会立即返回子代理 id;本地子代理接受后续消息,外部后端自动汇报单次执行结果。 | @@ -1126,9 +1126,9 @@ pwsh 工具是 Windows 组合中 bash 执行器 seam 的 PowerShell 方言消费 glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn 随包提供的 ripgrep 二进制文件(`@vscode/ripgrep`),并作为普通前台调用运行,绝不作为后台任务;无需在宿主机安装 `rg`,也不经过 shell 层。本目录使用 `sampleOverCapGlobResults: true`;部署必须显式选择该行为。结果超过上限时,会通过可选的 ctx.spillStore 后端保存完整的格式化列表;在共置部署中,如果后端公开本地路径,返回的定位信息可供后续读取/搜索。 - + -## `@deepseek-ai/dsh-tool-terminal` +## `@deepseek-ai/dsh-experimental-tool-terminal` ### `terminal_close` @@ -1149,7 +1149,7 @@ glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn } ``` -来源:[`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +来源:[`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_list` @@ -1162,7 +1162,7 @@ glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn } ``` -来源:[`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +来源:[`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_open` @@ -1191,7 +1191,7 @@ glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn } ``` -来源:[`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +来源:[`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_read` @@ -1220,7 +1220,7 @@ glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn } ``` -来源:[`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +来源:[`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_send` @@ -1254,7 +1254,7 @@ glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn } ``` -来源:[`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +来源:[`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) ### `terminal_signal` @@ -1287,7 +1287,7 @@ glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn } ``` -来源:[`packages/terminal/tool-terminal/src/index.ts`](../packages/terminal/tool-terminal/src/index.ts) +来源:[`packages/experimental/tool-terminal/src/index.ts`](../packages/experimental/tool-terminal/src/index.ts) 这 6 个终端工具需要选择启用,用于补充一次性 bash/文件系统工具。`terminal_send(run_in_background: true)` 会注册到 `ctx.jobs`;schema 不包含 TUI、具名按键序列、BEL、调整尺寸、自动启动和跨 agent 共享。 @@ -1726,9 +1726,9 @@ preset 或 Agent scope 挂载本包;由 preset 决定哪些 agent 获得这四 lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,因此其模型可见 schema 在更换提供方时保持稳定。运行时要求已注册提供方,例如 `@deepseek-ai/dsh-lsp-stdio`;如果没有提供方,查询会返回结构化 `LSP_UNAVAILABLE` 错误,而不会改变 schema。 - + -## `@deepseek-ai/dsh-tool-ralph` +## `@deepseek-ai/dsh-experimental-tool-ralph` ### `ralph` @@ -1753,7 +1753,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后, } ``` -来源:[`packages/workflow/tool-ralph/src/index.ts`](../packages/workflow/tool-ralph/src/index.ts) +来源:[`packages/experimental/tool-ralph/src/index.ts`](../packages/experimental/tool-ralph/src/index.ts) 固定的前台工作流会在每个 Round 启动一个全新的结构化子级;模型只能选择不可变目标和可选的 Round 上限。 diff --git a/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.i18n.yaml b/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.i18n.yaml new file mode 100644 index 0000000000..bfead634eb --- /dev/null +++ b/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.i18n.yaml @@ -0,0 +1,16 @@ +# Bilingual-pair consistency record for guide.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.md +/: + en: 222547ce1ccbf1cb + zh: 7890c66934821e45 +/experimental-package-names-and-explicit-composition: + en: 1ddb73ece556f6e5 + zh: 1f169e6d590f45e2 +/experimental-package-names-and-explicit-composition/change: + en: ae31baa97d4514be + zh: 936e1120fc433f1a +/experimental-package-names-and-explicit-composition/migration: + en: 80b390d9ed786f0b + zh: 4606a6e46a67ce2b diff --git a/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.md b/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.md new file mode 100644 index 0000000000..fd2fecf0fa --- /dev/null +++ b/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.md @@ -0,0 +1,41 @@ +--- +kind: upgrade-guide +description: "Nine optional packages use experimental names, and hook, webhook, Ralph, and badge configurations require explicit installation or insertion." +--- + +# Experimental package names and explicit composition + +English | [中文](guide.zh.md) + +## Change + +The next release replaces these v0.2.1-alpha.1 package names: + +| Old name suffix after `@deepseek-ai/dsh-` | New suffix | +|---|---| +| `hook-protocol` | `experimental-hook-protocol` | +| `hooks-claude-code` | `experimental-hooks-claude-code` | +| `hooks-codex` | `experimental-hooks-codex` | +| `webhook` | `experimental-webhook` | +| `webhook-github` | `experimental-webhook-github` | +| `session-title-all-prompts-llm` | `experimental-session-title-all-prompts-llm` | +| `tool-terminal` | `experimental-tool-terminal` | +| `tool-ralph` | `experimental-tool-ralph` | +| `skill-badge` | `experimental-skill-badge` | + +The CLI and Python runtime do not install the relocated hook bridges or Ralph. The CLI does not install the webhook pair. Base and the full Web presets omit dormant Ralph rows, and base omits its dormant badge row. Patches that only enable those removed IDs no longer insert a plugin. Default active behavior, plugin registration names, tool names, and recorded Session event names remain unchanged. + +## Migration + +1. Replace old npm names in dependencies, imports, profile patches, and overlays using the table. Do not rewrite recorded Session events. +2. Install the packages and missing peers into each affected profile. Profiles disable automatic peer installation. For example, run `dsh plugin --profile web add @deepseek-ai/dsh-experimental-hooks-claude-code @deepseek-ai/dsh-experimental-hook-protocol`. The Codex bridge needs the same protocol peer. The GitHub adapter needs `@deepseek-ai/dsh-experimental-webhook` alongside `@deepseek-ai/dsh-experimental-webhook-github`. +3. Replace an override of a removed row with a complete insertion. Add preset-local tools inside that preset's `config.plugins`, including the services they require. A host badge insertion is: + + ```yaml + - insert: + - id: skill-badge + name: '@deepseek-ai/dsh-experimental-skill-badge' + ``` + +4. For GitHub review, use the example distributed with the adapter instead of the removed CLI example. Follow the [installed-profile instructions](../../../user/guide/github-review.md); keep customized rule modules inside the profile so their imports resolve its installed packages. +5. Start the profile and confirm that its configured plugins activate without missing-package, missing-peer, or missing-row errors. Confirm the expected tool or skill is available in the intended Agent preset. diff --git a/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.zh.md b/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.zh.md new file mode 100644 index 0000000000..d7ce22f824 --- /dev/null +++ b/docs/upgrade-guide/v0.2.1-alpha.1/experimental-package-renames/guide.zh.md @@ -0,0 +1,41 @@ +--- +kind: upgrade-guide +description: "九个可选包使用实验性名称,钩子、webhook、Ralph 和徽章配置需要显式安装或插入。" +--- + +# 实验性包名称与显式组合 + +[English](guide.md) | 中文 + +## 变更 + +下一个版本替换以下 v0.2.1-alpha.1 包名称: + +| `@deepseek-ai/dsh-` 后的旧名称后缀 | 新后缀 | +|---|---| +| `hook-protocol` | `experimental-hook-protocol` | +| `hooks-claude-code` | `experimental-hooks-claude-code` | +| `hooks-codex` | `experimental-hooks-codex` | +| `webhook` | `experimental-webhook` | +| `webhook-github` | `experimental-webhook-github` | +| `session-title-all-prompts-llm` | `experimental-session-title-all-prompts-llm` | +| `tool-terminal` | `experimental-tool-terminal` | +| `tool-ralph` | `experimental-tool-ralph` | +| `skill-badge` | `experimental-skill-badge` | + +CLI 与 Python 运行时不再安装迁移后的钩子桥接或 Ralph。CLI 不再安装两个 webhook 包。Base 与完整 Web 预设省略休眠的 Ralph 行,base 也省略休眠的徽章行。只启用这些已删除 ID 的 patch 不会插入插件。默认活动行为、插件注册名称、工具名称与已记录的 Session 事件名称保持不变。 + +## 迁移 + +1. 按表替换依赖、导入、profile patch 和 overlay 中的旧 npm 名称。不要改写已记录的 Session 事件。 +2. 将包与缺失的 peer 安装到每个受影响的 profile。Profile 禁用自动 peer 安装。例如,运行 `dsh plugin --profile web add @deepseek-ai/dsh-experimental-hooks-claude-code @deepseek-ai/dsh-experimental-hook-protocol`。Codex 桥接需要相同的协议 peer。GitHub 适配器需要同时安装 `@deepseek-ai/dsh-experimental-webhook` 与 `@deepseek-ai/dsh-experimental-webhook-github`。 +3. 将覆盖已删除行的 patch 替换为完整插入。在预设的 `config.plugins` 中添加预设内工具及其需要的服务。宿主徽章插入示例: + + ```yaml + - insert: + - id: skill-badge + name: '@deepseek-ai/dsh-experimental-skill-badge' + ``` + +4. GitHub review 使用适配器随附的示例,替代已删除的 CLI 示例。遵循[安装版 profile 说明](../../../user/guide/github-review.zh.md);将定制规则模块保留在 profile 内,使其导入能解析该 profile 安装的包。 +5. 启动 profile,确认配置的插件激活时没有缺包、缺 peer 或缺行错误。确认预期工具或技能在目标 Agent 预设中可用。 diff --git a/docs/user/guide/github-review.i18n.yaml b/docs/user/guide/github-review.i18n.yaml index c2c413d88c..485e50afc4 100644 --- a/docs/user/guide/github-review.i18n.yaml +++ b/docs/user/guide/github-review.i18n.yaml @@ -9,8 +9,8 @@ en: 6784d85f90231608 zh: 3e62e9cadfdc2c18 /create-review-sessions-from-github-webhooks/start-dsh: - en: 5751931f5c89b1c0 - zh: 867950515a152d47 + en: 6c2c8394bfaf5d11 + zh: a863fa2ad6bc48bb /create-review-sessions-from-github-webhooks/expose-the-dedicated-endpoint: en: f18a2969b3082da9 zh: 87d3d0e58d25a62f diff --git a/docs/user/guide/github-review.md b/docs/user/guide/github-review.md index 69c61df95c..f0b2f24fe2 100644 --- a/docs/user/guide/github-review.md +++ b/docs/user/guide/github-review.md @@ -22,20 +22,17 @@ export DSH_GITHUB_WEBHOOK_SECRET="$(openssl rand -hex 32)" printf '%s\n' "$DSH_GITHUB_WEBHOOK_SECRET" ``` -From a development checkout: +Install both experimental packages into the Web profile first. Profiles do not install peers automatically; the GitHub adapter needs the webhook runtime explicitly: ```sh +dsh plugin --profile web add @deepseek-ai/dsh-experimental-webhook @deepseek-ai/dsh-experimental-webhook-github export DSH_GITHUB_REVIEW_WORKSPACE=/path/to/deepseek-harness -pnpm dsh web --patch apps/cli/config/examples/github-review/cordis.yml +dsh web --patch "${DSH_HOME:-$HOME/.dsh}/profiles/web/node_modules/@deepseek-ai/dsh-experimental-webhook-github/examples/github-review/cordis.yml" ``` -An installed DSH uses the same overlay through an absolute path: +The adapter distributes the example, which loads from the profile's installation directory so its rule module can resolve profile-installed peers. Do not run the rule from an arbitrary directory outside the profile. To customize it, copy both example files to `$DSH_HOME/profiles/web/github-review/`, edit the configuration, and point `--patch` at that copy of `cordis.yml`; use `~/.dsh` when `DSH_HOME` is unset. -```sh -dsh web --patch /absolute/path/to/github-review/cordis.yml -``` - -For a permanent profile, place `github-ready-review-rule.mjs` beside `$DSH_HOME/profiles/web/cordis.patch.yml`, append the rows from `cordis.yml` to that patch, and start with `dsh web`. The shipped CLI already contains both webhook packages; the overlay alone activates them. +The repository example lives under `packages/experimental/webhook-github/examples/github-review/`. The CLI does not install webhook packages or list them as Official plugins; installing the packages and supplying the overlay are separate steps. ## Expose the dedicated endpoint diff --git a/docs/user/guide/github-review.zh.md b/docs/user/guide/github-review.zh.md index 114aa6546d..98db87f2bc 100644 --- a/docs/user/guide/github-review.zh.md +++ b/docs/user/guide/github-review.zh.md @@ -22,20 +22,17 @@ export DSH_GITHUB_WEBHOOK_SECRET="$(openssl rand -hex 32)" printf '%s\n' "$DSH_GITHUB_WEBHOOK_SECRET" ``` -在开发 checkout 中运行: +先把两个实验包安装到 Web profile。Profile 不会自动安装 peer;GitHub 适配器需要显式安装 webhook 运行时: ```sh +dsh plugin --profile web add @deepseek-ai/dsh-experimental-webhook @deepseek-ai/dsh-experimental-webhook-github export DSH_GITHUB_REVIEW_WORKSPACE=/path/to/deepseek-harness -pnpm dsh web --patch apps/cli/config/examples/github-review/cordis.yml +dsh web --patch "${DSH_HOME:-$HOME/.dsh}/profiles/web/node_modules/@deepseek-ai/dsh-experimental-webhook-github/examples/github-review/cordis.yml" ``` -安装版 DSH 通过绝对路径使用同一 overlay: +示例随 GitHub 适配器发布,并从 profile 的安装目录加载,因此规则模块能解析该 profile 安装的 peer。不要把规则单独放到 profile 之外的任意目录运行。需要定制时,将示例的两个文件复制到 `$DSH_HOME/profiles/web/github-review/`,修改其配置并把 `--patch` 指向复制后的 `cordis.yml`;未设置 `DSH_HOME` 时使用 `~/.dsh`。 -```sh -dsh web --patch /absolute/path/to/github-review/cordis.yml -``` - -对于永久 profile,把 `github-ready-review-rule.mjs` 放在 `$DSH_HOME/profiles/web/cordis.patch.yml` 旁边,把 `cordis.yml` 中的行追加到该 patch,然后运行 `dsh web`。随附 CLI 已经包含两个 webhook 包;只需 overlay 即可激活它们。 +仓库中的示例位于 `packages/experimental/webhook-github/examples/github-review/`。Webhook 包不随 CLI 安装,也不出现在官方插件列表中;安装包与提供 overlay 是两个独立步骤。 ## 暴露专用端点 diff --git a/package.json b/package.json index 99b6e48822..0dabc11245 100644 --- a/package.json +++ b/package.json @@ -204,9 +204,14 @@ "mock:llm": "node --import tsx packages/test-support/llm-mock-server/src/bin.ts", "start:web": "node --import tsx/esm apps/cli/src/bin.ts web", "dev:web": "tsx scripts/dev-web.ts --poll", - "postinstall": "node scripts/install-lefthook.mjs" + "postinstall": "node scripts/install-lefthook.mjs", + "verify-product-use": "tsx scripts/verify-product-use.ts" }, "devDependencies": { + "@deepseek-ai/dsh-experimental-hooks-claude-code": "workspace:*", + "@deepseek-ai/dsh-experimental-hooks-codex": "workspace:*", + "@deepseek-ai/dsh-experimental-tool-ralph": "workspace:*", + "@deepseek-ai/dsh-experimental-tool-terminal": "workspace:*", "@deepseek-ai/dsh-agent": "workspace:*", "@deepseek-ai/dsh-browser-use": "workspace:*", "@deepseek-ai/dsh-experimental-browser-use-runtime": "workspace:*", diff --git a/packages/README.i18n.yaml b/packages/README.i18n.yaml index 331665509e..4e0d8a1cf7 100644 --- a/packages/README.i18n.yaml +++ b/packages/README.i18n.yaml @@ -15,11 +15,11 @@ en: ffc55792d6e922e1 zh: 83bd759638857e2d /packages/package-groups: - en: 989c5a7131853dc6 - zh: 259d15e2bceb0bb5 + en: 52d0ed3ab9643687 + zh: 79954308b188080b /packages/release-expectations: - en: 7a152a53e2b1f2e5 - zh: 3c154c20db49713d + en: 236081c1659b25ab + zh: 809110adf003802e /packages/dependencies: en: 9576e7c486bf123f zh: fedd18da3e27ad00 diff --git a/packages/README.md b/packages/README.md index 3322d3cb7d..664414dbc4 100644 --- a/packages/README.md +++ b/packages/README.md @@ -55,7 +55,6 @@ Every package lives in exactly one group; new packages join existing groups, and | [`jobs/`](jobs/README.md) | Generic background-job runtime and model-facing job control tools | | [`experimental/`](experimental/README.md) | Pre-stable prototypes with explicit private exceptions | | [`workflow/`](workflow/README.md) | Workflow seam, PTC process engine, and model-facing `workflow`/`ralph` tools | -| [`webhook/`](webhook/README.md) | Verified external events, trusted rules, and fire-and-forget Workspace Sessions | | [`web/`](web/README.md) | Web capability family: seam, search/fetch providers, model-facing web tools | | [`document/`](document/README.md) | Shared Host Office-to-PDF conversion | | [`attachment/`](attachment/README.md) | Durable attachment identity, validation, local content-addressed storage | @@ -67,7 +66,6 @@ Every package lives in exactly one group; new packages join existing groups, and | [`bundle/`](bundle/README.md) | Installable `dsh --profile` patch layers | | [`extensions/`](extensions/README.md) | Agent runtime self-modification: live plugin/service inspection and model-written mount/unmount | | [`mcp/`](mcp/README.md) | External Model Context Protocol servers exposed as native tools | -| [`hooks/`](hooks/README.md) | Hook bridges + the shared Claude Code / Codex wire-protocol library | | [`session/`](session/README.md) | Durable session data plane: persistence seam + backends, projection seam, log-backed titles, session reporting | | [`session-query/`](session-query/README.md) | Session retrieval family: logical corpus, bounded reads, lineage, semantic filtering, SQLite full-text search | | [`settings/`](settings/README.md) | User-settings seam + file-backed provider | @@ -88,7 +86,7 @@ Every package lives in exactly one group; new packages join existing groups, and ## Release expectations -Most groups are product — stable API. The exceptions: `experimental/` publishes without stability or support promises, and `test-support/` and `util/` are support with lower compatibility expectations. +Product groups have maintained product roles, while their public APIs remain pre-stable. [Experimental status](experimental/README.md#status) is independent of publication, installation, and optional delivery. Nonexperimental runtime packages must have product use or an explicit [package classification](../scripts/product-package-policy.ts); SDK, build, test, and declaration infrastructure have separate classifications. ----- diff --git a/packages/README.zh.md b/packages/README.zh.md index c187e74f52..7eeec29331 100644 --- a/packages/README.zh.md +++ b/packages/README.zh.md @@ -55,7 +55,6 @@ harness 由 `packages/` 下的 npm 包组装而成,按能力系列分组:会 | [`jobs/`](jobs/README.zh.md) | 通用后台任务运行时和面向模型的作业控制工具 | | [`experimental/`](experimental/README.zh.md) | 预稳定原型,包含显式私有例外 | | [`workflow/`](workflow/README.zh.md) | 工作流 seam、PTC 进程引擎、面向模型的 `workflow`/`ralph` 工具 | -| [`webhook/`](webhook/README.zh.md) | 已验证外部事件、受信规则与即发即弃 Workspace 会话 | | [`web/`](web/README.zh.md) | Web 能力系列:seam、搜索/获取提供方、面向模型的 Web 工具 | | [`document/`](document/README.zh.md) | 共享宿主 Office 到 PDF 转换 | | [`attachment/`](attachment/README.zh.md) | 持久附件标识、校验、本地内容寻址存储 | @@ -67,7 +66,6 @@ harness 由 `packages/` 下的 npm 包组装而成,按能力系列分组:会 | [`bundle/`](bundle/README.zh.md) | 可安装的 `dsh --profile` 补丁层 | | [`extensions/`](extensions/README.zh.md) | agent 运行时自修改:实时插件/服务检查与模型所写挂载/卸载 | | [`mcp/`](mcp/README.zh.md) | 将外部 Model Context Protocol 服务器的工具接入为原生工具 | -| [`hooks/`](hooks/README.zh.md) | 钩子桥接 + 共享的 Claude Code/Codex 线协议库 | | [`session/`](session/README.zh.md) | 持久会话数据平面:持久化 seam + 后端、投影 seam、基于日志的标题、会话上报 | | [`session-query/`](session-query/README.zh.md) | 会话检索系列:逻辑语料库、有界读取、血缘、语义过滤、SQLite 全文搜索 | | [`settings/`](settings/README.zh.md) | 用户设置 seam + 基于文件的提供方 | @@ -88,7 +86,7 @@ harness 由 `packages/` 下的 npm 包组装而成,按能力系列分组:会 ## 发布预期 -大多数组属于产品组,提供稳定 API。例外:`experimental/` 发布时不提供稳定性或支持承诺,`test-support/` 与 `util/` 是兼容性预期较低的支持组。 +产品组承担维护职责,但其公开 API 仍处于预稳定阶段。[实验性状态](experimental/README.zh.md#status)独立于发布、安装和可选交付。非实验运行时包必须被产品使用或在[包分类策略](../scripts/product-package-policy.ts)中明确列出;SDK、构建、测试与声明基础设施分别分类。 ----- diff --git a/packages/bundle/base/cordis.patch.yml b/packages/bundle/base/cordis.patch.yml index d3f6bf1fa9..ad48887e33 100644 --- a/packages/bundle/base/cordis.patch.yml +++ b/packages/bundle/base/cordis.patch.yml @@ -303,10 +303,6 @@ - id: skill-filesystem name: '@deepseek-ai/dsh-skill-filesystem' - - id: skill-badge - name: '@deepseek-ai/dsh-skill-badge' - disabled: true - - id: tool-skill name: '@deepseek-ai/dsh-tool-skill' @@ -440,20 +436,6 @@ - id: tool-goal name: '@deepseek-ai/dsh-tool-goal' - # Fresh-agent Ralph iteration over a build-time-fixed script. Off by - # default: the tool description restricts `ralph` to runs the human - # explicitly asked for, and completion is a worker self-report, not an - # independent evaluation. An overlay row restores it for a base-backed - # profile (`$DSH_HOME/cordis.patch.yml`, or a `--patch `): - # - id: tool-ralph - # disabled: false - - id: tool-ralph - name: '@deepseek-ai/dsh-tool-ralph' - disabled: true - config: - subagentProvider: spawn - maxRounds: 64 - # Consecutive-repeat reminders on the tool chain. - id: repeat-tool-reminder name: '@deepseek-ai/dsh-repeat-tool-reminder' diff --git a/packages/bundle/base/package.json b/packages/bundle/base/package.json index ffd89f1310..be152900d3 100644 --- a/packages/bundle/base/package.json +++ b/packages/bundle/base/package.json @@ -81,7 +81,6 @@ "@deepseek-ai/dsh-session-title": "workspace:*", "@deepseek-ai/dsh-session-title-first-prompt-llm": "workspace:*", "@deepseek-ai/dsh-skill": "workspace:*", - "@deepseek-ai/dsh-skill-badge": "workspace:*", "@deepseek-ai/dsh-skill-filesystem": "workspace:*", "@deepseek-ai/dsh-spill-local": "workspace:*", "@deepseek-ai/dsh-spill-policy": "workspace:*", @@ -102,7 +101,6 @@ "@deepseek-ai/dsh-tool-fs-search": "workspace:*", "@deepseek-ai/dsh-tool-goal": "workspace:*", "@deepseek-ai/dsh-tool-pwsh": "workspace:*", - "@deepseek-ai/dsh-tool-ralph": "workspace:*", "@deepseek-ai/dsh-tool-skill": "workspace:*", "@deepseek-ai/dsh-tool-subagent": "workspace:*", "@deepseek-ai/dsh-tool-subagent-control": "workspace:*", diff --git a/packages/bundle/web-app/cordis.patch.yml b/packages/bundle/web-app/cordis.patch.yml index 37ca90703a..795a7183f9 100644 --- a/packages/bundle/web-app/cordis.patch.yml +++ b/packages/bundle/web-app/cordis.patch.yml @@ -557,12 +557,6 @@ - id: tool-workflow disabled: true -# `base` ships this row disabled; the preset-plane gate reads declared row ids -# without regard to `disabled`, so this row must stay to keep `tool-ralph` off -# the host plane and out of collision with every preset's row. -- id: tool-ralph - disabled: true - - id: agent-instructions disabled: true diff --git a/packages/bundle/web-app/package.json b/packages/bundle/web-app/package.json index d71c50f66d..253a505ab5 100644 --- a/packages/bundle/web-app/package.json +++ b/packages/bundle/web-app/package.json @@ -160,7 +160,6 @@ "@deepseek-ai/dsh-tool-present": "workspace:*", "@deepseek-ai/dsh-tool-pwsh": "workspace:*", "@deepseek-ai/dsh-tool-pwsh-persistent": "workspace:*", - "@deepseek-ai/dsh-tool-ralph": "workspace:*", "@deepseek-ai/dsh-tool-schedule": "workspace:*", "@deepseek-ai/dsh-tool-skill": "workspace:*", "@deepseek-ai/dsh-tool-subagent": "workspace:*", diff --git a/packages/bundle/web-app/presets/cordis.patch.yml b/packages/bundle/web-app/presets/cordis.patch.yml index 6944a1fcf8..8ac2b0604e 100644 --- a/packages/bundle/web-app/presets/cordis.patch.yml +++ b/packages/bundle/web-app/presets/cordis.patch.yml @@ -132,12 +132,6 @@ provider: spawn - id: tool-workflow name: '@deepseek-ai/dsh-tool-workflow' - - id: tool-ralph - name: '@deepseek-ai/dsh-tool-ralph' - disabled: true - config: - subagentProvider: spawn - maxRounds: 64 - id: tool-ask-user name: '@deepseek-ai/dsh-tool-ask-user' - id: tool-todo diff --git a/packages/bundle/web-app/presets/ptc.patch.yml b/packages/bundle/web-app/presets/ptc.patch.yml index 0b3237669f..8af9c4a226 100644 --- a/packages/bundle/web-app/presets/ptc.patch.yml +++ b/packages/bundle/web-app/presets/ptc.patch.yml @@ -135,12 +135,6 @@ - id: tool-workflow name: '@deepseek-ai/dsh-tool-workflow' disabled: true - - id: tool-ralph - name: '@deepseek-ai/dsh-tool-ralph' - disabled: true - config: - subagentProvider: spawn - maxRounds: 64 - id: tool-ask-user name: '@deepseek-ai/dsh-tool-ask-user' - id: tool-todo diff --git a/packages/bundle/web-app/presets/standard.patch.yml b/packages/bundle/web-app/presets/standard.patch.yml index 453a9dcd46..912e9844e2 100644 --- a/packages/bundle/web-app/presets/standard.patch.yml +++ b/packages/bundle/web-app/presets/standard.patch.yml @@ -133,12 +133,6 @@ provider: spawn - id: tool-workflow name: '@deepseek-ai/dsh-tool-workflow' - - id: tool-ralph - name: '@deepseek-ai/dsh-tool-ralph' - disabled: true - config: - subagentProvider: spawn - maxRounds: 64 - id: tool-ask-user name: '@deepseek-ai/dsh-tool-ask-user' - id: tool-todo diff --git a/packages/client/ui-tool/package.json b/packages/client/ui-tool/package.json index a0e284f130..5698ad1f42 100644 --- a/packages/client/ui-tool/package.json +++ b/packages/client/ui-tool/package.json @@ -53,7 +53,7 @@ "@deepseek-ai/dsh-tools": "workspace:*", "@deepseek-ai/dsh-tool-jobs": "workspace:*", "@deepseek-ai/dsh-tool-session-query": "workspace:*", - "@deepseek-ai/dsh-tool-terminal": "workspace:*", + "@deepseek-ai/dsh-experimental-tool-terminal": "workspace:*", "@deepseek-ai/dsh-spill": "workspace:*", "@deepseek-ai/cordis": "workspace:~", "@deepseek-ai/dsh-api-remotes": "workspace:*", diff --git a/packages/client/ui-tool/tests/details-models.client.spec.ts b/packages/client/ui-tool/tests/details-models.client.spec.ts index 9642bd55f7..de6bcc173d 100644 --- a/packages/client/ui-tool/tests/details-models.client.spec.ts +++ b/packages/client/ui-tool/tests/details-models.client.spec.ts @@ -8,7 +8,7 @@ import { en as commonEn } from '@deepseek-ai/dsh-client-locale/src/locales/en.ts import { zh as commonZh } from '@deepseek-ai/dsh-client-locale/src/locales/zh.ts' import { statusLine } from '@deepseek-ai/dsh-tool-jobs/src/render.ts' import { presentation } from '@deepseek-ai/dsh-tool-session-query/src/presentation.ts' -import { renderList, renderRead, renderSpawn } from '@deepseek-ai/dsh-tool-terminal/src/render.ts' +import { renderList, renderRead, renderSpawn } from '@deepseek-ai/dsh-experimental-tool-terminal/src/render.ts' import { formatSpillNotice } from '@deepseek-ai/dsh-spill-policy/notice' import { detailBadge, detailJson, detailList, detailRecord, inspectionItems, nonempty } from '../src/client/tool/models/detail-model-shared.ts' import { detailsCardModel } from '../src/client/tool/models/details-card-model.ts' diff --git a/packages/core/agent-loop/tests/interception.spec.ts b/packages/core/agent-loop/tests/interception.spec.ts index 352583df36..3d7349c88a 100644 --- a/packages/core/agent-loop/tests/interception.spec.ts +++ b/packages/core/agent-loop/tests/interception.spec.ts @@ -730,7 +730,7 @@ describe('tools/pre-execute gate (native-plugin permission pattern, end-to-end t }) describe('worked example: a native hook plugin is just a cordis plugin on the seams', () => { - // The whole point of the interception taxonomy: a "native hook" needs no dsh-hook-protocol, + // The whole point of the interception taxonomy: a "native hook" needs no dsh-experimental-hook-protocol, // no external command, no hook/* log — it is an ordinary cordis plugin subscribing to the // canonical events and returning typed decisions. const NativeGuard = { diff --git a/packages/experimental/AGENTS.md b/packages/experimental/AGENTS.md index 0171d8b843..3fbb97eb09 100644 --- a/packages/experimental/AGENTS.md +++ b/packages/experimental/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS.md — Experimental packages -These rules supplement the [package rules](../AGENTS.md). The [experimental publication reference](README.md) owns the publication policy; the rules below define dependency isolation and promotion. +These rules supplement the [package rules](../AGENTS.md). The [experimental reference](README.md#status) defines experimental, optional, and Official status; the rules below define dependency isolation and promotion. - A package belongs here only when its complete public contract is experimental or internal-only. An experimental option inside a release package stays with its owning product role. - Every package here uses the `@deepseek-ai/dsh-experimental-*` npm prefix and joins the dsh release family by default: omit `private` and set `publishConfig.access: public`. Only directories in `PRIVATE_EXPERIMENTAL_PACKAGE_DIRECTORIES` in [the publication policy](../../scripts/experimental-package-policy.ts) stay private: set `private: true` and omit `publishConfig`. diff --git a/packages/experimental/README.i18n.yaml b/packages/experimental/README.i18n.yaml index 52cf6372c3..50d400cb28 100644 --- a/packages/experimental/README.i18n.yaml +++ b/packages/experimental/README.i18n.yaml @@ -9,14 +9,17 @@ en: 18bc48bb66b3e516 zh: 51f2340a5c921f36 /packages-experimental/summary: - en: b069b2b8ef04abd7 - zh: 330095b8c3f9aa7c + en: b268bb4e0a1f2013 + zh: bc4abacc015b44dc /packages-experimental/table-of-contents: - en: 1eb35b015a6c423f - zh: a8a3dceee2c9e943 + en: cd24cc2ef2ec742e + zh: 7db21f509a8620a5 +/packages-experimental/experimental-optional-and-official: + en: 5d86d3390fe062a0 + zh: 582d77571ba08f65 /packages-experimental/packages: - en: dc594ae77b05499c - zh: 06090a11e2144b47 + en: 8dbff5ff0843dd44 + zh: 5d8947f8a309f8b0 /packages-experimental/related-documentation: en: 1cb9d3448d44e48d zh: cd326d70a746b896 diff --git a/packages/experimental/README.md b/packages/experimental/README.md index 98591f9e94..9eb47dd124 100644 --- a/packages/experimental/README.md +++ b/packages/experimental/README.md @@ -9,21 +9,42 @@ English | [中文](README.zh.md) ## Summary -Experimental prototypes may change their contracts and carry no support promise. New packages publish by default; private packages must also appear in the [private-exception list](../../scripts/experimental-package-policy.ts). All current packages publish under their `@deepseek-ai/dsh-experimental-*` names, including the opt-in Agent Teams composition, Auto review, Cua Driver providers, browser-use backends, cross-realm Inspector, CPython PTC backend, and browser-worker preview libraries. Released products outside this group must not depend on experimental packages. The dsh installation ships its optional bundles switched off; the GUI plugin manager offers them in the Official group ([decision](../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md)); the other packages are libraries or explicit compositions. +Install and compose experimental capabilities explicitly, without a product-support commitment. Packages publish under `@deepseek-ai/dsh-experimental-*`; private packages require an entry in the [publication policy](../../scripts/experimental-package-policy.ts). The [optional-bundle rule](../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md) determines which capabilities ship switched off with the installation for explicit selection in the GUI plugin manager’s Official group. ## Table of Contents +- [Experimental, optional, and Official](#status) - [Packages](#packages) - [Related documentation](#related-documentation) - [Dev Note](#dev-note) ----- + +## Experimental, optional, and Official + +**Experimental** means the complete public capability remains under evaluation and is not a product-support commitment. Its behavior or API may change, and the capability may be withdrawn; engineering, security, documentation, testing, and released-data obligations still apply. A package belongs here only when its entire public contract is experimental or internal-only; an experimental option inside a product package stays with that product role. + +**Optional** means a user explicitly selects the capability. **Official** means the project maintains and lists the package in the Plugins page. Neither describes maturity; publication, default installation, and GUI visibility do not determine maturity either. Product packages outside this group have maintained product roles, while their public APIs still follow the repository's pre-stable policy. + +Promotion requires a named product role, documented public behavior and limitations, current consumers, release contents, and test evidence. Move the package to its product group, remove `experimental-` from its npm name, and update every consumer together. The [subtree rules](AGENTS.md) govern dependency isolation and publication. + +----- + ## Packages | Package | Role | ctx key | |---|---|---| +| [`hook-protocol`](hook-protocol/README.md) | Hook bridge wire types and durable events | — | +| [`hooks-claude-code`](hooks-claude-code/README.md) | Claude Code hook bridge | — | +| [`hooks-codex`](hooks-codex/README.md) | Codex hook bridge | — | +| [`webhook`](webhook/README.md) | Authenticated delivery dispatch and Workspace Session creation | `ctx.webhookRuntime` | +| [`webhook-github`](webhook-github/README.md) | Signed GitHub webhook ingress | — | +| [`session-title-all-prompts-llm`](session-title-all-prompts-llm/README.md) | Session titles from all human prompts | — | +| [`tool-terminal`](tool-terminal/README.md) | Persistent terminal tools | — | +| [`tool-ralph`](tool-ralph/README.md) | Bounded repeated delegated tasks | — | +| [`skill-badge`](skill-badge/README.md) | The powered-by-dsh badge skill | — | | [`translator`](translator/README.md) | Anonymous Google and Bing text translation | `ctx.translator` | | [`client-ui-cot-translation`](client-ui-cot-translation/README.md) | Expanded reasoning translation and original-text controls | `ctx.cotTranslation` | | [`cot-translation-bundle`](cot-translation-bundle/README.md) | Default-disabled reasoning translation composition | — | diff --git a/packages/experimental/README.zh.md b/packages/experimental/README.zh.md index 248abfde94..d58ab12346 100644 --- a/packages/experimental/README.zh.md +++ b/packages/experimental/README.zh.md @@ -9,21 +9,42 @@ kind: "package-group" ## 概述 -实验性原型的约定可能变更,且不提供支持承诺。新包默认发布;私有包还必须列入[私有例外列表](../../scripts/experimental-package-policy.ts)。所有当前包都以 `@deepseek-ai/dsh-experimental-*` 名称发布,包括显式启用的 Agent Teams 组合、Auto review、Cua Driver 提供方、浏览器操作后端、跨 realm Inspector、CPython PTC 后端与浏览器 worker 预览库。组外已发布产品不得依赖实验性包。dsh 安装随附默认关闭的可选 bundle,GUI 插件管理器在官方分组提供它们([决策](../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md));其余包是库或显式组合。 +实验性能力可按需安装和组合,但不提供产品支持承诺。各包以 `@deepseek-ai/dsh-experimental-*` 名称发布;私有包必须列入[发布策略](../../scripts/experimental-package-policy.ts)。[可选组合规则](../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md)决定哪些能力以默认关闭状态随安装提供,并在 GUI 插件管理器的官方分组显式启用。 ## 目录 +- [实验性、可选与官方](#status) - [包](#packages) - [相关文档](#related-documentation) - [开发备注](#dev-note) ----- + +## 实验性、可选与官方 + +**实验性**表示整个公开能力仍在评估中,不属于产品支持承诺。其行为或 API 可能变更,能力也可能被撤回;工程、安全、文档、测试和已发布数据的义务仍然适用。只有其完整公开约定均为实验性或仅限内部使用的包才属于本组;产品包中的实验选项仍归原产品职责所有。 + +**可选**表示用户显式选择该能力。**官方**表示项目维护并在插件页列出该包。两者均不表示成熟度;发布、默认安装和界面可见性也不决定成熟度。组外产品包承担维护职责,其公开 API 仍遵循仓库的预稳定政策。 + +晋升需要明确的产品职责、公开行为与限制、当前消费者、发布内容以及测试证据。晋升时将包移入对应产品组,去掉 npm 名称中的 `experimental-`,并同时更新所有消费者。[子树规则](AGENTS.md)规定依赖隔离和发布要求。 + +----- + ## 包 | 包 | 职责 | ctx 键 | |---|---|---| +| [`hook-protocol`](hook-protocol/README.zh.md) | 钩子桥接的通信类型与持久事件 | — | +| [`hooks-claude-code`](hooks-claude-code/README.zh.md) | Claude Code 钩子桥接 | — | +| [`hooks-codex`](hooks-codex/README.zh.md) | Codex 钩子桥接 | — | +| [`webhook`](webhook/README.zh.md) | 已认证投递分发与 Workspace Session 创建 | `ctx.webhookRuntime` | +| [`webhook-github`](webhook-github/README.zh.md) | 带签名的 GitHub webhook 入口 | — | +| [`session-title-all-prompts-llm`](session-title-all-prompts-llm/README.zh.md) | 根据所有人类提示生成会话标题 | — | +| [`tool-terminal`](tool-terminal/README.zh.md) | 持久终端工具 | — | +| [`tool-ralph`](tool-ralph/README.zh.md) | 有界重复委派任务 | — | +| [`skill-badge`](skill-badge/README.zh.md) | powered-by-dsh 徽章技能 | — | | [`translator`](translator/README.zh.md) | 免登录 Google 与 Bing 文本翻译 | `ctx.translator` | | [`client-ui-cot-translation`](client-ui-cot-translation/README.zh.md) | 展开的思考内容翻译与原文控件 | `ctx.cotTranslation` | | [`cot-translation-bundle`](cot-translation-bundle/README.zh.md) | 默认禁用的思考内容翻译组合 | — | diff --git a/packages/experimental/claude-code-mods/README.i18n.yaml b/packages/experimental/claude-code-mods/README.i18n.yaml index 75a4be20d1..3c0d307915 100644 --- a/packages/experimental/claude-code-mods/README.i18n.yaml +++ b/packages/experimental/claude-code-mods/README.i18n.yaml @@ -45,8 +45,8 @@ en: a141066b146cef7c zh: fe91851f05c008c4 /deepseek-ai-dsh-experimental-claude-code-mods/further-exploration: - en: 43c558ca826febdd - zh: 3dfd87ca60c6548d + en: 66d98f72199cbb41 + zh: 0409978863af3b1e /deepseek-ai-dsh-experimental-claude-code-mods/model-experience: en: 215e7ba838619b7b zh: a311da3843709f90 @@ -78,8 +78,8 @@ en: ca31263f47f654d9 zh: 17d55e6641705627 /deepseek-ai-dsh-experimental-claude-code-mods/known-limitations-and-deferred-work: - en: 99aaa73c8ef9c609 - zh: 46fab480bd2b1706 + en: c4e5cc431b15c7e5 + zh: a964d0a9a1f13b0f /deepseek-ai-dsh-experimental-claude-code-mods/known-limitations-and-deferred-work/dev-note: en: 4d1e26f4cc9c3c1c zh: d80209b56c56b11c diff --git a/packages/experimental/claude-code-mods/README.md b/packages/experimental/claude-code-mods/README.md index da606f5620..23e3ae2067 100644 --- a/packages/experimental/claude-code-mods/README.md +++ b/packages/experimental/claude-code-mods/README.md @@ -148,7 +148,7 @@ A call whose service is not composed rejects with the missing service's package - [Claude Code mods reference](https://code.claude.com/docs/en/plugins/mods/reference) — the events, methods, and limits this bridge mirrors. - [The Web band](../client-ui-claude-code-mods/README.md) — the Client package that draws `ui.render` trees in the input dock. - [Experimental packages](../README.md) — publication policy and dependency isolation. -- [Hooks group](../../hooks/README.md) — the settings-hook bridges; a plugin's `hooks.json` settings hooks need `dsh-hooks-claude-code`. +- [Hooks group](../README.md) — the settings-hook bridges; a plugin's `hooks.json` settings hooks need `dsh-experimental-hooks-claude-code`. - [Tool execution pipeline](../../../docs/tool-execution-pipeline.md) — the waterfalls `tool.call` runs around. - [Human commands](../../interaction/commands/README.md) — the registry `$.command.register` lands on. @@ -207,7 +207,7 @@ These limits describe where a Claude Code mod behaves differently through this b - **No sandbox, no static analysis, no hot reload** — the hooks module runs in-process with Node's globals and the process's full authority (its environment, network, filesystem, and tools); the `$`-only access rule, `claude plugin validate`, type generation, `--plugin-dir` watching, and the in-session mod authoring flow are not implemented. Mount only mods you would run as a plugin. Mounting a mod again re-runs `register` on the same evaluated module, so module-level variables keep their values. - **`turn.complete` text** — the `{ text }` a hook returns reaches the host log, not a line under the answer; `durationMs` counts from the turn's `turn/start`. - **`$.session.usage`** — `window` is `0` and `percent` absent until the route's context window and a provider usage report are known through the token meter; `rateLimits` is always empty. `$.fs.stat` reports `mtimeMs: 0`. -- **`plugin.json` and `hooks.json`** — not read; `defineMod` carries the identity, and a plugin's settings hooks need `@deepseek-ai/dsh-hooks-claude-code`. +- **`plugin.json` and `hooks.json`** — not read; `defineMod` carries the identity, and a plugin's settings hooks need `@deepseek-ai/dsh-experimental-hooks-claude-code`. ### Dev Note diff --git a/packages/experimental/claude-code-mods/README.zh.md b/packages/experimental/claude-code-mods/README.zh.md index 8d1edb94ff..0278f65622 100644 --- a/packages/experimental/claude-code-mods/README.zh.md +++ b/packages/experimental/claude-code-mods/README.zh.md @@ -148,7 +148,7 @@ Blast Radius 的 DSH 包装使用当前运行的可执行文件提供 Node 计 - [Claude Code 模组参考](https://code.claude.com/docs/en/plugins/mods/reference) — 本桥接镜像的事件、方法与限制。 - [Web 横幅](../client-ui-claude-code-mods/README.zh.md) — 在输入停靠区绘制 `ui.render` 树的 Client 包。 - [实验性包](../README.zh.md) — 发布策略与依赖隔离。 -- [Hooks 组](../../hooks/README.zh.md) — 设置钩子桥接;插件 `hooks.json` 中的设置钩子需要 `dsh-hooks-claude-code`。 +- [Hooks 组](../README.zh.md) — 设置钩子桥接;插件 `hooks.json` 中的设置钩子需要 `dsh-experimental-hooks-claude-code`。 - [工具执行流水线](../../../docs/tool-execution-pipeline.zh.md) — `tool.call` 所包裹的瀑布流。 - [人类命令](../../interaction/commands/README.zh.md) — `$.command.register` 落到的注册表。 @@ -207,7 +207,7 @@ Message from the "" mod: - **无沙箱、无静态分析、无热重载** — 钩子模块以 Node 全局对象在进程内运行,拥有本进程的全部权限(环境变量、网络、文件系统与工具);仅 `$` 访问规则、`claude plugin validate`、类型生成、`--plugin-dir` 监视与会话内模组编写流程均未实现。只挂载你愿意作为插件运行的模组。再次挂载模组会在同一已求值模块上重新运行 `register`,模块级变量保留其值。 - **`turn.complete` 文本** — 钩子返回的 `{ text }` 到达宿主日志,而非答案下方的一行;`durationMs` 从该轮的 `turn/start` 起算。 - **`$.session.usage`** — 在 token 计量器得知路由的上下文窗口与提供商用量报告之前,`window` 为 `0` 且无 `percent`;`rateLimits` 始终为空。`$.fs.stat` 报告 `mtimeMs: 0`。 -- **`plugin.json` 与 `hooks.json`** — 不读取;`defineMod` 承载身份,插件的设置钩子需要 `@deepseek-ai/dsh-hooks-claude-code`。 +- **`plugin.json` 与 `hooks.json`** — 不读取;`defineMod` 承载身份,插件的设置钩子需要 `@deepseek-ai/dsh-experimental-hooks-claude-code`。 ### 开发备注 diff --git a/packages/experimental/hook-protocol/README.i18n.yaml b/packages/experimental/hook-protocol/README.i18n.yaml new file mode 100644 index 0000000000..e5bea2416a --- /dev/null +++ b/packages/experimental/hook-protocol/README.i18n.yaml @@ -0,0 +1,61 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/hook-protocol/README.md +/: + en: 7cfe3761eedff848 + zh: 80b0bed5743d0924 +/deepseek-ai-dsh-experimental-hook-protocol: + en: 59c4379ae58d7ca3 + zh: 6d015de6ce018358 +/deepseek-ai-dsh-experimental-hook-protocol/summary: + en: 2831db16082fcbed + zh: 38c1eb54c1dd56dc +/deepseek-ai-dsh-experimental-hook-protocol/table-of-contents: + en: d152484eb41ac6b4 + zh: 09388d293f9be9cb +/deepseek-ai-dsh-experimental-hook-protocol/use-this-package: + en: 84b3719a71cc14a9 + zh: 8f500851d2f02784 +/deepseek-ai-dsh-experimental-hook-protocol/use-this-package/when-to-choose-it: + en: b1a1a4e9652ab792 + zh: 08f819dd3b0b98d4 +/deepseek-ai-dsh-experimental-hook-protocol/use-this-package/what-a-hook-can-do: + en: 043f54b3a5b518a7 + zh: a4115083a9b1cef1 +/deepseek-ai-dsh-experimental-hook-protocol/use-this-package/what-you-see-when-hooks-run: + en: ba2d6ed1db063f53 + zh: ab1b8d72dccd2ff1 +/deepseek-ai-dsh-experimental-hook-protocol/understand-the-implementation: + en: 08b3960150e9c5e2 + zh: 6bb2f236d697de01 +/deepseek-ai-dsh-experimental-hook-protocol/understand-the-implementation/processing-pipeline: + en: b25d80f19b551f1a + zh: 9c6602f008d89bce +/deepseek-ai-dsh-experimental-hook-protocol/understand-the-implementation/hook-session-events: + en: f01ab4ab98f052b3 + zh: 1da25fa50378bd19 +/deepseek-ai-dsh-experimental-hook-protocol/understand-the-implementation/design-philosophy: + en: 7f9239eaea5a945c + zh: 9ba6a2ea955d4934 +/deepseek-ai-dsh-experimental-hook-protocol/understand-the-implementation/source-map: + en: aa4983adf89ea45c + zh: cc83b0ede5ff156c +/deepseek-ai-dsh-experimental-hook-protocol/further-exploration: + en: 8b585ce73c2be2cc + zh: c0270fd001e1352b +/deepseek-ai-dsh-experimental-hook-protocol/model-experience: + en: 99188699e4c6e334 + zh: bba689b1e0f33d97 +/deepseek-ai-dsh-experimental-hook-protocol/model-experience/kv-cache-effect: + en: e290ccc9b3c92c08 + zh: cb3c8823f41e7afe +/deepseek-ai-dsh-experimental-hook-protocol/known-limitations-and-deferred-work: + en: 1ca6146a077a7d2d + zh: 369741569178fc79 +/deepseek-ai-dsh-experimental-hook-protocol/known-limitations-and-deferred-work/dev-note: + en: ac1d08360a93382b + zh: 6c58749bae9a6e65 +/deepseek-ai-dsh-experimental-hook-protocol/known-limitations-and-deferred-work/dev-note/future-run-level-halt: + en: bfb3db50de22c1d0 + zh: 2a979359b0edbbe7 diff --git a/packages/hooks/hook-protocol/README.md b/packages/experimental/hook-protocol/README.md similarity index 86% rename from packages/hooks/hook-protocol/README.md rename to packages/experimental/hook-protocol/README.md index b443839fd1..4c043ebb2e 100644 --- a/packages/hooks/hook-protocol/README.md +++ b/packages/experimental/hook-protocol/README.md @@ -3,13 +3,13 @@ description: "The shared hook rules behind the Claude Code and Codex bridges — kind: "package-library" --- -# @deepseek-ai/dsh-hook-protocol +# @deepseek-ai/dsh-experimental-hook-protocol English | [中文](README.zh.md) ## Summary -`dsh-hook-protocol` makes both bridges handle your hooks identically: it defines what a hook can do and what happens when it runs. You never install or configure it yourself — choose `dsh-hooks-claude-code` or `dsh-hooks-codex`, point it at your existing `hooks.json`, and these rules apply to your hooks. Through either bridge, a hook can block a prompt or tool call with a message the model sees, attach extra context to the conversation, or ask the run to stop. Only command hooks run; `http`, `mcp_tool`, `prompt`, and `agent` handlers are skipped with a warning. +`dsh-experimental-hook-protocol` makes both bridges handle your hooks identically: it defines what a hook can do and what happens when it runs. You never install or configure it yourself — choose `dsh-experimental-hooks-claude-code` or `dsh-experimental-hooks-codex`, point it at your existing `hooks.json`, and these rules apply to your hooks. Through either bridge, a hook can block a prompt or tool call with a message the model sees, attach extra context to the conversation, or ask the run to stop. Only command hooks run; `http`, `mcp_tool`, `prompt`, and `agent` handlers are skipped with a warning. ## Table of Contents @@ -25,11 +25,11 @@ English | [中文](README.zh.md) ## Use this package -You don't install or configure this package directly — mounting `dsh-hooks-claude-code` or `dsh-hooks-codex` applies these rules to your existing `hooks.json` hooks. Use this page to learn what a hook can do and what happens when it runs; the two bridge pages list which events each dialect supports. +You don't install or configure this package directly — mounting `dsh-experimental-hooks-claude-code` or `dsh-experimental-hooks-codex` applies these rules to your existing `hooks.json` hooks. Use this page to learn what a hook can do and what happens when it runs; the two bridge pages list which events each dialect supports. ### When to choose it -Choose `dsh-hooks-claude-code` or `dsh-hooks-codex` when you have existing Claude Code or Codex hooks and want them to keep working during agent runs. You never choose this package directly. Avoid the whole group for bespoke behavior with no reference-tool equivalent: a native Cordis plugin has the full harness API with no hook protocol in between. +Choose `dsh-experimental-hooks-claude-code` or `dsh-experimental-hooks-codex` when you have existing Claude Code or Codex hooks and want them to keep working during agent runs. You never choose this package directly. Avoid the whole group for bespoke behavior with no reference-tool equivalent: a native Cordis plugin has the full harness API with no hook protocol in between. ### What a hook can do @@ -112,7 +112,7 @@ Read these pages when the package-level contract is not enough. They move from t ## Model Experience -Indirectly, through `dsh-hooks-claude-code` and `dsh-hooks-codex`, which are the only consumers that render decoded hook output into model context. +Indirectly, through `dsh-experimental-hooks-claude-code` and `dsh-experimental-hooks-codex`, which are the only consumers that render decoded hook output into model context. #### KV Cache effect diff --git a/packages/hooks/hook-protocol/README.zh.md b/packages/experimental/hook-protocol/README.zh.md similarity index 86% rename from packages/hooks/hook-protocol/README.zh.md rename to packages/experimental/hook-protocol/README.zh.md index 6a7a444b65..a9e4c7d9dd 100644 --- a/packages/hooks/hook-protocol/README.zh.md +++ b/packages/experimental/hook-protocol/README.zh.md @@ -3,13 +3,13 @@ description: "Claude Code 与 Codex 桥接背后的共享钩子规则——钩 kind: "package-library" --- -# @deepseek-ai/dsh-hook-protocol +# @deepseek-ai/dsh-experimental-hook-protocol [English](README.md) | 中文 ## 概述 -`dsh-hook-protocol` 让两个桥接以相同方式处理你的钩子:它定义钩子能做什么、运行时会发生什么。你无需自行安装或配置它——选择 `dsh-hooks-claude-code` 或 `dsh-hooks-codex`,把它指向你现有的 `hooks.json`,这些规则就会作用于你的钩子。通过任一桥接,钩子都可以带一条模型可见的消息阻塞提示词或工具调用、向对话附加额外上下文,或请求运行停止。只有 command 钩子会运行;`http`、`mcp_tool`、`prompt` 与 `agent` handler 会被跳过并给出警告。 +`dsh-experimental-hook-protocol` 让两个桥接以相同方式处理你的钩子:它定义钩子能做什么、运行时会发生什么。你无需自行安装或配置它——选择 `dsh-experimental-hooks-claude-code` 或 `dsh-experimental-hooks-codex`,把它指向你现有的 `hooks.json`,这些规则就会作用于你的钩子。通过任一桥接,钩子都可以带一条模型可见的消息阻塞提示词或工具调用、向对话附加额外上下文,或请求运行停止。只有 command 钩子会运行;`http`、`mcp_tool`、`prompt` 与 `agent` handler 会被跳过并给出警告。 ## 目录 @@ -25,11 +25,11 @@ kind: "package-library" ## 使用本包 -你无需直接安装或配置本包——挂载 `dsh-hooks-claude-code` 或 `dsh-hooks-codex` 就会把这些规则应用到你的 `hooks.json` 钩子上。用本页了解钩子能做什么、运行时会发生什么;两个桥接页面列出各方言支持的事件。 +你无需直接安装或配置本包——挂载 `dsh-experimental-hooks-claude-code` 或 `dsh-experimental-hooks-codex` 就会把这些规则应用到你的 `hooks.json` 钩子上。用本页了解钩子能做什么、运行时会发生什么;两个桥接页面列出各方言支持的事件。 ### 何时选择 -当你持有现有的 Claude Code 或 Codex 钩子、希望它们在 agent(智能体)运行期间继续工作时,选择 `dsh-hooks-claude-code` 或 `dsh-hooks-codex`。你永远不会直接选择本包。没有参考工具对应物的定制行为请避开整个组:原生 Cordis 插件拥有完整的 harness API,无需中间的钩子协议。 +当你持有现有的 Claude Code 或 Codex 钩子、希望它们在 agent(智能体)运行期间继续工作时,选择 `dsh-experimental-hooks-claude-code` 或 `dsh-experimental-hooks-codex`。你永远不会直接选择本包。没有参考工具对应物的定制行为请避开整个组:原生 Cordis 插件拥有完整的 harness API,无需中间的钩子协议。 ### 钩子能做什么 @@ -112,7 +112,7 @@ kind: "package-library" ## 模型体验 -通过 `dsh-hooks-claude-code` 与 `dsh-hooks-codex` 间接影响;它们是将解码后的 hook 输出渲染为模型上下文的唯一消费方。 +通过 `dsh-experimental-hooks-claude-code` 与 `dsh-experimental-hooks-codex` 间接影响;它们是将解码后的 hook 输出渲染为模型上下文的唯一消费方。 #### KV Cache 影响 diff --git a/packages/hooks/hook-protocol/package.json b/packages/experimental/hook-protocol/package.json similarity index 90% rename from packages/hooks/hook-protocol/package.json rename to packages/experimental/hook-protocol/package.json index 9d20a52d35..20f1fac8b5 100644 --- a/packages/hooks/hook-protocol/package.json +++ b/packages/experimental/hook-protocol/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-hook-protocol", + "name": "@deepseek-ai/dsh-experimental-hook-protocol", "description": "Shared Claude Code / Codex hook wire protocol: matcher engine, stdin/exit-code/stdout codec, multi-hook merge, and hook/* session events", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/hooks/hook-protocol" + "directory": "packages/experimental/hook-protocol" }, "type": "module", "main": "lib/index.js", diff --git a/packages/hooks/hook-protocol/src/codec.ts b/packages/experimental/hook-protocol/src/codec.ts similarity index 99% rename from packages/hooks/hook-protocol/src/codec.ts rename to packages/experimental/hook-protocol/src/codec.ts index 273e86f312..c111b5291a 100644 --- a/packages/hooks/hook-protocol/src/codec.ts +++ b/packages/experimental/hook-protocol/src/codec.ts @@ -2,7 +2,7 @@ * Decode hook process outcomes for both dialects. Exit 0 may carry structured * JSON or plain stdout; exit 2 blocks with stderr as the reason; every other * exit is a non-blocking error. Bridges decide which recognized fields apply. - * @module @deepseek-ai/dsh-hook-protocol/codec + * @module @deepseek-ai/dsh-experimental-hook-protocol/codec */ import type { HookOutput } from './types.ts' diff --git a/packages/hooks/hook-protocol/src/detached.ts b/packages/experimental/hook-protocol/src/detached.ts similarity index 97% rename from packages/hooks/hook-protocol/src/detached.ts rename to packages/experimental/hook-protocol/src/detached.ts index 92eee06858..4493cdd872 100644 --- a/packages/hooks/hook-protocol/src/detached.ts +++ b/packages/experimental/hook-protocol/src/detached.ts @@ -2,7 +2,7 @@ * Quiescence tracking for emit-shaped hook runs that no extension point awaits. Bridges * track the run plus its continuation, pass the tracker signal into execution, * and drain on disposal so no process or late callback outlives the fiber. - * @module @deepseek-ai/dsh-hook-protocol/detached + * @module @deepseek-ai/dsh-experimental-hook-protocol/detached */ /** In-flight registry for one bridge's detached hook runs; see the module doc for the wiring contract. */ diff --git a/packages/hooks/hook-protocol/src/events.ts b/packages/experimental/hook-protocol/src/events.ts similarity index 98% rename from packages/hooks/hook-protocol/src/events.ts rename to packages/experimental/hook-protocol/src/events.ts index d7c93095e9..cf5525839b 100644 --- a/packages/hooks/hook-protocol/src/events.ts +++ b/packages/experimental/hook-protocol/src/events.ts @@ -3,7 +3,7 @@ * intent and must remain turn-enclosed and invoked/result paired. Mid-turn hook * points satisfy that boundary; SessionStart records injected context instead * and does not append `hook/*` outside a turn. - * @module @deepseek-ai/dsh-hook-protocol/events + * @module @deepseek-ai/dsh-experimental-hook-protocol/events */ import type { Session } from '@deepseek-ai/dsh-session' diff --git a/packages/hooks/hook-protocol/src/index.ts b/packages/experimental/hook-protocol/src/index.ts similarity index 95% rename from packages/hooks/hook-protocol/src/index.ts rename to packages/experimental/hook-protocol/src/index.ts index f36b86b44b..d6316d1fff 100644 --- a/packages/hooks/hook-protocol/src/index.ts +++ b/packages/experimental/hook-protocol/src/index.ts @@ -3,7 +3,7 @@ * decoding, restrictive outcome merging, durable event helpers, and detached * run quiescence. Claude Code and Codex bridges own their distinct payloads, * environment rules, matcher mode, and typed extension-point mappings. - * @module @deepseek-ai/dsh-hook-protocol + * @module @deepseek-ai/dsh-experimental-hook-protocol */ export type { diff --git a/packages/hooks/hook-protocol/src/matcher.ts b/packages/experimental/hook-protocol/src/matcher.ts similarity index 98% rename from packages/hooks/hook-protocol/src/matcher.ts rename to packages/experimental/hook-protocol/src/matcher.ts index f27c695234..3a8cbc2725 100644 --- a/packages/hooks/hook-protocol/src/matcher.ts +++ b/packages/experimental/hook-protocol/src/matcher.ts @@ -4,7 +4,7 @@ * treats every non-empty pattern as an unanchored regex. Missing, empty, and * `*` match all. Runtime matching contains invalid regexes as non-matches; * config parsers use {@link matcherDiagnostic} to reject them with a diagnostic. - * @module @deepseek-ai/dsh-hook-protocol/matcher + * @module @deepseek-ai/dsh-experimental-hook-protocol/matcher */ import type { MatcherGroup, MatcherMode } from './types.ts' diff --git a/packages/hooks/hook-protocol/src/merge.ts b/packages/experimental/hook-protocol/src/merge.ts similarity index 98% rename from packages/hooks/hook-protocol/src/merge.ts rename to packages/experimental/hook-protocol/src/merge.ts index c2d25f0ab5..100fffac3b 100644 --- a/packages/hooks/hook-protocol/src/merge.ts +++ b/packages/experimental/hook-protocol/src/merge.ts @@ -3,7 +3,7 @@ * is `deny > ask > allow`; the first `continue:false` stop is sticky; reasons * for the winning rank are joined; and context and system messages accumulate * in hook order. - * @module @deepseek-ai/dsh-hook-protocol/merge + * @module @deepseek-ai/dsh-experimental-hook-protocol/merge */ import type { HookOutput } from './types.ts' diff --git a/packages/hooks/hook-protocol/src/runner.ts b/packages/experimental/hook-protocol/src/runner.ts similarity index 98% rename from packages/hooks/hook-protocol/src/runner.ts rename to packages/experimental/hook-protocol/src/runner.ts index 197a743fc1..a0319466b0 100644 --- a/packages/hooks/hook-protocol/src/runner.ts +++ b/packages/experimental/hook-protocol/src/runner.ts @@ -3,7 +3,7 @@ * process-group cancellation, and timeout machinery. The bridge supplies the * trusted stdin payload and dialect environment, then this module decodes the * captured outcome. - * @module @deepseek-ai/dsh-hook-protocol/runner + * @module @deepseek-ai/dsh-experimental-hook-protocol/runner */ import type { ShellExecutor } from '@deepseek-ai/dsh-shell' diff --git a/packages/hooks/hook-protocol/src/types.ts b/packages/experimental/hook-protocol/src/types.ts similarity index 98% rename from packages/hooks/hook-protocol/src/types.ts rename to packages/experimental/hook-protocol/src/types.ts index 84fd04a210..dcdc9ab1a0 100644 --- a/packages/hooks/hook-protocol/src/types.ts +++ b/packages/experimental/hook-protocol/src/types.ts @@ -2,7 +2,7 @@ * Dialect-neutral vocabulary and log-only events shared by the Claude Code and * Codex hook bridges. Payload construction, matching differences, environment, * and extension-point-specific decision mapping remain owned by each bridge. - * @module @deepseek-ai/dsh-hook-protocol/types + * @module @deepseek-ai/dsh-experimental-hook-protocol/types */ declare module '@deepseek-ai/dsh-session/types' { diff --git a/packages/hooks/hook-protocol/tests/codec.spec.ts b/packages/experimental/hook-protocol/tests/codec.spec.ts similarity index 99% rename from packages/hooks/hook-protocol/tests/codec.spec.ts rename to packages/experimental/hook-protocol/tests/codec.spec.ts index 252caa4cff..ba65d56657 100644 --- a/packages/hooks/hook-protocol/tests/codec.spec.ts +++ b/packages/experimental/hook-protocol/tests/codec.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { parseHookOutput } from '@deepseek-ai/dsh-hook-protocol' +import { parseHookOutput } from '@deepseek-ai/dsh-experimental-hook-protocol' describe('parseHookOutput — exit code semantics', () => { it('exit 0 with no stdout is a neutral success', () => { diff --git a/packages/hooks/hook-protocol/tests/detached.spec.ts b/packages/experimental/hook-protocol/tests/detached.spec.ts similarity index 97% rename from packages/hooks/hook-protocol/tests/detached.spec.ts rename to packages/experimental/hook-protocol/tests/detached.spec.ts index 03e10c7a0d..643b3d6c6c 100644 --- a/packages/hooks/hook-protocol/tests/detached.spec.ts +++ b/packages/experimental/hook-protocol/tests/detached.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { createDetachedRuns } from '@deepseek-ai/dsh-hook-protocol' +import { createDetachedRuns } from '@deepseek-ai/dsh-experimental-hook-protocol' /** A promise settled from outside, so a test controls exactly when a tracked run finishes. */ function deferred(): { promise: Promise; resolve: () => void; reject: (error: Error) => void } { diff --git a/packages/hooks/hook-protocol/tests/events.spec.ts b/packages/experimental/hook-protocol/tests/events.spec.ts similarity index 98% rename from packages/hooks/hook-protocol/tests/events.spec.ts rename to packages/experimental/hook-protocol/tests/events.spec.ts index b8c21b3190..09ba471469 100644 --- a/packages/hooks/hook-protocol/tests/events.spec.ts +++ b/packages/experimental/hook-protocol/tests/events.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { Session, SessionId } from '@deepseek-ai/dsh-session' -import { appendHookInvoked, appendHookResult, summarizeStderr, type HookOutput } from '@deepseek-ai/dsh-hook-protocol' +import { appendHookInvoked, appendHookResult, summarizeStderr, type HookOutput } from '@deepseek-ai/dsh-experimental-hook-protocol' /** A {@link HookOutput} with the required stream fields defaulted. */ function output(over: Partial = {}): HookOutput { diff --git a/packages/hooks/hook-protocol/tests/matcher.spec.ts b/packages/experimental/hook-protocol/tests/matcher.spec.ts similarity index 98% rename from packages/hooks/hook-protocol/tests/matcher.spec.ts rename to packages/experimental/hook-protocol/tests/matcher.spec.ts index 39fae74d14..5e23ded9dd 100644 --- a/packages/hooks/hook-protocol/tests/matcher.spec.ts +++ b/packages/experimental/hook-protocol/tests/matcher.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { matcherDiagnostic, matchesMatcher, selectHookGroups, type MatcherGroup } from '@deepseek-ai/dsh-hook-protocol' +import { matcherDiagnostic, matchesMatcher, selectHookGroups, type MatcherGroup } from '@deepseek-ai/dsh-experimental-hook-protocol' describe('matchesMatcher — match-all sentinels (both dialects)', () => { for (const mode of ['claude-code', 'codex'] as const) { diff --git a/packages/hooks/hook-protocol/tests/merge.spec.ts b/packages/experimental/hook-protocol/tests/merge.spec.ts similarity index 96% rename from packages/hooks/hook-protocol/tests/merge.spec.ts rename to packages/experimental/hook-protocol/tests/merge.spec.ts index def2474927..5dd21e2b0a 100644 --- a/packages/hooks/hook-protocol/tests/merge.spec.ts +++ b/packages/experimental/hook-protocol/tests/merge.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { mergeHookOutputs } from '@deepseek-ai/dsh-hook-protocol' -import type { HookOutput } from '@deepseek-ai/dsh-hook-protocol' +import { mergeHookOutputs } from '@deepseek-ai/dsh-experimental-hook-protocol' +import type { HookOutput } from '@deepseek-ai/dsh-experimental-hook-protocol' function out(over: Partial = {}): HookOutput { return { exitCode: 0, stderr: '', stdout: '', ...over } diff --git a/packages/hooks/hook-protocol/tests/runner.spec.ts b/packages/experimental/hook-protocol/tests/runner.spec.ts similarity index 98% rename from packages/hooks/hook-protocol/tests/runner.spec.ts rename to packages/experimental/hook-protocol/tests/runner.spec.ts index 0aa27fb748..74f8d2eae2 100644 --- a/packages/hooks/hook-protocol/tests/runner.spec.ts +++ b/packages/experimental/hook-protocol/tests/runner.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, expectTypeOf, it } from 'vitest' import type { ShellExecRequest, ShellExecSpec, ShellExecution, ShellExecutor, ShellRunResult } from '@deepseek-ai/dsh-shell' -import { DEFAULT_HOOK_TIMEOUT_MS, runHook } from '@deepseek-ai/dsh-hook-protocol' -import type { RunHookOptions } from '@deepseek-ai/dsh-hook-protocol' +import { DEFAULT_HOOK_TIMEOUT_MS, runHook } from '@deepseek-ai/dsh-experimental-hook-protocol' +import type { RunHookOptions } from '@deepseek-ai/dsh-experimental-hook-protocol' /** * A minimal stand-in for the bits of {@link ShellExecutor} that {@link runHook} diff --git a/packages/hooks/hook-protocol/tsconfig.json b/packages/experimental/hook-protocol/tsconfig.json similarity index 100% rename from packages/hooks/hook-protocol/tsconfig.json rename to packages/experimental/hook-protocol/tsconfig.json diff --git a/packages/experimental/hooks-claude-code/README.i18n.yaml b/packages/experimental/hooks-claude-code/README.i18n.yaml new file mode 100644 index 0000000000..5527b802b5 --- /dev/null +++ b/packages/experimental/hooks-claude-code/README.i18n.yaml @@ -0,0 +1,88 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/hooks-claude-code/README.md +/: + en: 3570440302708236 + zh: 6e4217f2856879a1 +/deepseek-ai-dsh-experimental-hooks-claude-code: + en: 77dc8c195263a10d + zh: 51f3ab9fa13d950e +/deepseek-ai-dsh-experimental-hooks-claude-code/summary: + en: 6aaa917b54b3af85 + zh: 7054c24382ab6083 +/deepseek-ai-dsh-experimental-hooks-claude-code/table-of-contents: + en: d152484eb41ac6b4 + zh: 09388d293f9be9cb +/deepseek-ai-dsh-experimental-hooks-claude-code/use-this-package: + en: af7c3b8bcce24e7f + zh: 6b5225e34cbd1c85 +/deepseek-ai-dsh-experimental-hooks-claude-code/use-this-package/when-to-choose-it: + en: 5fdf4ff17e6d9a2e + zh: 82979c137758005d +/deepseek-ai-dsh-experimental-hooks-claude-code/use-this-package/smallest-working-setup: + en: 2c493d787543e82b + zh: fc2f7c595a5542f6 +/deepseek-ai-dsh-experimental-hooks-claude-code/use-this-package/what-your-hooks-can-do: + en: 6c3b126e6607c311 + zh: 33199f443edb2824 +/deepseek-ai-dsh-experimental-hooks-claude-code/use-this-package/how-hooks-run-and-fail: + en: 98d13f2e7207e3f3 + zh: 4e0336b32c2775e9 +/deepseek-ai-dsh-experimental-hooks-claude-code/understand-the-implementation: + en: d33ddd080880b3f5 + zh: 64328f5239c26752 +/deepseek-ai-dsh-experimental-hooks-claude-code/understand-the-implementation/hook-point-mapping: + en: d315f54ec60f8860 + zh: 53b7a6531d9f4bbb +/deepseek-ai-dsh-experimental-hooks-claude-code/understand-the-implementation/payloads-and-environment: + en: 0389b516653c7f45 + zh: 15ec2182113a9aa4 +/deepseek-ai-dsh-experimental-hooks-claude-code/understand-the-implementation/matcher-subjects-and-serial-execution: + en: 0f30690502687688 + zh: 19d4ec653c19f00e +/deepseek-ai-dsh-experimental-hooks-claude-code/understand-the-implementation/detached-runs-and-disposal: + en: aa09842e9c40ad82 + zh: f7b65a3f2604003c +/deepseek-ai-dsh-experimental-hooks-claude-code/understand-the-implementation/design-philosophy: + en: e9dc2e482e9a7b50 + zh: 5fa4e92b75884f93 +/deepseek-ai-dsh-experimental-hooks-claude-code/understand-the-implementation/source-map: + en: 0289ee9e374d3606 + zh: b88841c10ad5c10f +/deepseek-ai-dsh-experimental-hooks-claude-code/further-exploration: + en: 6f34fec52fcf5fd3 + zh: 15dde7f0ec896efc +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience: + en: 215e7ba838619b7b + zh: a311da3843709f90 +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience/hook-provided-context: + en: 7b2f5028dacd7146 + zh: e4d226735f7abfc2 +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience/hook-provided-context/what-the-model-sees: + en: 7b6edde085633c5f + zh: caadcfe8b9364c6d +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience/hook-provided-context/token-effect: + en: b70e3524b160cd63 + zh: e1011ee18d1bf12b +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience/hook-provided-context/kv-cache-effect: + en: f5d5f97a153f7c70 + zh: f681f89596f500f5 +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience/blocked-prompt-or-tool-outcome: + en: 82be8d95921ef639 + zh: 11c185068ec18932 +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience/blocked-prompt-or-tool-outcome/what-the-model-sees: + en: 1313b662532a2bda + zh: 4002d38540286a94 +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience/blocked-prompt-or-tool-outcome/token-effect: + en: 7c13e10d2a0e3151 + zh: 54ffd88bca4fce3a +/deepseek-ai-dsh-experimental-hooks-claude-code/model-experience/blocked-prompt-or-tool-outcome/kv-cache-effect: + en: f84fa6c0511cd113 + zh: f6ce9cdd47a72684 +/deepseek-ai-dsh-experimental-hooks-claude-code/known-limitations-and-deferred-work: + en: 23ab8cf19542ea03 + zh: e56f896b4393c1c5 +/deepseek-ai-dsh-experimental-hooks-claude-code/known-limitations-and-deferred-work/dev-note: + en: b1e9a373ae8b7bb0 + zh: 30446fe59d5ec8be diff --git a/packages/hooks/hooks-claude-code/README.md b/packages/experimental/hooks-claude-code/README.md similarity index 94% rename from packages/hooks/hooks-claude-code/README.md rename to packages/experimental/hooks-claude-code/README.md index 97dd24d8d7..a3d4e6529b 100644 --- a/packages/hooks/hooks-claude-code/README.md +++ b/packages/experimental/hooks-claude-code/README.md @@ -3,13 +3,13 @@ description: "Run your existing Claude Code hooks.json or settings hook config d kind: "package-reference" --- -# @deepseek-ai/dsh-hooks-claude-code +# @deepseek-ai/dsh-experimental-hooks-claude-code English | [中文](README.zh.md) ## Summary -`dsh-hooks-claude-code` runs command hooks from your existing Claude Code `hooks.json` or settings file during agent runs, without requiring a rewrite. Supported hooks can run when sessions, prompts, tools, stops, or subagents reach matching moments. They can block prompts or tool calls with model-visible reasons, add conversation context, or force another model turn. Choose this package to reuse Claude Code command hooks in the harness; use a native plugin for behavior that has no Claude Code equivalent. +`dsh-experimental-hooks-claude-code` runs command hooks from your existing Claude Code `hooks.json` or settings file during agent runs, without requiring a rewrite. Supported hooks can run when sessions, prompts, tools, stops, or subagents reach matching moments. They can block prompts or tool calls with model-visible reasons, add conversation context, or force another model turn. Choose this package to reuse Claude Code command hooks in the harness; use a native plugin for behavior that has no Claude Code equivalent. ## Table of Contents @@ -36,7 +36,7 @@ Use it when you own a Claude Code `hooks.json` (or a settings file whose `hooks` ### Smallest working setup ```yaml -- name: '@deepseek-ai/dsh-hooks-claude-code' +- name: '@deepseek-ai/dsh-experimental-hooks-claude-code' config: configPath: ./.claude/hooks.json pluginRoot: ./.claude/plugins/my-plugin @@ -51,7 +51,7 @@ Use it when you own a Claude Code `hooks.json` (or a settings file whose `hooks` | `defaultTimeoutMs` | `600,000` | Per-hook timeout when a hook sets none (the Claude Code default) | | `stderrSummaryMaxChars` | `500` | Character cap on the persisted `hook/result` stderr summary | -The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-hooks-claude-code) is the exhaustive source for every accepted field. +The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-experimental-hooks-claude-code) is the exhaustive source for every accepted field. ### What your hooks can do @@ -98,7 +98,7 @@ The matcher subject is the tool name (`PreToolUse` / `PostToolUse`), the session ### Detached runs and disposal -The three emit points (`SessionStart`, `SubagentStart`, `SubagentStop`) run detached — no extension point awaits them. Each run chain is tracked, and disposing the bridge aborts still-running hook processes, then drains the continuations before the dispose resolves (`createDetachedRuns` in `dsh-hook-protocol`). +The three emit points (`SessionStart`, `SubagentStart`, `SubagentStop`) run detached — no extension point awaits them. Each run chain is tracked, and disposing the bridge aborts still-running hook processes, then drains the continuations before the dispose resolves (`createDetachedRuns` in `dsh-experimental-hook-protocol`). ### Design philosophy @@ -130,7 +130,7 @@ Read these pages when the package-level contract is not enough. They move from t - [Hook protocol library](../hook-protocol/README.md) — the shared hook rules this bridge applies. - [Hook bridges Agent Note](../../../.agents/notes/archived/feature/2026-06-30-hook-bridges.md) — the bridge design, decision mapping, and deferred gaps. - [Interception extension-points reference](../../../docs/tool-execution-pipeline.md) — the typed-Decision surface the bridge maps onto. -- [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-hooks-claude-code) — every accepted config field and its source declaration. +- [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-experimental-hooks-claude-code) — every accepted config field and its source declaration. ----- diff --git a/packages/hooks/hooks-claude-code/README.zh.md b/packages/experimental/hooks-claude-code/README.zh.md similarity index 94% rename from packages/hooks/hooks-claude-code/README.zh.md rename to packages/experimental/hooks-claude-code/README.zh.md index 829ddd92bf..39dd0cccfd 100644 --- a/packages/hooks/hooks-claude-code/README.zh.md +++ b/packages/experimental/hooks-claude-code/README.zh.md @@ -3,13 +3,13 @@ description: "在 agent 运行期间使用你现有的 Claude Code hooks.json kind: "package-reference" --- -# @deepseek-ai/dsh-hooks-claude-code +# @deepseek-ai/dsh-experimental-hooks-claude-code [English](README.md) | 中文 ## 概述 -`dsh-hooks-claude-code` 在 agent(智能体)运行期间执行你现有 Claude Code `hooks.json` 或 settings 文件中的 command 钩子,无需重写。受支持的钩子会在会话、提示词、工具、停止或 subagent 到达对应时刻时运行。它们可以带模型可见的原因阻塞提示词或工具调用、添加对话上下文,或强制模型再执行一个轮次。需要在 harness 中复用 Claude Code command 钩子时选择本包;没有 Claude Code 对应物的行为应使用原生插件。 +`dsh-experimental-hooks-claude-code` 在 agent(智能体)运行期间执行你现有 Claude Code `hooks.json` 或 settings 文件中的 command 钩子,无需重写。受支持的钩子会在会话、提示词、工具、停止或 subagent 到达对应时刻时运行。它们可以带模型可见的原因阻塞提示词或工具调用、添加对话上下文,或强制模型再执行一个轮次。需要在 harness 中复用 Claude Code command 钩子时选择本包;没有 Claude Code 对应物的行为应使用原生插件。 ## 目录 @@ -36,7 +36,7 @@ kind: "package-reference" ### 最小配置 ```yaml -- name: '@deepseek-ai/dsh-hooks-claude-code' +- name: '@deepseek-ai/dsh-experimental-hooks-claude-code' config: configPath: ./.claude/hooks.json pluginRoot: ./.claude/plugins/my-plugin @@ -51,7 +51,7 @@ kind: "package-reference" | `defaultTimeoutMs` | `600,000` | hook 未设置时的每 hook 超时(即 Claude Code 默认值) | | `stderrSummaryMaxChars` | `500` | 持久化 `hook/result` stderr 摘要的字符上限 | -生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-hooks-claude-code)是每个受支持字段的穷尽式真源。 +生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-experimental-hooks-claude-code)是每个受支持字段的穷尽式真源。 ### 你的钩子能做什么 @@ -98,7 +98,7 @@ matcher subject 是工具名称(`PreToolUse`/`PostToolUse`)、会话源( ### 脱离运行与释放 -三个 emit 点(`SessionStart`、`SubagentStart`、`SubagentStop`)以脱离方式运行——没有扩展点等待它们。每条运行链都会被跟踪,对桥接执行 dispose(资源释放)时会中止仍在运行的 hook 进程,并在 dispose 完成前排空 continuation(`createDetachedRuns`,位于 `dsh-hook-protocol`)。 +三个 emit 点(`SessionStart`、`SubagentStart`、`SubagentStop`)以脱离方式运行——没有扩展点等待它们。每条运行链都会被跟踪,对桥接执行 dispose(资源释放)时会中止仍在运行的 hook 进程,并在 dispose 完成前排空 continuation(`createDetachedRuns`,位于 `dsh-experimental-hook-protocol`)。 ### 设计理念 @@ -130,7 +130,7 @@ matcher subject 是工具名称(`PreToolUse`/`PostToolUse`)、会话源( - [hook 协议库](../hook-protocol/README.zh.md)——本桥接应用的共享钩子规则。 - [钩子桥接 Agent Note](../../../.agents/notes/archived/feature/2026-06-30-hook-bridges.md)——桥接设计、决策映射与延期缺口。 - [拦截扩展点 参考](../../../docs/tool-execution-pipeline.zh.md)——桥接所映射的类型化 Decision 接口面。 -- [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-hooks-claude-code)——每个受支持配置字段及其源声明。 +- [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-experimental-hooks-claude-code)——每个受支持配置字段及其源声明。 ----- diff --git a/packages/hooks/hooks-claude-code/package.json b/packages/experimental/hooks-claude-code/package.json similarity index 88% rename from packages/hooks/hooks-claude-code/package.json rename to packages/experimental/hooks-claude-code/package.json index f186c440cd..1ea77c56ed 100644 --- a/packages/hooks/hooks-claude-code/package.json +++ b/packages/experimental/hooks-claude-code/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-hooks-claude-code", + "name": "@deepseek-ai/dsh-experimental-hooks-claude-code", "description": "Bridge plugin: run a Claude Code hooks.json / settings hook config on the DeepSeek Harness interception seams", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/hooks/hooks-claude-code" + "directory": "packages/experimental/hooks-claude-code" }, "type": "module", "main": "lib/index.js", @@ -31,7 +31,7 @@ }, "peerDependencies": { "@deepseek-ai/dsh-agent": "workspace:*", - "@deepseek-ai/dsh-hook-protocol": "workspace:*", + "@deepseek-ai/dsh-experimental-hook-protocol": "workspace:*", "@deepseek-ai/dsh-llm": "workspace:*", "@deepseek-ai/dsh-session": "workspace:*", "@deepseek-ai/dsh-subagent": "workspace:*", @@ -47,7 +47,7 @@ "@deepseek-ai/dsh-shell": "workspace:*", "@deepseek-ai/dsh-bash-local": "workspace:*", "@deepseek-ai/dsh-subprocess-local": "workspace:*", - "@deepseek-ai/dsh-hook-protocol": "workspace:*", + "@deepseek-ai/dsh-experimental-hook-protocol": "workspace:*", "@deepseek-ai/dsh-llm": "workspace:*", "@deepseek-ai/dsh-session": "workspace:*", "@deepseek-ai/dsh-session-persistence-jsonl": "workspace:*", diff --git a/packages/hooks/hooks-claude-code/src/config.ts b/packages/experimental/hooks-claude-code/src/config.ts similarity index 97% rename from packages/hooks/hooks-claude-code/src/config.ts rename to packages/experimental/hooks-claude-code/src/config.ts index 72bd55bfd5..3f628627da 100644 --- a/packages/hooks/hooks-claude-code/src/config.ts +++ b/packages/experimental/hooks-claude-code/src/config.ts @@ -3,10 +3,10 @@ * Only command hooks run; other hook types are returned as skipped so the * bridge can warn. Plugin-root and project-directory substitutions are applied * to commands at parse time. - * @module @deepseek-ai/dsh-hooks-claude-code/config + * @module @deepseek-ai/dsh-experimental-hooks-claude-code/config */ -import { matcherDiagnostic, type MatcherGroup } from '@deepseek-ai/dsh-hook-protocol' +import { matcherDiagnostic, type MatcherGroup } from '@deepseek-ai/dsh-experimental-hook-protocol' const CLAUDE_EVENTS = [ 'SessionStart', diff --git a/packages/hooks/hooks-claude-code/src/index.ts b/packages/experimental/hooks-claude-code/src/index.ts similarity index 98% rename from packages/hooks/hooks-claude-code/src/index.ts rename to packages/experimental/hooks-claude-code/src/index.ts index afbc60de08..2027ab42e1 100644 --- a/packages/hooks/hooks-claude-code/src/index.ts +++ b/packages/experimental/hooks-claude-code/src/index.ts @@ -2,10 +2,10 @@ * Bridge for unmodified Claude Code command hooks on harness interception * extension points. It supports SessionStart, prompt/tool pre/post, Stop, and subagent * start/stop. It owns Claude payloads, environment, substitution, and decision - * mapping; shared execution and parsing live in `dsh-hook-protocol`. + * mapping; shared execution and parsing live in `dsh-experimental-hook-protocol`. * `updatedInput` is logged and warned but not honored. Bespoke behavior should * use typed native plugins on the same extension points. - * @module @deepseek-ai/dsh-hooks-claude-code + * @module @deepseek-ai/dsh-experimental-hooks-claude-code */ import type {} from '@deepseek-ai/dsh-working-directory' @@ -36,7 +36,7 @@ import { selectHookGroups, type HookOutput, type MergedHookOutcome, -} from '@deepseek-ai/dsh-hook-protocol' +} from '@deepseek-ai/dsh-experimental-hook-protocol' // Pulls in the declaration-merged subagent events and the identity pairing their // start/end edges. import type { SubagentRunId } from '@deepseek-ai/dsh-subagent' diff --git a/packages/hooks/hooks-claude-code/tests/bridge.spec.ts b/packages/experimental/hooks-claude-code/tests/bridge.spec.ts similarity index 99% rename from packages/hooks/hooks-claude-code/tests/bridge.spec.ts rename to packages/experimental/hooks-claude-code/tests/bridge.spec.ts index f6b012bc28..c966b4d116 100644 --- a/packages/hooks/hooks-claude-code/tests/bridge.spec.ts +++ b/packages/experimental/hooks-claude-code/tests/bridge.spec.ts @@ -14,12 +14,12 @@ import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local' import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local' import { scopeTarget } from '@deepseek-ai/dsh-scope' import SubagentRuntime, { SubagentRunId } from '@deepseek-ai/dsh-subagent' -import * as HooksClaude from '@deepseek-ai/dsh-hooks-claude-code' +import * as HooksClaude from '@deepseek-ai/dsh-experimental-hooks-claude-code' import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' /** * Full-loop bridge tests: a scripted mock MODEL drives the REAL agent loop + REAL - * bash executor, and the REAL `dsh-hooks-claude-code` bridge runs REAL shell hook + * bash executor, and the REAL `dsh-experimental-hooks-claude-code` bridge runs REAL shell hook * scripts written to a temp dir — only the model is mocked (the "prefer the real * implementation" rule). Each test writes a `hooks.json` + executable scripts, * loads the bridge pointed at them, and asserts the hook's effect on the loop. diff --git a/packages/hooks/hooks-claude-code/tests/config.spec.ts b/packages/experimental/hooks-claude-code/tests/config.spec.ts similarity index 98% rename from packages/hooks/hooks-claude-code/tests/config.spec.ts rename to packages/experimental/hooks-claude-code/tests/config.spec.ts index a6f2e73050..69b21177c9 100644 --- a/packages/hooks/hooks-claude-code/tests/config.spec.ts +++ b/packages/experimental/hooks-claude-code/tests/config.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { parseClaudeCodeConfig, substituteCommand } from '@deepseek-ai/dsh-hooks-claude-code/src/config.ts' +import { parseClaudeCodeConfig, substituteCommand } from '@deepseek-ai/dsh-experimental-hooks-claude-code/src/config.ts' describe('substituteCommand', () => { it('replaces CLAUDE_PLUGIN_ROOT and CLAUDE_PROJECT_DIR (all occurrences)', () => { diff --git a/packages/hooks/hooks-claude-code/tests/coverage-cases.ts b/packages/experimental/hooks-claude-code/tests/coverage-cases.ts similarity index 99% rename from packages/hooks/hooks-claude-code/tests/coverage-cases.ts rename to packages/experimental/hooks-claude-code/tests/coverage-cases.ts index b77aa85c96..f5e59ed715 100644 --- a/packages/hooks/hooks-claude-code/tests/coverage-cases.ts +++ b/packages/experimental/hooks-claude-code/tests/coverage-cases.ts @@ -15,7 +15,7 @@ import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local' import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local' import { scopeTarget } from '@deepseek-ai/dsh-scope' import SubagentRuntime, { SubagentRunId } from '@deepseek-ai/dsh-subagent' -import * as HooksClaude from '@deepseek-ai/dsh-hooks-claude-code' +import * as HooksClaude from '@deepseek-ai/dsh-experimental-hooks-claude-code' import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' declare module '@deepseek-ai/dsh-llm' { diff --git a/packages/hooks/hooks-claude-code/tests/coverage-config.spec.ts b/packages/experimental/hooks-claude-code/tests/coverage-config.spec.ts similarity index 100% rename from packages/hooks/hooks-claude-code/tests/coverage-config.spec.ts rename to packages/experimental/hooks-claude-code/tests/coverage-config.spec.ts diff --git a/packages/hooks/hooks-claude-code/tests/coverage-context.spec.ts b/packages/experimental/hooks-claude-code/tests/coverage-context.spec.ts similarity index 100% rename from packages/hooks/hooks-claude-code/tests/coverage-context.spec.ts rename to packages/experimental/hooks-claude-code/tests/coverage-context.spec.ts diff --git a/packages/hooks/hooks-claude-code/tests/coverage-edge-paths.spec.ts b/packages/experimental/hooks-claude-code/tests/coverage-edge-paths.spec.ts similarity index 100% rename from packages/hooks/hooks-claude-code/tests/coverage-edge-paths.spec.ts rename to packages/experimental/hooks-claude-code/tests/coverage-edge-paths.spec.ts diff --git a/packages/hooks/hooks-claude-code/tests/coverage-stop.spec.ts b/packages/experimental/hooks-claude-code/tests/coverage-stop.spec.ts similarity index 100% rename from packages/hooks/hooks-claude-code/tests/coverage-stop.spec.ts rename to packages/experimental/hooks-claude-code/tests/coverage-stop.spec.ts diff --git a/packages/hooks/hooks-claude-code/tsconfig.json b/packages/experimental/hooks-claude-code/tsconfig.json similarity index 100% rename from packages/hooks/hooks-claude-code/tsconfig.json rename to packages/experimental/hooks-claude-code/tsconfig.json diff --git a/packages/experimental/hooks-codex/README.i18n.yaml b/packages/experimental/hooks-codex/README.i18n.yaml new file mode 100644 index 0000000000..9c3732a261 --- /dev/null +++ b/packages/experimental/hooks-codex/README.i18n.yaml @@ -0,0 +1,88 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/hooks-codex/README.md +/: + en: 9ee4cd57e234a8ff + zh: 59e5d8f84fa762ff +/deepseek-ai-dsh-experimental-hooks-codex: + en: 92a5fd5c6751a2ac + zh: 70e2ba81906d33dc +/deepseek-ai-dsh-experimental-hooks-codex/summary: + en: 717bfd84f7eda519 + zh: 31d2a38edbee47e7 +/deepseek-ai-dsh-experimental-hooks-codex/table-of-contents: + en: d152484eb41ac6b4 + zh: 09388d293f9be9cb +/deepseek-ai-dsh-experimental-hooks-codex/use-this-package: + en: 86b84a66b82845f8 + zh: bd7fbd4e066d06f8 +/deepseek-ai-dsh-experimental-hooks-codex/use-this-package/when-to-choose-it: + en: 44d77bc8d948bc6d + zh: 81afaf977570f4ef +/deepseek-ai-dsh-experimental-hooks-codex/use-this-package/smallest-working-setup: + en: 7e5d0d061053e561 + zh: 17a8f5ee928501a3 +/deepseek-ai-dsh-experimental-hooks-codex/use-this-package/what-your-hooks-can-do: + en: dee90142e7e87214 + zh: 8d83d7e0208ba1ef +/deepseek-ai-dsh-experimental-hooks-codex/use-this-package/how-hooks-run-and-fail: + en: 03b55a30e9ec5f0c + zh: 258907341232ca45 +/deepseek-ai-dsh-experimental-hooks-codex/understand-the-implementation: + en: d33ddd080880b3f5 + zh: 64328f5239c26752 +/deepseek-ai-dsh-experimental-hooks-codex/understand-the-implementation/hook-point-mapping: + en: 755ca39231841ffc + zh: 30e793dfaf11a336 +/deepseek-ai-dsh-experimental-hooks-codex/understand-the-implementation/payloads-and-environment: + en: 542413d7e8cfeaf4 + zh: 3b5d0d3fdd0231f2 +/deepseek-ai-dsh-experimental-hooks-codex/understand-the-implementation/matcher-subjects-and-serial-execution: + en: fd52c0eb70bf0094 + zh: 6415f109fbd763d3 +/deepseek-ai-dsh-experimental-hooks-codex/understand-the-implementation/detached-runs-and-disposal: + en: 070e9ebe76c4509b + zh: c88b544ba0446449 +/deepseek-ai-dsh-experimental-hooks-codex/understand-the-implementation/design-philosophy: + en: 6f882aab3d924115 + zh: 7ed83a6d16a22c77 +/deepseek-ai-dsh-experimental-hooks-codex/understand-the-implementation/source-map: + en: 8f74796cf859a750 + zh: be4dd22dccba1782 +/deepseek-ai-dsh-experimental-hooks-codex/further-exploration: + en: a9de5a64fb0cc815 + zh: 7d3d715bfedf9fb7 +/deepseek-ai-dsh-experimental-hooks-codex/model-experience: + en: 215e7ba838619b7b + zh: a311da3843709f90 +/deepseek-ai-dsh-experimental-hooks-codex/model-experience/hook-provided-context: + en: 7b2f5028dacd7146 + zh: e4d226735f7abfc2 +/deepseek-ai-dsh-experimental-hooks-codex/model-experience/hook-provided-context/what-the-model-sees: + en: 3f94df641a34a437 + zh: 21bc5823229dbb6c +/deepseek-ai-dsh-experimental-hooks-codex/model-experience/hook-provided-context/token-effect: + en: b70e3524b160cd63 + zh: e1011ee18d1bf12b +/deepseek-ai-dsh-experimental-hooks-codex/model-experience/hook-provided-context/kv-cache-effect: + en: f5d5f97a153f7c70 + zh: f681f89596f500f5 +/deepseek-ai-dsh-experimental-hooks-codex/model-experience/blocked-prompt-or-tool-outcome: + en: 82be8d95921ef639 + zh: 11c185068ec18932 +/deepseek-ai-dsh-experimental-hooks-codex/model-experience/blocked-prompt-or-tool-outcome/what-the-model-sees: + en: fd44027de2255f3f + zh: d880eb4d2d3f6af8 +/deepseek-ai-dsh-experimental-hooks-codex/model-experience/blocked-prompt-or-tool-outcome/token-effect: + en: 7c13e10d2a0e3151 + zh: 54ffd88bca4fce3a +/deepseek-ai-dsh-experimental-hooks-codex/model-experience/blocked-prompt-or-tool-outcome/kv-cache-effect: + en: f84fa6c0511cd113 + zh: f6ce9cdd47a72684 +/deepseek-ai-dsh-experimental-hooks-codex/known-limitations-and-deferred-work: + en: 11c88847e78bdbc5 + zh: dea334c689116d0f +/deepseek-ai-dsh-experimental-hooks-codex/known-limitations-and-deferred-work/dev-note: + en: 5f03857c3bb6834a + zh: 54f485d08db9020f diff --git a/packages/hooks/hooks-codex/README.md b/packages/experimental/hooks-codex/README.md similarity index 93% rename from packages/hooks/hooks-codex/README.md rename to packages/experimental/hooks-codex/README.md index 3c054a0613..e67784bbcf 100644 --- a/packages/hooks/hooks-codex/README.md +++ b/packages/experimental/hooks-codex/README.md @@ -3,13 +3,13 @@ description: "Run your existing Codex hooks.json hook config during agent runs kind: "package-reference" --- -# @deepseek-ai/dsh-hooks-codex +# @deepseek-ai/dsh-experimental-hooks-codex English | [中文](README.zh.md) ## Summary -`dsh-hooks-codex` runs command hooks from an existing Codex `hooks.json` during agent runs, so prompt and tool gates work without being rewritten. It supports five Codex hook points: session start, prompt submission, before and after tool execution, and stop. Hooks can block prompts or tool calls with model-visible reasons, add conversation context, or force another agent step. Choose this package to reuse Codex command hooks in the harness; use a native plugin for behavior outside this supported subset. +`dsh-experimental-hooks-codex` runs command hooks from an existing Codex `hooks.json` during agent runs, so prompt and tool gates work without being rewritten. It supports five Codex hook points: session start, prompt submission, before and after tool execution, and stop. Hooks can block prompts or tool calls with model-visible reasons, add conversation context, or force another agent step. Choose this package to reuse Codex command hooks in the harness; use a native plugin for behavior outside this supported subset. ## Table of Contents @@ -36,7 +36,7 @@ Use it when you own a Codex `hooks.json` and its command hooks should gate promp ### Smallest working setup ```yaml -- name: '@deepseek-ai/dsh-hooks-codex' +- name: '@deepseek-ai/dsh-experimental-hooks-codex' config: configPath: ./.codex/hooks.json model: deepseek-v4 @@ -49,7 +49,7 @@ Use it when you own a Codex `hooks.json` and its command hooks should gate promp | `defaultTimeoutMs` | `600,000` | Per-hook timeout when a hook sets none (the Codex default) | | `stderrSummaryMaxChars` | `500` | Character cap on the persisted `hook/result` stderr summary | -The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-hooks-codex) is the exhaustive source for every accepted field. +The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-experimental-hooks-codex) is the exhaustive source for every accepted field. ### What your hooks can do @@ -94,7 +94,7 @@ The matcher subject is the tool name (`PreToolUse` / `PostToolUse`) or the sessi ### Detached runs and disposal -`SessionStart` is the one emit point and runs detached — no extension point awaits it. Each run chain is tracked, and disposing the bridge aborts a still-running hook process, then drains the continuation before the dispose resolves (`createDetachedRuns` in `dsh-hook-protocol`). +`SessionStart` is the one emit point and runs detached — no extension point awaits it. Each run chain is tracked, and disposing the bridge aborts a still-running hook process, then drains the continuation before the dispose resolves (`createDetachedRuns` in `dsh-experimental-hook-protocol`). ### Design philosophy @@ -126,7 +126,7 @@ Read these pages when the package-level contract is not enough. They move from t - [Hook protocol library](../hook-protocol/README.md) — the shared hook rules this bridge applies. - [Hook bridges Agent Note](../../../.agents/notes/archived/feature/2026-06-30-hook-bridges.md) — the bridge design, decision mapping, and deferred gaps. - [Interception extension-points reference](../../../docs/tool-execution-pipeline.md) — the typed-Decision surface the bridge maps onto. -- [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-hooks-codex) — every accepted config field and its source declaration. +- [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-experimental-hooks-codex) — every accepted config field and its source declaration. ----- diff --git a/packages/hooks/hooks-codex/README.zh.md b/packages/experimental/hooks-codex/README.zh.md similarity index 93% rename from packages/hooks/hooks-codex/README.zh.md rename to packages/experimental/hooks-codex/README.zh.md index 420e13b2fb..1bf5783500 100644 --- a/packages/hooks/hooks-codex/README.zh.md +++ b/packages/experimental/hooks-codex/README.zh.md @@ -3,13 +3,13 @@ description: "在 agent 运行期间使用你现有的 Codex hooks.json 钩子 kind: "package-reference" --- -# @deepseek-ai/dsh-hooks-codex +# @deepseek-ai/dsh-experimental-hooks-codex [English](README.md) | 中文 ## 概述 -`dsh-hooks-codex` 在 agent(智能体)运行期间执行现有 Codex `hooks.json` 中的 command 钩子,让提示词与工具把关逻辑无需重写即可生效。它支持 5 个 Codex hook 点:会话开始、提示词提交、工具执行前后以及停止。钩子可以用模型可见的原因阻塞提示词或工具调用、添加对话上下文,或强制 agent 再执行一步。需要在 harness 中复用 Codex command 钩子时选择本包;超出这一受支持子集的行为应使用原生插件。 +`dsh-experimental-hooks-codex` 在 agent(智能体)运行期间执行现有 Codex `hooks.json` 中的 command 钩子,让提示词与工具把关逻辑无需重写即可生效。它支持 5 个 Codex hook 点:会话开始、提示词提交、工具执行前后以及停止。钩子可以用模型可见的原因阻塞提示词或工具调用、添加对话上下文,或强制 agent 再执行一步。需要在 harness 中复用 Codex command 钩子时选择本包;超出这一受支持子集的行为应使用原生插件。 ## 目录 @@ -36,7 +36,7 @@ kind: "package-reference" ### 最小配置 ```yaml -- name: '@deepseek-ai/dsh-hooks-codex' +- name: '@deepseek-ai/dsh-experimental-hooks-codex' config: configPath: ./.codex/hooks.json model: deepseek-v4 @@ -49,7 +49,7 @@ kind: "package-reference" | `defaultTimeoutMs` | `600,000` | hook 未设置时的每 hook 超时(即 Codex 默认值) | | `stderrSummaryMaxChars` | `500` | 持久化 `hook/result` stderr 摘要的字符上限 | -生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-hooks-codex)是每个受支持字段的穷尽式真源。 +生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-experimental-hooks-codex)是每个受支持字段的穷尽式真源。 ### 你的钩子能做什么 @@ -94,7 +94,7 @@ matcher subject 是工具名称(`PreToolUse`/`PostToolUse`)或会话源( ### 脱离运行与释放 -`SessionStart` 是唯一的 emit 点,它脱离运行——没有扩展点等待它。每条运行链都会被跟踪,对桥接执行 dispose(资源释放)时会中止仍在运行的 hook 进程,并在 dispose 完成前排空 continuation(`createDetachedRuns`,位于 `dsh-hook-protocol`)。 +`SessionStart` 是唯一的 emit 点,它脱离运行——没有扩展点等待它。每条运行链都会被跟踪,对桥接执行 dispose(资源释放)时会中止仍在运行的 hook 进程,并在 dispose 完成前排空 continuation(`createDetachedRuns`,位于 `dsh-experimental-hook-protocol`)。 ### 设计理念 @@ -126,7 +126,7 @@ matcher subject 是工具名称(`PreToolUse`/`PostToolUse`)或会话源( - [hook 协议库](../hook-protocol/README.zh.md)——本桥接应用的共享钩子规则。 - [钩子桥接 Agent Note](../../../.agents/notes/archived/feature/2026-06-30-hook-bridges.md)——桥接设计、决策映射与延期缺口。 - [拦截扩展点 参考](../../../docs/tool-execution-pipeline.zh.md)——桥接所映射的类型化 Decision 接口面。 -- [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-hooks-codex)——每个受支持配置字段及其源声明。 +- [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-experimental-hooks-codex)——每个受支持配置字段及其源声明。 ----- diff --git a/packages/hooks/hooks-codex/package.json b/packages/experimental/hooks-codex/package.json similarity index 88% rename from packages/hooks/hooks-codex/package.json rename to packages/experimental/hooks-codex/package.json index 178a583825..babdca9027 100644 --- a/packages/hooks/hooks-codex/package.json +++ b/packages/experimental/hooks-codex/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-hooks-codex", + "name": "@deepseek-ai/dsh-experimental-hooks-codex", "description": "Bridge plugin: run a Codex hooks.json hook config on the DeepSeek Harness interception seams", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/hooks/hooks-codex" + "directory": "packages/experimental/hooks-codex" }, "type": "module", "main": "lib/index.js", @@ -31,7 +31,7 @@ }, "peerDependencies": { "@deepseek-ai/dsh-agent": "workspace:*", - "@deepseek-ai/dsh-hook-protocol": "workspace:*", + "@deepseek-ai/dsh-experimental-hook-protocol": "workspace:*", "@deepseek-ai/dsh-llm": "workspace:*", "@deepseek-ai/dsh-session": "workspace:*", "@deepseek-ai/dsh-tools": "workspace:*", @@ -46,7 +46,7 @@ "@deepseek-ai/dsh-shell": "workspace:*", "@deepseek-ai/dsh-bash-local": "workspace:*", "@deepseek-ai/dsh-subprocess-local": "workspace:*", - "@deepseek-ai/dsh-hook-protocol": "workspace:*", + "@deepseek-ai/dsh-experimental-hook-protocol": "workspace:*", "@deepseek-ai/dsh-llm": "workspace:*", "@deepseek-ai/dsh-session": "workspace:*", "@deepseek-ai/dsh-session-persistence-jsonl": "workspace:*", diff --git a/packages/hooks/hooks-codex/src/config.ts b/packages/experimental/hooks-codex/src/config.ts similarity index 97% rename from packages/hooks/hooks-codex/src/config.ts rename to packages/experimental/hooks-codex/src/config.ts index ae82340ad4..24df5d810d 100644 --- a/packages/hooks/hooks-codex/src/config.ts +++ b/packages/experimental/hooks-codex/src/config.ts @@ -2,10 +2,10 @@ * Parse Codex's five-event hook subset into shared {@link MatcherGroup}s. Only synchronous command * hooks run; other types and `async: true` commands are recorded as skipped. Codex performs no * command substitution. - * @module @deepseek-ai/dsh-hooks-codex/config + * @module @deepseek-ai/dsh-experimental-hooks-codex/config */ -import { matcherDiagnostic, type MatcherGroup } from '@deepseek-ai/dsh-hook-protocol' +import { matcherDiagnostic, type MatcherGroup } from '@deepseek-ai/dsh-experimental-hook-protocol' /** The five Codex hook points this bridge supports. */ export const CODEX_EVENTS = ['PreToolUse', 'PostToolUse', 'SessionStart', 'UserPromptSubmit', 'Stop'] as const diff --git a/packages/hooks/hooks-codex/src/index.ts b/packages/experimental/hooks-codex/src/index.ts similarity index 99% rename from packages/hooks/hooks-codex/src/index.ts rename to packages/experimental/hooks-codex/src/index.ts index 8dc76fef58..1c3fdcb00c 100644 --- a/packages/hooks/hooks-codex/src/index.ts +++ b/packages/experimental/hooks-codex/src/index.ts @@ -4,8 +4,8 @@ * matchers, snake_case payloads without a trailing newline, no hook environment * or command substitution, and no pre-tool approval or rewrite path; only * blocking decisions are honored. Shared execution and parsing live in - * `dsh-hook-protocol`. - * @module @deepseek-ai/dsh-hooks-codex + * `dsh-experimental-hook-protocol`. + * @module @deepseek-ai/dsh-experimental-hooks-codex */ // Each dialect bridge keeps its complete dependency list visible at the entry @@ -39,7 +39,7 @@ import { selectHookGroups, type HookOutput, type MergedHookOutcome, -} from '@deepseek-ai/dsh-hook-protocol' +} from '@deepseek-ai/dsh-experimental-hook-protocol' import { parseCodexConfig, type CodexHookConfig } from './config.ts' /* jscpd:ignore-end */ diff --git a/packages/hooks/hooks-codex/tests/bridge.spec.ts b/packages/experimental/hooks-codex/tests/bridge.spec.ts similarity index 99% rename from packages/hooks/hooks-codex/tests/bridge.spec.ts rename to packages/experimental/hooks-codex/tests/bridge.spec.ts index 242eb91819..441fa5faa2 100644 --- a/packages/hooks/hooks-codex/tests/bridge.spec.ts +++ b/packages/experimental/hooks-codex/tests/bridge.spec.ts @@ -12,7 +12,7 @@ import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local' import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local' -import * as HooksCodex from '@deepseek-ai/dsh-hooks-codex' +import * as HooksCodex from '@deepseek-ai/dsh-experimental-hooks-codex' import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' /** diff --git a/packages/hooks/hooks-codex/tests/config.spec.ts b/packages/experimental/hooks-codex/tests/config.spec.ts similarity index 99% rename from packages/hooks/hooks-codex/tests/config.spec.ts rename to packages/experimental/hooks-codex/tests/config.spec.ts index 8503d13151..365ed71505 100644 --- a/packages/hooks/hooks-codex/tests/config.spec.ts +++ b/packages/experimental/hooks-codex/tests/config.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { parseCodexConfig, CODEX_EVENTS } from '@deepseek-ai/dsh-hooks-codex/src/config.ts' +import { parseCodexConfig, CODEX_EVENTS } from '@deepseek-ai/dsh-experimental-hooks-codex/src/config.ts' describe('parseCodexConfig', () => { it('honors only the five bridge-supported Codex events, dropping the rest', () => { diff --git a/packages/hooks/hooks-codex/tests/coverage-cases.ts b/packages/experimental/hooks-codex/tests/coverage-cases.ts similarity index 99% rename from packages/hooks/hooks-codex/tests/coverage-cases.ts rename to packages/experimental/hooks-codex/tests/coverage-cases.ts index 499a4a8fc1..c193d6d77c 100644 --- a/packages/hooks/hooks-codex/tests/coverage-cases.ts +++ b/packages/experimental/hooks-codex/tests/coverage-cases.ts @@ -13,7 +13,7 @@ import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local' import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local' -import * as HooksCodex from '@deepseek-ai/dsh-hooks-codex' +import * as HooksCodex from '@deepseek-ai/dsh-experimental-hooks-codex' import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' declare module '@deepseek-ai/dsh-llm' { diff --git a/packages/hooks/hooks-codex/tests/coverage-post-tool.spec.ts b/packages/experimental/hooks-codex/tests/coverage-post-tool.spec.ts similarity index 100% rename from packages/hooks/hooks-codex/tests/coverage-post-tool.spec.ts rename to packages/experimental/hooks-codex/tests/coverage-post-tool.spec.ts diff --git a/packages/hooks/hooks-codex/tests/coverage-prompt.spec.ts b/packages/experimental/hooks-codex/tests/coverage-prompt.spec.ts similarity index 100% rename from packages/hooks/hooks-codex/tests/coverage-prompt.spec.ts rename to packages/experimental/hooks-codex/tests/coverage-prompt.spec.ts diff --git a/packages/hooks/hooks-codex/tests/coverage-result-shape.spec.ts b/packages/experimental/hooks-codex/tests/coverage-result-shape.spec.ts similarity index 100% rename from packages/hooks/hooks-codex/tests/coverage-result-shape.spec.ts rename to packages/experimental/hooks-codex/tests/coverage-result-shape.spec.ts diff --git a/packages/hooks/hooks-codex/tsconfig.json b/packages/experimental/hooks-codex/tsconfig.json similarity index 100% rename from packages/hooks/hooks-codex/tsconfig.json rename to packages/experimental/hooks-codex/tsconfig.json diff --git a/packages/experimental/session-title-all-prompts-llm/README.i18n.yaml b/packages/experimental/session-title-all-prompts-llm/README.i18n.yaml new file mode 100644 index 0000000000..7fff2ef7c1 --- /dev/null +++ b/packages/experimental/session-title-all-prompts-llm/README.i18n.yaml @@ -0,0 +1,64 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/session-title-all-prompts-llm/README.md +/: + en: 0718b02e4cdd4cc6 + zh: 2b5b4a729ce4d97e +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm: + en: 84039f66b655cce8 + zh: 5a9a2b0d3a279bd9 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/summary: + en: 68a4af9049b1ff36 + zh: 4af9408d01ecf8fc +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/table-of-contents: + en: d152484eb41ac6b4 + zh: 09388d293f9be9cb +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/use-this-package: + en: 2c0bccf753fe70eb + zh: 36b96a547ddddfc1 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/use-this-package/when-titles-are-generated: + en: 3c9e14df96e6000e + zh: a13f12a3df426380 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/use-this-package/configuration: + en: 13fc86b28d0d5116 + zh: 4d677bfe375539cc +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/use-this-package/failures-and-recovery: + en: 6077a4665a4edb87 + zh: 539c4e5969f9bb9b +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/understand-the-implementation: + en: 506933ffa7745b7d + zh: a9bb6f06a32b7c18 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/understand-the-implementation/design-concept: + en: 2c307e1480e5c319 + zh: 60c7394728f7ff9c +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/understand-the-implementation/source-map: + en: e7ae42597cc501a6 + zh: 2e55e9b293b25958 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/understand-the-implementation/scheduling: + en: ca23821924af2b14 + zh: a384479d5e69b0f8 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/further-exploration: + en: 05c91c92fa3b1c7d + zh: 8e90078647bdb018 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/model-experience: + en: 215e7ba838619b7b + zh: a311da3843709f90 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/model-experience/all-messages-title-request: + en: 42380e2d029288cf + zh: e9c9f21ac00e3c9d +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/model-experience/all-messages-title-request/what-the-model-sees: + en: 39cb7059a3ab1fe6 + zh: a3fd93ac52f12a43 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/model-experience/all-messages-title-request/token-effect: + en: 1a075b8073c16ce3 + zh: a51ff16156f9c137 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/model-experience/all-messages-title-request/kv-cache-effect: + en: 6a70f43f38b8c075 + zh: 2b823aff93344134 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/known-limitations-and-deferred-work: + en: d0486c65afaebb85 + zh: 186a77e0d68bd968 +/deepseek-ai-dsh-experimental-session-title-all-prompts-llm/known-limitations-and-deferred-work/dev-note: + en: e67f633dc6fe7773 + zh: 3bb0c20c93f16f98 diff --git a/packages/session/session-title-all-prompts-llm/README.md b/packages/experimental/session-title-all-prompts-llm/README.md similarity index 68% rename from packages/session/session-title-all-prompts-llm/README.md rename to packages/experimental/session-title-all-prompts-llm/README.md index d8213753ac..dfba9cfe7f 100644 --- a/packages/session/session-title-all-prompts-llm/README.md +++ b/packages/experimental/session-title-all-prompts-llm/README.md @@ -3,13 +3,13 @@ description: "All-messages LLM session-title provider for users and maintainers kind: "package-reference" --- -# @deepseek-ai/dsh-session-title-all-prompts-llm +# @deepseek-ai/dsh-experimental-session-title-all-prompts-llm English | [中文](README.zh.md) ## Summary -`dsh-session-title-all-prompts-llm` summarizes every eligible human message through `ctx.llm` as an optional `ctx.sessionTitle` provider. It registers the `all-prompts` cadence and starts a new revision after each new human prompt, using seeded history and child-session prompts. A newer revision aborts and supersedes older work, and even a provider that ignores cancellation cannot commit stale output. It uses the complete required shared LLM configuration from `dsh-session-title-llm`, so route, prompt, budget, and cancellation behavior cannot drift. Automatic behavior and configuration come first; the implementation is a thin registration over the shared policy. +`dsh-experimental-session-title-all-prompts-llm` summarizes every eligible human message through `ctx.llm` as an optional `ctx.sessionTitle` provider. It registers the `all-prompts` cadence and starts a new revision after each new human prompt, using seeded history and child-session prompts. A newer revision aborts and supersedes older work, and even a provider that ignores cancellation cannot commit stale output. It uses the complete required shared LLM configuration from `dsh-session-title-llm`, so route, prompt, budget, and cancellation behavior cannot drift. Automatic behavior and configuration come first; the implementation is a thin registration over the shared policy. ## Table of Contents @@ -25,7 +25,7 @@ English | [中文](README.zh.md) ## Use this package -Mount this plugin beside the title service when a session should be retitled as it grows, so the title keeps representing the whole conversation. It requires the full [shared LLM configuration](../session-title-llm/README.md#configuration) with no defaults. +Mount this plugin beside the title service when a session should be retitled as it grows, so the title keeps representing the whole conversation. It requires the full [shared LLM configuration](../../session/session-title-llm/README.md#configuration) with no defaults. ### When titles are generated @@ -33,7 +33,7 @@ A new revision starts after each new eligible human prompt, including prompts in ### Configuration -The plugin accepts the complete required [shared LLM configuration](../session-title-llm/README.md#configuration): `targetWords`, `targetCjkCharacters`, `maxInputBytes`, `maxOutputTokens`, `timeoutMs`, and the optional paired `provider`/`model` route. Omit both to inherit the exact route from each current logged main request, or set both to route title generation independently. The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-session-title-all-prompts-llm) is the exhaustive source for every accepted field. +The plugin accepts the complete required [shared LLM configuration](../../session/session-title-llm/README.md#configuration): `targetWords`, `targetCjkCharacters`, `maxInputBytes`, `maxOutputTokens`, `timeoutMs`, and the optional paired `provider`/`model` route. Omit both to inherit the exact route from each current logged main request, or set both to route title generation independently. The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-experimental-session-title-all-prompts-llm) is the exhaustive source for every accepted field. ### Failures and recovery @@ -51,7 +51,7 @@ This section explains the plugin's shape; the observable behavior is fully cover ### Design concept -A thin provider plugin: it registers the `all-prompts` cadence with an identity selector over all eligible messages, and delegates everything else to the [shared LLM policy](../session-title-llm/README.md). +A thin provider plugin: it registers the `all-prompts` cadence with an identity selector over all eligible messages, and delegates everything else to the [shared LLM policy](../../session/session-title-llm/README.md). ### Source map @@ -72,10 +72,10 @@ The title service schedules automatic work: for the `all-prompts` cadence, every Read these pages when the provider contract is not enough. They move from the shared policy to the alternative cadence and the service it plugs into. -- [Shared LLM title policy](../session-title-llm/README.md) — the generation helper this provider uses. -- [First-message title provider](../session-title-first-prompt-llm/README.md) — the cadence that titles a session once from its first prompt. -- [Session title service](../session-title/README.md) — fallback behavior, rename, refresh, and provider registration. -- [Session package map](../README.md) — adjacent persistence, projection, title, and telemetry packages. +- [Shared LLM title policy](../../session/session-title-llm/README.md) — the generation helper this provider uses. +- [First-message title provider](../../session/session-title-first-prompt-llm/README.md) — the cadence that titles a session once from its first prompt. +- [Session title service](../../session/session-title/README.md) — fallback behavior, rename, refresh, and provider registration. +- [Session package map](../../session/README.md) — adjacent persistence, projection, title, and telemetry packages. ----- diff --git a/packages/session/session-title-all-prompts-llm/README.zh.md b/packages/experimental/session-title-all-prompts-llm/README.zh.md similarity index 66% rename from packages/session/session-title-all-prompts-llm/README.zh.md rename to packages/experimental/session-title-all-prompts-llm/README.zh.md index 8e590367c8..98da4d9381 100644 --- a/packages/session/session-title-all-prompts-llm/README.zh.md +++ b/packages/experimental/session-title-all-prompts-llm/README.zh.md @@ -3,13 +3,13 @@ description: "面向用户与维护者的全消息 LLM(大语言模型)会 kind: "package-reference" --- -# @deepseek-ai/dsh-session-title-all-prompts-llm +# @deepseek-ai/dsh-experimental-session-title-all-prompts-llm [English](README.md) | 中文 ## 概述 -`dsh-session-title-all-prompts-llm` 作为可选的 `ctx.sessionTitle` 提供方,通过 `ctx.llm` 总结所有符合条件的用户消息。它注册 `all-prompts` 节奏,并在每条新用户提示词后启动新修订,使用预置历史与子会话提示词。较新的修订会中止并取代旧工作,即使提供方忽略取消,也无法提交陈旧输出。它使用 `dsh-session-title-llm` 的完整必填共享 LLM 配置,因此路由、提示词、预算与取消行为不会漂移。本文优先介绍自动行为与配置;实现只是基于共享策略进行的轻量注册。 +`dsh-experimental-session-title-all-prompts-llm` 作为可选的 `ctx.sessionTitle` 提供方,通过 `ctx.llm` 总结所有符合条件的用户消息。它注册 `all-prompts` 节奏,并在每条新用户提示词后启动新修订,使用预置历史与子会话提示词。较新的修订会中止并取代旧工作,即使提供方忽略取消,也无法提交陈旧输出。它使用 `dsh-session-title-llm` 的完整必填共享 LLM 配置,因此路由、提示词、预算与取消行为不会漂移。本文优先介绍自动行为与配置;实现只是基于共享策略进行的轻量注册。 ## 目录 @@ -25,7 +25,7 @@ kind: "package-reference" ## 使用本包 -当会话应随其增长而重新生成标题、使标题持续代表整个对话时,在标题服务旁挂载此插件。它要求完整的[共享 LLM 配置](../session-title-llm/README.zh.md#configuration),且无默认值。 +当会话应随其增长而重新生成标题、使标题持续代表整个对话时,在标题服务旁挂载此插件。它要求完整的[共享 LLM 配置](../../session/session-title-llm/README.zh.md#configuration),且无默认值。 ### 标题生成时机 @@ -33,7 +33,7 @@ kind: "package-reference" ### 配置 -插件接受完整必填的[共享 LLM 配置](../session-title-llm/README.zh.md#configuration):`targetWords`、`targetCjkCharacters`、`maxInputBytes`、`maxOutputTokens`、`timeoutMs`,以及可选成对的 `provider`/`model` 路由。同时省略二者,会继承每个当前已记录主请求的确切路由;同时设置二者,则让标题生成使用独立路由。生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-session-title-all-prompts-llm)是每个受支持字段的穷尽式真源。 +插件接受完整必填的[共享 LLM 配置](../../session/session-title-llm/README.zh.md#configuration):`targetWords`、`targetCjkCharacters`、`maxInputBytes`、`maxOutputTokens`、`timeoutMs`,以及可选成对的 `provider`/`model` 路由。同时省略二者,会继承每个当前已记录主请求的确切路由;同时设置二者,则让标题生成使用独立路由。生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-experimental-session-title-all-prompts-llm)是每个受支持字段的穷尽式真源。 ### 失败与恢复 @@ -51,7 +51,7 @@ kind: "package-reference" ### 设计理念 -一个薄提供方插件:它注册 `all-prompts` 节奏,用恒等选择器选取所有符合条件消息,其余全部委托给[共享 LLM 策略](../session-title-llm/README.zh.md)。 +一个薄提供方插件:它注册 `all-prompts` 节奏,用恒等选择器选取所有符合条件消息,其余全部委托给[共享 LLM 策略](../../session/session-title-llm/README.zh.md)。 ### 源码地图 @@ -72,10 +72,10 @@ kind: "package-reference" 当提供方约定不够用时阅读以下页面。它们从共享策略逐步进入替代节奏与它所插入的服务。 -- [共享 LLM 标题策略](../session-title-llm/README.zh.md)——此提供方使用的生成辅助模块。 -- [首消息标题提供方](../session-title-first-prompt-llm/README.zh.md)——只根据首条提示词为会话生成一次标题的节奏。 -- [会话标题服务](../session-title/README.zh.md)——回退行为、重命名、刷新与提供方注册。 -- [会话包映射](../README.zh.md)——相邻的持久化、投影、标题与遥测包。 +- [共享 LLM 标题策略](../../session/session-title-llm/README.zh.md)——此提供方使用的生成辅助模块。 +- [首消息标题提供方](../../session/session-title-first-prompt-llm/README.zh.md)——只根据首条提示词为会话生成一次标题的节奏。 +- [会话标题服务](../../session/session-title/README.zh.md)——回退行为、重命名、刷新与提供方注册。 +- [会话包映射](../../session/README.zh.md)——相邻的持久化、投影、标题与遥测包。 ----- diff --git a/packages/session/session-title-all-prompts-llm/package.json b/packages/experimental/session-title-all-prompts-llm/package.json similarity index 90% rename from packages/session/session-title-all-prompts-llm/package.json rename to packages/experimental/session-title-all-prompts-llm/package.json index 619a198ed4..f5b7e9e8ed 100644 --- a/packages/session/session-title-all-prompts-llm/package.json +++ b/packages/experimental/session-title-all-prompts-llm/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-session-title-all-prompts-llm", + "name": "@deepseek-ai/dsh-experimental-session-title-all-prompts-llm", "description": "All-user-messages LLM provider plugin for DeepSeek Harness session titles", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/session/session-title-all-prompts-llm" + "directory": "packages/experimental/session-title-all-prompts-llm" }, "type": "module", "main": "lib/index.js", diff --git a/packages/session/session-title-all-prompts-llm/src/index.ts b/packages/experimental/session-title-all-prompts-llm/src/index.ts similarity index 100% rename from packages/session/session-title-all-prompts-llm/src/index.ts rename to packages/experimental/session-title-all-prompts-llm/src/index.ts diff --git a/packages/session/session-title-all-prompts-llm/tests/provider.spec.ts b/packages/experimental/session-title-all-prompts-llm/tests/provider.spec.ts similarity index 97% rename from packages/session/session-title-all-prompts-llm/tests/provider.spec.ts rename to packages/experimental/session-title-all-prompts-llm/tests/provider.spec.ts index 429f1f5bd3..09b3d52983 100644 --- a/packages/session/session-title-all-prompts-llm/tests/provider.spec.ts +++ b/packages/experimental/session-title-all-prompts-llm/tests/provider.spec.ts @@ -6,7 +6,7 @@ import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import { turnBoundaryProjectionDefinition } from '@deepseek-ai/dsh-agent-loop' import SessionTitleService from '@deepseek-ai/dsh-session-title' -import * as providerPlugin from '@deepseek-ai/dsh-session-title-all-prompts-llm' +import * as providerPlugin from '@deepseek-ai/dsh-experimental-session-title-all-prompts-llm' class RecordingAdapter extends LlmAdapter { readonly requests: GenerateOptions[] = [] diff --git a/packages/session/session-title-all-prompts-llm/tsconfig.json b/packages/experimental/session-title-all-prompts-llm/tsconfig.json similarity index 76% rename from packages/session/session-title-all-prompts-llm/tsconfig.json rename to packages/experimental/session-title-all-prompts-llm/tsconfig.json index 2e120efa2c..e5167d715c 100644 --- a/packages/session/session-title-all-prompts-llm/tsconfig.json +++ b/packages/experimental/session-title-all-prompts-llm/tsconfig.json @@ -7,7 +7,7 @@ { "path": "../../../vendor/cordis" }, { "path": "../../../vendor/schemastery" }, { "path": "../../llm/llm" }, - { "path": "../session-title" }, - { "path": "../session-title-llm" } + { "path": "../../session/session-title" }, + { "path": "../../session/session-title-llm" } ] } diff --git a/packages/experimental/skill-badge/README.i18n.yaml b/packages/experimental/skill-badge/README.i18n.yaml new file mode 100644 index 0000000000..9cce41d7d3 --- /dev/null +++ b/packages/experimental/skill-badge/README.i18n.yaml @@ -0,0 +1,55 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/skill-badge/README.md +/: + en: c32f79a869ebd48a + zh: 44e64fb59fa75e57 +/deepseek-ai-dsh-experimental-skill-badge: + en: 010ea3c872c7967e + zh: 7c2e653c73f0ec24 +/deepseek-ai-dsh-experimental-skill-badge/summary: + en: 49bdd760ee9e4370 + zh: 2a4e68a7ef28d3e6 +/deepseek-ai-dsh-experimental-skill-badge/table-of-contents: + en: d152484eb41ac6b4 + zh: 09388d293f9be9cb +/deepseek-ai-dsh-experimental-skill-badge/use-this-package: + en: a559a5ed8a76e342 + zh: 6558f9af8d6c9625 +/deepseek-ai-dsh-experimental-skill-badge/use-this-package/when-to-choose-it: + en: a3276561ace9e681 + zh: d2541ab4846fefa2 +/deepseek-ai-dsh-experimental-skill-badge/use-this-package/enable-the-plugin: + en: bdd4d54b093d597b + zh: f1628bc93844f35d +/deepseek-ai-dsh-experimental-skill-badge/use-this-package/what-the-badge-skill-provides: + en: 7144db5613266a9b + zh: d1b7edf6c1253e9a +/deepseek-ai-dsh-experimental-skill-badge/use-this-package/observable-success-and-failures: + en: 1b3c8501e0899f1e + zh: 909684f272051d5f +/deepseek-ai-dsh-experimental-skill-badge/understand-the-implementation: + en: 63465b0133f30e85 + zh: 84bebb7c1fe0ceba +/deepseek-ai-dsh-experimental-skill-badge/understand-the-implementation/design-concept: + en: 52ff92fad6d26ee9 + zh: 071c7859c158513d +/deepseek-ai-dsh-experimental-skill-badge/understand-the-implementation/source-map: + en: 259b9b2073da8ddd + zh: e0d621f0a3b0470c +/deepseek-ai-dsh-experimental-skill-badge/further-exploration: + en: 1b5434b8bcbd5b0b + zh: d170cddf3837e655 +/deepseek-ai-dsh-experimental-skill-badge/model-experience: + en: b9912bc3f1ba0680 + zh: e288cc67b6d079f6 +/deepseek-ai-dsh-experimental-skill-badge/model-experience/kv-cache-effect: + en: 6a8366520852a607 + zh: 453ec29827b82bbc +/deepseek-ai-dsh-experimental-skill-badge/known-limitations-and-deferred-work: + en: c7e405ebbc1d4602 + zh: 05a57fb4359da265 +/deepseek-ai-dsh-experimental-skill-badge/known-limitations-and-deferred-work/dev-note: + en: e67f633dc6fe7773 + zh: 3bb0c20c93f16f98 diff --git a/packages/skill/skill-badge/README.md b/packages/experimental/skill-badge/README.md similarity index 85% rename from packages/skill/skill-badge/README.md rename to packages/experimental/skill-badge/README.md index 26bcadc13f..91777b0785 100644 --- a/packages/skill/skill-badge/README.md +++ b/packages/experimental/skill-badge/README.md @@ -3,13 +3,13 @@ description: "The bundled 'powered by dsh' badge skill for users and maintainers kind: "package-reference" --- -# @deepseek-ai/dsh-skill-badge +# @deepseek-ai/dsh-experimental-skill-badge English | [中文](README.zh.md) ## Summary -Agents can load the official "powered by dsh" badge skill from this bundled provider and follow its instructions for adding attribution badges to documents, PRs, and other content produced with DeepSeek Harness. The provider has no configuration, and the shipped CLI composition includes the plugin disabled, so deployments enable it explicitly. The skill ships both Markdown snippets and a packaged PNG for systems that cannot reliably import remote images. +Agents can load the official "powered by dsh" badge skill from this bundled provider and follow its instructions for adding attribution badges to documents, PRs, and other content produced with DeepSeek Harness. The provider has no configuration; deployments install it and insert its plugin row explicitly. The skill ships both Markdown snippets and a packaged PNG for systems that cannot reliably import remote images. ## Table of Contents @@ -33,10 +33,12 @@ Choose this provider when content produced with DeepSeek Harness should carry of ### Enable the plugin -The plugin has no configuration. Add its composition row to a composition; the shipped CLI composition carries the row as `disabled: true`, so enable it explicitly there. +Install `@deepseek-ai/dsh-experimental-skill-badge` into the profile and insert its plugin row. The default composition does not declare it. ```yaml -- name: '@deepseek-ai/dsh-skill-badge' +- insert: + - id: skill-badge + name: '@deepseek-ai/dsh-experimental-skill-badge' ``` After enabling, `dsh-badge` appears in the available skills of the session catalog. The skill covers remote Markdown badges (Shields.io-based) and a packaged PNG badge asset for targets that cannot fetch remote images reliably. @@ -81,8 +83,8 @@ The provider is an immutable, synchronously registered skill source: it register Read these pages when the package-level contract is not enough. They move from the registry this provider registers on to how the skill reaches the model. - [Skill subsystem reference](../../../docs/subsystems/skills.md) — the registry and provider contract this provider implements. -- [skill package](../skill/README.md) — the registry the provider registers on, and the shared rendering of loaded skills. -- [tool-skill package](../tool-skill/README.md) — how the badge skill reaches the session catalog and the model. +- [skill package](../../skill/skill/README.md) — the registry the provider registers on, and the shared rendering of loaded skills. +- [tool-skill package](../../skill/tool-skill/README.md) — how the badge skill reaches the session catalog and the model. ----- diff --git a/packages/skill/skill-badge/README.zh.md b/packages/experimental/skill-badge/README.zh.md similarity index 85% rename from packages/skill/skill-badge/README.zh.md rename to packages/experimental/skill-badge/README.zh.md index 2e71214a20..1dcac1eaf1 100644 --- a/packages/skill/skill-badge/README.zh.md +++ b/packages/experimental/skill-badge/README.zh.md @@ -3,13 +3,13 @@ description: "随包附带的「powered by dsh」徽章 skill(技能),供 kind: "package-reference" --- -# @deepseek-ai/dsh-skill-badge +# @deepseek-ai/dsh-experimental-skill-badge [English](README.md) | 中文 ## 概述 -agent(智能体)可以通过该内置提供方加载官方「powered by dsh」徽章 skill,并遵循其指令,给文档、PR(Pull Request)以及其他用 DeepSeek Harness 生成的内容添加署名徽章。该提供方没有配置,随附 CLI(命令行界面)组合以禁用状态包含该插件,因此部署方需要显式启用。该 skill 同时提供 Markdown 片段和随包分发的 PNG,供无法可靠导入远程图片的系统使用。 +agent(智能体)可以通过该内置提供方加载官方「powered by dsh」徽章 skill,并遵循其指令,给文档、PR(Pull Request)以及其他用 DeepSeek Harness 生成的内容添加署名徽章。该提供方没有配置;部署方需要显式安装并插入插件行。该 skill 同时提供 Markdown 片段和随包分发的 PNG,供无法可靠导入远程图片的系统使用。 ## 目录 @@ -33,10 +33,12 @@ agent(智能体)可以通过该内置提供方加载官方「powered by dsh ### 启用插件 -该插件没有配置。把它的组合行加入组合即可;随附 CLI 组合以 `disabled: true` 携带该行,因此在那里需要显式启用。 +将 `@deepseek-ai/dsh-experimental-skill-badge` 安装到 profile,并插入插件行。默认组合不声明该行。 ```yaml -- name: '@deepseek-ai/dsh-skill-badge' +- insert: + - id: skill-badge + name: '@deepseek-ai/dsh-experimental-skill-badge' ``` 启用后,`dsh-badge` 会出现在会话目录的可用 skill 中。该 skill 覆盖远程 Markdown 徽章(基于 Shields.io)和随包分发的 PNG 徽章资源,后者用于无法可靠获取远程图片的目标环境。 @@ -81,8 +83,8 @@ agent(智能体)可以通过该内置提供方加载官方「powered by dsh 当包级约定不够用时,请阅读以下页面。这些页面先介绍该提供方注册到的注册表,再说明 skill 如何到达模型。 - [skill 子系统参考](../../../docs/subsystems/skills.zh.md)——该提供方实现的注册表与提供方约定。 -- [skill 包](../skill/README.zh.md)——该提供方注册到的注册表,以及已加载 skill 的共享渲染。 -- [tool-skill 包](../tool-skill/README.zh.md)——徽章 skill 如何到达会话目录与模型。 +- [skill 包](../../skill/skill/README.zh.md)——该提供方注册到的注册表,以及已加载 skill 的共享渲染。 +- [tool-skill 包](../../skill/tool-skill/README.zh.md)——徽章 skill 如何到达会话目录与模型。 ----- diff --git a/packages/skill/skill-badge/assets/dsh-badge.md b/packages/experimental/skill-badge/assets/dsh-badge.md similarity index 100% rename from packages/skill/skill-badge/assets/dsh-badge.md rename to packages/experimental/skill-badge/assets/dsh-badge.md diff --git a/packages/skill/skill-badge/assets/dsh-badge.png b/packages/experimental/skill-badge/assets/dsh-badge.png similarity index 100% rename from packages/skill/skill-badge/assets/dsh-badge.png rename to packages/experimental/skill-badge/assets/dsh-badge.png diff --git a/packages/skill/skill-badge/package.json b/packages/experimental/skill-badge/package.json similarity index 88% rename from packages/skill/skill-badge/package.json rename to packages/experimental/skill-badge/package.json index 8a72b44615..399af02f9b 100644 --- a/packages/skill/skill-badge/package.json +++ b/packages/experimental/skill-badge/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-skill-badge", + "name": "@deepseek-ai/dsh-experimental-skill-badge", "description": "Bundled dsh badge skill provider for DeepSeek Harness", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/skill/skill-badge" + "directory": "packages/experimental/skill-badge" }, "type": "module", "main": "lib/index.js", diff --git a/packages/skill/skill-badge/src/index.ts b/packages/experimental/skill-badge/src/index.ts similarity index 97% rename from packages/skill/skill-badge/src/index.ts rename to packages/experimental/skill-badge/src/index.ts index 753d51f817..c75b8252c3 100644 --- a/packages/skill/skill-badge/src/index.ts +++ b/packages/experimental/skill-badge/src/index.ts @@ -1,7 +1,7 @@ /** * Bundled `dsh-badge` skill provider. * - * @module @deepseek-ai/dsh-skill-badge + * @module @deepseek-ai/dsh-experimental-skill-badge */ import { readFile } from 'node:fs/promises' diff --git a/packages/skill/skill-badge/tests/skill-badge.spec.ts b/packages/experimental/skill-badge/tests/skill-badge.spec.ts similarity index 93% rename from packages/skill/skill-badge/tests/skill-badge.spec.ts rename to packages/experimental/skill-badge/tests/skill-badge.spec.ts index f66e1bb9dc..4243bd3fdf 100644 --- a/packages/skill/skill-badge/tests/skill-badge.spec.ts +++ b/packages/experimental/skill-badge/tests/skill-badge.spec.ts @@ -4,9 +4,9 @@ import { fileURLToPath } from 'node:url' import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import SkillRegistry from '@deepseek-ai/dsh-skill' -import * as SkillBadge from '@deepseek-ai/dsh-skill-badge' +import * as SkillBadge from '@deepseek-ai/dsh-experimental-skill-badge' -describe('dsh-skill-badge', () => { +describe('dsh-experimental-skill-badge', () => { it('registers and disposes the bundled badge skill', async () => { const ctx = new Context() await ctx.plugin(SkillRegistry) diff --git a/packages/skill/skill-badge/tsconfig.json b/packages/experimental/skill-badge/tsconfig.json similarity index 87% rename from packages/skill/skill-badge/tsconfig.json rename to packages/experimental/skill-badge/tsconfig.json index ade98cfa06..d90f92afe7 100644 --- a/packages/skill/skill-badge/tsconfig.json +++ b/packages/experimental/skill-badge/tsconfig.json @@ -8,6 +8,6 @@ "references": [ { "path": "../../../vendor/cosmokit" }, { "path": "../../../vendor/cordis" }, - { "path": "../skill" } + { "path": "../../skill/skill" } ] } diff --git a/packages/experimental/tool-ralph/README.i18n.yaml b/packages/experimental/tool-ralph/README.i18n.yaml new file mode 100644 index 0000000000..d0bc4d5933 --- /dev/null +++ b/packages/experimental/tool-ralph/README.i18n.yaml @@ -0,0 +1,100 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/tool-ralph/README.md +/: + en: e2a31cca62823561 + zh: c06ff93cf98b67e4 +/deepseek-ai-dsh-experimental-tool-ralph: + en: 58151c8408ee0683 + zh: f82cca40f517d2d4 +/deepseek-ai-dsh-experimental-tool-ralph/summary: + en: 9821960147153443 + zh: 0b24aab94a5dc12b +/deepseek-ai-dsh-experimental-tool-ralph/table-of-contents: + en: d152484eb41ac6b4 + zh: 09388d293f9be9cb +/deepseek-ai-dsh-experimental-tool-ralph/use-this-package: + en: 13380e1170c6a3b5 + zh: 2f2665f2ee5ff6f7 +/deepseek-ai-dsh-experimental-tool-ralph/use-this-package/calling-the-tool: + en: f43e8fbcf272ac45 + zh: 46719b415d9ad4bf +/deepseek-ai-dsh-experimental-tool-ralph/use-this-package/what-each-round-sees: + en: 2d8b861c4bcb9424 + zh: 63c7b2d00c324727 +/deepseek-ai-dsh-experimental-tool-ralph/use-this-package/config: + en: 45eed16eb7d1a6d0 + zh: a080e65eff58f393 +/deepseek-ai-dsh-experimental-tool-ralph/understand-the-implementation: + en: 0999ea3a4c9da48c + zh: 83013ee36a8689af +/deepseek-ai-dsh-experimental-tool-ralph/understand-the-implementation/design-concept: + en: 3777bac0215c7366 + zh: 18240f47506c67bd +/deepseek-ai-dsh-experimental-tool-ralph/understand-the-implementation/fixed-script-and-routing: + en: fa2cfda2d9d121e6 + zh: 75720bd6244a2c96 +/deepseek-ai-dsh-experimental-tool-ralph/understand-the-implementation/report-validation: + en: 65f90bce7ef1fe5b + zh: 04c8d5ad08a9007c +/deepseek-ai-dsh-experimental-tool-ralph/understand-the-implementation/lifecycle-and-cancellation: + en: fdd98f9e2d2ec378 + zh: 72e3da1f3c717aa6 +/deepseek-ai-dsh-experimental-tool-ralph/understand-the-implementation/render-intent: + en: 07e071bd44b1df65 + zh: 26f1cb2eab8c25b0 +/deepseek-ai-dsh-experimental-tool-ralph/understand-the-implementation/source-map: + en: 1bc11234792b4e3f + zh: 872d2c5f8df37b72 +/deepseek-ai-dsh-experimental-tool-ralph/further-exploration: + en: 966417f5c0659ef9 + zh: 6c95a000db46ce0f +/deepseek-ai-dsh-experimental-tool-ralph/model-experience: + en: 215e7ba838619b7b + zh: a311da3843709f90 +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/system-prompt: + en: cf78b9dd5596495f + zh: bd44560f8c2435e8 +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/system-prompt/what-the-model-sees: + en: bcfb20c5be49c2c4 + zh: c666f686a648fc0f +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/system-prompt/what-the-model-sees/ralph-guidance: + en: 4ee32d69a7ae2aba + zh: bdf2035f010ab56a +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/system-prompt/token-effect: + en: dab67480bfde6224 + zh: 85bbf18da3767aa7 +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/system-prompt/kv-cache-effect: + en: 13e7c6007bf6b5dc + zh: 2b0da8b6dc00aa5e +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/tool-schema: + en: e4c7376d4f29dbd5 + zh: 6b7a9eaf69c9ea53 +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/tool-schema/what-the-model-sees: + en: 11d15d6c18d57a3c + zh: 41f6ea487cd4d610 +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/tool-schema/token-effect: + en: 0af719618f9f99d2 + zh: a719a4e5df1406a4 +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/tool-schema/kv-cache-effect: + en: 79a20d1db0f4a32e + zh: c72a19d9a6c0bff3 +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/child-requests-and-parent-result: + en: 55181fb745ab8135 + zh: ebeea6a8748986d2 +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/child-requests-and-parent-result/what-the-model-sees: + en: 788029304e88ea74 + zh: 0e0281c7cc393dff +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/child-requests-and-parent-result/token-effect: + en: ab2d30ed91979cbc + zh: bb074b02c4b05e4f +/deepseek-ai-dsh-experimental-tool-ralph/model-experience/child-requests-and-parent-result/kv-cache-effect: + en: 8f28959dc87d1f2f + zh: c034c5c0bdaf9bba +/deepseek-ai-dsh-experimental-tool-ralph/known-limitations-and-deferred-work: + en: 4e3629e8de05fe18 + zh: 5b33af22079a2ca7 +/deepseek-ai-dsh-experimental-tool-ralph/known-limitations-and-deferred-work/dev-note: + en: 8f24c317039e1974 + zh: c6209969ad21f16c diff --git a/packages/workflow/tool-ralph/README.md b/packages/experimental/tool-ralph/README.md similarity index 93% rename from packages/workflow/tool-ralph/README.md rename to packages/experimental/tool-ralph/README.md index bc755bce30..9130fc6358 100644 --- a/packages/workflow/tool-ralph/README.md +++ b/packages/experimental/tool-ralph/README.md @@ -3,7 +3,7 @@ description: "The model-facing ralph tool: a fixed foreground fresh-agent loop t kind: "package-reference" --- -# @deepseek-ai/dsh-tool-ralph +# @deepseek-ai/dsh-experimental-tool-ralph English | [中文](README.zh.md) @@ -44,7 +44,7 @@ Each child receives only the immutable objective, its current round and cap, a s | `maxHandoffChars` | `16384` | Maximum serialized characters in one round report. | | `maxResultChars` | `16384` | Maximum characters in the complete successful parent result. | -The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-tool-ralph) is the exhaustive source for every accepted field. The configured provider must exist, support structured output, and report `inheritsParentContext: false`; a call against a provider that violates this fails loudly before any round starts. +The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-experimental-tool-ralph) is the exhaustive source for every accepted field. The configured provider must exist, support structured output, and report `inheritsParentContext: false`; a call against a provider that violates this fails loudly before any round starts. ----- @@ -92,8 +92,8 @@ The pending call is a `generic` card titled `ralph` with the immutable objective Read these pages when the tool-level contract is not enough. They move from the shared workflow model to the engine, the subagent seam, and the adjacent goal domain. - [Workflow subsystem](../../../docs/subsystems/workflow.md) — the seam contract behind the fixed loop. -- [Workflow seam](../workflow/README.md) — the run and result vocabulary. -- [PTC workflow engine](../workflow-ptc/README.md) — the engine that executes the fixed script. +- [Workflow seam](../../workflow/workflow/README.md) — the run and result vocabulary. +- [PTC workflow engine](../../workflow/workflow-ptc/README.md) — the engine that executes the fixed script. - [subagent seam](../../subagent/subagent/README.md) — the fresh-child provider contract. - [Goal group](../../goal/goal/README.md) — same-session goal tools for ordinary long-running objectives. - [historical Harness-level goal-based execution Agent Note](../../../.agents/notes/archived/feature/2026-07-16-harness-level-loop.md) — the policy, provider requirements, and deferred work. @@ -127,7 +127,7 @@ Prefix-stable while the plugin scope and guidance text are unchanged. Activation #### What the model sees -The generated [`ralph` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-ralph) exposes one required `objective` string and one optional `maxRounds` number. Provider choice, handoff size, report schema, workflow script, and orchestration behavior are deployment-owned and absent from the call schema. +The generated [`ralph` schema](../../../docs/tool-catalog.md#deepseek-aidsh-experimental-tool-ralph) exposes one required `objective` string and one optional `maxRounds` number. Provider choice, handoff size, report schema, workflow script, and orchestration behavior are deployment-owned and absent from the call schema. #### Token effect diff --git a/packages/workflow/tool-ralph/README.zh.md b/packages/experimental/tool-ralph/README.zh.md similarity index 92% rename from packages/workflow/tool-ralph/README.zh.md rename to packages/experimental/tool-ralph/README.zh.md index e5846b9268..67404e3d83 100644 --- a/packages/workflow/tool-ralph/README.zh.md +++ b/packages/experimental/tool-ralph/README.zh.md @@ -3,7 +3,7 @@ description: "面向模型的 ralph 工具:固定前台 agent loop(智能体 kind: "package-reference" --- -# @deepseek-ai/dsh-tool-ralph +# @deepseek-ai/dsh-experimental-tool-ralph [English](README.md) | 中文 @@ -44,7 +44,7 @@ kind: "package-reference" | `maxHandoffChars` | `16384` | 一份 Round 报告序列化后的最大字符数。 | | `maxResultChars` | `16384` | 返回给父级的完整成功结果最大字符数。 | -生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-tool-ralph)是每个受支持字段的穷尽式真源。配置的提供方必须存在、支持结构化输出,并报告 `inheritsParentContext: false`;针对违反此要求的提供方发起调用时,会在任何 Round 开始前直接报错。 +生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-experimental-tool-ralph)是每个受支持字段的穷尽式真源。配置的提供方必须存在、支持结构化输出,并报告 `inheritsParentContext: false`;针对违反此要求的提供方发起调用时,会在任何 Round 开始前直接报错。 ----- @@ -92,8 +92,8 @@ kind: "package-reference" 当工具级契约不够用时阅读以下页面。它们从共享工作流模型逐步进入引擎、subagent seam 与相邻的 goal 领域。 - [工作流子系统](../../../docs/subsystems/workflow.zh.md)——固定循环背后的 seam 约定。 -- [工作流 seam](../workflow/README.zh.md)——运行与结果词汇。 -- [PTC 工作流引擎](../workflow-ptc/README.zh.md)——执行固定脚本的引擎。 +- [工作流 seam](../../workflow/workflow/README.zh.md)——运行与结果词汇。 +- [PTC 工作流引擎](../../workflow/workflow-ptc/README.zh.md)——执行固定脚本的引擎。 - [subagent seam](../../subagent/subagent/README.zh.md)——全新子 agent 的提供方约定。 - [goal 组](../../goal/goal/README.zh.md)——面向普通长期目标的同会话 goal 工具。 - [历史Harness 层目标式执行 Agent Note](../../../.agents/notes/archived/feature/2026-07-16-harness-level-loop.md)——策略、提供方要求与暂缓事项。 @@ -127,7 +127,7 @@ Use the ralph tool ONLY when the direct human explicitly asks for a Ralph loop o #### 模型看到什么 -已生成的 [`ralph` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-ralph) 公开一个必填 `objective` 字符串与一个可选 `maxRounds` 数字。提供方选择、交接大小、报告 schema、工作流脚本与编排行为均由部署侧控制,不在调用 schema 中。 +已生成的 [`ralph` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-experimental-tool-ralph) 公开一个必填 `objective` 字符串与一个可选 `maxRounds` 数字。提供方选择、交接大小、报告 schema、工作流脚本与编排行为均由部署侧控制,不在调用 schema 中。 #### Token 影响 diff --git a/packages/workflow/tool-ralph/package.json b/packages/experimental/tool-ralph/package.json similarity index 94% rename from packages/workflow/tool-ralph/package.json rename to packages/experimental/tool-ralph/package.json index 382cb1b319..8ad56870ca 100644 --- a/packages/workflow/tool-ralph/package.json +++ b/packages/experimental/tool-ralph/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-tool-ralph", + "name": "@deepseek-ai/dsh-experimental-tool-ralph", "description": "Model-facing fresh-agent Ralph loop over the workflow and subagent seams", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/workflow/tool-ralph" + "directory": "packages/experimental/tool-ralph" }, "type": "module", "main": "lib/index.js", diff --git a/packages/workflow/tool-ralph/src/index.ts b/packages/experimental/tool-ralph/src/index.ts similarity index 99% rename from packages/workflow/tool-ralph/src/index.ts rename to packages/experimental/tool-ralph/src/index.ts index 48708c12ca..a760d23d37 100644 --- a/packages/workflow/tool-ralph/src/index.ts +++ b/packages/experimental/tool-ralph/src/index.ts @@ -2,7 +2,7 @@ * Model-facing foreground Ralph loop over the workflow and subagent seams. A * fixed script starts one fresh structured-output child per round, carrying * only the immutable objective and the previous bounded handoff between them. - * @module @deepseek-ai/dsh-tool-ralph + * @module @deepseek-ai/dsh-experimental-tool-ralph */ import type { Context } from '@deepseek-ai/cordis' diff --git a/packages/workflow/tool-ralph/tests/integration.spec.ts b/packages/experimental/tool-ralph/tests/integration.spec.ts similarity index 98% rename from packages/workflow/tool-ralph/tests/integration.spec.ts rename to packages/experimental/tool-ralph/tests/integration.spec.ts index a83ad93fc6..f6b774389d 100644 --- a/packages/workflow/tool-ralph/tests/integration.spec.ts +++ b/packages/experimental/tool-ralph/tests/integration.spec.ts @@ -15,7 +15,7 @@ import * as spawn from '@deepseek-ai/dsh-subagent-spawn-in-process' import PtcWorkflowEngine from '@deepseek-ai/dsh-workflow-ptc' import { MockAdapter, maxTokensResponse, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' import * as toolRalph from '../src/index.ts' -import { mountWorkflowRuntime } from '../../workflow-ptc/tests/setup.ts' +import { mountWorkflowRuntime } from '../../../workflow/workflow-ptc/tests/setup.ts' type MockScript = ConstructorParameters[0] const testToolSignal = new AbortController().signal @@ -51,7 +51,7 @@ async function mountRalph(script: MockScript, config: toolRalph.Config) { return { ctx, adapter, parentHandle, parent: parentHandle.agent } } -describe('dsh-tool-ralph over the real spawn and sandboxed PTC stack', () => { +describe('dsh-experimental-tool-ralph over the real spawn and sandboxed PTC stack', () => { it('uses distinct empty-seed children, shared cwd, and only the prior bounded handoff', { timeout: 90_000 }, async () => { const firstReport = { status: 'continue', diff --git a/packages/workflow/tool-ralph/tests/tool-ralph.spec.ts b/packages/experimental/tool-ralph/tests/tool-ralph.spec.ts similarity index 99% rename from packages/workflow/tool-ralph/tests/tool-ralph.spec.ts rename to packages/experimental/tool-ralph/tests/tool-ralph.spec.ts index b9e3044d9d..5789cce6d8 100644 --- a/packages/workflow/tool-ralph/tests/tool-ralph.spec.ts +++ b/packages/experimental/tool-ralph/tests/tool-ralph.spec.ts @@ -146,7 +146,7 @@ async function settleCompleted( return pending } -describe('dsh-tool-ralph', () => { +describe('dsh-experimental-tool-ralph', () => { it('starts the fixed workflow through the configured fresh provider and renders completion', async () => { const { ctx, engine, parent } = await setup({ config: { maxRounds: 9, maxHandoffChars: 9000 } }) const pending = execute(ctx, { objective: ' Finish the migration. ', maxRounds: 4 }, { agent: parent }) diff --git a/packages/workflow/tool-ralph/tsconfig.json b/packages/experimental/tool-ralph/tsconfig.json similarity index 93% rename from packages/workflow/tool-ralph/tsconfig.json rename to packages/experimental/tool-ralph/tsconfig.json index 294a851a5b..77ebc9e761 100644 --- a/packages/workflow/tool-ralph/tsconfig.json +++ b/packages/experimental/tool-ralph/tsconfig.json @@ -33,7 +33,7 @@ "path": "../../core/tools" }, { - "path": "../workflow" + "path": "../../workflow/workflow" } ] } diff --git a/packages/experimental/tool-terminal/README.i18n.yaml b/packages/experimental/tool-terminal/README.i18n.yaml new file mode 100644 index 0000000000..d8ff65f534 --- /dev/null +++ b/packages/experimental/tool-terminal/README.i18n.yaml @@ -0,0 +1,100 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/tool-terminal/README.md +/: + en: fc74eecdf1f2ad5b + zh: dc9c2a28ce96ce67 +/deepseek-ai-dsh-experimental-tool-terminal: + en: 5eb5942c44854a88 + zh: 57a1fd4dbc5d05f8 +/deepseek-ai-dsh-experimental-tool-terminal/summary: + en: b355d2eef6e79be3 + zh: 1e5dbafd01f1e601 +/deepseek-ai-dsh-experimental-tool-terminal/table-of-contents: + en: d152484eb41ac6b4 + zh: 09388d293f9be9cb +/deepseek-ai-dsh-experimental-tool-terminal/use-this-package: + en: dcc6b2ac23494026 + zh: f5b755ec75994458 +/deepseek-ai-dsh-experimental-tool-terminal/use-this-package/the-six-tools: + en: 3e9b6211dd72ec64 + zh: aa4cd15195cb43d6 +/deepseek-ai-dsh-experimental-tool-terminal/use-this-package/composition: + en: 4ce2a232b60ff77d + zh: 3a8a0f13371ca6b9 +/deepseek-ai-dsh-experimental-tool-terminal/use-this-package/configuration: + en: 3bf7e6c40c325fd8 + zh: 6bfe66f9bfc32d0f +/deepseek-ai-dsh-experimental-tool-terminal/use-this-package/background-sends: + en: 2ad49d4f69deb06d + zh: 5f29972b5feec7e3 +/deepseek-ai-dsh-experimental-tool-terminal/use-this-package/observable-outcomes-and-failures: + en: 321a982fdbbf4ada + zh: 8c2636e5379815e1 +/deepseek-ai-dsh-experimental-tool-terminal/understand-the-implementation: + en: 6302fca8fef89136 + zh: 6327d56edb798ab2 +/deepseek-ai-dsh-experimental-tool-terminal/understand-the-implementation/design-concept: + en: dc500eeff749a06f + zh: 9402f5005d7ca338 +/deepseek-ai-dsh-experimental-tool-terminal/understand-the-implementation/source-map: + en: a59f4e76dc926bed + zh: 24813cb1bd8fbf32 +/deepseek-ai-dsh-experimental-tool-terminal/understand-the-implementation/result-bounding: + en: c1953779a1617d09 + zh: cc6a4a6e76fa021c +/deepseek-ai-dsh-experimental-tool-terminal/understand-the-implementation/ui-render-intents: + en: 03e5bb37f0c3aada + zh: 8d51eeb758eabe9c +/deepseek-ai-dsh-experimental-tool-terminal/further-exploration: + en: eb3aaab52499b332 + zh: e39e5c6e87d7535b +/deepseek-ai-dsh-experimental-tool-terminal/model-experience: + en: 215e7ba838619b7b + zh: a311da3843709f90 +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/system-prompt: + en: cf78b9dd5596495f + zh: bd44560f8c2435e8 +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/system-prompt/what-the-model-sees: + en: 99887ae1de81aaeb + zh: 4846a1d3ea8a3dc3 +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/system-prompt/what-the-model-sees/terminal-guidance: + en: 3ab4211f41e40211 + zh: b730cc3f278be17c +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/system-prompt/token-effect: + en: c9d6d1a8238b74ab + zh: 7f4b12d6180b9bac +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/system-prompt/kv-cache-effect: + en: 7fdc10b826aeeb51 + zh: 998c86c09efe43bd +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/tool-schemas: + en: 3039bc5e7a796b21 + zh: 6b7a9eaf69c9ea53 +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/tool-schemas/what-the-model-sees: + en: 81df219069f3907a + zh: 4dd03f0ca5618f5a +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/tool-schemas/token-effect: + en: 824644a1f5fe76df + zh: b34c7dd78c5ce3cd +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/tool-schemas/kv-cache-effect: + en: c8cbbef533bdb90f + zh: c0b00813b8419f46 +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/tool-results-and-task-context: + en: 54e0c8a019f02479 + zh: 7331b10d1a455d59 +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/tool-results-and-task-context/what-the-model-sees: + en: cc1e88a508d0679e + zh: a219be277705c0ab +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/tool-results-and-task-context/token-effect: + en: e4746b7b386944df + zh: be52cd2fd38276b5 +/deepseek-ai-dsh-experimental-tool-terminal/model-experience/tool-results-and-task-context/kv-cache-effect: + en: ac583ab16185a93c + zh: 78df55a519b2ec1f +/deepseek-ai-dsh-experimental-tool-terminal/known-limitations-and-deferred-work: + en: ba974b703d6ed0bc + zh: 655810d5d338343c +/deepseek-ai-dsh-experimental-tool-terminal/known-limitations-and-deferred-work/dev-note: + en: e67f633dc6fe7773 + zh: 3bb0c20c93f16f98 diff --git a/packages/terminal/tool-terminal/README.md b/packages/experimental/tool-terminal/README.md similarity index 84% rename from packages/terminal/tool-terminal/README.md rename to packages/experimental/tool-terminal/README.md index fb482bbf52..d518ca39e0 100644 --- a/packages/terminal/tool-terminal/README.md +++ b/packages/experimental/tool-terminal/README.md @@ -3,13 +3,13 @@ description: "Six model-facing persistent terminal tools with owner isolation, b kind: "package-reference" --- -# @deepseek-ai/dsh-tool-terminal +# @deepseek-ai/dsh-experimental-tool-terminal English | [中文](README.zh.md) ## Summary -Use `dsh-tool-terminal` when an agent needs persistent terminal state or interactive input across calls. It can open, send to, read, signal, close, and list terminal sessions while preventing one agent from operating another agent's sessions. Sends may wait for bounded foreground output or return a background job id for later collection or interruption. `maxResultBytes` caps each result, which remains in session history until compaction. The model is guided to prefer one-shot tools for bounded work. +Use `dsh-experimental-tool-terminal` when an agent needs persistent terminal state or interactive input across calls. It can open, send to, read, signal, close, and list terminal sessions while preventing one agent from operating another agent's sessions. Sends may wait for bounded foreground output or return a background job id for later collection or interruption. `maxResultBytes` caps each result, which remains in session history until compaction. The model is guided to prefer one-shot tools for bounded work. ## Table of Contents @@ -45,7 +45,7 @@ Enable these tools when the composition mounts a terminal backend and the model ```yaml - name: '@deepseek-ai/dsh-terminal' - name: '@deepseek-ai/dsh-terminal-bash' -- name: '@deepseek-ai/dsh-tool-terminal' +- name: '@deepseek-ai/dsh-experimental-tool-terminal' ``` The tools need `ctx.terminals` — a backend must be mounted — and the system-prompt service for the guidance section. Background sends additionally require the jobs service and its model-facing controller (`@deepseek-ai/dsh-tool-jobs`). @@ -57,7 +57,7 @@ The tools need `ctx.terminals` — a backend must be mounted — and the system- | `enableRunInBackground` | `true` | Expose and accept `run_in_background`; `false` removes the schema field and rejects the argument | | `maxResultBytes` | `262144` | UTF-8 cap (minimum `64`) for each complete terminal result after wait, session, pagination, truncation, and job-status metadata | -The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-tool-terminal) and [tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-tool-terminal) are the exhaustive sources for config fields and schemas. +The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-experimental-tool-terminal) and [tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-experimental-tool-terminal) are the exhaustive sources for config fields and schemas. ### Background sends @@ -105,10 +105,10 @@ Foreground sends use terminal call and result cards; background sends and the ot Read these pages when the package-level contract is not enough. They move from the generated schemas to the service contract, the backend, and the background-job surface. -- [Tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-tool-terminal) — the six generated schemas and result shapes. +- [Tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-experimental-tool-terminal) — the six generated schemas and result shapes. - [Terminal subsystem reference](../../../docs/subsystems/terminal.md) — the service contract and shared types behind the tools. -- [terminal service](../terminal/README.md) — session operations, owner fencing, and cleanup semantics. -- [terminal-bash backend](../terminal-bash/README.md) — the shipped shell backend that provides sessions. +- [terminal service](../../terminal/terminal/README.md) — session operations, owner fencing, and cleanup semantics. +- [terminal-bash backend](../../terminal/terminal-bash/README.md) — the shipped shell backend that provides sessions. - [jobs package map](../../jobs/README.md) — the background-job surface that collects and kills background sends. - [Persistent PTY Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md) — the capability design and deferred boundaries. @@ -141,7 +141,7 @@ Prefix-stable while the registration scope and guidance text are unchanged. #### What the model sees -The six generated schemas are listed in the [`dsh-tool-terminal` catalog section](../../../docs/tool-catalog.md#deepseek-aidsh-tool-terminal). Their fixed schema tokens are present whenever this plugin is active; agent-scoped tool filtering may hide them. +The six generated schemas are listed in the [`dsh-experimental-tool-terminal` catalog section](../../../docs/tool-catalog.md#deepseek-aidsh-experimental-tool-terminal). Their fixed schema tokens are present whenever this plugin is active; agent-scoped tool filtering may hide them. #### Token effect diff --git a/packages/terminal/tool-terminal/README.zh.md b/packages/experimental/tool-terminal/README.zh.md similarity index 84% rename from packages/terminal/tool-terminal/README.zh.md rename to packages/experimental/tool-terminal/README.zh.md index 1ec5763c09..a357b697dc 100644 --- a/packages/terminal/tool-terminal/README.zh.md +++ b/packages/experimental/tool-terminal/README.zh.md @@ -3,13 +3,13 @@ description: "面向需要跨调用终端状态的 agent(智能体)的 6 个 kind: "package-reference" --- -# @deepseek-ai/dsh-tool-terminal +# @deepseek-ai/dsh-experimental-tool-terminal [English](README.md) | 中文 ## 概述 -当 agent 需要跨调用保留终端状态或提供交互式输入时,使用 `dsh-tool-terminal`。它可以打开、发送、读取、传递信号、关闭和列出终端会话,同时防止一个 agent 操作其他 agent 的会话。发送可以等待有界的前台输出,也可以返回供后续收集或中断的后台任务 job id。`maxResultBytes` 限制每个结果的大小,而结果会保留在会话历史中直到压缩(compaction)。指引会让模型对有界工作优先使用单次工具。 +当 agent 需要跨调用保留终端状态或提供交互式输入时,使用 `dsh-experimental-tool-terminal`。它可以打开、发送、读取、传递信号、关闭和列出终端会话,同时防止一个 agent 操作其他 agent 的会话。发送可以等待有界的前台输出,也可以返回供后续收集或中断的后台任务 job id。`maxResultBytes` 限制每个结果的大小,而结果会保留在会话历史中直到压缩(compaction)。指引会让模型对有界工作优先使用单次工具。 ## 目录 @@ -45,7 +45,7 @@ kind: "package-reference" ```yaml - name: '@deepseek-ai/dsh-terminal' - name: '@deepseek-ai/dsh-terminal-bash' -- name: '@deepseek-ai/dsh-tool-terminal' +- name: '@deepseek-ai/dsh-experimental-tool-terminal' ``` 工具需要 `ctx.terminals`——必须挂载一个后端——以及用于指引章节的系统提示词服务。后台发送还额外要求任务服务及其面向模型的控制器(`@deepseek-ai/dsh-tool-jobs`)。 @@ -57,7 +57,7 @@ kind: "package-reference" | `enableRunInBackground` | `true` | 公开并接受 `run_in_background`;设为 `false` 时移除 schema 字段并拒绝该参数 | | `maxResultBytes` | `262144` | 每个完整终端结果的 UTF-8 上限(最小值 `64`);在等待、会话、分页、截断与任务状态元数据全部加入后计算 | -生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-tool-terminal)与[工具目录](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-terminal)是配置字段与 schema 的穷尽式真源。 +生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-experimental-tool-terminal)与[工具目录](../../../docs/tool-catalog.zh.md#deepseek-aidsh-experimental-tool-terminal)是配置字段与 schema 的穷尽式真源。 ### 后台发送 @@ -105,10 +105,10 @@ kind: "package-reference" 当包级约定不够用时阅读以下页面。它们从生成的 schema 进入服务约定、后端与后台任务接口面。 -- [工具目录](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-terminal)——6 个生成的 schema 与结果形态。 +- [工具目录](../../../docs/tool-catalog.zh.md#deepseek-aidsh-experimental-tool-terminal)——6 个生成的 schema 与结果形态。 - [终端子系统参考](../../../docs/subsystems/terminal.zh.md)——工具背后的服务约定与共享类型。 -- [terminal 服务](../terminal/README.zh.md)——会话操作、所有者限制与清理语义。 -- [terminal-bash 后端](../terminal-bash/README.zh.md)——提供会话的随附 shell 后端。 +- [terminal 服务](../../terminal/terminal/README.zh.md)——会话操作、所有者限制与清理语义。 +- [terminal-bash 后端](../../terminal/terminal-bash/README.zh.md)——提供会话的随附 shell 后端。 - [jobs 包映射](../../jobs/README.zh.md)——收集与停止后台发送的后台任务接口面。 - [持久 PTY Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md)——能力设计与暂缓边界。 @@ -141,7 +141,7 @@ Use a terminal session only when work needs persistent terminal state or interac #### 模型看到什么 -6 个生成的 schema 列在 [`dsh-tool-terminal` 目录章节](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-terminal)中。此插件活跃时,请求中会包含它们的固定 schema token;按 agent 范围过滤工具时可能隐藏这些 schema。 +6 个生成的 schema 列在 [`dsh-experimental-tool-terminal` 目录章节](../../../docs/tool-catalog.zh.md#deepseek-aidsh-experimental-tool-terminal)中。此插件活跃时,请求中会包含它们的固定 schema token;按 agent 范围过滤工具时可能隐藏这些 schema。 #### Token 影响 diff --git a/packages/terminal/tool-terminal/package.json b/packages/experimental/tool-terminal/package.json similarity index 95% rename from packages/terminal/tool-terminal/package.json rename to packages/experimental/tool-terminal/package.json index eaea210752..123c592bd6 100644 --- a/packages/terminal/tool-terminal/package.json +++ b/packages/experimental/tool-terminal/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-tool-terminal", + "name": "@deepseek-ai/dsh-experimental-tool-terminal", "description": "Six model-facing persistent PTY tools with owner isolation and generic background-job integration", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/terminal/tool-terminal" + "directory": "packages/experimental/tool-terminal" }, "type": "module", "main": "lib/index.js", diff --git a/packages/terminal/tool-terminal/src/background.ts b/packages/experimental/tool-terminal/src/background.ts similarity index 95% rename from packages/terminal/tool-terminal/src/background.ts rename to packages/experimental/tool-terminal/src/background.ts index 47494f7cff..808cd086f4 100644 --- a/packages/terminal/tool-terminal/src/background.ts +++ b/packages/experimental/tool-terminal/src/background.ts @@ -2,7 +2,7 @@ * Generic-job adaptation for background terminal sends: the registry pull * source over the backend's consuming send reader. * - * @module @deepseek-ai/dsh-tool-terminal/background + * @module @deepseek-ai/dsh-experimental-tool-terminal/background */ import type { JobOutputSource } from '@deepseek-ai/dsh-jobs' diff --git a/packages/terminal/tool-terminal/src/index.ts b/packages/experimental/tool-terminal/src/index.ts similarity index 99% rename from packages/terminal/tool-terminal/src/index.ts rename to packages/experimental/tool-terminal/src/index.ts index c27b7d68d6..5d69fb1f8f 100644 --- a/packages/terminal/tool-terminal/src/index.ts +++ b/packages/experimental/tool-terminal/src/index.ts @@ -1,7 +1,7 @@ /** * Six model-facing persistent terminal tools. Owner identity comes from the exact * tool execution Agent; generic `ctx.jobs` owns background ids and collection. - * @module @deepseek-ai/dsh-tool-terminal + * @module @deepseek-ai/dsh-experimental-tool-terminal */ import type {} from '@deepseek-ai/dsh-working-directory' diff --git a/packages/terminal/tool-terminal/src/render.ts b/packages/experimental/tool-terminal/src/render.ts similarity index 100% rename from packages/terminal/tool-terminal/src/render.ts rename to packages/experimental/tool-terminal/src/render.ts diff --git a/packages/terminal/tool-terminal/tests/loader-composition.spec.ts b/packages/experimental/tool-terminal/tests/loader-composition.spec.ts similarity index 96% rename from packages/terminal/tool-terminal/tests/loader-composition.spec.ts rename to packages/experimental/tool-terminal/tests/loader-composition.spec.ts index 9d2db58481..ba2d97bd0c 100644 --- a/packages/terminal/tool-terminal/tests/loader-composition.spec.ts +++ b/packages/experimental/tool-terminal/tests/loader-composition.spec.ts @@ -20,7 +20,7 @@ import SandboxPolicyService from '@deepseek-ai/dsh-sandbox-policy' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' import LocalSubprocessRuntime from '@deepseek-ai/dsh-subprocess-local' import * as TerminalLocal from '@deepseek-ai/dsh-terminal-bash' -import * as ToolPty from '@deepseek-ai/dsh-tool-terminal' +import * as ToolPty from '@deepseek-ai/dsh-experimental-tool-terminal' let root: string | undefined let context: Context | undefined @@ -85,7 +85,7 @@ suite('terminal real Loader composition through cordis.yml', () => { ' handoffGraceMs: 250', ' timeoutMs: 2000', ' disposeGraceMs: 500', - "- name: '@deepseek-ai/dsh-tool-terminal'", + "- name: '@deepseek-ai/dsh-experimental-tool-terminal'", '', ].join('\n')) @@ -105,7 +105,7 @@ suite('terminal real Loader composition through cordis.yml', () => { ['@deepseek-ai/dsh-sandbox-policy', SandboxPolicyService], ['@deepseek-ai/dsh-subprocess-local', LocalSubprocessRuntime], ['@deepseek-ai/dsh-terminal-bash', TerminalLocal], - ['@deepseek-ai/dsh-tool-terminal', ToolPty], + ['@deepseek-ai/dsh-experimental-tool-terminal', ToolPty], ]) context.loader.internal = { version: 'v2', diff --git a/packages/terminal/tool-terminal/tests/render.spec.ts b/packages/experimental/tool-terminal/tests/render.spec.ts similarity index 97% rename from packages/terminal/tool-terminal/tests/render.spec.ts rename to packages/experimental/tool-terminal/tests/render.spec.ts index f247f189ee..6b0dd94b3b 100644 --- a/packages/terminal/tool-terminal/tests/render.spec.ts +++ b/packages/experimental/tool-terminal/tests/render.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { TerminalSessionId } from '@deepseek-ai/dsh-terminal' -import { boundTerminalText, renderList, renderRead, renderSend, renderSendRead, renderSpawn } from '@deepseek-ai/dsh-tool-terminal/src/render.ts' +import { boundTerminalText, renderList, renderRead, renderSend, renderSendRead, renderSpawn } from '@deepseek-ai/dsh-experimental-tool-terminal/src/render.ts' describe('tool-terminal rendering', () => { it('renders spawn with and without names or MOTD', () => { diff --git a/packages/terminal/tool-terminal/tests/tools.spec.ts b/packages/experimental/tool-terminal/tests/tools.spec.ts similarity index 99% rename from packages/terminal/tool-terminal/tests/tools.spec.ts rename to packages/experimental/tool-terminal/tests/tools.spec.ts index 8f6f3a5897..c0c8d68d5b 100644 --- a/packages/terminal/tool-terminal/tests/tools.spec.ts +++ b/packages/experimental/tool-terminal/tests/tools.spec.ts @@ -12,7 +12,7 @@ import TerminalSessionService, { TerminalSessionId } from '@deepseek-ai/dsh-term import type { TerminalBackend, TerminalBackendSession, TerminalSendOperation, TerminalSendRead, TerminalSendRequest, TerminalSessionStatus, TerminalSignal } from '@deepseek-ai/dsh-terminal' import LocalJobRegistry from '@deepseek-ai/dsh-jobs-local' import * as ToolJobs from '@deepseek-ai/dsh-tool-jobs' -import * as ToolPty from '@deepseek-ai/dsh-tool-terminal' +import * as ToolPty from '@deepseek-ai/dsh-experimental-tool-terminal' import { sendSource } from '../src/background.ts' async function fakeAgent(ctx: Context, rawId: string): Promise { diff --git a/packages/terminal/tool-terminal/tsconfig.json b/packages/experimental/tool-terminal/tsconfig.json similarity index 94% rename from packages/terminal/tool-terminal/tsconfig.json rename to packages/experimental/tool-terminal/tsconfig.json index 6692fb8eca..a9bb35d5ca 100644 --- a/packages/terminal/tool-terminal/tsconfig.json +++ b/packages/experimental/tool-terminal/tsconfig.json @@ -21,7 +21,7 @@ "path": "../../util/output-retention" }, { - "path": "../terminal" + "path": "../../terminal/terminal" }, { "path": "../../core/agent" diff --git a/packages/experimental/webhook-github/README.i18n.yaml b/packages/experimental/webhook-github/README.i18n.yaml new file mode 100644 index 0000000000..fd92dbc51f --- /dev/null +++ b/packages/experimental/webhook-github/README.i18n.yaml @@ -0,0 +1,37 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/webhook-github/README.md +/: + en: 60db7ae899ed9fd9 + zh: 4fe10fa8823aa6d1 +/deepseek-ai-dsh-experimental-webhook-github: + en: 1fa2c31f0d7f265b + zh: f0f0d6433816355f +/deepseek-ai-dsh-experimental-webhook-github/summary: + en: f39045a4a4168bbe + zh: 01298bd3e609edc3 +/deepseek-ai-dsh-experimental-webhook-github/table-of-contents: + en: b946752a1c17cd00 + zh: cdaaea55e4da6831 +/deepseek-ai-dsh-experimental-webhook-github/configuration: + en: a32a5195a6ae6a61 + zh: a135089e86948290 +/deepseek-ai-dsh-experimental-webhook-github/http-contract: + en: 2d8b5cb8d44bef8e + zh: a98ec470d9d6bc2d +/deepseek-ai-dsh-experimental-webhook-github/dedicated-listener-composition: + en: fec88ad475169c2f + zh: 992572e6fb76a05b +/deepseek-ai-dsh-experimental-webhook-github/model-experience: + en: b5cc7b3fe7fe0cc1 + zh: 196653a3926c68fb +/deepseek-ai-dsh-experimental-webhook-github/model-experience/kv-cache-effect: + en: a7c54f451f61179e + zh: aaf25d0781ad4d6b +/deepseek-ai-dsh-experimental-webhook-github/known-limitations-and-deferred-work: + en: 0c3192c3e300bb46 + zh: 7c84d20e6a8a768e +/deepseek-ai-dsh-experimental-webhook-github/known-limitations-and-deferred-work/dev-note: + en: e67f633dc6fe7773 + zh: e88aeb617ffb74ea diff --git a/packages/webhook/webhook-github/README.md b/packages/experimental/webhook-github/README.md similarity index 79% rename from packages/webhook/webhook-github/README.md rename to packages/experimental/webhook-github/README.md index ce0e2da0aa..1d20bc5a48 100644 --- a/packages/webhook/webhook-github/README.md +++ b/packages/experimental/webhook-github/README.md @@ -3,13 +3,13 @@ description: "Signed GitHub webhook adapter for deployments routing authenticate kind: "package-reference" --- -# @deepseek-ai/dsh-webhook-github +# @deepseek-ai/dsh-experimental-webhook-github English | [中文](README.zh.md) ## Summary -`dsh-webhook-github` registers one exact HTTP route on the injected `ctx.webServer`. It bounds and verifies GitHub's raw JSON body, projects a provider-neutral delivery, calls `ctx.webhookRuntime.dispatch()`, and returns `202` without waiting for rules or Sessions. Use it when a deployment needs authenticated GitHub ingress for the generic webhook runtime. +`dsh-experimental-webhook-github` registers one exact HTTP route on the injected `ctx.webServer`. It bounds and verifies GitHub's raw JSON body, projects a provider-neutral delivery, calls `ctx.webhookRuntime.dispatch()`, and returns `202` without waiting for rules or Sessions. Use it when a deployment needs authenticated GitHub ingress for the generic webhook runtime. ## Table of Contents @@ -56,10 +56,12 @@ Only `POST application/json` is accepted. The adapter reads a bounded UTF-8 body The normal Web profile already owns `ctx.webServer`. Mount another `dsh-host-webserver` and this adapter inside a group that isolates only `webServer`; the adapter still inherits credentials and `webhookRuntime`. The [GitHub review guide](../../../docs/user/guide/github-review.md) uses `127.0.0.1:3081/github` behind a TLS reverse proxy while the UI remains on port 3080. +The package distributes the example overlay and rule module under `examples/github-review/`. Install this package and its `dsh-experimental-webhook` peer into the profile before loading that installed overlay; the [guide](../../../docs/user/guide/github-review.md) gives the complete commands. + ## Model Experience -Indirectly, through `dsh-webhook`: this adapter contributes no prompt or tool schema; a matching rule owns the Session request and model-visible text. +Indirectly, through `dsh-experimental-webhook`: this adapter contributes no prompt or tool schema; a matching rule owns the Session request and model-visible text. #### KV Cache effect diff --git a/packages/webhook/webhook-github/README.zh.md b/packages/experimental/webhook-github/README.zh.md similarity index 78% rename from packages/webhook/webhook-github/README.zh.md rename to packages/experimental/webhook-github/README.zh.md index 5d2221e06d..91421abe32 100644 --- a/packages/webhook/webhook-github/README.zh.md +++ b/packages/experimental/webhook-github/README.zh.md @@ -3,13 +3,13 @@ description: "面向把已认证 JSON 事件路由到 webhook 运行时的部署 kind: "package-reference" --- -# @deepseek-ai/dsh-webhook-github +# @deepseek-ai/dsh-experimental-webhook-github [English](README.md) | 中文 ## 概述 -`dsh-webhook-github` 会在注入的 `ctx.webServer` 上注册一条精确 HTTP 路由。它限制并验证 GitHub 原始 JSON body,投影提供方无关的交付,调用 `ctx.webhookRuntime.dispatch()`,并在不等待规则或会话的情况下返回 `202`。部署需要为通用 webhook 运行时提供经过身份验证的 GitHub 入口时,请使用它。 +`dsh-experimental-webhook-github` 会在注入的 `ctx.webServer` 上注册一条精确 HTTP 路由。它限制并验证 GitHub 原始 JSON body,投影提供方无关的交付,调用 `ctx.webhookRuntime.dispatch()`,并在不等待规则或会话的情况下返回 `202`。部署需要为通用 webhook 运行时提供经过身份验证的 GitHub 入口时,请使用它。 ## 目录 @@ -56,10 +56,12 @@ kind: "package-reference" 普通 Web profile 已经拥有 `ctx.webServer`。把另一个 `dsh-host-webserver` 和此适配器挂载到仅隔离 `webServer` 的 group 内;适配器仍会继承凭据与 `webhookRuntime`。[GitHub 评审指南](../../../docs/user/guide/github-review.zh.md)在 TLS 反向代理后使用 `127.0.0.1:3081/github`,而 UI 继续位于端口 3080。 +示例的 overlay 与规则模块随本包发布,位于 `examples/github-review/`。先将本包及其 `dsh-experimental-webhook` peer 安装到 profile,再从该安装目录加载 overlay;[指南](../../../docs/user/guide/github-review.zh.md)给出完整命令。 + ## 模型体验 -通过 `dsh-webhook` 间接产生影响:此适配器不贡献提示词或工具 schema;匹配规则拥有会话请求与模型可见文本。 +通过 `dsh-experimental-webhook` 间接产生影响:此适配器不贡献提示词或工具 schema;匹配规则拥有会话请求与模型可见文本。 #### KV Cache 影响 diff --git a/apps/cli/config/examples/github-review/cordis.yml b/packages/experimental/webhook-github/examples/github-review/cordis.yml similarity index 85% rename from apps/cli/config/examples/github-review/cordis.yml rename to packages/experimental/webhook-github/examples/github-review/cordis.yml index 71466d6e9f..de2abcbf97 100644 --- a/apps/cli/config/examples/github-review/cordis.yml +++ b/packages/experimental/webhook-github/examples/github-review/cordis.yml @@ -3,13 +3,13 @@ - insert: - id: webhook-runtime - name: '@deepseek-ai/dsh-webhook' + name: '@deepseek-ai/dsh-experimental-webhook' - id: github-ready-review-rule name: './github-ready-review-rule.mjs' config: source: primary-github - repository: deepseek-ai/deepseek-harness + repository: deepseek-harness/deepseek-harness workspacePath: !!js process.env.DSH_GITHUB_REVIEW_WORKSPACE ?? process.cwd() agentPreset: standard permissionPreset: read-only @@ -27,7 +27,7 @@ port: !!js Number(process.env.DSH_GITHUB_WEBHOOK_PORT ?? 3081) - id: github-webhook-adapter - name: '@deepseek-ai/dsh-webhook-github' + name: '@deepseek-ai/dsh-experimental-webhook-github' config: source: primary-github path: /github diff --git a/apps/cli/config/examples/github-review/github-ready-review-rule.mjs b/packages/experimental/webhook-github/examples/github-review/github-ready-review-rule.mjs similarity index 97% rename from apps/cli/config/examples/github-review/github-ready-review-rule.mjs rename to packages/experimental/webhook-github/examples/github-review/github-ready-review-rule.mjs index 3b055269fd..084a9df7e8 100644 --- a/apps/cli/config/examples/github-review/github-ready-review-rule.mjs +++ b/packages/experimental/webhook-github/examples/github-review/github-ready-review-rule.mjs @@ -1,5 +1,5 @@ import z from '@deepseek-ai/schemastery' -import { WebhookRuleId } from '@deepseek-ai/dsh-webhook' +import { WebhookRuleId } from '@deepseek-ai/dsh-experimental-webhook' export const name = 'github-ready-review-rule' export const inject = ['webhookRuntime'] diff --git a/packages/webhook/webhook-github/package.json b/packages/experimental/webhook-github/package.json similarity index 77% rename from packages/webhook/webhook-github/package.json rename to packages/experimental/webhook-github/package.json index 4ed729ff5e..83f616fc7a 100644 --- a/packages/webhook/webhook-github/package.json +++ b/packages/experimental/webhook-github/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-webhook-github", + "name": "@deepseek-ai/dsh-experimental-webhook-github", "description": "Signed GitHub HTTP webhook adapter for the DeepSeek Harness webhook runtime", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/webhook/webhook-github" + "directory": "packages/experimental/webhook-github" }, "type": "module", "main": "lib/index.js", @@ -23,10 +23,13 @@ "default": "./lib/types/types.js" }, "./src/*": "./src/*", - "./package.json": "./package.json" + "./package.json": "./package.json", + "./examples/*": "./examples/*" }, "files": [ "lib/index.js", + "examples/github-review/cordis.yml", + "examples/github-review/github-ready-review-rule.mjs", "lib/types/**/*.js", "lib/types/**/*.d.ts" ], @@ -36,7 +39,7 @@ "@deepseek-ai/dsh-credentials": "workspace:*", "@deepseek-ai/dsh-host-webserver": "workspace:*", "@deepseek-ai/dsh-session": "workspace:*", - "@deepseek-ai/dsh-webhook": "workspace:*" + "@deepseek-ai/dsh-experimental-webhook": "workspace:*" }, "dependencies": { "@deepseek-ai/dsh-util-values": "workspace:*", @@ -50,6 +53,6 @@ "@deepseek-ai/dsh-credentials": "workspace:*", "@deepseek-ai/dsh-host-webserver": "workspace:*", "@deepseek-ai/dsh-session": "workspace:*", - "@deepseek-ai/dsh-webhook": "workspace:*" + "@deepseek-ai/dsh-experimental-webhook": "workspace:*" } } diff --git a/packages/webhook/webhook-github/src/body.ts b/packages/experimental/webhook-github/src/body.ts similarity index 100% rename from packages/webhook/webhook-github/src/body.ts rename to packages/experimental/webhook-github/src/body.ts diff --git a/packages/webhook/webhook-github/src/handler.ts b/packages/experimental/webhook-github/src/handler.ts similarity index 99% rename from packages/webhook/webhook-github/src/handler.ts rename to packages/experimental/webhook-github/src/handler.ts index d4ea1fcefa..7c036f6320 100644 --- a/packages/webhook/webhook-github/src/handler.ts +++ b/packages/experimental/webhook-github/src/handler.ts @@ -9,7 +9,7 @@ import { WebhookDeliveryId, WebhookSourceId, type VerifiedWebhookDelivery, -} from '@deepseek-ai/dsh-webhook' +} from '@deepseek-ai/dsh-experimental-webhook' import type { WebRoute } from '@deepseek-ai/dsh-host-webserver' import { readBoundedUtf8Body, WebhookHttpError } from './body.ts' import type { GitHubJsonObject } from './types.ts' diff --git a/packages/webhook/webhook-github/src/index.ts b/packages/experimental/webhook-github/src/index.ts similarity index 100% rename from packages/webhook/webhook-github/src/index.ts rename to packages/experimental/webhook-github/src/index.ts diff --git a/packages/webhook/webhook-github/src/types.ts b/packages/experimental/webhook-github/src/types.ts similarity index 92% rename from packages/webhook/webhook-github/src/types.ts rename to packages/experimental/webhook-github/src/types.ts index 151b2ef715..533a7d9a36 100644 --- a/packages/webhook/webhook-github/src/types.ts +++ b/packages/experimental/webhook-github/src/types.ts @@ -13,7 +13,7 @@ export interface GitHubWebhookEvent { readonly payload: GitHubJsonObject } -declare module '@deepseek-ai/dsh-webhook' { +declare module '@deepseek-ai/dsh-experimental-webhook' { interface WebhookEventMap { github: GitHubWebhookEvent } diff --git a/packages/webhook/webhook-github/tests/body.spec.ts b/packages/experimental/webhook-github/tests/body.spec.ts similarity index 100% rename from packages/webhook/webhook-github/tests/body.spec.ts rename to packages/experimental/webhook-github/tests/body.spec.ts diff --git a/packages/webhook/webhook-github/tests/config.spec.ts b/packages/experimental/webhook-github/tests/config.spec.ts similarity index 100% rename from packages/webhook/webhook-github/tests/config.spec.ts rename to packages/experimental/webhook-github/tests/config.spec.ts diff --git a/packages/webhook/webhook-github/tests/handler.spec.ts b/packages/experimental/webhook-github/tests/handler.spec.ts similarity index 100% rename from packages/webhook/webhook-github/tests/handler.spec.ts rename to packages/experimental/webhook-github/tests/handler.spec.ts diff --git a/packages/webhook/webhook-github/tests/loader-composition.spec.ts b/packages/experimental/webhook-github/tests/loader-composition.spec.ts similarity index 95% rename from packages/webhook/webhook-github/tests/loader-composition.spec.ts rename to packages/experimental/webhook-github/tests/loader-composition.spec.ts index 5316e9e35a..5a3fd23d98 100644 --- a/packages/webhook/webhook-github/tests/loader-composition.spec.ts +++ b/packages/experimental/webhook-github/tests/loader-composition.spec.ts @@ -30,7 +30,7 @@ describe('real Loader composition', () => { ' config:', " host: '127.0.0.1'", ' port: 0', - "- name: '@deepseek-ai/dsh-webhook-github'", + "- name: '@deepseek-ai/dsh-experimental-webhook-github'", ' config:', ' source: loader', ' path: /github', @@ -56,7 +56,7 @@ describe('real Loader composition', () => { const modules = new Map([ ['fixture-dependencies', dependencies], ['@deepseek-ai/dsh-host-webserver', WebServer], - ['@deepseek-ai/dsh-webhook-github', GitHubAdapter], + ['@deepseek-ai/dsh-experimental-webhook-github', GitHubAdapter], ]) context.loader.internal = { version: 'v2', diff --git a/packages/webhook/webhook-github/tsconfig.json b/packages/experimental/webhook-github/tsconfig.json similarity index 100% rename from packages/webhook/webhook-github/tsconfig.json rename to packages/experimental/webhook-github/tsconfig.json diff --git a/packages/experimental/webhook/README.i18n.yaml b/packages/experimental/webhook/README.i18n.yaml new file mode 100644 index 0000000000..9c6f312918 --- /dev/null +++ b/packages/experimental/webhook/README.i18n.yaml @@ -0,0 +1,46 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/webhook/README.md +/: + en: e4ac1bc2fef159c0 + zh: a2d724d2cffb6608 +/deepseek-ai-dsh-experimental-webhook: + en: 26532180f2b36a85 + zh: 2975d07b79822215 +/deepseek-ai-dsh-experimental-webhook/summary: + en: 9bb80560acedf068 + zh: 8cdb82333d601b61 +/deepseek-ai-dsh-experimental-webhook/table-of-contents: + en: 2c6f2175556251ee + zh: 753d216d980e1735 +/deepseek-ai-dsh-experimental-webhook/rule-interface: + en: d9674188535399ab + zh: c52fe9b7ebe8fe79 +/deepseek-ai-dsh-experimental-webhook/session-request: + en: e4d096efc8633575 + zh: b1bf7d45fe76c380 +/deepseek-ai-dsh-experimental-webhook/composition: + en: 6a19f22997772945 + zh: b92bec411e0406bc +/deepseek-ai-dsh-experimental-webhook/model-experience: + en: 215e7ba838619b7b + zh: a311da3843709f90 +/deepseek-ai-dsh-experimental-webhook/model-experience/rule-authored-initial-prompt: + en: d9d6f7525ae75c28 + zh: 981d9ea68b9e884b +/deepseek-ai-dsh-experimental-webhook/model-experience/rule-authored-initial-prompt/what-the-model-sees: + en: 44859d5d877a1484 + zh: 0f6c96ff6435167b +/deepseek-ai-dsh-experimental-webhook/model-experience/rule-authored-initial-prompt/token-effect: + en: 13937f95014a6bea + zh: c61031459298c4ab +/deepseek-ai-dsh-experimental-webhook/model-experience/rule-authored-initial-prompt/kv-cache-effect: + en: 88b78de3ce71698f + zh: d13964bad7485d4e +/deepseek-ai-dsh-experimental-webhook/known-limitations-and-deferred-work: + en: 49d9bd7c7c327cc0 + zh: ab94de11bbda1936 +/deepseek-ai-dsh-experimental-webhook/known-limitations-and-deferred-work/dev-note: + en: e67f633dc6fe7773 + zh: e88aeb617ffb74ea diff --git a/packages/webhook/webhook/README.md b/packages/experimental/webhook/README.md similarity index 91% rename from packages/webhook/webhook/README.md rename to packages/experimental/webhook/README.md index 685bf3befa..0d677fb149 100644 --- a/packages/webhook/webhook/README.md +++ b/packages/experimental/webhook/README.md @@ -3,13 +3,13 @@ description: "Webhook rule runtime for maintainers registering trusted external- kind: "package-reference" --- -# @deepseek-ai/dsh-webhook +# @deepseek-ai/dsh-experimental-webhook English | [中文](README.zh.md) ## Summary -`dsh-webhook` provides the Host `ctx.webhookRuntime`: a registry for trusted programmatic webhook rules plus the one built-in action, creating an ordinary root Session inside a Web Workspace. The interface stays at `register(rule)` and `dispatch(delivery)`; provider authentication belongs to adapter packages. Use it when a trusted rule must turn an external event into a new agent Session. +`dsh-experimental-webhook` provides the Host `ctx.webhookRuntime`: a registry for trusted programmatic webhook rules plus the one built-in action, creating an ordinary root Session inside a Web Workspace. The interface stays at `register(rule)` and `dispatch(delivery)`; provider authentication belongs to adapter packages. Use it when a trusted rule must turn an external event into a new agent Session. ## Table of Contents diff --git a/packages/webhook/webhook/README.zh.md b/packages/experimental/webhook/README.zh.md similarity index 90% rename from packages/webhook/webhook/README.zh.md rename to packages/experimental/webhook/README.zh.md index db0801fcbd..bbca16b436 100644 --- a/packages/webhook/webhook/README.zh.md +++ b/packages/experimental/webhook/README.zh.md @@ -3,13 +3,13 @@ description: "面向注册可信外部事件策略并创建 Workspace 会话的 kind: "package-reference" --- -# @deepseek-ai/dsh-webhook +# @deepseek-ai/dsh-experimental-webhook [English](README.md) | 中文 ## 概述 -`dsh-webhook` 提供 Host 侧的 `ctx.webhookRuntime`:它既是受信任程序化 webhook 规则的注册表,也拥有唯一内置动作——在 Web Workspace 中创建普通根会话。接口只包含 `register(rule)` 和 `dispatch(delivery)`;提供方身份验证属于适配器包。当受信任规则必须把外部事件变成新的 agent(智能体)会话时,请使用它。 +`dsh-experimental-webhook` 提供 Host 侧的 `ctx.webhookRuntime`:它既是受信任程序化 webhook 规则的注册表,也拥有唯一内置动作——在 Web Workspace 中创建普通根会话。接口只包含 `register(rule)` 和 `dispatch(delivery)`;提供方身份验证属于适配器包。当受信任规则必须把外部事件变成新的 agent(智能体)会话时,请使用它。 ## 目录 diff --git a/packages/webhook/webhook/package.json b/packages/experimental/webhook/package.json similarity index 95% rename from packages/webhook/webhook/package.json rename to packages/experimental/webhook/package.json index aaf20b1be7..65b68563d7 100644 --- a/packages/webhook/webhook/package.json +++ b/packages/experimental/webhook/package.json @@ -1,5 +1,5 @@ { - "name": "@deepseek-ai/dsh-webhook", + "name": "@deepseek-ai/dsh-experimental-webhook", "description": "Fire-and-forget webhook rule runtime that creates Workspace-backed DeepSeek Harness Sessions", "version": "0.2.1-alpha.1", "publishConfig": { @@ -8,7 +8,7 @@ "repository": { "type": "git", "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", - "directory": "packages/webhook/webhook" + "directory": "packages/experimental/webhook" }, "type": "module", "main": "lib/index.js", diff --git a/packages/webhook/webhook/src/brand.ts b/packages/experimental/webhook/src/brand.ts similarity index 100% rename from packages/webhook/webhook/src/brand.ts rename to packages/experimental/webhook/src/brand.ts diff --git a/packages/webhook/webhook/src/index.ts b/packages/experimental/webhook/src/index.ts similarity index 100% rename from packages/webhook/webhook/src/index.ts rename to packages/experimental/webhook/src/index.ts diff --git a/packages/webhook/webhook/src/session.ts b/packages/experimental/webhook/src/session.ts similarity index 100% rename from packages/webhook/webhook/src/session.ts rename to packages/experimental/webhook/src/session.ts diff --git a/packages/webhook/webhook/src/types.ts b/packages/experimental/webhook/src/types.ts similarity index 100% rename from packages/webhook/webhook/src/types.ts rename to packages/experimental/webhook/src/types.ts diff --git a/packages/webhook/webhook/tests/loader-composition.spec.ts b/packages/experimental/webhook/tests/loader-composition.spec.ts similarity index 96% rename from packages/webhook/webhook/tests/loader-composition.spec.ts rename to packages/experimental/webhook/tests/loader-composition.spec.ts index 1ddd743910..b3c1b9629d 100644 --- a/packages/webhook/webhook/tests/loader-composition.spec.ts +++ b/packages/experimental/webhook/tests/loader-composition.spec.ts @@ -28,7 +28,7 @@ describe('real Loader composition', () => { const configPath = join(root, 'cordis.yml') await writeFile(configPath, [ '- name: fixture-dependencies', - "- name: '@deepseek-ai/dsh-webhook'", + "- name: '@deepseek-ai/dsh-experimental-webhook'", '- name: fixture-rule', '', ].join('\n')) @@ -65,7 +65,7 @@ describe('real Loader composition', () => { context.loader.builtins.include = Include const modules = new Map([ ['fixture-dependencies', dependencies], - ['@deepseek-ai/dsh-webhook', WebhookRuntime], + ['@deepseek-ai/dsh-experimental-webhook', WebhookRuntime], ['fixture-rule', rule], ]) context.loader.internal = { diff --git a/packages/webhook/webhook/tests/runtime.spec.ts b/packages/experimental/webhook/tests/runtime.spec.ts similarity index 100% rename from packages/webhook/webhook/tests/runtime.spec.ts rename to packages/experimental/webhook/tests/runtime.spec.ts diff --git a/packages/webhook/webhook/tests/session.spec.ts b/packages/experimental/webhook/tests/session.spec.ts similarity index 100% rename from packages/webhook/webhook/tests/session.spec.ts rename to packages/experimental/webhook/tests/session.spec.ts diff --git a/packages/webhook/webhook/tsconfig.json b/packages/experimental/webhook/tsconfig.json similarity index 100% rename from packages/webhook/webhook/tsconfig.json rename to packages/experimental/webhook/tsconfig.json diff --git a/packages/hooks/README.i18n.yaml b/packages/hooks/README.i18n.yaml deleted file mode 100644 index babf03e0ab..0000000000 --- a/packages/hooks/README.i18n.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/hooks/README.md -/: - en: d66bed32f14204db - zh: 71dfbd7adec88262 -/packages-hooks: - en: c7be9e13f2038f5d - zh: 348d34f2f6f63641 -/packages-hooks/summary: - en: 878fda232af5ba6b - zh: 30f93c4fcf0919b6 -/packages-hooks/table-of-contents: - en: 1eb35b015a6c423f - zh: a8a3dceee2c9e943 -/packages-hooks/packages: - en: d6fc8d4395a61393 - zh: e010dfac4e3f1e9b -/packages-hooks/related-documentation: - en: 9b4c979f72e1faa6 - zh: ff676cfe1fa00957 -/packages-hooks/dev-note: - en: 5de1d6304e00c58f - zh: 8d8225361cfa29e5 diff --git a/packages/hooks/README.md b/packages/hooks/README.md deleted file mode 100644 index 1e4459d986..0000000000 --- a/packages/hooks/README.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: "The hooks group map: run existing Claude Code and Codex shell-hook configs during agent runs, for users and maintainers navigating the group." -kind: "package-group" ---- - -# packages/hooks - -English | [中文](README.zh.md) - -## Summary - -The hooks group lets agent runs reuse shell hooks written for Claude Code or Codex. Point the matching integration at an existing `hooks.json` to run supported command hooks when sessions start, prompts arrive, tools run, or runs stop. These hooks can block prompts or tool calls with model-visible messages, add conversation context, or require the run to continue. Choose this group to preserve existing hook configurations; each integration supports only the command-hook subset documented by its source tool. - -## Table of Contents - -- [Packages](#packages) -- [Related documentation](#related-documentation) -- [Dev Note](#dev-note) - ------ - - -## Packages - -| Package | Role | Shape | -|---|---|---| -| [`hook-protocol`](hook-protocol/README.md) | Shared hook engine both bridges use; never configured directly | library | -| [`hooks-claude-code`](hooks-claude-code/README.md) | Run your existing Claude Code `hooks.json` hooks during agent runs | plugin | -| [`hooks-codex`](hooks-codex/README.md) | Run your existing Codex `hooks.json` hooks during agent runs | plugin | - ------ - - -## Related documentation - -- [Interception extension-points reference](../../docs/tool-execution-pipeline.md) — the typed-Decision surface the bridges program against. -- [Hook bridges Agent Note](../../.agents/notes/archived/feature/2026-06-30-hook-bridges.md) — the bridge design and its decision mapping. -- [Hook protocol library Agent Note](../../.agents/notes/archived/feature/2026-06-30-hook-protocol-lib.md) — what the shared library owns and why. - ------ - - -## Dev Note - -
-Working context for maintainers — click to expand - -None. - -
diff --git a/packages/hooks/README.zh.md b/packages/hooks/README.zh.md deleted file mode 100644 index 81e5769cac..0000000000 --- a/packages/hooks/README.zh.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -description: "hooks 组地图:在 agent(智能体)运行期间使用现有的 Claude Code 与 Codex shell 钩子配置,供浏览本组的用户与维护者阅读。" -kind: "package-group" ---- - -# packages/hooks - -[English](README.md) | 中文 - -## 概述 - -hooks 组让 agent 运行可以复用为 Claude Code 或 Codex 编写的 shell 钩子。把对应集成指向现有的 `hooks.json`,即可在会话开始、提示词到达、工具运行或运行停止时执行受支持的 command hook。这些钩子可以用模型可见消息阻止提示词或工具调用、向对话添加上下文,或要求运行继续。当你需要保留现有钩子配置时,选择本组;每项集成只支持其来源工具所记录的 command hook 子集。 - -## 目录 - -- [包](#packages) -- [相关文档](#related-documentation) -- [开发备注](#dev-note) - ------ - - -## 包 - -| 包 | 职责 | 形态 | -|---|---|---| -| [`hook-protocol`](hook-protocol/README.zh.md) | 两个桥接共享的钩子引擎;不得直接配置 | 库 | -| [`hooks-claude-code`](hooks-claude-code/README.zh.md) | 在 agent 运行期间运行你现有的 Claude Code `hooks.json` 钩子 | 插件 | -| [`hooks-codex`](hooks-codex/README.zh.md) | 在 agent 运行期间运行你现有的 Codex `hooks.json` 钩子 | 插件 | - ------ - - -## 相关文档 - -- [拦截扩展点 参考](../../docs/tool-execution-pipeline.zh.md)——桥接所面向的类型化 Decision 接口面。 -- [钩子桥接 Agent Note](../../.agents/notes/archived/feature/2026-06-30-hook-bridges.md)——桥接设计及其决策映射。 -- [钩子协议库 Agent Note](../../.agents/notes/archived/feature/2026-06-30-hook-protocol-lib.md)——共享库负责的内容及其原因。 - ------ - - -## 开发备注 - -
-维护者的工作上下文——点击展开 - -无。 - -
diff --git a/packages/hooks/hook-protocol/README.i18n.yaml b/packages/hooks/hook-protocol/README.i18n.yaml deleted file mode 100644 index 001fcad228..0000000000 --- a/packages/hooks/hook-protocol/README.i18n.yaml +++ /dev/null @@ -1,61 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/hooks/hook-protocol/README.md -/: - en: 7cfe3761eedff848 - zh: 80b0bed5743d0924 -/deepseek-ai-dsh-hook-protocol: - en: bcf8ec6c43311fb7 - zh: 4ef45c5aaced087d -/deepseek-ai-dsh-hook-protocol/summary: - en: e8ab847d0db16043 - zh: 5c1e72f4b4a54fe1 -/deepseek-ai-dsh-hook-protocol/table-of-contents: - en: d152484eb41ac6b4 - zh: 09388d293f9be9cb -/deepseek-ai-dsh-hook-protocol/use-this-package: - en: 4b29a18ac60be5bb - zh: 4a02b48f9e914101 -/deepseek-ai-dsh-hook-protocol/use-this-package/when-to-choose-it: - en: 435c1a335f8dfccf - zh: efe58c06dc40d4d9 -/deepseek-ai-dsh-hook-protocol/use-this-package/what-a-hook-can-do: - en: 043f54b3a5b518a7 - zh: a4115083a9b1cef1 -/deepseek-ai-dsh-hook-protocol/use-this-package/what-you-see-when-hooks-run: - en: ba2d6ed1db063f53 - zh: ab1b8d72dccd2ff1 -/deepseek-ai-dsh-hook-protocol/understand-the-implementation: - en: 08b3960150e9c5e2 - zh: 6bb2f236d697de01 -/deepseek-ai-dsh-hook-protocol/understand-the-implementation/processing-pipeline: - en: f71878539d98392e - zh: 826a0dd95475fff3 -/deepseek-ai-dsh-hook-protocol/understand-the-implementation/hook-session-events: - en: f01ab4ab98f052b3 - zh: 1da25fa50378bd19 -/deepseek-ai-dsh-hook-protocol/understand-the-implementation/design-philosophy: - en: 7f9239eaea5a945c - zh: 9ba6a2ea955d4934 -/deepseek-ai-dsh-hook-protocol/understand-the-implementation/source-map: - en: 0d8956a6d8608ee0 - zh: 9f554284c4c0a36e -/deepseek-ai-dsh-hook-protocol/further-exploration: - en: 65a937c4c5f221d5 - zh: 3b9d6485493dfb8d -/deepseek-ai-dsh-hook-protocol/model-experience: - en: 53d2f59435a4a88f - zh: 79c8fc2849b20718 -/deepseek-ai-dsh-hook-protocol/model-experience/kv-cache-effect: - en: e290ccc9b3c92c08 - zh: cb3c8823f41e7afe -/deepseek-ai-dsh-hook-protocol/known-limitations-and-deferred-work: - en: 1ca6146a077a7d2d - zh: 369741569178fc79 -/deepseek-ai-dsh-hook-protocol/known-limitations-and-deferred-work/dev-note: - en: ac1d08360a93382b - zh: 6c58749bae9a6e65 -/deepseek-ai-dsh-hook-protocol/known-limitations-and-deferred-work/dev-note/future-run-level-halt: - en: bfb3db50de22c1d0 - zh: 2a979359b0edbbe7 diff --git a/packages/hooks/hooks-claude-code/README.i18n.yaml b/packages/hooks/hooks-claude-code/README.i18n.yaml deleted file mode 100644 index 136e11d2ab..0000000000 --- a/packages/hooks/hooks-claude-code/README.i18n.yaml +++ /dev/null @@ -1,88 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/hooks/hooks-claude-code/README.md -/: - en: 3570440302708236 - zh: 6e4217f2856879a1 -/deepseek-ai-dsh-hooks-claude-code: - en: 75bf646e3e8954d0 - zh: b03df967b39b5b1a -/deepseek-ai-dsh-hooks-claude-code/summary: - en: fd56bd2d9107d126 - zh: de7e8358840e23b1 -/deepseek-ai-dsh-hooks-claude-code/table-of-contents: - en: d152484eb41ac6b4 - zh: 09388d293f9be9cb -/deepseek-ai-dsh-hooks-claude-code/use-this-package: - en: 7534e384c3ba85f2 - zh: dd28c3a11d096796 -/deepseek-ai-dsh-hooks-claude-code/use-this-package/when-to-choose-it: - en: 5fdf4ff17e6d9a2e - zh: 82979c137758005d -/deepseek-ai-dsh-hooks-claude-code/use-this-package/smallest-working-setup: - en: b2724490aee1f8e0 - zh: abbcb0eebb3207a4 -/deepseek-ai-dsh-hooks-claude-code/use-this-package/what-your-hooks-can-do: - en: 6c3b126e6607c311 - zh: 33199f443edb2824 -/deepseek-ai-dsh-hooks-claude-code/use-this-package/how-hooks-run-and-fail: - en: d2da19a016554a19 - zh: 5c579bc80b04e7a4 -/deepseek-ai-dsh-hooks-claude-code/understand-the-implementation: - en: d33ddd080880b3f5 - zh: 64328f5239c26752 -/deepseek-ai-dsh-hooks-claude-code/understand-the-implementation/hook-point-mapping: - en: d315f54ec60f8860 - zh: 53b7a6531d9f4bbb -/deepseek-ai-dsh-hooks-claude-code/understand-the-implementation/payloads-and-environment: - en: 0389b516653c7f45 - zh: 15ec2182113a9aa4 -/deepseek-ai-dsh-hooks-claude-code/understand-the-implementation/matcher-subjects-and-serial-execution: - en: 0f30690502687688 - zh: 19d4ec653c19f00e -/deepseek-ai-dsh-hooks-claude-code/understand-the-implementation/detached-runs-and-disposal: - en: b04f07b845653345 - zh: 9159c4a908e292cb -/deepseek-ai-dsh-hooks-claude-code/understand-the-implementation/design-philosophy: - en: e9dc2e482e9a7b50 - zh: 5fa4e92b75884f93 -/deepseek-ai-dsh-hooks-claude-code/understand-the-implementation/source-map: - en: 0289ee9e374d3606 - zh: b88841c10ad5c10f -/deepseek-ai-dsh-hooks-claude-code/further-exploration: - en: fd35632dd0c80b8f - zh: e51f95219a580723 -/deepseek-ai-dsh-hooks-claude-code/model-experience: - en: 215e7ba838619b7b - zh: a311da3843709f90 -/deepseek-ai-dsh-hooks-claude-code/model-experience/hook-provided-context: - en: 7b2f5028dacd7146 - zh: e4d226735f7abfc2 -/deepseek-ai-dsh-hooks-claude-code/model-experience/hook-provided-context/what-the-model-sees: - en: 7b6edde085633c5f - zh: caadcfe8b9364c6d -/deepseek-ai-dsh-hooks-claude-code/model-experience/hook-provided-context/token-effect: - en: b70e3524b160cd63 - zh: e1011ee18d1bf12b -/deepseek-ai-dsh-hooks-claude-code/model-experience/hook-provided-context/kv-cache-effect: - en: f5d5f97a153f7c70 - zh: f681f89596f500f5 -/deepseek-ai-dsh-hooks-claude-code/model-experience/blocked-prompt-or-tool-outcome: - en: 82be8d95921ef639 - zh: 11c185068ec18932 -/deepseek-ai-dsh-hooks-claude-code/model-experience/blocked-prompt-or-tool-outcome/what-the-model-sees: - en: 1313b662532a2bda - zh: 4002d38540286a94 -/deepseek-ai-dsh-hooks-claude-code/model-experience/blocked-prompt-or-tool-outcome/token-effect: - en: 7c13e10d2a0e3151 - zh: 54ffd88bca4fce3a -/deepseek-ai-dsh-hooks-claude-code/model-experience/blocked-prompt-or-tool-outcome/kv-cache-effect: - en: f84fa6c0511cd113 - zh: f6ce9cdd47a72684 -/deepseek-ai-dsh-hooks-claude-code/known-limitations-and-deferred-work: - en: 23ab8cf19542ea03 - zh: e56f896b4393c1c5 -/deepseek-ai-dsh-hooks-claude-code/known-limitations-and-deferred-work/dev-note: - en: b1e9a373ae8b7bb0 - zh: 30446fe59d5ec8be diff --git a/packages/hooks/hooks-codex/README.i18n.yaml b/packages/hooks/hooks-codex/README.i18n.yaml deleted file mode 100644 index 2ce0e98852..0000000000 --- a/packages/hooks/hooks-codex/README.i18n.yaml +++ /dev/null @@ -1,88 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/hooks/hooks-codex/README.md -/: - en: 9ee4cd57e234a8ff - zh: 59e5d8f84fa762ff -/deepseek-ai-dsh-hooks-codex: - en: d3c2f23b8348572e - zh: 507dc13c5c4c16b2 -/deepseek-ai-dsh-hooks-codex/summary: - en: e02e93d326449402 - zh: 5de5f527d2182537 -/deepseek-ai-dsh-hooks-codex/table-of-contents: - en: d152484eb41ac6b4 - zh: 09388d293f9be9cb -/deepseek-ai-dsh-hooks-codex/use-this-package: - en: ea8333ed6fbca7f3 - zh: a08be14b26816d95 -/deepseek-ai-dsh-hooks-codex/use-this-package/when-to-choose-it: - en: 44d77bc8d948bc6d - zh: 81afaf977570f4ef -/deepseek-ai-dsh-hooks-codex/use-this-package/smallest-working-setup: - en: 2b8374fe112d8125 - zh: 9067b8cb714e911b -/deepseek-ai-dsh-hooks-codex/use-this-package/what-your-hooks-can-do: - en: dee90142e7e87214 - zh: 8d83d7e0208ba1ef -/deepseek-ai-dsh-hooks-codex/use-this-package/how-hooks-run-and-fail: - en: f373e44302e514d0 - zh: 7fc88478ec7047a4 -/deepseek-ai-dsh-hooks-codex/understand-the-implementation: - en: d33ddd080880b3f5 - zh: 64328f5239c26752 -/deepseek-ai-dsh-hooks-codex/understand-the-implementation/hook-point-mapping: - en: 755ca39231841ffc - zh: 30e793dfaf11a336 -/deepseek-ai-dsh-hooks-codex/understand-the-implementation/payloads-and-environment: - en: 542413d7e8cfeaf4 - zh: 3b5d0d3fdd0231f2 -/deepseek-ai-dsh-hooks-codex/understand-the-implementation/matcher-subjects-and-serial-execution: - en: fd52c0eb70bf0094 - zh: 6415f109fbd763d3 -/deepseek-ai-dsh-hooks-codex/understand-the-implementation/detached-runs-and-disposal: - en: b45f1eafa8f4f467 - zh: a073a76e1d7670e6 -/deepseek-ai-dsh-hooks-codex/understand-the-implementation/design-philosophy: - en: 6f882aab3d924115 - zh: 7ed83a6d16a22c77 -/deepseek-ai-dsh-hooks-codex/understand-the-implementation/source-map: - en: 8f74796cf859a750 - zh: be4dd22dccba1782 -/deepseek-ai-dsh-hooks-codex/further-exploration: - en: a99ee322c3462a1d - zh: 2695c45b3152e915 -/deepseek-ai-dsh-hooks-codex/model-experience: - en: 215e7ba838619b7b - zh: a311da3843709f90 -/deepseek-ai-dsh-hooks-codex/model-experience/hook-provided-context: - en: 7b2f5028dacd7146 - zh: e4d226735f7abfc2 -/deepseek-ai-dsh-hooks-codex/model-experience/hook-provided-context/what-the-model-sees: - en: 3f94df641a34a437 - zh: 21bc5823229dbb6c -/deepseek-ai-dsh-hooks-codex/model-experience/hook-provided-context/token-effect: - en: b70e3524b160cd63 - zh: e1011ee18d1bf12b -/deepseek-ai-dsh-hooks-codex/model-experience/hook-provided-context/kv-cache-effect: - en: f5d5f97a153f7c70 - zh: f681f89596f500f5 -/deepseek-ai-dsh-hooks-codex/model-experience/blocked-prompt-or-tool-outcome: - en: 82be8d95921ef639 - zh: 11c185068ec18932 -/deepseek-ai-dsh-hooks-codex/model-experience/blocked-prompt-or-tool-outcome/what-the-model-sees: - en: fd44027de2255f3f - zh: d880eb4d2d3f6af8 -/deepseek-ai-dsh-hooks-codex/model-experience/blocked-prompt-or-tool-outcome/token-effect: - en: 7c13e10d2a0e3151 - zh: 54ffd88bca4fce3a -/deepseek-ai-dsh-hooks-codex/model-experience/blocked-prompt-or-tool-outcome/kv-cache-effect: - en: f84fa6c0511cd113 - zh: f6ce9cdd47a72684 -/deepseek-ai-dsh-hooks-codex/known-limitations-and-deferred-work: - en: 11c88847e78bdbc5 - zh: dea334c689116d0f -/deepseek-ai-dsh-hooks-codex/known-limitations-and-deferred-work/dev-note: - en: 5f03857c3bb6834a - zh: 54f485d08db9020f diff --git a/packages/session/README.i18n.yaml b/packages/session/README.i18n.yaml index d8787fe5d0..4da1820901 100644 --- a/packages/session/README.i18n.yaml +++ b/packages/session/README.i18n.yaml @@ -24,14 +24,14 @@ en: 706441e1ab2fa853 zh: a7fa44caab3ddada /session-durable-session-data-plane/packages/titles: - en: b59b3cf49aef2a4b - zh: d6078f3c96e4f5d1 + en: ca5da2f0648e6246 + zh: cda50ccf5f245153 /session-durable-session-data-plane/packages/telemetry: en: e0edfc0566463495 zh: 4af9904d7ba97d97 /session-durable-session-data-plane/related-documentation: - en: 8f0b13af3a3602bd - zh: 76707f543684b36f + en: 9380a0278b1453e8 + zh: 6cf3e8d1e5e9f27a /session-durable-session-data-plane/dev-note: en: b75c8458928b72b9 zh: 003ba4e17b4b5269 diff --git a/packages/session/README.md b/packages/session/README.md index de3ad68bd2..7230f81bd8 100644 --- a/packages/session/README.md +++ b/packages/session/README.md @@ -57,7 +57,6 @@ The group splits into four families: durable storage (persistence seam, backends | [`session-title/`](session-title/README.md) | Log-backed session titles with a deterministic fallback and one optional provider | `ctx.sessionTitle` | | [`session-title-llm/`](session-title-llm/README.md) | Shared model-backed title-generation policy for the provider packages | library — no ctx key | | [`session-title-first-prompt-llm/`](session-title-first-prompt-llm/README.md) | Titles a session from its first eligible human message | registers on `ctx.sessionTitle` | -| [`session-title-all-prompts-llm/`](session-title-all-prompts-llm/README.md) | Titles a session from all eligible human messages | registers on `ctx.sessionTitle` | ### Telemetry @@ -80,6 +79,8 @@ Only one title provider may register at a time; without one, the title service k - [Session telemetry subsystem](../../docs/subsystems/session-telemetry.md) — capture, redaction, and delivery modes. - [Session subsystem](../../docs/subsystems/session.md) — the live event log every package in this group persists or derives from. +See [`session-title-all-prompts-llm`](../experimental/session-title-all-prompts-llm/README.md) for the experimental optional capability. + ## Dev Note diff --git a/packages/session/README.zh.md b/packages/session/README.zh.md index dd18899cae..35cc5ff4c2 100644 --- a/packages/session/README.zh.md +++ b/packages/session/README.zh.md @@ -57,7 +57,6 @@ session 组让对话持久保存,恢复已发布的日志格式,并使已提 | [`session-title/`](session-title/README.zh.md) | 基于日志的会话标题,带确定性回退与一个可选提供方 | `ctx.sessionTitle` | | [`session-title-llm/`](session-title-llm/README.zh.md) | 供提供方包共享的模型标题生成策略 | 库,不使用 ctx key | | [`session-title-first-prompt-llm/`](session-title-first-prompt-llm/README.zh.md) | 根据第一条合格的人类消息为会话生成标题 | 注册到 `ctx.sessionTitle` | -| [`session-title-all-prompts-llm/`](session-title-all-prompts-llm/README.zh.md) | 根据所有合格的人类消息为会话生成标题 | 注册到 `ctx.sessionTitle` | ### 遥测 @@ -80,6 +79,8 @@ session 组让对话持久保存,恢复已发布的日志格式,并使已提 - [会话遥测子系统](../../docs/subsystems/session-telemetry.zh.md)——捕获、脱敏与投递模式。 - [会话子系统](../../docs/subsystems/session.zh.md)——本组每个包持久化或派生的实时事件日志。 +实验性可选能力见 [`session-title-all-prompts-llm`](../experimental/session-title-all-prompts-llm/README.zh.md)。 + ## 开发备注 diff --git a/packages/session/session-title-all-prompts-llm/README.i18n.yaml b/packages/session/session-title-all-prompts-llm/README.i18n.yaml deleted file mode 100644 index 1f92051cb8..0000000000 --- a/packages/session/session-title-all-prompts-llm/README.i18n.yaml +++ /dev/null @@ -1,64 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/session/session-title-all-prompts-llm/README.md -/: - en: 0718b02e4cdd4cc6 - zh: 2b5b4a729ce4d97e -/deepseek-ai-dsh-session-title-all-prompts-llm: - en: 14b9552b617bc7a9 - zh: 9253c5d935bff697 -/deepseek-ai-dsh-session-title-all-prompts-llm/summary: - en: 9f64c4dd5e30f1c8 - zh: 35cf397596083be5 -/deepseek-ai-dsh-session-title-all-prompts-llm/table-of-contents: - en: d152484eb41ac6b4 - zh: 09388d293f9be9cb -/deepseek-ai-dsh-session-title-all-prompts-llm/use-this-package: - en: 2c0bccf753fe70eb - zh: 36b96a547ddddfc1 -/deepseek-ai-dsh-session-title-all-prompts-llm/use-this-package/when-titles-are-generated: - en: 3c9e14df96e6000e - zh: a13f12a3df426380 -/deepseek-ai-dsh-session-title-all-prompts-llm/use-this-package/configuration: - en: 1965c9ce7dedb2e7 - zh: 9b9c9b68af995b51 -/deepseek-ai-dsh-session-title-all-prompts-llm/use-this-package/failures-and-recovery: - en: 6077a4665a4edb87 - zh: 539c4e5969f9bb9b -/deepseek-ai-dsh-session-title-all-prompts-llm/understand-the-implementation: - en: 506933ffa7745b7d - zh: a9bb6f06a32b7c18 -/deepseek-ai-dsh-session-title-all-prompts-llm/understand-the-implementation/design-concept: - en: 2c307e1480e5c319 - zh: 60c7394728f7ff9c -/deepseek-ai-dsh-session-title-all-prompts-llm/understand-the-implementation/source-map: - en: e7ae42597cc501a6 - zh: 2e55e9b293b25958 -/deepseek-ai-dsh-session-title-all-prompts-llm/understand-the-implementation/scheduling: - en: ca23821924af2b14 - zh: a384479d5e69b0f8 -/deepseek-ai-dsh-session-title-all-prompts-llm/further-exploration: - en: 05c91c92fa3b1c7d - zh: 8e90078647bdb018 -/deepseek-ai-dsh-session-title-all-prompts-llm/model-experience: - en: 215e7ba838619b7b - zh: a311da3843709f90 -/deepseek-ai-dsh-session-title-all-prompts-llm/model-experience/all-messages-title-request: - en: 42380e2d029288cf - zh: e9c9f21ac00e3c9d -/deepseek-ai-dsh-session-title-all-prompts-llm/model-experience/all-messages-title-request/what-the-model-sees: - en: 39cb7059a3ab1fe6 - zh: a3fd93ac52f12a43 -/deepseek-ai-dsh-session-title-all-prompts-llm/model-experience/all-messages-title-request/token-effect: - en: 1a075b8073c16ce3 - zh: a51ff16156f9c137 -/deepseek-ai-dsh-session-title-all-prompts-llm/model-experience/all-messages-title-request/kv-cache-effect: - en: 6a70f43f38b8c075 - zh: 2b823aff93344134 -/deepseek-ai-dsh-session-title-all-prompts-llm/known-limitations-and-deferred-work: - en: d0486c65afaebb85 - zh: 186a77e0d68bd968 -/deepseek-ai-dsh-session-title-all-prompts-llm/known-limitations-and-deferred-work/dev-note: - en: e67f633dc6fe7773 - zh: 3bb0c20c93f16f98 diff --git a/packages/session/session-title-first-prompt-llm/README.i18n.yaml b/packages/session/session-title-first-prompt-llm/README.i18n.yaml index 5165240f5b..85d05058d9 100644 --- a/packages/session/session-title-first-prompt-llm/README.i18n.yaml +++ b/packages/session/session-title-first-prompt-llm/README.i18n.yaml @@ -39,8 +39,8 @@ en: a79488f550380f5e zh: 0ca8a457084c0fca /deepseek-ai-dsh-session-title-first-prompt-llm/further-exploration: - en: 5ba595b20a534949 - zh: 3c26ead34d3d06bd + en: a70619b36cdd416e + zh: d40851bb696c0efc /deepseek-ai-dsh-session-title-first-prompt-llm/model-experience: en: 215e7ba838619b7b zh: a311da3843709f90 diff --git a/packages/session/session-title-first-prompt-llm/README.md b/packages/session/session-title-first-prompt-llm/README.md index 29a01e8e26..a7b10be560 100644 --- a/packages/session/session-title-first-prompt-llm/README.md +++ b/packages/session/session-title-first-prompt-llm/README.md @@ -73,7 +73,7 @@ The title service schedules automatic work: for the `first-prompt` cadence it st Read these pages when the provider contract is not enough. They move from the shared policy to the alternative cadence and the service it plugs into. - [Shared LLM title policy](../session-title-llm/README.md) — the generation helper this provider uses. -- [All-messages title provider](../session-title-all-prompts-llm/README.md) — the cadence that retitles after every new prompt. +- [All-messages title provider](../../experimental/session-title-all-prompts-llm/README.md) — the cadence that retitles after every new prompt. - [Session title service](../session-title/README.md) — fallback behavior, rename, refresh, and provider registration. - [Session package map](../README.md) — adjacent persistence, projection, title, and telemetry packages. diff --git a/packages/session/session-title-first-prompt-llm/README.zh.md b/packages/session/session-title-first-prompt-llm/README.zh.md index 8a60d132bb..ceac9f8c91 100644 --- a/packages/session/session-title-first-prompt-llm/README.zh.md +++ b/packages/session/session-title-first-prompt-llm/README.zh.md @@ -73,7 +73,7 @@ kind: "package-reference" 当提供方约定不够用时阅读以下页面。它们从共享策略逐步进入替代节奏与它所插入的服务。 - [共享 LLM 标题策略](../session-title-llm/README.zh.md)——此提供方使用的生成辅助模块。 -- [全消息标题提供方](../session-title-all-prompts-llm/README.zh.md)——在每条新提示词后重新生成标题的节奏。 +- [全消息标题提供方](../../experimental/session-title-all-prompts-llm/README.zh.md)——在每条新提示词后重新生成标题的节奏。 - [会话标题服务](../session-title/README.zh.md)——回退行为、重命名、刷新与提供方注册。 - [会话包映射](../README.zh.md)——相邻的持久化、投影、标题与遥测包。 diff --git a/packages/session/session-title-llm/README.i18n.yaml b/packages/session/session-title-llm/README.i18n.yaml index 87458171b5..fcceb0daa5 100644 --- a/packages/session/session-title-llm/README.i18n.yaml +++ b/packages/session/session-title-llm/README.i18n.yaml @@ -15,8 +15,8 @@ en: d152484eb41ac6b4 zh: 09388d293f9be9cb /deepseek-ai-dsh-session-title-llm/use-this-package: - en: fa90841c0783ae27 - zh: 8fbd293f8050d345 + en: 6ea51316a841bce7 + zh: df455b74ac9d4a91 /deepseek-ai-dsh-session-title-llm/use-this-package/registering-a-provider: en: cf61c021b1bdb52f zh: dac17588e4143815 @@ -39,8 +39,8 @@ en: 4a4ca58e3ae2e075 zh: daf4a642d815833b /deepseek-ai-dsh-session-title-llm/further-exploration: - en: 641f31c35c48916b - zh: 8e809fbdfef61b61 + en: d9844c0fc3e16c5c + zh: 1e0c0b4b5d566972 /deepseek-ai-dsh-session-title-llm/model-experience: en: 215e7ba838619b7b zh: a311da3843709f90 diff --git a/packages/session/session-title-llm/README.md b/packages/session/session-title-llm/README.md index 9bca311f63..3833a904f5 100644 --- a/packages/session/session-title-llm/README.md +++ b/packages/session/session-title-llm/README.md @@ -25,7 +25,7 @@ English | [中文](README.zh.md) ## Use this package -As a deployment, configure this policy through the [first-prompt](../session-title-first-prompt-llm/README.md) or [all-prompts](../session-title-all-prompts-llm/README.md) provider plugin. As a provider author, register through the shared helper instead of hand-rolling generation. +As a deployment, configure this policy through the [first-prompt](../session-title-first-prompt-llm/README.md) or [all-prompts](../../experimental/session-title-all-prompts-llm/README.md) provider plugin. As a provider author, register through the shared helper instead of hand-rolling generation. ### Registering a provider @@ -86,7 +86,7 @@ Read these pages when the generation policy is not enough. They move from the se - [Session title service](../session-title/README.md) — the title service, fallback behavior, and provider registration contract. - [Session title subsystem](../../../docs/subsystems/session-title.md) — durable title state and the auxiliary request record. - [First-message title provider](../session-title-first-prompt-llm/README.md) — titles from the first eligible human message. -- [All-messages title provider](../session-title-all-prompts-llm/README.md) — titles from every eligible human message. +- [All-messages title provider](../../experimental/session-title-all-prompts-llm/README.md) — titles from every eligible human message. - [Session package map](../README.md) — adjacent persistence, projection, title, and telemetry packages. ----- diff --git a/packages/session/session-title-llm/README.zh.md b/packages/session/session-title-llm/README.zh.md index d79fae09ea..81c4c6d4a5 100644 --- a/packages/session/session-title-llm/README.zh.md +++ b/packages/session/session-title-llm/README.zh.md @@ -25,7 +25,7 @@ kind: "package-library" ## 使用本包 -作为部署方,通过[首消息](../session-title-first-prompt-llm/README.zh.md)或[全消息](../session-title-all-prompts-llm/README.zh.md)提供方插件配置此策略。作为提供方作者,通过共享辅助函数注册,而不是手写生成逻辑。 +作为部署方,通过[首消息](../session-title-first-prompt-llm/README.zh.md)或[全消息](../../experimental/session-title-all-prompts-llm/README.zh.md)提供方插件配置此策略。作为提供方作者,通过共享辅助函数注册,而不是手写生成逻辑。 ### 注册提供方 @@ -86,7 +86,7 @@ kind: "package-library" - [会话标题服务](../session-title/README.zh.md)——标题服务、回退行为与提供方注册约定。 - [会话标题子系统](../../../docs/subsystems/session-title.zh.md)——持久标题状态与辅助请求记录。 - [首消息标题提供方](../session-title-first-prompt-llm/README.zh.md)——根据第一条符合条件的用户消息生成标题。 -- [全消息标题提供方](../session-title-all-prompts-llm/README.zh.md)——根据所有符合条件的用户消息生成标题。 +- [全消息标题提供方](../../experimental/session-title-all-prompts-llm/README.zh.md)——根据所有符合条件的用户消息生成标题。 - [会话包映射](../README.zh.md)——相邻的持久化、投影、标题与遥测包。 ----- diff --git a/packages/session/session-title/README.i18n.yaml b/packages/session/session-title/README.i18n.yaml index b1de0743f3..3b2871b1a2 100644 --- a/packages/session/session-title/README.i18n.yaml +++ b/packages/session/session-title/README.i18n.yaml @@ -24,8 +24,8 @@ en: f72239b38a91783b zh: 07e22375c09906a6 /deepseek-ai-dsh-session-title/use-this-package/adding-a-provider: - en: 2e1e7b56a1f26478 - zh: 750800b2d9e73595 + en: a1cdb4d0faf16f67 + zh: 2107c5abf6cb0ff2 /deepseek-ai-dsh-session-title/use-this-package/reading-titles: en: 34148c23c20ee6f4 zh: b0d10677722f3f63 @@ -48,8 +48,8 @@ en: 0fa22531683cc824 zh: c6379873eb809e76 /deepseek-ai-dsh-session-title/further-exploration: - en: 8b405b3bb2abf7cd - zh: 71e8a58bfae99a36 + en: 7e0e5c9491acf9e5 + zh: df1fec7ecc66a47b /deepseek-ai-dsh-session-title/model-experience: en: 215e7ba838619b7b zh: a311da3843709f90 diff --git a/packages/session/session-title/README.md b/packages/session/session-title/README.md index 09778e4e2b..090a80c0ef 100644 --- a/packages/session/session-title/README.md +++ b/packages/session/session-title/README.md @@ -54,7 +54,7 @@ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-a ### Adding a provider -One optional asynchronous provider may be registered through `ctx.sessionTitle.register(provider)`; a second registration throws. The shipped model-backed providers are [first-prompt](../session-title-first-prompt-llm/README.md) and [all-prompts](../session-title-all-prompts-llm/README.md), both using the shared [LLM generation policy](../session-title-llm/README.md). A provider starts only after a marked loop-built request's exact route matches the logged `request/header`, and a newer revision supersedes and aborts older work. +One optional asynchronous provider may be registered through `ctx.sessionTitle.register(provider)`; a second registration throws. The shipped model-backed providers are [first-prompt](../session-title-first-prompt-llm/README.md) and [all-prompts](../../experimental/session-title-all-prompts-llm/README.md), both using the shared [LLM generation policy](../session-title-llm/README.md). A provider starts only after a marked loop-built request's exact route matches the logged `request/header`, and a newer revision supersedes and aborts older work. ### Reading titles @@ -106,7 +106,7 @@ Read these pages when the service contract is not enough. They move from the sub - [Session title subsystem](../../../docs/subsystems/session-title.md) — durable title state and the provider vocabulary types. - [Shared LLM title policy](../session-title-llm/README.md) — the model-backed generation helper both shipped providers use. - [First-message title provider](../session-title-first-prompt-llm/README.md) — titles from the first eligible human message. -- [All-messages title provider](../session-title-all-prompts-llm/README.md) — titles from every eligible human message. +- [All-messages title provider](../../experimental/session-title-all-prompts-llm/README.md) — titles from every eligible human message. - [Session package map](../README.md) — adjacent persistence, projection, title, and telemetry packages. ----- diff --git a/packages/session/session-title/README.zh.md b/packages/session/session-title/README.zh.md index db9efaa2ab..ee5e25e846 100644 --- a/packages/session/session-title/README.zh.md +++ b/packages/session/session-title/README.zh.md @@ -54,7 +54,7 @@ kind: "package-reference" ### 添加提供方 -可选异步提供方可通过 `ctx.sessionTitle.register(provider)` 注册一个;第二次注册会立即抛出。随附的模型支持提供方是[首消息](../session-title-first-prompt-llm/README.zh.md)与[全消息](../session-title-all-prompts-llm/README.zh.md),两者都使用共享的 [LLM(大语言模型)生成策略](../session-title-llm/README.zh.md)。提供方只有在带标记、由循环构建的请求的确切路由与已记录 `request/header` 匹配时才启动,较新的修订会取代并中止旧工作。 +可选异步提供方可通过 `ctx.sessionTitle.register(provider)` 注册一个;第二次注册会立即抛出。随附的模型支持提供方是[首消息](../session-title-first-prompt-llm/README.zh.md)与[全消息](../../experimental/session-title-all-prompts-llm/README.zh.md),两者都使用共享的 [LLM(大语言模型)生成策略](../session-title-llm/README.zh.md)。提供方只有在带标记、由循环构建的请求的确切路由与已记录 `request/header` 匹配时才启动,较新的修订会取代并中止旧工作。 ### 读取标题 @@ -106,7 +106,7 @@ kind: "package-reference" - [会话标题子系统](../../../docs/subsystems/session-title.zh.md)——持久标题状态与提供方词汇类型。 - [共享 LLM 标题策略](../session-title-llm/README.zh.md)——两个随附提供方共用的模型生成辅助模块。 - [首消息标题提供方](../session-title-first-prompt-llm/README.zh.md)——根据第一条符合条件的用户消息生成标题。 -- [全消息标题提供方](../session-title-all-prompts-llm/README.zh.md)——根据所有符合条件的用户消息生成标题。 +- [全消息标题提供方](../../experimental/session-title-all-prompts-llm/README.zh.md)——根据所有符合条件的用户消息生成标题。 - [会话包映射](../README.zh.md)——相邻的持久化、投影、标题与遥测包。 ----- diff --git a/packages/shell/tool-bash-persistent/README.i18n.yaml b/packages/shell/tool-bash-persistent/README.i18n.yaml index 870921df88..ab0611f17b 100644 --- a/packages/shell/tool-bash-persistent/README.i18n.yaml +++ b/packages/shell/tool-bash-persistent/README.i18n.yaml @@ -42,8 +42,8 @@ en: 3b7bf7c20b266c31 zh: 85a325ef65fa7ac7 /deepseek-ai-dsh-tool-bash-persistent/further-exploration: - en: 3a700d3333442a0c - zh: 67fb851aaf297d27 + en: 42c387ccaab7e64c + zh: e58ec4ea60cf7711 /deepseek-ai-dsh-tool-bash-persistent/model-experience: en: 215e7ba838619b7b zh: a311da3843709f90 diff --git a/packages/shell/tool-bash-persistent/README.md b/packages/shell/tool-bash-persistent/README.md index c8c8922c55..22ea00bed1 100644 --- a/packages/shell/tool-bash-persistent/README.md +++ b/packages/shell/tool-bash-persistent/README.md @@ -99,7 +99,7 @@ Read these pages when the package-level contract is not enough. They move from t - [terminal package map](../../terminal/README.md) — the persistent PTY capability family. - [terminal seam](../../terminal/terminal/README.md) — the `ctx.terminals` service behind the tool. - [terminal-bash backend](../../terminal/terminal-bash/README.md) — the default `shell` backend. -- [tool-terminal](../../terminal/tool-terminal/README.md) — six model-facing terminal tools for interactive work. +- [tool-terminal](../../experimental/tool-terminal/README.md) — six model-facing terminal tools for interactive work. - [Persistent PTY sessions Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md) — the owner-scoped session design and its rationale. - [Generated tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-tool-bash-persistent) — the exact `bash` argument schema. - [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-tool-bash-persistent) — every accepted config field and its source declaration. diff --git a/packages/shell/tool-bash-persistent/README.zh.md b/packages/shell/tool-bash-persistent/README.zh.md index 01fe3787fd..c51bb4a00f 100644 --- a/packages/shell/tool-bash-persistent/README.zh.md +++ b/packages/shell/tool-bash-persistent/README.zh.md @@ -99,7 +99,7 @@ kind: "package-reference" - [terminal 包映射](../../terminal/README.zh.md)——持久 PTY 能力家族。 - [terminal seam](../../terminal/terminal/README.zh.md)——工具背后的 `ctx.terminals` 服务。 - [terminal-bash 后端](../../terminal/terminal-bash/README.zh.md)——默认的 `shell` 后端。 -- [tool-terminal](../../terminal/tool-terminal/README.zh.md)——面向交互工作的六个模型侧 terminal 工具。 +- [tool-terminal](../../experimental/tool-terminal/README.zh.md)——面向交互工作的六个模型侧 terminal 工具。 - [持久 PTY 会话 Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md)——按所有者会话的设计及其理由。 - [生成的工具目录](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-bash-persistent)——`bash` 参数 schema 的确切内容。 - [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-tool-bash-persistent)——每个受支持配置字段及其源声明。 diff --git a/packages/skill/README.i18n.yaml b/packages/skill/README.i18n.yaml index 310d471918..56604614c2 100644 --- a/packages/skill/README.i18n.yaml +++ b/packages/skill/README.i18n.yaml @@ -9,17 +9,17 @@ en: 0b439cfc74ac0737 zh: fd4f28f03ac7c06c /skill-skill-capability-family/summary: - en: 3119b70ce39aa67a - zh: ca05b86efbf84141 + en: 7cbda887d3e37854 + zh: bbbc87a2c443c47e /skill-skill-capability-family/table-of-contents: en: 1eb35b015a6c423f zh: a8a3dceee2c9e943 /skill-skill-capability-family/packages: - en: c539cb44637a4415 - zh: e327e6dc6c84bf60 + en: 4b67afb3d4d24fbc + zh: e90e882d4e1f5bfd /skill-skill-capability-family/related-documentation: - en: d81019bb266350c7 - zh: c652588415e5dd92 + en: eb122812eb6640d5 + zh: 18a46fd45e7994a6 /skill-skill-capability-family/dev-note: en: 5de1d6304e00c58f zh: 8d8225361cfa29e5 diff --git a/packages/skill/README.md b/packages/skill/README.md index 459eed7bb2..04aaf0089d 100644 --- a/packages/skill/README.md +++ b/packages/skill/README.md @@ -9,7 +9,7 @@ English | [中文](README.zh.md) ## Summary -The skill family lets agents and users discover and load reusable task instructions only when needed. Use `skill/` to combine catalogs and expose one instruction set per name; choose `skill-filesystem` for project, custom, or user-directory discovery, `skill-badge` for the optional official badge, and `skill-office` for Word, PowerPoint, and Excel workflows. Add `tool-skill` when models should receive a sorted, durable session catalog, load full instructions through the `skill` tool, or accept direct `/name` invocation. Different sources produce the same model-visible format, and model access requires at least one source. +The skill family lets agents and users discover and load reusable task instructions only when needed. Use `skill/` to combine catalogs and expose one instruction set per name; choose `skill-filesystem` for project, custom, or user-directory discovery, `skill-office` for Word, PowerPoint, and Excel workflows. Add `tool-skill` when models should receive a sorted, durable session catalog, load full instructions through the `skill` tool, or accept direct `/name` invocation. Different sources produce the same model-visible format, and model access requires at least one source. ## Table of Contents @@ -26,7 +26,6 @@ The skill family lets agents and users discover and load reusable task instructi |---|---|---| | [`skill/`](skill/README.md) | Registry that merges skill catalogs from any provider and resolves the winning skill for a name | `ctx.skills` | | [`skill-filesystem/`](skill-filesystem/README.md) | Discovers skills from project, custom, and user directories and watches them for changes | registers on `ctx.skills` | -| [`skill-badge/`](skill-badge/README.md) | Bundles the official "powered by dsh" badge skill, disabled by default | registers on `ctx.skills` | | [`skill-office/`](skill-office/README.md) | Bundles Word, PowerPoint, and Excel workflows with structural file checks | registers on `ctx.skills` | | [`tool-skill/`](tool-skill/README.md) | Publishes the session skill catalog and the model-facing `skill` loader tool | registers on `ctx.tools` | | [`tool-workspace-dependencies/`](tool-workspace-dependencies/README.md) | Reports bundled Office interpreter paths and versions for Desktop and SDK carriers | registers on `ctx.tools` | @@ -43,6 +42,8 @@ Start with the subsystem reference for the shared vocabulary, then read the Agen ----- +See [`skill-badge`](../experimental/skill-badge/README.md) for the experimental optional capability. + ## Dev Note diff --git a/packages/skill/README.zh.md b/packages/skill/README.zh.md index 2949622c91..6b2f5abde9 100644 --- a/packages/skill/README.zh.md +++ b/packages/skill/README.zh.md @@ -9,7 +9,7 @@ kind: "package-group" ## 概述 -skill 家族让 agent 和用户仅在需要时发现并加载可复用的任务指令。使用 `skill/` 合并目录并为每个名称提供一组指令;需要从项目、自定义或用户目录发现 skill 时选择 `skill-filesystem`,需要可选的官方徽章时选择 `skill-badge`,需要 Word、PowerPoint 和 Excel 工作流时选择 `skill-office`。需要让模型获得排序且持久的会话目录、通过 `skill` 工具加载完整指令,或接受 `/name` 直接调用时,请添加 `tool-skill`。不同来源生成相同的模型可见格式,启用模型访问前必须配置至少一个来源。 +skill 家族让 agent 和用户仅在需要时发现并加载可复用的任务指令。使用 `skill/` 合并目录并为每个名称提供一组指令;需要从项目、自定义或用户目录发现 skill 时选择 `skill-filesystem`,需要 Word、PowerPoint 和 Excel 工作流时选择 `skill-office`。需要让模型获得排序且持久的会话目录、通过 `skill` 工具加载完整指令,或接受 `/name` 直接调用时,请添加 `tool-skill`。不同来源生成相同的模型可见格式,启用模型访问前必须配置至少一个来源。 ## 目录 @@ -26,7 +26,6 @@ skill 家族让 agent 和用户仅在需要时发现并加载可复用的任务 |---|---|---| | [`skill/`](skill/README.zh.md) | 合并任意提供方的 skill 目录、并按名称解析出胜出 skill 的注册表 | `ctx.skills` | | [`skill-filesystem/`](skill-filesystem/README.zh.md) | 从项目、自定义与用户目录发现 skill,并监视其变更 | 注册到 `ctx.skills` | -| [`skill-badge/`](skill-badge/README.zh.md) | 随包附带官方「powered by dsh」徽章 skill,默认禁用 | 注册到 `ctx.skills` | | [`skill-office/`](skill-office/README.zh.md) | 随包提供 Word、PowerPoint 和 Excel 工作流及文件结构检查 | 注册到 `ctx.skills` | | [`tool-skill/`](tool-skill/README.zh.md) | 发布会话 skill 目录与面向模型的 `skill` 加载工具 | 注册到 `ctx.tools` | | [`tool-workspace-dependencies/`](tool-workspace-dependencies/README.zh.md) | 为 Desktop 与 SDK 载体报告内置 Office 解释器路径和版本 | 注册到 `ctx.tools` | @@ -43,6 +42,8 @@ skill 家族让 agent 和用户仅在需要时发现并加载可复用的任务 ----- +实验性可选能力见 [`skill-badge`](../experimental/skill-badge/README.zh.md)。 + ## 开发备注 diff --git a/packages/skill/skill-badge/README.i18n.yaml b/packages/skill/skill-badge/README.i18n.yaml deleted file mode 100644 index 230a31d901..0000000000 --- a/packages/skill/skill-badge/README.i18n.yaml +++ /dev/null @@ -1,55 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/skill/skill-badge/README.md -/: - en: c32f79a869ebd48a - zh: 44e64fb59fa75e57 -/deepseek-ai-dsh-skill-badge: - en: 173ba0ed0aa79510 - zh: 8b0cb7a81db06283 -/deepseek-ai-dsh-skill-badge/summary: - en: ccb1ebcc64163d39 - zh: 3c89c981873e3b5e -/deepseek-ai-dsh-skill-badge/table-of-contents: - en: d152484eb41ac6b4 - zh: 09388d293f9be9cb -/deepseek-ai-dsh-skill-badge/use-this-package: - en: a559a5ed8a76e342 - zh: 6558f9af8d6c9625 -/deepseek-ai-dsh-skill-badge/use-this-package/when-to-choose-it: - en: a3276561ace9e681 - zh: d2541ab4846fefa2 -/deepseek-ai-dsh-skill-badge/use-this-package/enable-the-plugin: - en: fbee982ca0bbcf25 - zh: b3e802857d784384 -/deepseek-ai-dsh-skill-badge/use-this-package/what-the-badge-skill-provides: - en: 7144db5613266a9b - zh: d1b7edf6c1253e9a -/deepseek-ai-dsh-skill-badge/use-this-package/observable-success-and-failures: - en: 1b3c8501e0899f1e - zh: 909684f272051d5f -/deepseek-ai-dsh-skill-badge/understand-the-implementation: - en: 63465b0133f30e85 - zh: 84bebb7c1fe0ceba -/deepseek-ai-dsh-skill-badge/understand-the-implementation/design-concept: - en: 52ff92fad6d26ee9 - zh: 071c7859c158513d -/deepseek-ai-dsh-skill-badge/understand-the-implementation/source-map: - en: 259b9b2073da8ddd - zh: e0d621f0a3b0470c -/deepseek-ai-dsh-skill-badge/further-exploration: - en: 1b5434b8bcbd5b0b - zh: d170cddf3837e655 -/deepseek-ai-dsh-skill-badge/model-experience: - en: b9912bc3f1ba0680 - zh: e288cc67b6d079f6 -/deepseek-ai-dsh-skill-badge/model-experience/kv-cache-effect: - en: 6a8366520852a607 - zh: 453ec29827b82bbc -/deepseek-ai-dsh-skill-badge/known-limitations-and-deferred-work: - en: c7e405ebbc1d4602 - zh: 05a57fb4359da265 -/deepseek-ai-dsh-skill-badge/known-limitations-and-deferred-work/dev-note: - en: e67f633dc6fe7773 - zh: 3bb0c20c93f16f98 diff --git a/packages/terminal/README.i18n.yaml b/packages/terminal/README.i18n.yaml index 81ab999d6f..1379be4cf2 100644 --- a/packages/terminal/README.i18n.yaml +++ b/packages/terminal/README.i18n.yaml @@ -9,17 +9,17 @@ en: 23811d44b564b29d zh: a74d2f7625f5f6dd /terminal-persistent-pty-capability-family/summary: - en: 46a33b055e27a19a - zh: 63be22dcced5db81 + en: 07d4e06f5d65348a + zh: d2f9bc7efa388659 /terminal-persistent-pty-capability-family/table-of-contents: en: 1eb35b015a6c423f zh: a8a3dceee2c9e943 /terminal-persistent-pty-capability-family/packages: - en: 5e04c5c04ff4133b - zh: 55913a1fc3537342 + en: f024e6265bf65cd9 + zh: 6ff2b362466513f5 /terminal-persistent-pty-capability-family/related-documentation: - en: 2abf795bb34e5aea - zh: a268d0d5bb74e4d7 + en: a6b75a7138b492dc + zh: c0417c9fb9ed69f0 /terminal-persistent-pty-capability-family/dev-note: en: 5de1d6304e00c58f zh: 8d8225361cfa29e5 diff --git a/packages/terminal/README.md b/packages/terminal/README.md index 3f63b1b1f8..a00e9339bf 100644 --- a/packages/terminal/README.md +++ b/packages/terminal/README.md @@ -9,7 +9,7 @@ English | [中文](README.zh.md) ## Summary -The `terminal/` family lets agents keep interactive shell and REPL sessions alive across tool calls, including the working directory, environment variables, and running child processes. Use `terminal/` for owner-isolated session management, `terminal-bash/` for sandboxed interactive bash or pwsh sessions, and `tool-terminal/` for six model-facing terminal operations with bounded results. Choose this family when a task needs interactive input or state that a one-shot bash command cannot retain. Sessions remain local to one harness process and do not survive a restart. +The `terminal/` family lets agents keep interactive shell and REPL sessions alive across tool calls, including the working directory, environment variables, and running child processes. Use `terminal/` for owner-isolated session management, `terminal-bash/` for sandboxed interactive bash or pwsh sessions. Choose this family when a task needs interactive input or state that a one-shot bash command cannot retain. Sessions remain local to one harness process and do not survive a restart. ## Table of Contents @@ -28,7 +28,6 @@ The family is one session service, one shell backend, and one set of model-facin |---|---|---| | [`terminal/`](terminal/README.md) | Session service: owner-scoped sessions with opaque ids, exact-owner fencing, and awaited cleanup | `ctx.terminals` | | [`terminal-bash/`](terminal-bash/README.md) | Shell backend: interactive bash or pwsh under the shared sandbox policy, with readiness detection and bounded output | registers a backend on `ctx.terminals` | -| [`tool-terminal/`](tool-terminal/README.md) | Six model-facing tools with owner isolation and optional background sends | registers on `ctx.tools` | ----- @@ -41,6 +40,8 @@ Start with the subsystem reference for the shared types and the service surface, - [Persistent PTY Agent Note](../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md) — the design decision, alternatives, and deferred work. - [Capability seams](../../docs/capability-seams.md) — the Service Definition / Service Provider / Consumer split this family follows. +See [`tool-terminal`](../experimental/tool-terminal/README.md) for the experimental optional capability. + ## Dev Note diff --git a/packages/terminal/README.zh.md b/packages/terminal/README.zh.md index a3c21d9f90..d55d08946b 100644 --- a/packages/terminal/README.zh.md +++ b/packages/terminal/README.zh.md @@ -9,7 +9,7 @@ kind: "package-group" ## 概述 -`terminal/` 家族让 agent(智能体)的交互式 shell 和 REPL 会话跨工具调用持续存在,包括工作目录、环境变量和运行中的子进程。使用 `terminal/` 管理所有者隔离的会话,使用 `terminal-bash/` 启动受沙箱约束的交互式 bash 或 pwsh 会话,使用 `tool-terminal/` 获得 6 个结果有界的面向模型终端操作。任务需要交互式输入或需要保留单次 bash 命令无法保存的状态时,选择这个家族。会话仅存在于一个 harness 进程中,重启后不会恢复。 +`terminal/` 家族让 agent(智能体)的交互式 shell 和 REPL 会话跨工具调用持续存在,包括工作目录、环境变量和运行中的子进程。使用 `terminal/` 管理所有者隔离的会话,使用 `terminal-bash/` 启动受沙箱约束的交互式 bash 或 pwsh 会话。任务需要交互式输入或需要保留单次 bash 命令无法保存的状态时,选择这个家族。会话仅存在于一个 harness 进程中,重启后不会恢复。 ## 目录 @@ -28,7 +28,6 @@ kind: "package-group" |---|---|---| | [`terminal/`](terminal/README.zh.md) | 会话服务:限定所有者范围的会话、不透明 id、精确到所有者的限制与等待完成的清理 | `ctx.terminals` | | [`terminal-bash/`](terminal-bash/README.zh.md) | shell 后端:在共享沙箱策略下启动交互式 bash 或 pwsh,带就绪检测与有界输出 | 注册后端到 `ctx.terminals` | -| [`tool-terminal/`](tool-terminal/README.zh.md) | 6 个面向模型的工具,带所有者隔离与可选后台发送 | 注册到 `ctx.tools` | ----- @@ -41,6 +40,8 @@ kind: "package-group" - [持久 PTY Agent Note](../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md)——设计决策、备选方案与延期工作。 - [能力 seam](../../docs/capability-seams.zh.md)——本家族遵循的 Service Definition / Service Provider / Consumer 拆分。 +实验性可选能力见 [`tool-terminal`](../experimental/tool-terminal/README.zh.md)。 + ## 开发备注 diff --git a/packages/terminal/terminal-bash/README.i18n.yaml b/packages/terminal/terminal-bash/README.i18n.yaml index 6c0257fab1..b5d37d1127 100644 --- a/packages/terminal/terminal-bash/README.i18n.yaml +++ b/packages/terminal/terminal-bash/README.i18n.yaml @@ -54,8 +54,8 @@ en: a88b693ec539ac28 zh: a309bbe671166027 /deepseek-ai-dsh-terminal-bash/further-exploration: - en: 648ee87712ed5c66 - zh: 6444df8b1fabbc17 + en: 0c44b6dab2f819b7 + zh: bdd3da50d9180977 /deepseek-ai-dsh-terminal-bash/model-experience: en: 215e7ba838619b7b zh: a311da3843709f90 @@ -63,8 +63,8 @@ en: a601a3c4f5b848cd zh: ec617f79f706aaa1 /deepseek-ai-dsh-terminal-bash/model-experience/indirect-consumer/what-the-model-sees: - en: ffd1d7a3a65ce703 - zh: 6e892fb3aa6ac293 + en: 11e4eb1ce3f242d6 + zh: fc41c83b71556842 /deepseek-ai-dsh-terminal-bash/model-experience/indirect-consumer/token-effect: en: 41bd9bec80350376 zh: bdd2db111e86282f diff --git a/packages/terminal/terminal-bash/README.md b/packages/terminal/terminal-bash/README.md index 4d6fd091e7..d2d43cdd25 100644 --- a/packages/terminal/terminal-bash/README.md +++ b/packages/terminal/terminal-bash/README.md @@ -43,7 +43,7 @@ Mount the terminal service, a subprocess provider, the sandbox and policy servic - name: '@deepseek-ai/dsh-sandbox-local' - name: '@deepseek-ai/dsh-sandbox-policy' - name: '@deepseek-ai/dsh-terminal-bash' -- name: '@deepseek-ai/dsh-tool-terminal' +- name: '@deepseek-ai/dsh-experimental-tool-terminal' ``` `danger-full-access` starts the shell directly. Confined modes require a same-world `ctx.sandbox` provider: without one, the spawn fails before the shell starts. Confinement preparation receives the opening signal; cancellation prevents terminal allocation even if the provider returns later. @@ -121,7 +121,7 @@ Read these pages when the package-level contract is not enough. They move from t - [Terminal subsystem reference](../../../docs/subsystems/terminal.md) — the service contract this backend implements and the generated `ctx.terminals` surface. - [terminal service](../terminal/README.md) — backend registration, owner fencing, and cleanup semantics. -- [tool-terminal tools](../tool-terminal/README.md) — the model-facing tools that operate sessions. +- [tool-terminal tools](../../experimental/tool-terminal/README.md) — the model-facing tools that operate sessions. - [Subprocess seam](../../../docs/subsystems/subprocess.md) — the terminal primitive that owns PTY allocation and process-tree cleanup. - [Persistent PTY Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md) — the capability design and deferred boundaries. - [Persistent pwsh Agent Note](../../../.agents/notes/archived/architecture/2026-08-11-pwsh-persistent-pty.md) — the Windows substrate and the pwsh dialect. @@ -135,7 +135,7 @@ Read these pages when the package-level contract is not enough. They move from t #### What the model sees -This package registers no prompt or tool. Through `@deepseek-ai/dsh-tool-terminal` or another PTY consumer, the model may receive bounded startup output, send deltas, scrollback pages, readiness reasons, and cleanup errors. +This package registers no prompt or tool. Through `@deepseek-ai/dsh-experimental-tool-terminal` or another PTY consumer, the model may receive bounded startup output, send deltas, scrollback pages, readiness reasons, and cleanup errors. #### Token effect diff --git a/packages/terminal/terminal-bash/README.zh.md b/packages/terminal/terminal-bash/README.zh.md index 83368a0df5..7dc81e95f8 100644 --- a/packages/terminal/terminal-bash/README.zh.md +++ b/packages/terminal/terminal-bash/README.zh.md @@ -43,7 +43,7 @@ kind: "package-reference" - name: '@deepseek-ai/dsh-sandbox-local' - name: '@deepseek-ai/dsh-sandbox-policy' - name: '@deepseek-ai/dsh-terminal-bash' -- name: '@deepseek-ai/dsh-tool-terminal' +- name: '@deepseek-ai/dsh-experimental-tool-terminal' ``` `danger-full-access` 直接启动 shell。受限模式要求同一执行世界中存在 `ctx.sandbox` 提供方:缺少时,spawn 会在 shell 启动前失败。限制准备过程接收打开操作的取消信号;即使提供方稍后返回,取消仍会阻止终端分配。 @@ -121,7 +121,7 @@ Scrollback 和尚未读取的发送输出保留独立拥有的字符串,并增 - [终端子系统参考](../../../docs/subsystems/terminal.zh.md)——此后端实现的服务约定与生成的 `ctx.terminals` 接口面。 - [terminal 服务](../terminal/README.zh.md)——后端注册、所有者限制与清理语义。 -- [tool-terminal 工具](../tool-terminal/README.zh.md)——操作会话的面向模型工具。 +- [tool-terminal 工具](../../experimental/tool-terminal/README.zh.md)——操作会话的面向模型工具。 - [子进程 seam](../../../docs/subsystems/subprocess.zh.md)——负责 PTY 分配与进程树清理的终端原语。 - [持久 PTY Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md)——能力设计与暂缓边界。 - [持久 pwsh Agent Note](../../../.agents/notes/archived/architecture/2026-08-11-pwsh-persistent-pty.md)——Windows 基底与 pwsh 方言。 @@ -135,7 +135,7 @@ Scrollback 和尚未读取的发送输出保留独立拥有的字符串,并增 #### 模型看到什么 -此包不注册提示词或工具。模型通过 `@deepseek-ai/dsh-tool-terminal` 或其他 PTY 消费方可能收到有界的启动输出、发送增量、scrollback 页、就绪原因与清理错误。 +此包不注册提示词或工具。模型通过 `@deepseek-ai/dsh-experimental-tool-terminal` 或其他 PTY 消费方可能收到有界的启动输出、发送增量、scrollback 页、就绪原因与清理错误。 #### Token 影响 diff --git a/packages/terminal/terminal/README.i18n.yaml b/packages/terminal/terminal/README.i18n.yaml index e51c2910e1..9c9889718a 100644 --- a/packages/terminal/terminal/README.i18n.yaml +++ b/packages/terminal/terminal/README.i18n.yaml @@ -9,14 +9,14 @@ en: 51faab4a45b4d0a3 zh: c026cbe279584a55 /deepseek-ai-dsh-terminal/summary: - en: b275cca5aa0ccbd6 - zh: 0452420c4b45c7db + en: 7f75a16057c6d9f6 + zh: 85b1cb0a5ec314b7 /deepseek-ai-dsh-terminal/table-of-contents: en: d152484eb41ac6b4 zh: 09388d293f9be9cb /deepseek-ai-dsh-terminal/use-this-package: - en: 51bfe428d2b44ee2 - zh: 557154468269985e + en: 1aa2eff13dbcb282 + zh: d56cd093b00bf9c6 /deepseek-ai-dsh-terminal/use-this-package/when-to-choose-it: en: c4244a1757ca3584 zh: b6fb10e30146b347 @@ -51,8 +51,8 @@ en: 5815723cd0c6089c zh: 0c612ffa4b8c466c /deepseek-ai-dsh-terminal/further-exploration: - en: 0e744f900665e8ad - zh: bd7b20a82fad207e + en: 8459a3b70a9f8bad + zh: 21372aa8939d2182 /deepseek-ai-dsh-terminal/model-experience: en: 215e7ba838619b7b zh: a311da3843709f90 @@ -60,14 +60,14 @@ en: a601a3c4f5b848cd zh: ec617f79f706aaa1 /deepseek-ai-dsh-terminal/model-experience/indirect-consumer/what-the-model-sees: - en: be5049f4851a1b2a - zh: 056ddf9f9f1fc112 + en: 8a6120faf56092b7 + zh: 4267a85c7d3d396f /deepseek-ai-dsh-terminal/model-experience/indirect-consumer/token-effect: en: 477da21b0a5be3a6 zh: 3ae1d37fe671ef96 /deepseek-ai-dsh-terminal/model-experience/indirect-consumer/kv-cache-effect: - en: 2d1f12c1eb4164e5 - zh: 7d22b2cd3f9649ff + en: 131c437dcc66af19 + zh: a8e095584e3c87a5 /deepseek-ai-dsh-terminal/known-limitations-and-deferred-work: en: a133ebc47a4df34f zh: 9bb949487ee566d5 diff --git a/packages/terminal/terminal/README.md b/packages/terminal/terminal/README.md index 3ad10ff7f8..0ab1f41808 100644 --- a/packages/terminal/terminal/README.md +++ b/packages/terminal/terminal/README.md @@ -9,7 +9,7 @@ English | [中文](README.zh.md) ## Summary -`dsh-terminal` provides persistent, owner-scoped terminal sessions to the harness: a session keeps shell or REPL state across tool calls, and every operation is fenced to the exact agent that created it. It provides the `ctx.terminals` service, which mints opaque session ids, routes session creation through registered backends, and waits for quiescent cleanup when an owner or the service disposes. It defines no terminal mechanics itself: backends such as the shipped `dsh-terminal-bash` own spawning and readiness, and the model-facing tools in `dsh-tool-terminal` own presentation. Sessions are process-local: they do not survive a harness restart. +`dsh-terminal` provides persistent, owner-scoped terminal sessions to the harness: a session keeps shell or REPL state across tool calls, and every operation is fenced to the exact agent that created it. It provides the `ctx.terminals` service, which mints opaque session ids, routes session creation through registered backends, and waits for quiescent cleanup when an owner or the service disposes. It defines no terminal mechanics itself: backends such as the shipped `dsh-terminal-bash` own spawning and readiness, and the model-facing tools in `dsh-experimental-tool-terminal` own presentation. Sessions are process-local: they do not survive a harness restart. ## Table of Contents @@ -25,7 +25,7 @@ English | [中文](README.zh.md) ## Use this package -Mount `@deepseek-ai/dsh-terminal` whenever a composition needs terminal sessions whose state survives across tool calls. The service alone does nothing useful: pair it with a backend such as `@deepseek-ai/dsh-terminal-bash` and a tool package such as `@deepseek-ai/dsh-tool-terminal`, and load all three in one composition. +Mount `@deepseek-ai/dsh-terminal` whenever a composition needs terminal sessions whose state survives across tool calls. The service alone does nothing useful: pair it with a backend such as `@deepseek-ai/dsh-terminal-bash` and a tool package such as `@deepseek-ai/dsh-experimental-tool-terminal`, and load all three in one composition. ### When to choose it @@ -38,7 +38,7 @@ Load the session service together with a backend and a tool package: ```yaml - name: '@deepseek-ai/dsh-terminal' - name: '@deepseek-ai/dsh-terminal-bash' -- name: '@deepseek-ai/dsh-tool-terminal' +- name: '@deepseek-ai/dsh-experimental-tool-terminal' ``` A backend provides one stable type — the shipped shell backend provides `shell` — and the tools open sessions by that type. The shell backend additionally requires the sandbox, sandbox-policy, and subprocess providers; see its [README](../terminal-bash/README.md) for the full composition. @@ -102,7 +102,7 @@ Read these pages when the package-level contract is not enough. They move from t - [Terminal subsystem reference](../../../docs/subsystems/terminal.md) — shared types, backend and session contracts, and the generated `ctx.terminals` surface. - [terminal/ package map](../README.md) — the three-package family and how it composes. - [terminal-bash backend](../terminal-bash/README.md) — the shipped shell backend that provides the `shell` type. -- [tool-terminal tools](../tool-terminal/README.md) — the six model-facing tools that operate sessions. +- [tool-terminal tools](../../experimental/tool-terminal/README.md) — the six model-facing tools that operate sessions. - [Persistent PTY Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md) — design rationale, alternatives, and deferred boundaries. ----- @@ -114,7 +114,7 @@ Read these pages when the package-level contract is not enough. They move from t #### What the model sees -Nothing directly. This package registers no prompt or tool; `@deepseek-ai/dsh-tool-terminal` owns visible schemas and result text. +Nothing directly. This package registers no prompt or tool; `@deepseek-ai/dsh-experimental-tool-terminal` owns visible schemas and result text. #### Token effect @@ -122,7 +122,7 @@ None directly. Live session state stays process-local until a consumer returns a #### KV Cache effect -No direct invalidation; `@deepseek-ai/dsh-tool-terminal` owns request-prefix changes. +No direct invalidation; `@deepseek-ai/dsh-experimental-tool-terminal` owns request-prefix changes. ## Known Limitations and Deferred Work diff --git a/packages/terminal/terminal/README.zh.md b/packages/terminal/terminal/README.zh.md index f4fa796b9a..f020cffb8a 100644 --- a/packages/terminal/terminal/README.zh.md +++ b/packages/terminal/terminal/README.zh.md @@ -9,7 +9,7 @@ kind: "package-reference" ## 概述 -`dsh-terminal` 为 harness 提供持久且限定所有者范围的终端会话:会话让 shell 或 REPL 状态跨工具调用存活,且每个操作都被限制在创建它的那个确切 agent(智能体)内。本包提供 `ctx.terminals` 服务,负责生成不透明的会话 id、通过已注册的后端路由会话创建,并在所有者或服务 dispose(资源释放)时等待完全停稳的清理。它本身不定义任何终端机制:`dsh-terminal-bash` 之类的后端负责启动与就绪检测,`dsh-tool-terminal` 中的面向模型工具负责呈现。会话只存在于进程本地:harness 重启后不会恢复。 +`dsh-terminal` 为 harness 提供持久且限定所有者范围的终端会话:会话让 shell 或 REPL 状态跨工具调用存活,且每个操作都被限制在创建它的那个确切 agent(智能体)内。本包提供 `ctx.terminals` 服务,负责生成不透明的会话 id、通过已注册的后端路由会话创建,并在所有者或服务 dispose(资源释放)时等待完全停稳的清理。它本身不定义任何终端机制:`dsh-terminal-bash` 之类的后端负责启动与就绪检测,`dsh-experimental-tool-terminal` 中的面向模型工具负责呈现。会话只存在于进程本地:harness 重启后不会恢复。 ## 目录 @@ -25,7 +25,7 @@ kind: "package-reference" ## 使用本包 -当组合需要状态跨工具调用存活的终端会话时,挂载 `@deepseek-ai/dsh-terminal`。单独的服务本身没有用处:请与 `@deepseek-ai/dsh-terminal-bash` 之类的后端、`@deepseek-ai/dsh-tool-terminal` 之类的工具包配对,并在同一个组合中一起加载。 +当组合需要状态跨工具调用存活的终端会话时,挂载 `@deepseek-ai/dsh-terminal`。单独的服务本身没有用处:请与 `@deepseek-ai/dsh-terminal-bash` 之类的后端、`@deepseek-ai/dsh-experimental-tool-terminal` 之类的工具包配对,并在同一个组合中一起加载。 ### 何时选择 @@ -38,7 +38,7 @@ kind: "package-reference" ```yaml - name: '@deepseek-ai/dsh-terminal' - name: '@deepseek-ai/dsh-terminal-bash' -- name: '@deepseek-ai/dsh-tool-terminal' +- name: '@deepseek-ai/dsh-experimental-tool-terminal' ``` 后端提供一个稳定类型——随附的 shell 后端提供 `shell`——工具按该类型打开会话。shell 后端还额外要求沙箱、沙箱策略与子进程提供方;完整组合见其 [README](../terminal-bash/README.zh.md)。 @@ -102,7 +102,7 @@ kind: "package-reference" - [终端子系统参考](../../../docs/subsystems/terminal.zh.md)——共享类型、后端与会话约定,以及生成的 `ctx.terminals` 接口面。 - [terminal/ 包映射](../README.zh.md)——三包家族及其组合方式。 - [terminal-bash 后端](../terminal-bash/README.zh.md)——提供 `shell` 类型的随附 shell 后端。 -- [tool-terminal 工具](../tool-terminal/README.zh.md)——操作会话的 6 个面向模型工具。 +- [tool-terminal 工具](../../experimental/tool-terminal/README.zh.md)——操作会话的 6 个面向模型工具。 - [持久 PTY Agent Note](../../../.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md)——设计理由、备选方案与暂缓边界。 ----- @@ -114,7 +114,7 @@ kind: "package-reference" #### 模型看到什么 -没有直接可见内容。此包不注册提示词或工具;可见 schema 与结果文本由 `@deepseek-ai/dsh-tool-terminal` 负责。 +没有直接可见内容。此包不注册提示词或工具;可见 schema 与结果文本由 `@deepseek-ai/dsh-experimental-tool-terminal` 负责。 #### Token 影响 @@ -122,7 +122,7 @@ kind: "package-reference" #### KV Cache 影响 -不会直接失效;请求前缀变更由 `@deepseek-ai/dsh-tool-terminal` 负责。 +不会直接失效;请求前缀变更由 `@deepseek-ai/dsh-experimental-tool-terminal` 负责。 ## 已知限制与延期工作 diff --git a/packages/terminal/tool-terminal/README.i18n.yaml b/packages/terminal/tool-terminal/README.i18n.yaml deleted file mode 100644 index fb8e5e646f..0000000000 --- a/packages/terminal/tool-terminal/README.i18n.yaml +++ /dev/null @@ -1,100 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/terminal/tool-terminal/README.md -/: - en: fc74eecdf1f2ad5b - zh: dc9c2a28ce96ce67 -/deepseek-ai-dsh-tool-terminal: - en: 47fa84b67ff171b9 - zh: bbd625bbf85694e1 -/deepseek-ai-dsh-tool-terminal/summary: - en: c0e810d4279333a5 - zh: 7e79b6a63fa10029 -/deepseek-ai-dsh-tool-terminal/table-of-contents: - en: d152484eb41ac6b4 - zh: 09388d293f9be9cb -/deepseek-ai-dsh-tool-terminal/use-this-package: - en: 43b602baf5b35116 - zh: caffb91711393c3b -/deepseek-ai-dsh-tool-terminal/use-this-package/the-six-tools: - en: 3e9b6211dd72ec64 - zh: aa4cd15195cb43d6 -/deepseek-ai-dsh-tool-terminal/use-this-package/composition: - en: 4ce2a232b60ff77d - zh: 3a8a0f13371ca6b9 -/deepseek-ai-dsh-tool-terminal/use-this-package/configuration: - en: 0af09df923fcb322 - zh: 6d9d766c24c530bc -/deepseek-ai-dsh-tool-terminal/use-this-package/background-sends: - en: 2ad49d4f69deb06d - zh: 5f29972b5feec7e3 -/deepseek-ai-dsh-tool-terminal/use-this-package/observable-outcomes-and-failures: - en: 321a982fdbbf4ada - zh: 8c2636e5379815e1 -/deepseek-ai-dsh-tool-terminal/understand-the-implementation: - en: 6302fca8fef89136 - zh: 6327d56edb798ab2 -/deepseek-ai-dsh-tool-terminal/understand-the-implementation/design-concept: - en: dc500eeff749a06f - zh: 9402f5005d7ca338 -/deepseek-ai-dsh-tool-terminal/understand-the-implementation/source-map: - en: a59f4e76dc926bed - zh: 24813cb1bd8fbf32 -/deepseek-ai-dsh-tool-terminal/understand-the-implementation/result-bounding: - en: c1953779a1617d09 - zh: cc6a4a6e76fa021c -/deepseek-ai-dsh-tool-terminal/understand-the-implementation/ui-render-intents: - en: 03e5bb37f0c3aada - zh: 8d51eeb758eabe9c -/deepseek-ai-dsh-tool-terminal/further-exploration: - en: 45a0c33ed8104fb1 - zh: ae50c9e583ef4867 -/deepseek-ai-dsh-tool-terminal/model-experience: - en: 215e7ba838619b7b - zh: a311da3843709f90 -/deepseek-ai-dsh-tool-terminal/model-experience/system-prompt: - en: cf78b9dd5596495f - zh: bd44560f8c2435e8 -/deepseek-ai-dsh-tool-terminal/model-experience/system-prompt/what-the-model-sees: - en: 99887ae1de81aaeb - zh: 4846a1d3ea8a3dc3 -/deepseek-ai-dsh-tool-terminal/model-experience/system-prompt/what-the-model-sees/terminal-guidance: - en: 3ab4211f41e40211 - zh: b730cc3f278be17c -/deepseek-ai-dsh-tool-terminal/model-experience/system-prompt/token-effect: - en: c9d6d1a8238b74ab - zh: 7f4b12d6180b9bac -/deepseek-ai-dsh-tool-terminal/model-experience/system-prompt/kv-cache-effect: - en: 7fdc10b826aeeb51 - zh: 998c86c09efe43bd -/deepseek-ai-dsh-tool-terminal/model-experience/tool-schemas: - en: 3039bc5e7a796b21 - zh: 6b7a9eaf69c9ea53 -/deepseek-ai-dsh-tool-terminal/model-experience/tool-schemas/what-the-model-sees: - en: 32127d768242d8c4 - zh: 3095d987d6011f44 -/deepseek-ai-dsh-tool-terminal/model-experience/tool-schemas/token-effect: - en: 824644a1f5fe76df - zh: b34c7dd78c5ce3cd -/deepseek-ai-dsh-tool-terminal/model-experience/tool-schemas/kv-cache-effect: - en: c8cbbef533bdb90f - zh: c0b00813b8419f46 -/deepseek-ai-dsh-tool-terminal/model-experience/tool-results-and-task-context: - en: 54e0c8a019f02479 - zh: 7331b10d1a455d59 -/deepseek-ai-dsh-tool-terminal/model-experience/tool-results-and-task-context/what-the-model-sees: - en: cc1e88a508d0679e - zh: a219be277705c0ab -/deepseek-ai-dsh-tool-terminal/model-experience/tool-results-and-task-context/token-effect: - en: e4746b7b386944df - zh: be52cd2fd38276b5 -/deepseek-ai-dsh-tool-terminal/model-experience/tool-results-and-task-context/kv-cache-effect: - en: ac583ab16185a93c - zh: 78df55a519b2ec1f -/deepseek-ai-dsh-tool-terminal/known-limitations-and-deferred-work: - en: ba974b703d6ed0bc - zh: 655810d5d338343c -/deepseek-ai-dsh-tool-terminal/known-limitations-and-deferred-work/dev-note: - en: e67f633dc6fe7773 - zh: 3bb0c20c93f16f98 diff --git a/packages/webhook/README.i18n.yaml b/packages/webhook/README.i18n.yaml deleted file mode 100644 index 0f3a4c5b42..0000000000 --- a/packages/webhook/README.i18n.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/webhook/README.md -/: - en: 4b01653e4ccb53d2 - zh: 85df5bd61bac9fe6 -/webhook-verified-external-events-to-dsh-sessions: - en: 56361bc7c10f73ad - zh: 2a40c90775045766 -/webhook-verified-external-events-to-dsh-sessions/summary: - en: 297975121095f74a - zh: 9530dbf3c90d1ae0 -/webhook-verified-external-events-to-dsh-sessions/table-of-contents: - en: 1eb35b015a6c423f - zh: a8a3dceee2c9e943 -/webhook-verified-external-events-to-dsh-sessions/packages: - en: 7bebbc165a382b0d - zh: ee601ab6a4c467ee -/webhook-verified-external-events-to-dsh-sessions/related-documentation: - en: 24b7903a3f1f7dce - zh: fab213faf1d22760 -/webhook-verified-external-events-to-dsh-sessions/dev-note: - en: b75c8458928b72b9 - zh: 003ba4e17b4b5269 diff --git a/packages/webhook/README.md b/packages/webhook/README.md deleted file mode 100644 index fa35bf07d2..0000000000 --- a/packages/webhook/README.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -description: "Package map for verified external events, programmatic rules, and fire-and-forget DSH Session creation." -kind: "package-group" ---- - -# webhook/ — verified external events to DSH Sessions - -English | [中文](README.zh.md) - -## Summary - -The Webhook family receives authenticated provider events and runs trusted programmatic rules. A rule can create an ordinary root Session inside a Web Workspace. Dispatch is process-local and fire-and-forget, with no delivery database, queue, retry, deduplication, or Agent-completion state. - -## Table of Contents - -- [Packages](#packages) -- [Related documentation](#related-documentation) -- [Dev Note](#dev-note) - ------ - - -## Packages - -| Package | Role | ctx key | -|---|---|---| -| [`webhook/`](webhook/README.md) | Rule registry, callback lifecycle, and Workspace-backed Session creation | `ctx.webhookRuntime` | -| [`webhook-github/`](webhook-github/README.md) | Signed GitHub HTTP adapter | consumes `ctx.webhookRuntime` and `ctx.webServer` | - - -## Related documentation - -Provider adapters authenticate and normalize deliveries. Rules own arbitrary conditions and external calls, then return `null` or one Session request. The [Webhook subsystem reference](../../docs/subsystems/webhook.md) owns the shared types and timing guarantees. - - -## Dev Note - -None. diff --git a/packages/webhook/README.zh.md b/packages/webhook/README.zh.md deleted file mode 100644 index fa941391b2..0000000000 --- a/packages/webhook/README.zh.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -description: "经验证的外部事件、程序化规则与即发即弃 DSH 会话创建的包映射。" -kind: "package-group" ---- - -# webhook/ — 从已验证外部事件到 DSH 会话 - -[English](README.md) | 中文 - -## 概述 - -Webhook 系列接收通过身份验证的提供方事件,并运行受信任的程序化规则。规则可以在 Web Workspace 中创建普通根会话。分发仅存在于进程内并采用 fire-and-forget,不拥有交付数据库、队列、重试、去重或 agent(智能体)完成状态。 - -## 目录 - -- [包](#packages) -- [相关文档](#related-documentation) -- [开发备注](#dev-note) - ------ - - -## 包 - -| 包 | 角色 | ctx key | -|---|---|---| -| [`webhook/`](webhook/README.zh.md) | 规则注册表、回调生命周期与基于 Workspace 的会话创建 | `ctx.webhookRuntime` | -| [`webhook-github/`](webhook-github/README.zh.md) | GitHub HTTP 签名验证适配器 | 消费 `ctx.webhookRuntime` 与 `ctx.webServer` | - - -## 相关文档 - -提供方适配器负责验证身份并规范化交付。规则拥有任意条件和外部调用,随后返回 `null` 或一个会话请求。[Webhook 子系统参考](../../docs/subsystems/webhook.zh.md)拥有共享类型与时序保证。 - - -## 开发备注 - -无。 diff --git a/packages/webhook/webhook-github/README.i18n.yaml b/packages/webhook/webhook-github/README.i18n.yaml deleted file mode 100644 index a540bf7a00..0000000000 --- a/packages/webhook/webhook-github/README.i18n.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/webhook/webhook-github/README.md -/: - en: 60db7ae899ed9fd9 - zh: 4fe10fa8823aa6d1 -/deepseek-ai-dsh-webhook-github: - en: 23be5c358de960ea - zh: 23862fc948bc76a2 -/deepseek-ai-dsh-webhook-github/summary: - en: 2db19f03dc3daea7 - zh: 291598d5f67485b9 -/deepseek-ai-dsh-webhook-github/table-of-contents: - en: b946752a1c17cd00 - zh: cdaaea55e4da6831 -/deepseek-ai-dsh-webhook-github/configuration: - en: a32a5195a6ae6a61 - zh: a135089e86948290 -/deepseek-ai-dsh-webhook-github/http-contract: - en: 2d8b5cb8d44bef8e - zh: a98ec470d9d6bc2d -/deepseek-ai-dsh-webhook-github/dedicated-listener-composition: - en: 8197edec97bbd8fe - zh: 7e3d070a5d4a985d -/deepseek-ai-dsh-webhook-github/model-experience: - en: 17c5ff7cc39c5a2e - zh: f6fe32ae981dc4b6 -/deepseek-ai-dsh-webhook-github/model-experience/kv-cache-effect: - en: a7c54f451f61179e - zh: aaf25d0781ad4d6b -/deepseek-ai-dsh-webhook-github/known-limitations-and-deferred-work: - en: 0c3192c3e300bb46 - zh: 7c84d20e6a8a768e -/deepseek-ai-dsh-webhook-github/known-limitations-and-deferred-work/dev-note: - en: e67f633dc6fe7773 - zh: e88aeb617ffb74ea diff --git a/packages/webhook/webhook/README.i18n.yaml b/packages/webhook/webhook/README.i18n.yaml deleted file mode 100644 index a67106a1a8..0000000000 --- a/packages/webhook/webhook/README.i18n.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/webhook/webhook/README.md -/: - en: e4ac1bc2fef159c0 - zh: a2d724d2cffb6608 -/deepseek-ai-dsh-webhook: - en: eb5cd36cbfde500e - zh: 482692e07c7aea4e -/deepseek-ai-dsh-webhook/summary: - en: 406c9bffd5078cb3 - zh: c7e732b80df254a8 -/deepseek-ai-dsh-webhook/table-of-contents: - en: 2c6f2175556251ee - zh: 753d216d980e1735 -/deepseek-ai-dsh-webhook/rule-interface: - en: d9674188535399ab - zh: c52fe9b7ebe8fe79 -/deepseek-ai-dsh-webhook/session-request: - en: e4d096efc8633575 - zh: b1bf7d45fe76c380 -/deepseek-ai-dsh-webhook/composition: - en: 6a19f22997772945 - zh: b92bec411e0406bc -/deepseek-ai-dsh-webhook/model-experience: - en: 215e7ba838619b7b - zh: a311da3843709f90 -/deepseek-ai-dsh-webhook/model-experience/rule-authored-initial-prompt: - en: d9d6f7525ae75c28 - zh: 981d9ea68b9e884b -/deepseek-ai-dsh-webhook/model-experience/rule-authored-initial-prompt/what-the-model-sees: - en: 44859d5d877a1484 - zh: 0f6c96ff6435167b -/deepseek-ai-dsh-webhook/model-experience/rule-authored-initial-prompt/token-effect: - en: 13937f95014a6bea - zh: c61031459298c4ab -/deepseek-ai-dsh-webhook/model-experience/rule-authored-initial-prompt/kv-cache-effect: - en: 88b78de3ce71698f - zh: d13964bad7485d4e -/deepseek-ai-dsh-webhook/known-limitations-and-deferred-work: - en: 49d9bd7c7c327cc0 - zh: ab94de11bbda1936 -/deepseek-ai-dsh-webhook/known-limitations-and-deferred-work/dev-note: - en: e67f633dc6fe7773 - zh: e88aeb617ffb74ea diff --git a/packages/workflow/README.i18n.yaml b/packages/workflow/README.i18n.yaml index 0fe96d14a7..c8fb53aaf5 100644 --- a/packages/workflow/README.i18n.yaml +++ b/packages/workflow/README.i18n.yaml @@ -15,11 +15,11 @@ en: 1eb35b015a6c423f zh: a8a3dceee2c9e943 /packages-workflow/packages: - en: 02e5fd1d11016051 - zh: 750f4df962466241 + en: e9129c49136545bc + zh: c65e319b99b1ef7d /packages-workflow/related-documentation: - en: d74d332db4883554 - zh: 50abddd786de907b + en: 6163fe417d1e3128 + zh: ba5d30fc180fdf6d /packages-workflow/dev-note: en: 5de1d6304e00c58f zh: 8d8225361cfa29e5 diff --git a/packages/workflow/README.md b/packages/workflow/README.md index 54bb22bd66..ae56fedb4c 100644 --- a/packages/workflow/README.md +++ b/packages/workflow/README.md @@ -27,7 +27,6 @@ The workflow group lets an agent run orchestration scripts that delegate work to | [`workflow`](workflow/README.md) | Runs a model-written orchestration script that fans out subagents | `ctx.workflowEngine` | | [`workflow-ptc`](workflow-ptc/README.md) | Runs workflow scripts through the shared sandboxed PTC Node process runtime | registers on `ctx.workflowEngine` | | [`tool-workflow`](tool-workflow/README.md) | Gives the model the `workflow` tool for scripted multi-agent orchestration | registers on `ctx.tools` | -| [`tool-ralph`](tool-ralph/README.md) | Gives the model the `ralph` tool for fresh-agent iterative loops | registers on `ctx.tools` | ----- @@ -36,10 +35,10 @@ The workflow group lets an agent run orchestration scripts that delegate work to - [Workflow subsystem](../../docs/subsystems/workflow.md) — the seam's types, start request, and `workflow/*` events. - [Generated tool catalog](../../docs/tool-catalog.md#deepseek-aidsh-tool-workflow) — the `workflow` tool schema the model receives. -- [Generated tool catalog](../../docs/tool-catalog.md#deepseek-aidsh-tool-ralph) — the `ralph` tool schema the model receives. +- [Generated tool catalog](../../docs/tool-catalog.md#deepseek-aidsh-experimental-tool-ralph) — the `ralph` tool schema the model receives. - [Generated configuration catalog](../../docs/config-catalog.md#deepseek-aidsh-workflow-ptc) — every accepted engine config field. - [historical Dynamic workflows Agent Note](../../.agents/notes/archived/feature/2026-07-05-dynamic-workflows.md) — the seam design and its decisions. -- [Harness-level goal-based execution reference](tool-ralph/README.md) — the fixed fresh-agent loop design and deferred work. +- [Harness-level goal-based execution reference](../experimental/tool-ralph/README.md) — the fixed fresh-agent loop design and deferred work. ----- diff --git a/packages/workflow/README.zh.md b/packages/workflow/README.zh.md index 60e47cb997..0f502d0ac9 100644 --- a/packages/workflow/README.zh.md +++ b/packages/workflow/README.zh.md @@ -27,7 +27,6 @@ workflow 组让 agent(智能体)可以运行编排脚本,将工作委派 | [`workflow`](workflow/README.zh.md) | 运行由模型编写的、扇出 subagent 的编排脚本 | `ctx.workflowEngine` | | [`workflow-ptc`](workflow-ptc/README.zh.md) | 通过共享的沙箱化 PTC Node 进程运行时执行工作流脚本 | 注册到 `ctx.workflowEngine` | | [`tool-workflow`](tool-workflow/README.zh.md) | 把 `workflow` 工具交给模型,用于脚本化多 agent 编排 | 注册到 `ctx.tools` | -| [`tool-ralph`](tool-ralph/README.zh.md) | 把 `ralph` 工具交给模型,用于全新 agent 迭代循环 | 注册到 `ctx.tools` | ----- @@ -36,10 +35,10 @@ workflow 组让 agent(智能体)可以运行编排脚本,将工作委派 - [工作流子系统](../../docs/subsystems/workflow.zh.md)——seam 的类型、启动请求与 `workflow/*` 事件。 - [生成的工具目录](../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-workflow)——模型接收的 `workflow` 工具 schema。 -- [生成的工具目录](../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-ralph)——模型接收的 `ralph` 工具 schema。 +- [生成的工具目录](../../docs/tool-catalog.zh.md#deepseek-aidsh-experimental-tool-ralph)——模型接收的 `ralph` 工具 schema。 - [生成的配置目录](../../docs/config-catalog.zh.md#deepseek-aidsh-workflow-ptc)——每个受支持的引擎配置字段。 - [历史动态工作流 Agent Note](../../.agents/notes/archived/feature/2026-07-05-dynamic-workflows.md)——seam 设计及其决策。 -- [Harness 层目标式执行 参考](tool-ralph/README.zh.md)——固定全新 agent 循环的设计与暂缓事项。 +- [Harness 层目标式执行 参考](../experimental/tool-ralph/README.zh.md)——固定全新 agent 循环的设计与暂缓事项。 ----- diff --git a/packages/workflow/tool-ralph/README.i18n.yaml b/packages/workflow/tool-ralph/README.i18n.yaml deleted file mode 100644 index d23cf3f87e..0000000000 --- a/packages/workflow/tool-ralph/README.i18n.yaml +++ /dev/null @@ -1,100 +0,0 @@ -# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/workflow/tool-ralph/README.md -/: - en: e2a31cca62823561 - zh: c06ff93cf98b67e4 -/deepseek-ai-dsh-tool-ralph: - en: 9b8347f16cf12c09 - zh: f5593f514c261301 -/deepseek-ai-dsh-tool-ralph/summary: - en: 9821960147153443 - zh: 0b24aab94a5dc12b -/deepseek-ai-dsh-tool-ralph/table-of-contents: - en: d152484eb41ac6b4 - zh: 09388d293f9be9cb -/deepseek-ai-dsh-tool-ralph/use-this-package: - en: 13380e1170c6a3b5 - zh: 2f2665f2ee5ff6f7 -/deepseek-ai-dsh-tool-ralph/use-this-package/calling-the-tool: - en: f43e8fbcf272ac45 - zh: 46719b415d9ad4bf -/deepseek-ai-dsh-tool-ralph/use-this-package/what-each-round-sees: - en: 2d8b861c4bcb9424 - zh: 63c7b2d00c324727 -/deepseek-ai-dsh-tool-ralph/use-this-package/config: - en: 4f0ba81742e46af0 - zh: e47ba7d9737fa51f -/deepseek-ai-dsh-tool-ralph/understand-the-implementation: - en: 0999ea3a4c9da48c - zh: 83013ee36a8689af -/deepseek-ai-dsh-tool-ralph/understand-the-implementation/design-concept: - en: 3777bac0215c7366 - zh: 18240f47506c67bd -/deepseek-ai-dsh-tool-ralph/understand-the-implementation/fixed-script-and-routing: - en: fa2cfda2d9d121e6 - zh: 75720bd6244a2c96 -/deepseek-ai-dsh-tool-ralph/understand-the-implementation/report-validation: - en: 65f90bce7ef1fe5b - zh: 04c8d5ad08a9007c -/deepseek-ai-dsh-tool-ralph/understand-the-implementation/lifecycle-and-cancellation: - en: fdd98f9e2d2ec378 - zh: 72e3da1f3c717aa6 -/deepseek-ai-dsh-tool-ralph/understand-the-implementation/render-intent: - en: 07e071bd44b1df65 - zh: 26f1cb2eab8c25b0 -/deepseek-ai-dsh-tool-ralph/understand-the-implementation/source-map: - en: 1bc11234792b4e3f - zh: 872d2c5f8df37b72 -/deepseek-ai-dsh-tool-ralph/further-exploration: - en: 966417f5c0659ef9 - zh: 6c95a000db46ce0f -/deepseek-ai-dsh-tool-ralph/model-experience: - en: 215e7ba838619b7b - zh: a311da3843709f90 -/deepseek-ai-dsh-tool-ralph/model-experience/system-prompt: - en: cf78b9dd5596495f - zh: bd44560f8c2435e8 -/deepseek-ai-dsh-tool-ralph/model-experience/system-prompt/what-the-model-sees: - en: bcfb20c5be49c2c4 - zh: c666f686a648fc0f -/deepseek-ai-dsh-tool-ralph/model-experience/system-prompt/what-the-model-sees/ralph-guidance: - en: 4ee32d69a7ae2aba - zh: bdf2035f010ab56a -/deepseek-ai-dsh-tool-ralph/model-experience/system-prompt/token-effect: - en: dab67480bfde6224 - zh: 85bbf18da3767aa7 -/deepseek-ai-dsh-tool-ralph/model-experience/system-prompt/kv-cache-effect: - en: 13e7c6007bf6b5dc - zh: 2b0da8b6dc00aa5e -/deepseek-ai-dsh-tool-ralph/model-experience/tool-schema: - en: e4c7376d4f29dbd5 - zh: 6b7a9eaf69c9ea53 -/deepseek-ai-dsh-tool-ralph/model-experience/tool-schema/what-the-model-sees: - en: d3e219e3f0e507ed - zh: daf8093ed21eb9cf -/deepseek-ai-dsh-tool-ralph/model-experience/tool-schema/token-effect: - en: 0af719618f9f99d2 - zh: a719a4e5df1406a4 -/deepseek-ai-dsh-tool-ralph/model-experience/tool-schema/kv-cache-effect: - en: 79a20d1db0f4a32e - zh: c72a19d9a6c0bff3 -/deepseek-ai-dsh-tool-ralph/model-experience/child-requests-and-parent-result: - en: 55181fb745ab8135 - zh: ebeea6a8748986d2 -/deepseek-ai-dsh-tool-ralph/model-experience/child-requests-and-parent-result/what-the-model-sees: - en: 788029304e88ea74 - zh: 0e0281c7cc393dff -/deepseek-ai-dsh-tool-ralph/model-experience/child-requests-and-parent-result/token-effect: - en: ab2d30ed91979cbc - zh: bb074b02c4b05e4f -/deepseek-ai-dsh-tool-ralph/model-experience/child-requests-and-parent-result/kv-cache-effect: - en: 8f28959dc87d1f2f - zh: c034c5c0bdaf9bba -/deepseek-ai-dsh-tool-ralph/known-limitations-and-deferred-work: - en: 4e3629e8de05fe18 - zh: 5b33af22079a2ca7 -/deepseek-ai-dsh-tool-ralph/known-limitations-and-deferred-work/dev-note: - en: 8f24c317039e1974 - zh: c6209969ad21f16c diff --git a/packages/workflow/workflow-ptc/README.i18n.yaml b/packages/workflow/workflow-ptc/README.i18n.yaml index 774435de36..68dab81cb8 100644 --- a/packages/workflow/workflow-ptc/README.i18n.yaml +++ b/packages/workflow/workflow-ptc/README.i18n.yaml @@ -15,8 +15,8 @@ en: d152484eb41ac6b4 zh: 09388d293f9be9cb /deepseek-ai-dsh-workflow-ptc/use-this-package: - en: 83b0c102b3c07260 - zh: 7890bb8609063777 + en: 42a8bbf28fb1369d + zh: 657d724d87735e44 /deepseek-ai-dsh-workflow-ptc/use-this-package/minimal-configuration: en: 9c31c6e17ba018ed zh: 85ffe20ce8a5a371 @@ -42,8 +42,8 @@ en: 8b8806d701e3d32d zh: cfa21c4962be2fa4 /deepseek-ai-dsh-workflow-ptc/further-exploration: - en: 8fa36196dfbb0906 - zh: 301c6efb8a7dfffe + en: 07733b39d2029089 + zh: a4d54dd2fd7d21d3 /deepseek-ai-dsh-workflow-ptc/model-experience: en: 215e7ba838619b7b zh: a311da3843709f90 diff --git a/packages/workflow/workflow-ptc/README.md b/packages/workflow/workflow-ptc/README.md index f7d036a24b..1f0047d5d6 100644 --- a/packages/workflow/workflow-ptc/README.md +++ b/packages/workflow/workflow-ptc/README.md @@ -25,7 +25,7 @@ Run JavaScript workflows in fresh Node processes under the calling Session's fil ## Use this package -Mount this engine in a composition that provides subagents, sandbox policy and the [Node PTC runtime](../../ptc-runtime/ptc-runtime-node/README.md). It supplies workflow execution for `dsh-tool-workflow` and for `dsh-tool-ralph` when explicitly enabled. Ralph remains disabled in shipped defaults. The engine rejects non-TypeScript PTC providers when it loads. Python PTC compositions must disable the `workflow-ptc`, `tool-workflow` and any enabled `tool-ralph` rows. +Mount this engine in a composition that provides subagents, sandbox policy and the [Node PTC runtime](../../ptc-runtime/ptc-runtime-node/README.md). It supplies workflow execution for `dsh-tool-workflow` and for `dsh-experimental-tool-ralph` when explicitly enabled. Ralph remains disabled in shipped defaults. The engine rejects non-TypeScript PTC providers when it loads. Python PTC compositions must disable the `workflow-ptc`, `tool-workflow` and any enabled `tool-ralph` rows. ### Minimal configuration @@ -109,7 +109,7 @@ Use these references for the shared execution guarantees and workflow contracts. - [Workflow service](../workflow/README.md) — caller-owned runs and cleanup. - [Node PTC runtime](../../ptc-runtime/ptc-runtime-node/README.md) — file policy, process limits and deployment choices. - [workflow tool](../tool-workflow/README.md) — model-facing scripted orchestration. -- [Ralph tool](../tool-ralph/README.md) — opt-in fixed fresh-agent iteration. +- [Ralph tool](../../experimental/tool-ralph/README.md) — opt-in fixed fresh-agent iteration. - [Workflow sandbox reuse](../../../.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.md) — execution ownership and tradeoffs. ----- diff --git a/packages/workflow/workflow-ptc/README.zh.md b/packages/workflow/workflow-ptc/README.zh.md index 7b73dccc6d..0339a45514 100644 --- a/packages/workflow/workflow-ptc/README.zh.md +++ b/packages/workflow/workflow-ptc/README.zh.md @@ -25,7 +25,7 @@ kind: "package-reference" ## 使用本包 -在提供 subagent、沙箱策略和 [Node PTC 运行时](../../ptc-runtime/ptc-runtime-node/README.zh.md)的组合中挂载本引擎。它为 `dsh-tool-workflow` 及显式启用时的 `dsh-tool-ralph` 提供工作流执行。Ralph 在已发布默认组合中保持禁用。引擎在加载时拒绝非 TypeScript 的 PTC 提供方。Python PTC 组合必须禁用 `workflow-ptc`、`tool-workflow` 以及任何已启用的 `tool-ralph` 条目。 +在提供 subagent、沙箱策略和 [Node PTC 运行时](../../ptc-runtime/ptc-runtime-node/README.zh.md)的组合中挂载本引擎。它为 `dsh-tool-workflow` 及显式启用时的 `dsh-experimental-tool-ralph` 提供工作流执行。Ralph 在已发布默认组合中保持禁用。引擎在加载时拒绝非 TypeScript 的 PTC 提供方。Python PTC 组合必须禁用 `workflow-ptc`、`tool-workflow` 以及任何已启用的 `tool-ralph` 条目。 ### 最小配置 @@ -109,7 +109,7 @@ Host 分别跟踪待完成的启动与已接受的 Activation。取消会中止 - [工作流服务](../workflow/README.zh.md)——调用方拥有的运行与清理。 - [Node PTC 运行时](../../ptc-runtime/ptc-runtime-node/README.zh.md)——文件策略、进程限制与部署选择。 - [workflow 工具](../tool-workflow/README.zh.md)——面向模型的脚本编排。 -- [Ralph 工具](../tool-ralph/README.zh.md)——需显式启用的固定全新 agent 迭代。 +- [Ralph 工具](../../experimental/tool-ralph/README.zh.md)——需显式启用的固定全新 agent 迭代。 - [工作流沙箱复用](../../../.agents/notes/implemented/architecture/2026-09-13-workflow-ptc-sandbox-reuse.zh.md)——执行归属与取舍。 ----- diff --git a/python/sdk-runtime/package.json b/python/sdk-runtime/package.json index 45b4dc75b0..d401b5ba81 100644 --- a/python/sdk-runtime/package.json +++ b/python/sdk-runtime/package.json @@ -57,9 +57,6 @@ "@deepseek-ai/dsh-goal": "workspace:*", "@deepseek-ai/dsh-goal-round-driver": "workspace:*", "@deepseek-ai/dsh-home-paths": "workspace:*", - "@deepseek-ai/dsh-hook-protocol": "workspace:*", - "@deepseek-ai/dsh-hooks-claude-code": "workspace:*", - "@deepseek-ai/dsh-hooks-codex": "workspace:*", "@deepseek-ai/dsh-host-plugin-inventory": "workspace:*", "@deepseek-ai/dsh-host-webserver": "workspace:*", "@deepseek-ai/dsh-http-proxy": "workspace:*", @@ -135,7 +132,6 @@ "@deepseek-ai/dsh-tool-present": "workspace:*", "@deepseek-ai/dsh-tool-pwsh": "workspace:*", "@deepseek-ai/dsh-tool-pwsh-persistent": "workspace:*", - "@deepseek-ai/dsh-tool-ralph": "workspace:*", "@deepseek-ai/dsh-tool-skill": "workspace:*", "@deepseek-ai/dsh-tool-str-replace-editor": "workspace:*", "@deepseek-ai/dsh-tool-subagent": "workspace:*", diff --git a/scripts/build-exe-for-python-sdk-assets.spec.ts b/scripts/build-exe-for-python-sdk-assets.spec.ts index 0a963f3f1e..9d00ff5463 100644 --- a/scripts/build-exe-for-python-sdk-assets.spec.ts +++ b/scripts/build-exe-for-python-sdk-assets.spec.ts @@ -22,7 +22,7 @@ describe('Python runtime executable assets', () => { expect(result.status).toBe(0) expect(result.stdout).toContain('node_modules/@deepseek-ai/dsh-web-frontend/dist/**/*') - expect(result.stdout).toContain('node_modules/@deepseek-ai/dsh-skill-badge/assets/**/*') + expect(result.stdout).not.toContain('skill-badge/assets/**/*') expect(result.stdout).toContain('node_modules/@deepseek-ai/dsh-sandbox-windows-acl/assets/**/*') expect(result.stdout).not.toContain('node_modules/**/*.py') }) diff --git a/scripts/build-exe-for-python-sdk.ts b/scripts/build-exe-for-python-sdk.ts index adb63352af..b8b5b8085b 100644 --- a/scripts/build-exe-for-python-sdk.ts +++ b/scripts/build-exe-for-python-sdk.ts @@ -48,7 +48,7 @@ const ASSET_GLOBS = [ 'node_modules/**/*.mjs', 'node_modules/**/package.json', 'node_modules/**/*.json', - // Package-owned Markdown includes runtime skill instructions and badge content. + // Package-owned Markdown includes runtime skill instructions. 'node_modules/**/*.md', 'node_modules/**/*.dylib', 'node_modules/**/*.dll', @@ -60,8 +60,6 @@ const ASSET_GLOBS = [ 'node_modules/**/*.yml', // web-app builds this path dynamically, so pkg cannot discover the static frontend. 'node_modules/@deepseek-ai/dsh-web-frontend/dist/**/*', - // skill-badge resolves both Markdown and image resources through import.meta.url. - 'node_modules/@deepseek-ai/dsh-skill-badge/assets/**/*', // The diagnosis provider extracts its PowerShell script for an external interpreter. 'node_modules/@deepseek-ai/dsh-sandbox-windows-acl/assets/**/*', ] diff --git a/scripts/check-workspace-constraints.ts b/scripts/check-workspace-constraints.ts index a31cf299b1..2415de275c 100644 --- a/scripts/check-workspace-constraints.ts +++ b/scripts/check-workspace-constraints.ts @@ -168,6 +168,7 @@ export function readWorkspaceManifests(repositoryRoot: string): WorkspaceManifes } const packageFileExtras: Readonly> = { + '@deepseek-ai/dsh-experimental-webhook-github': ['examples/github-review/cordis.yml', 'examples/github-review/github-ready-review-rule.mjs'], // Owned Worker bundles import this public bootstrap before their business entry. '@deepseek-ai/dsh-app-boot': ['lib/worker/profile-resolution-bootstrap.js'], // Statically linked client libraries keep their stylesheets next to the emitted @@ -202,7 +203,7 @@ const packageFileExtras: Readonly> = { // sandbox-local resolves it through the package's ./runner export. tsdown // also shares its generated FFI code through a hashed runtime chunk. '@deepseek-ai/dsh-sandbox-windows-acl': ['lib/runner.js', 'lib/types-*.js', 'assets'], - '@deepseek-ai/dsh-skill-badge': ['assets'], + '@deepseek-ai/dsh-experimental-skill-badge': ['assets'], '@deepseek-ai/dsh-skill-office': ['assets'], '@deepseek-ai/dsh-subprocess': ['lib/control.js'], // SSH launches a private helper and shares wire definitions and TLS setup diff --git a/scripts/doc-standard.spec.ts b/scripts/doc-standard.spec.ts index 29f120b1e9..cd29b4926b 100644 --- a/scripts/doc-standard.spec.ts +++ b/scripts/doc-standard.spec.ts @@ -65,7 +65,7 @@ const PACKAGE_LIBRARIES: Readonly> = { 'packages/core/scope': 'Scoped-context primitives; exports functions and types without a plugin entry.', 'packages/experimental/webworker-packer': 'Build-time VFS image packer and command library.', 'packages/experimental/webworker-runtime': 'Browser worker runtime library with explicit host entry points.', - 'packages/hooks/hook-protocol': 'Shared wire-protocol library between the hook bridges.', + 'packages/experimental/hook-protocol': 'Shared wire-protocol library between the hook bridges.', 'packages/identity/anonymous-user-id': 'Harness-home identity helper with no plugin registration.', 'packages/sandbox/sandbox-windows-acl': 'Windows ACL sandbox library consumed by sandbox-local.', 'packages/sdk/client': 'Client-process library; the spawned runtime owns plugin behavior.', diff --git a/scripts/gen-doc-graphs.ts b/scripts/gen-doc-graphs.ts index eedde2ae9a..97390a7c9a 100644 --- a/scripts/gen-doc-graphs.ts +++ b/scripts/gen-doc-graphs.ts @@ -376,7 +376,7 @@ const SERVICE_ROLES: ServiceRole[] = [ title: 'Durable session persistence seam', mode: 'seam', implementations: ['session-persistence-jsonl'], - consumers: ['agent-loop', 'tool-bash', 'hooks-claude-code', 'hooks-codex', 'session-query', 'session-query-sqlite', 'message-feedback'], + consumers: ['agent-loop', 'tool-bash', 'experimental-hooks-claude-code', 'experimental-hooks-codex', 'session-query', 'session-query-sqlite', 'message-feedback'], note: 'The JSONL backend persists the SessionEvent vocabulary as one artifact per Session.', }, { @@ -531,7 +531,7 @@ const SERVICE_ROLES: ServiceRole[] = [ pkg: 'session-title', title: 'Log-backed session titles', mode: 'seam', - implementations: ['session-title-first-prompt-llm', 'session-title-all-prompts-llm'], + implementations: ['session-title-first-prompt-llm', 'experimental-session-title-all-prompts-llm'], note: 'Owns the deterministic fallback, latest-title fold, and sole optional asynchronous provider registration.', }, { @@ -539,7 +539,7 @@ const SERVICE_ROLES: ServiceRole[] = [ pkg: 'system-prompt', title: 'System prompt assembly registry', mode: 'core', - consumers: ['agent-loop', 'tools', 'tool-fs', 'tool-terminal', 'tool-web'], + consumers: ['agent-loop', 'tools', 'tool-fs', 'experimental-tool-terminal', 'tool-web'], note: 'Collects prompt sections and model-facing tool schemas for each step.', }, { @@ -547,7 +547,7 @@ const SERVICE_ROLES: ServiceRole[] = [ pkg: 'tools', title: 'Tool registry and guarded execution pipeline', mode: 'core', - consumers: ['agent-loop', 'tool-ask-user', 'tool-bash', 'tool-cordis', 'tool-fs', 'tool-terminal', 'tool-skill', 'tool-subagent', 'tool-todo', 'tool-web'], + consumers: ['agent-loop', 'tool-ask-user', 'tool-bash', 'tool-cordis', 'tool-fs', 'experimental-tool-terminal', 'tool-skill', 'tool-subagent', 'tool-todo', 'tool-web'], note: 'Registers capabilities, owns PTC mode transport, and routes calls through pre-policy, monotonic guards, around dispatch, post-policy, and final-result observation.', }, { @@ -600,7 +600,7 @@ const SERVICE_ROLES: ServiceRole[] = [ pkg: 'skill', title: 'Skill provider registry', mode: 'seam', - implementations: ['sandbox-windows-acl', 'skill-badge', 'skill-filesystem', 'skill-office'], + implementations: ['sandbox-windows-acl', 'experimental-skill-badge', 'skill-filesystem', 'skill-office'], consumers: ['tool-skill'], note: 'Merges provider skill catalogs; tool-skill renders the session-prefix catalog and loads complete skill bodies.', }, @@ -665,7 +665,7 @@ const SERVICE_ROLES: ServiceRole[] = [ title: 'Bash executor seam', mode: 'seam', implementations: ['bash-local', 'bash-sandbox', 'pwsh-local'], - consumers: ['tool-bash', 'tool-pwsh', 'hooks-claude-code', 'hooks-codex'], + consumers: ['tool-bash', 'tool-pwsh', 'experimental-hooks-claude-code', 'experimental-hooks-codex'], note: 'The model-facing shell tools and hook bridges consume this seam; sandboxed, remote, or PowerShell executors replace bash-local without touching them.', }, { @@ -682,7 +682,7 @@ const SERVICE_ROLES: ServiceRole[] = [ title: 'Persistent PTY session registry', mode: 'seam', implementations: ['terminal-bash'], - consumers: ['tool-terminal'], + consumers: ['experimental-tool-terminal'], note: 'The registry owns exact-Agent session identity and cleanup; backends own terminal mechanics, while tool-terminal exposes the owner-scoped model tools.', }, { @@ -754,7 +754,7 @@ const SERVICE_ROLES: ServiceRole[] = [ title: 'Subagent provider and continuation service', mode: 'seam', implementations: ['subagent-spawn-in-process', 'subagent-fork-in-process', 'subagent-acp', 'subagent-codex', 'subagent-claude-code', 'subagent-dsh-sdk'], - consumers: ['tool-subagent', 'tool-subagent-control', 'tool-ralph'], + consumers: ['tool-subagent', 'tool-subagent-control', 'experimental-tool-ralph'], note: 'Providers prepare local children or execute external tasks; one activation manager owns both lifecycles. The delegation tool selects a backend, control tools deliver local follow-ups, and workflows await activation results.', }, { @@ -794,7 +794,7 @@ const SERVICE_ROLES: ServiceRole[] = [ title: 'Background job registry', mode: 'seam', implementations: ['jobs-local'], - consumers: ['tool-bash', 'tool-pwsh', 'tool-terminal', 'tool-jobs', 'api-job-controller'], + consumers: ['tool-bash', 'tool-pwsh', 'experimental-tool-terminal', 'tool-jobs', 'api-job-controller'], note: 'Producers (background bash/pwsh and PTY sends) register running work; record-declaring jobs additionally stream raw output for non-consuming observers; tool-jobs is the model-facing controller that reads, lists, and kills it; jobs-local is the process-local registry.', }, { @@ -846,15 +846,15 @@ const SERVICE_ROLES: ServiceRole[] = [ title: 'Workflow script engine', mode: 'seam', implementations: ['workflow-ptc'], - consumers: ['tool-workflow', 'tool-ralph'], + consumers: ['tool-workflow', 'experimental-tool-ralph'], note: 'One engine per context, as in bash, with no named-provider registry; the general workflow and fixed Ralph consumers start runs whose agent() calls fan out through ctx.subagents.', }, { key: 'webhookRuntime', - pkg: 'webhook', + pkg: 'experimental-webhook', title: 'Webhook rule runtime', mode: 'core', - consumers: ['webhook-github'], + consumers: ['experimental-webhook-github'], note: 'Provider adapters dispatch authenticated deliveries; trusted plugins register independent process-local rules, and the runtime turns non-null results into ordinary Workspace-backed Sessions without delivery or completion state.', }, { diff --git a/scripts/gen-tool-catalog.ts b/scripts/gen-tool-catalog.ts index d248f743ea..2b8ddbd383 100644 --- a/scripts/gen-tool-catalog.ts +++ b/scripts/gen-tool-catalog.ts @@ -54,7 +54,7 @@ import * as ToolFs from '@deepseek-ai/dsh-tool-fs' import * as ToolFsSearch from '@deepseek-ai/dsh-tool-fs-search' import * as ToolStrReplaceEditor from '@deepseek-ai/dsh-tool-str-replace-editor' import TerminalSessionService from '@deepseek-ai/dsh-terminal' -import * as ToolPty from '@deepseek-ai/dsh-tool-terminal' +import * as ToolPty from '@deepseek-ai/dsh-experimental-tool-terminal' import * as ToolGoal from '@deepseek-ai/dsh-tool-goal' import * as ToolSchedule from '@deepseek-ai/dsh-tool-schedule' import type ScheduleService from '@deepseek-ai/dsh-schedule' @@ -77,7 +77,7 @@ import { registerListSubagentModels } from '../packages/subagent/tool-subagent/s import * as ToolWeb from '@deepseek-ai/dsh-tool-web' import WorkflowEngine from '@deepseek-ai/dsh-workflow' import type { WorkflowRun, WorkflowStartRequest } from '@deepseek-ai/dsh-workflow' -import * as ToolRalph from '@deepseek-ai/dsh-tool-ralph' +import * as ToolRalph from '@deepseek-ai/dsh-experimental-tool-ralph' import * as ToolWorkflow from '@deepseek-ai/dsh-tool-workflow' import * as ToolWorkspaceDependencies from '@deepseek-ai/dsh-tool-workspace-dependencies' import { githubSlug } from './verify-md-links.ts' @@ -400,9 +400,9 @@ const TOOL_PACKAGES: ToolPackage[] = [ 'glob and grep are unconditional discovery tools that spawn the packaged ripgrep binary (`@vscode/ripgrep`) through ctx.subprocess as ordinary foreground calls (never background jobs) — no host `rg` install and no shell layer. The catalog uses `sampleOverCapGlobResults: true`; deployments must choose that behavior explicitly. Capped results save the complete formatted list through the optional ctx.spillStore backend; returned locators are follow-up-readable/searchable when the backend exposes local paths in co-located deployments.', }, { - pkg: '@deepseek-ai/dsh-tool-terminal', + pkg: '@deepseek-ai/dsh-experimental-tool-terminal', dir: 'tool-terminal', - source: 'packages/terminal/tool-terminal/src/index.ts', + source: 'packages/experimental/tool-terminal/src/index.ts', requires: ['ctx.workingDirectory', 'ctx.tools', 'ctx.terminals', 'ctx.systemPrompt', 'ctx.jobs at call time for run_in_background'], writes: ['tool/call', 'tool/result'], async mount(ctx) { @@ -460,9 +460,9 @@ const TOOL_PACKAGES: ToolPackage[] = [ 'The lsp tool keeps provider selection and language-server subprocesses behind ctx.lsp, so its model-visible schema stays stable across providers. Requires a registered provider (e.g. `@deepseek-ai/dsh-lsp-stdio`) at runtime; without one, a query returns the structured `LSP_UNAVAILABLE` error rather than changing the schema.', }, { - pkg: '@deepseek-ai/dsh-tool-ralph', + pkg: '@deepseek-ai/dsh-experimental-tool-ralph', dir: 'tool-ralph', - source: 'packages/workflow/tool-ralph/src/index.ts', + source: 'packages/experimental/tool-ralph/src/index.ts', requires: ['ctx.tools', 'ctx.workflowEngine', 'ctx.subagents', 'ctx.systemPrompt', 'a calling Agent (exec.agent parents every fresh round)'], writes: ['tool/call', 'tool/result', 'workflow and child session events during execution'], async mount(ctx) { diff --git a/scripts/no-unknown-casts.baseline.json b/scripts/no-unknown-casts.baseline.json index c60994dc96..61e8da8e1c 100644 --- a/scripts/no-unknown-casts.baseline.json +++ b/scripts/no-unknown-casts.baseline.json @@ -1276,18 +1276,18 @@ "packages/goal/goal/src/index.ts": { "09a26f55e58db3477446e73f59bd3cdf678ae76ff8f54d185ec4a0ce0dc7da2d": 1 }, - "packages/hooks/hook-protocol/tests/events.spec.ts": { + "packages/experimental/hook-protocol/tests/events.spec.ts": { "a59fe57e5f3994018a6bd25208b9c2f56a7bcf7353d6ec2d453564f3f5c225f2": 1 }, - "packages/hooks/hooks-claude-code/tests/bridge.spec.ts": { + "packages/experimental/hooks-claude-code/tests/bridge.spec.ts": { "38a7cf3dfd5da2f739390f5b233b97731f3bfa1ac3a51fdb8e1594735764bb80": 1 }, - "packages/hooks/hooks-claude-code/tests/coverage-cases.ts": { + "packages/experimental/hooks-claude-code/tests/coverage-cases.ts": { "38a7cf3dfd5da2f739390f5b233b97731f3bfa1ac3a51fdb8e1594735764bb80": 1, "54f541ed10b92b1386306754b4a96741f6d9e40058ddac191f5aed03af30c32a": 1, "593ac2fabae51a87153bf285d326f2de6ddb84bf2581f2ac280083b9bc130188": 1 }, - "packages/hooks/hooks-codex/tests/bridge.spec.ts": { + "packages/experimental/hooks-codex/tests/bridge.spec.ts": { "bced8a97654435422589a4bdd1b46b5147d4120cd5b496dcf055c453494ce0ab": 1 }, "packages/host/directory-picker-auto/tests/loader-composition.spec.ts": { @@ -1977,7 +1977,7 @@ "237785adfc64f6fe0cf84ce292d1da4b2065b11f82093029312356e10a3703f0": 6, "e87443b2dcbfcd641eba56e2afb1b9daaa697f89df846c40cdea6bfb9b8a7ef3": 2 }, - "packages/terminal/tool-terminal/tests/loader-composition.spec.ts": { + "packages/experimental/tool-terminal/tests/loader-composition.spec.ts": { "59c63f734e8bba862325f776e3fcbebd78a84cfb4161f8df41c216950d9bf351": 1 }, "packages/test-support/client-runtime/src/assembly/modules.ts": { @@ -2102,29 +2102,29 @@ "598014dcfe77101781e3c6a02709097e3b0151a335e909c44719fac08fdea433": 2, "ed2fec09418bc1a78fde5097fd01d5aabf903166ed1bf480a5e38bccdd3948a6": 1 }, - "packages/webhook/webhook-github/tests/body.spec.ts": { + "packages/experimental/webhook-github/tests/body.spec.ts": { "130dbbbe723b0d72d5a736596b3513f42b65a6e3909164b05bce810393f36b96": 1 }, - "packages/webhook/webhook-github/tests/handler.spec.ts": { + "packages/experimental/webhook-github/tests/handler.spec.ts": { "171a57417a610abfca8b6ef7c8a8bfe71a2c5cc27f6a52158bb9de709d51c234": 1, "981ca4f4ab5668c2c8d0d0bddf9bff66535bbdd27c8bb47816a83e610b60432f": 1, "e60b9922c7a65986547062e8ce78ac09d83b0c0ac9533030deed3a596d3067b3": 2, "f4fa3c346edf323b9d6e18fa1fc720d828de054c14daf95822308634e0e7fe15": 1 }, - "packages/webhook/webhook-github/tests/loader-composition.spec.ts": { + "packages/experimental/webhook-github/tests/loader-composition.spec.ts": { "59c63f734e8bba862325f776e3fcbebd78a84cfb4161f8df41c216950d9bf351": 1 }, - "packages/webhook/webhook/tests/loader-composition.spec.ts": { + "packages/experimental/webhook/tests/loader-composition.spec.ts": { "59c63f734e8bba862325f776e3fcbebd78a84cfb4161f8df41c216950d9bf351": 1 }, - "packages/webhook/webhook/tests/session.spec.ts": { + "packages/experimental/webhook/tests/session.spec.ts": { "febbe0687d7079e44a15b802235157043bad5a5f188348db89fe00f50532bee8": 1 }, - "packages/workflow/tool-ralph/src/index.ts": { + "packages/experimental/tool-ralph/src/index.ts": { "6fe9024d30e0d4757a348b83d246925b3f5aeaf2e79a0eff4bf12f3c9fb5826b": 1, "cec7714d93bd00a87b261199e97562ce99a73ae4b4e2414728d874d24bfed7a4": 1 }, - "packages/workflow/tool-ralph/tests/tool-ralph.spec.ts": { + "packages/experimental/tool-ralph/tests/tool-ralph.spec.ts": { "47df8a1ea0e482122f196eb20bb3ae93a50e59d7c80d822c5e8a29efd1c05eb8": 1 }, "packages/workflow/tool-workflow/tests/tool-workflow.spec.ts": { diff --git a/scripts/product-package-policy.ts b/scripts/product-package-policy.ts new file mode 100644 index 0000000000..76961bd03c --- /dev/null +++ b/scripts/product-package-policy.ts @@ -0,0 +1,50 @@ +/** Non-default package roles retained outside the experimental group. */ + +/** Product role that does not require a default runtime mount. */ +export type ProductPackageCategory = 'optional' | 'sdk' | 'build' | 'test' | 'web-distribution' | 'declarations' + +/** One explicitly maintained package role and its reason. */ +export interface ProductPackagePolicy { + /** Why this package remains outside the experimental group. */ + readonly reason: string + /** The supported product role checked against its directory. */ + readonly category: ProductPackageCategory +} + +/** + * Exceptions to default runtime reachability, keyed by repository-relative package directory. + * Optional integrations may be reached by an optional bundle without becoming default capabilities. + */ +export const PRODUCT_PACKAGE_POLICY: Readonly> = { + 'packages/browser-use/browser-use': { category: 'optional', reason: 'Service definition used by explicitly selected browser providers.' }, + 'packages/computer-use/computer-use': { category: 'optional', reason: 'Service definition used by explicitly selected computer providers.' }, + 'packages/lsp/lsp': { category: 'optional', reason: 'Service definition for deployment-configured language servers.' }, + 'packages/lsp/lsp-stdio': { category: 'optional', reason: 'Requires an explicit server list and language-server executables.' }, + 'packages/lsp/tool-lsp': { category: 'optional', reason: 'Model tools selected together with a configured LSP provider.' }, + 'packages/ssh/ssh': { category: 'optional', reason: 'Explicit remote connection and helper configuration.' }, + 'packages/ssh/fs-ssh': { category: 'optional', reason: 'Remote filesystem provider selected in an SSH composition.' }, + 'packages/ssh/sandbox-ssh': { category: 'optional', reason: 'Remote confinement provider selected in an SSH composition.' }, + 'packages/ssh/subprocess-ssh': { category: 'optional', reason: 'Remote process provider selected in an SSH composition.' }, + 'packages/storage/storage-sqlite': { category: 'optional', reason: 'Persistent storage requires an explicit database path and backend selection.' }, + 'packages/subagent/subagent-acp': { category: 'optional', reason: 'Requires a configured external ACP agent command.' }, + 'packages/subagent/subagent-claude-code': { category: 'optional', reason: 'Separately installed native Claude Code agent integration.' }, + 'packages/subagent/subagent-codex': { category: 'optional', reason: 'Separately installed native Codex agent integration.' }, + 'packages/subagent/subagent-dsh-sdk': { category: 'optional', reason: 'Requires an explicitly configured external DSH home.' }, + 'packages/web/web-search-exa': { category: 'optional', reason: 'Alternative search provider requiring its own API credentials.' }, + 'packages/web/web-search-perplexity': { category: 'optional', reason: 'Alternative search provider requiring its own API credentials.' }, + 'packages/context/tmux-context': { category: 'optional', reason: 'Context contribution requiring a tmux pane.' }, + 'packages/session-query/tool-session-query': { category: 'optional', reason: 'Session search tools selected with content indexing.' }, + 'packages/fs/tool-str-replace-editor': { category: 'optional', reason: 'Explicit alternative to the default filesystem editing tools.' }, + 'packages/sdk/client': { category: 'sdk', reason: 'Published TypeScript embedding client runs in the consumer process.' }, + 'packages/typert/generator': { category: 'build', reason: 'Build-time generation of type metadata.' }, + 'packages/test-support/agent-loop-testkit': { category: 'test', reason: 'Published agent-loop test harness.' }, + 'packages/test-support/client-runtime': { category: 'test', reason: 'Published browser plugin test harness.' }, + 'packages/test-support/llm-mock-server': { category: 'test', reason: 'Published model-provider test server.' }, + 'packages/test-support/llm-replay': { category: 'test', reason: 'Published recorded-model replay harness.' }, + 'packages/test-support/loader-smoke': { category: 'test', reason: 'Published plugin Loader smoke-test harness.' }, + 'packages/test-support/remote-mock': { category: 'test', reason: 'Published typed Remote test proxies.' }, + 'packages/test-support/session-snapshot': { category: 'test', reason: 'Published Session snapshot replay harness.' }, + 'packages/client/web': { category: 'web-distribution', reason: 'Browser boot kernel bundled into the Web distribution.' }, + 'packages/client/ui-dockkit': { category: 'web-distribution', reason: 'Layout library bundled into the Web distribution.' }, + 'packages/util/package-manifest': { category: 'declarations', reason: 'Shared package metadata declarations have no runtime mount.' }, +} diff --git a/scripts/run-gates.spec.ts b/scripts/run-gates.spec.ts index 4f2541cfa1..aac0cd7252 100644 --- a/scripts/run-gates.spec.ts +++ b/scripts/run-gates.spec.ts @@ -354,7 +354,7 @@ describe('gate graph validation', () => { const ids = withPnpmEntrypoint(() => gatesForMode('hygiene').map(subject => subject.id)) expect(ids).toEqual([ - 'rescope-vendor', 'publint', 'constraints', 'default-product-isolation', 'package-dependencies', 'application-entrypoints', + 'rescope-vendor', 'publint', 'constraints', 'default-product-isolation', 'product-use', 'package-dependencies', 'application-entrypoints', 'dsh-package-licenses', 'node-next-types', 'optional-dependency-imports', 'client-packages', 'client-ui-i18n', 'client-route-resolution', 'no-bare-dispatcher', 'plugin-record-callers', 'no-unknown-casts', diff --git a/scripts/run-gates.ts b/scripts/run-gates.ts index 0181121b57..ee355e4595 100644 --- a/scripts/run-gates.ts +++ b/scripts/run-gates.ts @@ -345,6 +345,7 @@ function ciSharedStaticGates(): Gate[] { return [ pnpmScript('runtime-closure', 'verify-runtime-closure', { label: 'runtime closure' }), pnpmScript('default-product-isolation', 'verify-default-product-isolation', { label: 'default product isolation' }), + pnpmScript('product-use', 'verify-product-use', { label: 'product package classification' }), pnpmScript('application-entrypoints', 'verify-application-entrypoints', { label: 'application entrypoints' }), pnpmScript('constraints', 'constraints'), pnpmScript('package-dependencies', 'verify-package-dependencies', { label: 'package dependencies' }), @@ -758,6 +759,7 @@ function hygieneLeafGates(options: { artifactNeeds?: string[] } = {}): Gate[] { pnpmScript('publint', 'publint', artifactOptions), pnpmScript('constraints', 'constraints'), pnpmScript('default-product-isolation', 'verify-default-product-isolation', { label: 'default product isolation' }), + pnpmScript('product-use', 'verify-product-use', { label: 'product package classification' }), pnpmScript('package-dependencies', 'verify-package-dependencies', { label: 'package dependencies' }), pnpmScript('application-entrypoints', 'verify-application-entrypoints', { label: 'application entrypoints' }), pnpmScript('dsh-package-licenses', 'verify-dsh-package-licenses', { label: 'DSH package licenses' }), diff --git a/scripts/smoke-python-runtime.py b/scripts/smoke-python-runtime.py index e7426ad5e2..d2b02d37ea 100644 --- a/scripts/smoke-python-runtime.py +++ b/scripts/smoke-python-runtime.py @@ -85,7 +85,6 @@ LEGACY_CUSTOM_DISABLED_ROWS = ( "tool-fs", "tool-fs-search", "tool-goal", - "tool-ralph", "tool-skill", "tool-str-replace-editor", "tool-subagent-control", diff --git a/scripts/verify-package-readme-model-experience.ts b/scripts/verify-package-readme-model-experience.ts index b59ac84d97..5823f9b671 100644 --- a/scripts/verify-package-readme-model-experience.ts +++ b/scripts/verify-package-readme-model-experience.ts @@ -164,13 +164,13 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly> = { 'packages/context/file-reference': { kind: 'indirect', reason: 'The discovery seam and grammar delegate model guidance to the composed provider.' }, 'packages/fs/fs': { kind: 'indirect', reason: 'The service interface delegates model rendering to dsh-tool-fs.' }, 'packages/fs/fs-local': { kind: 'indirect', reason: 'The provider backend delegates model rendering to dsh-tool-fs.' }, - 'packages/hooks/hook-protocol': { kind: 'indirect', reason: 'Only the hook bridge plugins render decoded hook output to a model.' }, + 'packages/experimental/hook-protocol': { kind: 'indirect', reason: 'Only the hook bridge plugins render decoded hook output to a model.' }, 'packages/host/directory-picker': { kind: 'none', reason: 'The GUI-host picking seam registers nothing model-facing.' }, 'packages/host/directory-picker-auto': { kind: 'none', reason: 'The GUI-host picking chooser only mounts a backend row; it registers nothing model-facing.' }, 'packages/host/directory-picker-browse': { kind: 'none', reason: 'The GUI-host picking backend registers nothing model-facing.' }, 'packages/host/directory-picker-native': { kind: 'none', reason: 'The GUI-host picking backend registers nothing model-facing.' }, 'packages/host/webserver': { kind: 'none', reason: 'The HTTP carrier bridges browser and API handler and registers nothing model-facing.' }, - 'packages/webhook/webhook-github': { kind: 'indirect', reason: 'The adapter delegates model-visible text to matching rules and dsh-webhook.' }, + 'packages/experimental/webhook-github': { kind: 'indirect', reason: 'The adapter delegates model-visible text to matching rules and dsh-experimental-webhook.' }, 'packages/host/frontend-static': { kind: 'none', reason: 'The SPA dist server answers browser asset requests and registers nothing model-facing.' }, 'packages/host/plugin-inventory': { kind: 'none', reason: 'Host-side read-only Loader projection; registers nothing model-facing.' }, 'packages/host/open-in-app': { kind: 'none', reason: 'Host routes opening desktop applications for a human; registers nothing model-facing.' }, @@ -203,7 +203,7 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly> = { 'packages/session/session-telemetry-otel': { kind: 'none', reason: 'The backend forwards seam records into the OTel SDK pipeline and registers nothing model-facing.' }, 'packages/identity/anonymous-user-id': { kind: 'none', reason: 'The shared identifier reaches DeepSeek only as model-hidden HTTP metadata; it registers nothing model-facing.' }, 'packages/skill/skill': { kind: 'indirect', reason: 'The provider registry delegates model rendering to dsh-tool-skill.' }, - 'packages/skill/skill-badge': { kind: 'indirect', reason: 'The bundled provider delegates model rendering to dsh-tool-skill.' }, + 'packages/experimental/skill-badge': { kind: 'indirect', reason: 'The bundled provider delegates model rendering to dsh-tool-skill.' }, 'packages/skill/skill-office': { kind: 'indirect', reason: 'The bundled Office provider delegates model rendering to dsh-tool-skill.' }, 'packages/skill/skill-filesystem': { kind: 'indirect', reason: 'The provider backend delegates model rendering to dsh-tool-skill.' }, 'packages/spill/spill': { kind: 'indirect', reason: 'The storage seam delegates model rendering to spill consumers.' }, diff --git a/scripts/verify-product-use.spec.ts b/scripts/verify-product-use.spec.ts new file mode 100644 index 0000000000..a405302c06 --- /dev/null +++ b/scripts/verify-product-use.spec.ts @@ -0,0 +1,288 @@ +/** Product-use regressions exercise source reachability and effective Loader composition. */ + +import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' +import { afterEach, describe, expect, it } from 'vitest' +import type { ProductPackagePolicy } from './product-package-policy.ts' +import { verifyProductUse } from './verify-product-use.ts' + +const roots: string[] = [] +const base = '@deepseek-ai/dsh-base' +const core = '@deepseek-ai/dsh-core' +const candidate = '@deepseek-ai/dsh-candidate' +const candidateDir = 'packages/core/candidate' +const profile = 'packages/boot/app-boot/src/profile.ts' +const patch = 'packages/bundle/base/cordis.patch.yml' + +function write(root: string, path: string, value: unknown): void { + const target = join(root, path) + mkdirSync(dirname(target), { recursive: true }) + writeFileSync(target, typeof value === 'string' ? value : `${JSON.stringify(value)}\n`) +} + +function pkg(root: string, directory: string, name: string, fields: Record = {}): void { + write(root, `${directory}/package.json`, { name, ...fields }) + write(root, `${directory}/src/index.ts`, 'export {}\n') + const config = JSON.parse(readFileSync(join(root, 'tsconfig.base.json'), 'utf8')) as { + compilerOptions: { paths: Record } + } + config.compilerOptions.paths[name] = [`./${directory}/src/index.ts`] + config.compilerOptions.paths[`${name}/*`] = [`./${directory}/src/*.ts`] + write(root, 'tsconfig.base.json', config) +} + +function profiles(root: string, optional: string[] = []): void { + write(root, profile, `export const PROFILE_TEMPLATES = ${JSON.stringify(Object.fromEntries( + ['web', 'acp', 'headless', 'sdk', 'sdk-minimal'].map(name => [name, { bundles: [base] }]), + ))}\nexport const DEFAULT_PROFILE_BUNDLES = ['${base}']\nexport const OPTIONAL_BUNDLES = ${JSON.stringify(optional)}\n`) +} + +function fixture(): string { + const root = mkdtempSync(join(tmpdir(), 'dsh-product-use-')) + roots.push(root) + write(root, 'tsconfig.base.json', { compilerOptions: { moduleResolution: 'bundler', paths: {} } }) + pkg(root, 'apps/cli', '@deepseek-ai/dsh') + pkg(root, 'apps/desktop', '@fixture/desktop') + pkg(root, 'apps/web', '@fixture/web') + write(root, 'apps/cli/src/bin.ts', 'export {}\n') + write(root, 'apps/desktop/src/main.ts', 'export {}\n') + write(root, 'apps/web/src/main.ts', 'export {}\n') + write(root, 'apps/web/index.html', '') + pkg(root, 'packages/bundle/base', base, { dsh: { bundle: { patch: './cordis.patch.yml' } } }) + pkg(root, 'packages/core/core', core) + write(root, patch, [{ insert: [{ id: 'core', name: core }] }]) + profiles(root) + return root +} + +function declarations(category: ProductPackagePolicy['category'] = 'optional'): Record { + return { [candidateDir]: { category, reason: 'Selected by the operator.' } } +} + +function failures(root: string, policy: Record = {}): string { + return verifyProductUse(root, policy).failures.join('\n') +} + +afterEach(() => { + for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true }) +}) + +describe('product package use', () => { + it('accepts a complete effective composition without build outputs', () => { + expect(verifyProductUse(fixture(), {})).toMatchObject({ failures: [], optionalPackages: [], configCount: 1 }) + }) + + it('rejects an orphan even when an app manifest installs it', () => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, 'apps/cli/package.json', { name: '@deepseek-ai/dsh', dependencies: { [candidate]: '*' } }) + expect(failures(root)).toContain(`${candidateDir} (${candidate}): no product runtime use`) + expect(failures(root, declarations())).toBe('') + }) + + it.each([ + `import type { Shape } from '${candidate}'`, + `import { type Shape } from '${candidate}'`, + `export type * from '${candidate}'`, + `type Shape = import('${candidate}').Shape`, + ])('does not count type-only source: %s', (source) => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, 'apps/cli/src/bin.ts', source) + expect(failures(root)).toContain('no product runtime use') + }) + + it.each([ + `import '${candidate}'`, `export * from '${candidate}'`, + `await import('${candidate}')`, `const value = require('${candidate}')`, + ])('follows runtime source: %s', (source) => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, 'apps/cli/src/bin.ts', source) + expect(failures(root)).toBe('') + expect(failures(root, declarations())).toContain('stale optional policy') + }) + + it('follows only reached local modules, including cycles and worker URLs', () => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, 'apps/cli/src/unreachable.ts', `import '${candidate}'`) + expect(failures(root)).toContain('no product runtime use') + write(root, 'apps/cli/src/bin.ts', "import './cycle.ts'\nnew URL('./worker.js', import.meta.url)") + write(root, 'apps/cli/src/cycle.ts', "import './bin.ts'") + write(root, 'apps/cli/src/worker.ts', `import '${candidate}'`) + expect(failures(root)).toBe('') + }) + + it.each(['apps/desktop/src/main.ts', 'apps/web/src/main.ts'])('reaches the %s entrypoint', (entry) => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, entry, `import '${candidate}'`) + expect(failures(root)).toBe('') + }) + + it.each(['acp', 'headless', 'sdk', 'sdk-minimal'])('composes the %s profile independently', (name) => { + const root = fixture() + pkg(root, candidateDir, candidate, { dsh: { bundle: { patch: './feature.patch.yml' } } }) + write(root, `${candidateDir}/feature.patch.yml`, [{ insert: [{ name: candidate }] }]) + const source = readFileSync(join(root, profile), 'utf8') + write(root, profile, source.replace(`"${name}":{"bundles":["${base}"]}`, `"${name}":{"bundles":["${base}","${candidate}"]}`)) + expect(failures(root)).toBe('') + }) + + it.each([true, false])('excludes disabled Include children with initial=%s', (initial) => { + const root = fixture() + pkg(root, candidateDir, candidate) + const children = [{ name: candidate }] + if (!initial) write(root, 'packages/boot/app-boot/src/included.yml', children) + write(root, patch, [{ insert: [{ name: core }, { + name: 'cordis:include', disabled: true, config: { path: './included.yml', ...(initial ? { initial: children } : {}) }, + }] }]) + expect(failures(root)).toContain('no product runtime use') + }) + + it('honors disabled groups, presets, nested initial entries, and conditional disabled expressions', () => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, patch, [{ insert: [{ name: core }, { group: true, disabled: true, config: [{ name: candidate }] }, + { name: 'cordis:include', config: { path: './missing.yml', initial: [{ disabled: true, group: true, config: [{ name: candidate }] }] } }] }]) + expect(failures(root)).toContain('no product runtime use') + write(root, patch, `- insert:\n - name: '${core}'\n - name: '${candidate}'\n disabled: !!js process.platform === 'win32'\n`) + expect(failures(root)).toBe('') + }) + + it('applies Include patches before collecting runtime mounts and uses files ahead of initial entries', () => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, 'packages/boot/app-boot/src/included.yml', [{ id: 'child', name: candidate }]) + write(root, patch, [{ insert: [{ name: core }, { name: 'cordis:include', config: { + path: './included.yml', initial: [{ name: candidate }], patches: [{ id: 'child', disabled: true }], + } }] }]) + expect(failures(root)).toContain('no product runtime use') + write(root, 'packages/boot/app-boot/src/included.yml', []) + expect(failures(root)).toContain('no product runtime use') + }) + + it('ignores unmatched insertions and later replaced or disabled rows', () => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, patch, [ + { insert: [{ id: 'root', group: true, config: [{ name: candidate }] }, { id: 'candidate', name: candidate }, { name: core }] }, + { id: 'missing', insert: [{ name: candidate }] }, + { id: 'root', config: [] }, { id: 'candidate', disabled: true }, + ]) + expect(failures(root)).toContain('no product runtime use') + }) + + it('visits nested preset entries only while the preset is enabled', () => { + const root = fixture() + pkg(root, candidateDir, candidate) + pkg(root, 'packages/preset/agent-preset', '@deepseek-ai/dsh-agent-preset') + const entry = { id: 'preset', name: '@deepseek-ai/dsh-agent-preset', config: { + id: 'standard', plugins: [{ group: true, config: [{ name: candidate }] }], + } } + write(root, patch, [{ insert: [{ name: core }, entry] }]) + expect(failures(root)).toBe('') + write(root, patch, [{ insert: [{ name: core }, entry] }, { id: 'preset', disabled: true }]) + expect(failures(root)).toContain(`${candidateDir} (${candidate}): no product runtime use`) + }) + + it('keeps optional selection and its runtime closure separate from default use', () => { + const root = fixture() + const bundle = '@deepseek-ai/dsh-experimental-feature' + pkg(root, 'packages/experimental/feature', bundle, { dsh: { bundle: { patch: './cordis.patch.yml' } } }) + pkg(root, candidateDir, candidate) + pkg(root, 'packages/core/indirect', '@deepseek-ai/dsh-indirect') + write(root, `${candidateDir}/src/index.ts`, "import '@deepseek-ai/dsh-indirect'") + write(root, 'packages/experimental/feature/cordis.patch.yml', [{ insert: [{ name: candidate }] }]) + profiles(root, [bundle]) + const result = verifyProductUse(root, declarations()) + expect(result.failures).toEqual([]) + expect(result.optionalPackages).toEqual([candidateDir, 'packages/core/indirect', 'packages/experimental/feature']) + expect(result.defaultPackages).not.toContain(candidateDir) + }) + + it('does not count an optional patch whose target is absent', () => { + const root = fixture() + const bundle = '@deepseek-ai/dsh-experimental-feature' + pkg(root, 'packages/experimental/feature', bundle, { dsh: { bundle: { patch: './cordis.patch.yml' } } }) + pkg(root, candidateDir, candidate) + write(root, 'packages/experimental/feature/cordis.patch.yml', [{ id: 'absent', insert: [{ name: candidate }] }]) + profiles(root, [bundle]) + expect(failures(root)).toContain('no product runtime use') + }) + + it('counts declared generated Remote metadata without loading an artifact or its Host implementation', () => { + const root = fixture() + pkg(root, candidateDir, candidate, { exports: { './remote': { + types: './lib/typert.remote-client.d.ts', default: './lib/typert.remote-client.js', + } } }) + pkg(root, 'packages/core/host-only', '@deepseek-ai/dsh-host-only') + write(root, `${candidateDir}/src/index.ts`, "import '@deepseek-ai/dsh-host-only'") + write(root, 'apps/web/src/main.ts', `import '${candidate}/remote'`) + const result = verifyProductUse(root, {}) + expect(result.defaultPackages).toContain(candidateDir) + expect(result.defaultPackages).not.toContain('packages/core/host-only') + expect(result.failures).toEqual([ + 'packages/core/host-only (@deepseek-ai/dsh-host-only): no product runtime use; mount it, declare its maintained role, or move it to experimental', + ]) + }) + + it('rejects a missing workspace source mapping instead of consulting built exports', () => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, 'apps/cli/src/bin.ts', `import '${candidate}/missing'`) + expect(failures(root)).toContain('does not resolve to workspace source') + }) + + it('resolves an inserted relative plugin beside its declaring bundle', () => { + const root = fixture() + pkg(root, candidateDir, candidate) + write(root, 'packages/bundle/base/local.ts', `import '${candidate}'`) + write(root, patch, [{ insert: [{ name: core }, { name: './local.ts' }] }]) + expect(failures(root)).toBe('') + }) + + it('follows explicit directory-picker dynamic mounts and their client face', () => { + const root = fixture() + const picker = '@deepseek-ai/dsh-host-directory-picker-auto' + pkg(root, 'packages/host/directory-picker-auto', picker) + pkg(root, candidateDir, candidate, { dsh: { client: { platform: 'web' } } }) + pkg(root, 'packages/client/indirect', '@deepseek-ai/dsh-client-indirect') + write(root, `${candidateDir}/src/client.ts`, "import '@deepseek-ai/dsh-client-indirect'") + write(root, 'packages/host/directory-picker-auto/src/index.ts', + `export const BACKEND_PACKAGES = { native: '${candidate}' }\nexport const SURFACE_PACKAGES = { native: '${candidate}' }\n`) + write(root, patch, [{ insert: [{ name: core }, { name: picker }] }]) + expect(failures(root)).toBe('') + }) + + it('accepts declaration-only infrastructure and rejects missing or miscategorized policy entries', () => { + const root = fixture() + const directory = 'packages/util/package-manifest' + pkg(root, directory, '@deepseek-ai/dsh-package-manifest') + expect(failures(root)).toContain(`${directory} (@deepseek-ai/dsh-package-manifest): no product runtime use`) + expect(failures(root, { [directory]: { category: 'declarations', reason: 'Shared public metadata types.' } })).toBe('') + pkg(root, candidateDir, candidate) + expect(failures(root, declarations('declarations'))).toContain('invalid policy category declarations') + expect(failures(root, { 'packages/core/missing': { category: 'optional', reason: 'Missing.' } })).toContain('stale package policy') + }) + + it('requires a declared Web distribution package to remain source-reachable', () => { + const root = fixture() + const directory = 'packages/client/web' + const name = '@deepseek-ai/dsh-client-web' + pkg(root, directory, name) + const policy = { [directory]: { category: 'web-distribution', reason: 'Browser boot kernel.' } } as const + expect(failures(root, policy)).toContain('stale web-distribution policy') + write(root, 'apps/web/src/main.ts', `import '${name}'`) + expect(failures(root, policy)).toBe('') + }) + + it('fails when the shipped profile corpus is narrowed', () => { + const root = fixture() + const source = readFileSync(join(root, profile), 'utf8') + write(root, profile, source.replace(/"acp":\{"bundles":\[[^\]]+\]\},/, '')) + expect(failures(root)).toContain('missing shipped acp profile') + }) +}) diff --git a/scripts/verify-product-use.ts b/scripts/verify-product-use.ts new file mode 100644 index 0000000000..09860f5622 --- /dev/null +++ b/scripts/verify-product-use.ts @@ -0,0 +1,312 @@ +/** Check that maintained packages have effective product use or an explicit non-default role. */ + +import { existsSync, globSync, readFileSync, statSync } from 'node:fs' +import { dirname, extname, relative, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { JSDOM } from 'jsdom' +import ts from 'typescript' +import { applyEntryPatches, type PatchOptions } from '@deepseek-ai/cordis-plugin-include' +import type { EntryOptions } from '@deepseek-ai/cordis-plugin-loader' +import { loadOverlayPatches } from '../packages/boot/app-boot/src/index.ts' +import { bundlePatchPaths, composeEntries } from '../packages/boot/app-boot/src/profile.ts' +import type { DshBundleManifest } from '../packages/util/package-manifest/src/types.ts' +import { assertNever } from '../packages/util/values/src/index.ts' +import { isAgentPresetEntry, isCordisGroupEntry, loadCordisYaml } from './cordis-yaml.ts' +import { PRODUCT_PACKAGE_POLICY, type ProductPackagePolicy } from './product-package-policy.ts' +import { collectRuntimeLocalSourceSpecifiers, collectRuntimeSourceSpecifiers } from './verify-client-packages.ts' + +const PROFILE_SOURCE = 'packages/boot/app-boot/src/profile.ts' +const PROFILES = ['acp', 'web', 'headless', 'sdk', 'sdk-minimal'] +const PICKER_SOURCE = 'packages/host/directory-picker-auto/src/index.ts' +const DYNAMIC_MOUNTS: Readonly> = { + [PICKER_SOURCE]: ['BACKEND_PACKAGES', 'SURFACE_PACKAGES'], +} + +interface Package { + directory: string + name: string + bundle?: DshBundleManifest + client: boolean + generatedRemote: boolean +} + +interface Reachability { + packages: Set + sources: Set +} + +/** Effective runtime package use, with explicit selections separated from shipped defaults. */ +export interface ProductUseResult { + /** Violations name the package and the required correction. */ + failures: string[] + /** Repository-relative package directories reached by a default product entry. */ + defaultPackages: string[] + /** Repository-relative package directories reached only after optional selection. */ + optionalPackages: string[] + /** Workspace packages inventoried, including experimental packages and app roots. */ + packageCount: number + /** Distinct source modules reached across both selections. */ + sourceCount: number + /** Effective compositions read, including Include files. */ + configCount: number +} + +/** + * Verify effective product composition and source imports without reading built workspace outputs. + * @param root - Repository root with source mappings and shipped profile declarations. + * @param policy - Explicit non-default roles; defaults to the repository-owned policy. + * @returns Default/optional reachability and every undeclared or stale package-policy violation. + */ +export function verifyProductUse( + root: string, policy: Readonly> = PRODUCT_PACKAGE_POLICY, +): ProductUseResult { + const failures: string[] = [] + const display = (path: string): string => relative(root, path).replaceAll('\\', '/') + const packages = new Map() + const directories = new Map() + const configs = new Set() + const defaults: Reachability = { packages: new Set(), sources: new Set() } + const optional: Reachability = { packages: new Set(), sources: new Set() } + const config = ts.readConfigFile(resolve(root, 'tsconfig.base.json'), path => ts.sys.readFile(path)) + if (config.error !== undefined) throw new Error(ts.flattenDiagnosticMessageText(config.error.messageText, '\n')) + const converted = ts.convertCompilerOptionsFromJson( + (config.config as { compilerOptions?: unknown }).compilerOptions, root, + ) + if (converted.errors.length > 0) throw new Error(converted.errors.map(error => ts.flattenDiagnosticMessageText(error.messageText, '\n')).join('\n')) + const host: ts.ModuleResolutionHost = { ...ts.sys, getCurrentDirectory: () => root } + const resolutionCache = ts.createModuleResolutionCache(root, path => path, converted.options) + for (const path of globSync(['apps/*/package.json', 'packages/*/*/package.json', 'vendor/*/package.json'], { cwd: root }).map(path => path.replaceAll('\\', '/')).sort()) { + const manifest = JSON.parse(readFileSync(resolve(root, path), 'utf8')) as { + name: string + exports?: Record + dsh?: { bundle?: DshBundleManifest; client?: unknown } + } + if (typeof manifest.name !== 'string' || manifest.name === '') throw new Error(`${path}: missing package name`) + if (packages.has(manifest.name)) throw new Error(`${path}: duplicate package name ${manifest.name}`) + const remote = manifest.exports?.['./remote'] + const pkg: Package = { directory: dirname(path), name: manifest.name, client: manifest.dsh?.client !== undefined, + generatedRemote: isRecord(remote) && remote.default === './lib/typert.remote-client.js' + && remote.types === './lib/typert.remote-client.d.ts', + ...(manifest.dsh?.bundle === undefined ? {} : { bundle: manifest.dsh.bundle }) } + packages.set(pkg.name, pkg) + directories.set(resolve(root, pkg.directory), pkg) + } + if (packages.size === 0) failures.push('no workspace packages found; restore the package inventory') + const ownerOf = (path: string): Package | undefined => { + for (let dir = dirname(path); dir !== dirname(dir); dir = dirname(dir)) { + const pkg = directories.get(dir) + if (pkg !== undefined) return pkg + } + return undefined + } + const resolveModule = (specifier: string, from: string): string | undefined => { + const resolved = ts.resolveModuleName(specifier, from, converted.options, host, resolutionCache).resolvedModule + if (resolved === undefined || resolved.resolvedFileName.replaceAll('\\', '/').includes('/node_modules/')) return undefined + const path = resolved.resolvedFileName + if (/(?:^|\/)lib\//.test(display(path)) || path.endsWith('.d.ts')) return undefined + return path + } + const scanSource = (path: string, reach: Reachability): void => { + if (reach.sources.has(path)) return + if (!existsSync(path)) { failures.push(`${display(path)}: missing product source entry`); return } + reach.sources.add(path) + const owner = ownerOf(path) + if (owner !== undefined) reach.packages.add(owner.directory) + const source = readFileSync(path, 'utf8') + for (const specifier of collectRuntimeSourceSpecifiers(path, source)) reference(specifier, path, reach) + for (const specifier of collectRuntimeLocalSourceSpecifiers(path, source, true)) { + const resolved = specifier.startsWith('/') + ? sourceFile(resolve(root, 'apps/web', `.${specifier}`)) : resolveModule(specifier, path) + if (resolved !== undefined) scanSource(resolved, reach) + else if (/\.[cm]?[jt]sx?$/.test(specifier)) failures.push(`${display(path)}: source import ${specifier} does not resolve to source`) + } + const file = ts.createSourceFile(path, source, ts.ScriptTarget.Latest, true) + const visit = (node: ts.Node): void => { + if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'URL') { + const first = node.arguments?.[0] + const base = node.arguments?.[1] + if (first !== undefined && ts.isStringLiteralLike(first) && first.text.startsWith('.') + && base?.getText(file) === 'import.meta.url') { + const target = sourceFile(resolve(dirname(path), first.text)) + if (target !== undefined) scanSource(target, reach) + } + } + ts.forEachChild(node, visit) + } + visit(file) + for (const declaration of DYNAMIC_MOUNTS[display(path)] ?? []) { + const value = literalDeclaration(file, declaration) + if (!isRecord(value) || Object.keys(value).length === 0 || !Object.values(value).every(item => typeof item === 'string')) { + failures.push(`${display(path)}: dynamic mount ${declaration} must declare literal package targets`) + continue + } + for (const target of Object.values(value)) if (typeof target === 'string') mount(target, path, reach) + } + } + const reference = (specifier: string, from: string, reach: Reachability): void => { + if (specifier.startsWith('cordis:')) return + const normalized = specifier.startsWith('file:') ? fileURLToPath(specifier) : specifier + const name = /^(?:@[^/]+\/)?[^/]+/.exec(specifier)?.[0] ?? specifier + const pkg = packages.get(name) + if (pkg !== undefined) reach.packages.add(pkg.directory) + // Typert Remote contributions contain generated descriptors and external codecs, with no workspace runtime imports. + if (pkg?.generatedRemote && specifier === `${pkg.name}/remote`) return + const target = resolveModule(normalized, from) + if (target !== undefined) scanSource(target, reach) + else if (pkg !== undefined && !/\.(?:json|css|svg|ya?ml)$/.test(specifier)) { + failures.push(`${display(from)}: ${specifier} does not resolve to workspace source; add a tsconfig.base.json paths mapping`) + } else if (pkg === undefined && specifier.startsWith('@deepseek-ai/dsh-')) { + failures.push(`${display(from)}: unknown workspace package ${specifier}`) + } + } + const mount = (specifier: string, from: string, reach: Reachability): void => { + reference(specifier, from, reach) + const pkg = packages.get(specifier) + if (pkg?.client) reference(`${specifier}/client`, from, reach) + } + const scanEntries = (entries: readonly unknown[], from: string, reach: Reachability, stack: ReadonlySet = new Set()): void => { + for (const row of entries) { + if (!isRecord(row) || row.disabled === true) continue + if (typeof row.name === 'string') mount(row.name, from, reach) + if (isCordisGroupEntry(row) || row.name === 'cordis:group' && Array.isArray(row.config)) { + scanEntries(row.config as unknown[], from, reach, stack) + } + if (isAgentPresetEntry(row)) scanEntries(row.config.plugins, from, reach, stack) + if ((row.name !== '@deepseek-ai/cordis-plugin-include' && row.name !== 'cordis:include') || !isRecord(row.config)) continue + const path = row.config.path + if (typeof path !== 'string') { failures.push(`${display(from)}: Include path must be a literal string`); continue } + const filename = path.startsWith('file:') ? fileURLToPath(path) : resolve(dirname(from), path) + if (stack.has(filename)) { failures.push(`${display(from)}: cyclic Include ${display(filename)}`); continue } + const content: unknown = existsSync(filename) ? loadCordisYaml(readFileSync(filename, 'utf8')) : row.config.initial + configs.add(filename) + if (!Array.isArray(content)) { failures.push(`${display(filename)}: Include requires an entry array or initial entries`); continue } + const entries = applyEntryPatches(content as EntryOptions[], row.config.patches as PatchOptions[] | undefined, () => {}) + scanEntries(entries, filename, reach, new Set([...stack, filename])) + } + } + const profilePath = resolve(root, PROFILE_SOURCE) + const profileFile = ts.createSourceFile(profilePath, readFileSync(profilePath, 'utf8'), ts.ScriptTarget.Latest, true) + const templates = literalDeclaration(profileFile, 'PROFILE_TEMPLATES') + const fallback = stringList(literalDeclaration(profileFile, 'DEFAULT_PROFILE_BUNDLES'), PROFILE_SOURCE) + const optionals = stringList(literalDeclaration(profileFile, 'OPTIONAL_BUNDLES'), PROFILE_SOURCE) + if (!isRecord(templates)) throw new Error(`${PROFILE_SOURCE}: PROFILE_TEMPLATES must be a literal object`) + for (const name of PROFILES) if (!isRecord(templates[name])) failures.push(`${PROFILE_SOURCE}: missing shipped ${name} profile`) + const layers = (names: readonly string[], reach: Reachability): PatchOptions[][] => names.flatMap((name) => { + const pkg = packages.get(name) + if (pkg?.bundle === undefined) { failures.push(`${PROFILE_SOURCE}: ${name} must declare dsh.bundle.patch`); return [] } + reach.packages.add(pkg.directory) + return [bundlePatchPaths(resolve(root, pkg.directory), pkg.bundle).flatMap((path) => { + configs.add(path) + return loadOverlayPatches('verify-product-use', path) + })] + }) + const profiles = [...Object.entries(templates).map(([name, value]) => { + if (!isRecord(value)) throw new Error(`${PROFILE_SOURCE}: invalid ${name} profile`) + return stringList(value.bundles, `${PROFILE_SOURCE} ${name}`) + }), fallback] + for (const names of profiles) { + if (names.length === 0) failures.push(`${PROFILE_SOURCE}: shipped profile has no bundles`) + scanEntries(composeEntries(layers(names, defaults)), profilePath, defaults) + } + const web = templates.web + if (isRecord(web)) { + const webBundles = stringList(web.bundles, `${PROFILE_SOURCE} web`) + for (const bundle of optionals) scanEntries(composeEntries(layers([...webBundles, bundle], optional)), profilePath, optional) + } + for (const path of ['apps/cli/src/bin.ts', 'apps/desktop/src/main.ts']) scanSource(resolve(root, path), defaults) + const htmlPath = resolve(root, 'apps/web/index.html') + const dom = new JSDOM(readFileSync(htmlPath, 'utf8')) + try { + const scripts = [...dom.window.document.querySelectorAll('script[type="module"]')] + if (scripts.length === 0) failures.push('apps/web/index.html: missing product module entry') + for (const script of scripts) { + const path = script.getAttribute('src') + if (path === null || /^(?:https?:)?\/\//.test(path)) { + failures.push('apps/web/index.html: product module entries must name local source files') + } else scanSource(resolve(root, 'apps/web', path.replace(/^\//, '')), defaults) + } + } finally { dom.window.close() } + for (const [path, entry] of Object.entries(policy)) { + const pkg = directories.get(resolve(root, path)) + if (!/^packages\/[^/]+\/[^/]+$/.test(path) || path.startsWith('packages/experimental/') || pkg === undefined) { + failures.push(`${path}: stale package policy; remove the missing or ineligible directory`) + continue + } + if (entry.reason.trim() === '') failures.push(`${path} (${pkg.name}): package policy requires a reason`) + if (!validCategory(path, entry.category)) failures.push(`${path} (${pkg.name}): invalid policy category ${entry.category}`) + if (entry.category !== 'web-distribution' && defaults.packages.has(path)) { + failures.push(`${path} (${pkg.name}): stale ${entry.category} policy; default runtime use requires removing this declaration`) + } + if (entry.category === 'web-distribution' && !defaults.packages.has(path)) { + failures.push(`${path} (${pkg.name}): stale web-distribution policy; restore its product source entry or correct its role`) + } + } + for (const pkg of packages.values()) { + if (!pkg.directory.startsWith('packages/') || pkg.directory.startsWith('packages/experimental/')) continue + if (!defaults.packages.has(pkg.directory) && !optional.packages.has(pkg.directory) && policy[pkg.directory] === undefined) { + failures.push(`${pkg.directory} (${pkg.name}): no product runtime use; mount it, declare its maintained role, or move it to experimental`) + } + } + return { failures: [...new Set(failures)].sort(), defaultPackages: [...defaults.packages].sort(), + optionalPackages: [...optional.packages].filter(path => !defaults.packages.has(path)).sort(), packageCount: packages.size, + sourceCount: new Set([...defaults.sources, ...optional.sources]).size, configCount: configs.size } +} + +function validCategory(path: string, category: ProductPackagePolicy['category']): boolean { + switch (category) { + case 'optional': return !path.startsWith('packages/test-support/') + case 'test': return path.startsWith('packages/test-support/') + case 'sdk': return path === 'packages/sdk/client' + case 'build': return path === 'packages/typert/generator' + case 'web-distribution': return path === 'packages/client/web' || path === 'packages/client/ui-dockkit' + case 'declarations': return path === 'packages/util/package-manifest' + default: return assertNever(category) + } +} + +function sourceFile(path: string): string | undefined { + if (!/\.[cm]?[jt]sx?$/.test(path)) return undefined + const stem = path.slice(0, -extname(path).length) + return [path, `${stem}.ts`, `${stem}.tsx`, `${stem}.mts`, `${stem}.cts`] + .find(candidate => existsSync(candidate) && statSync(candidate).isFile() && !candidate.endsWith('.d.ts')) +} + +function isRecord(value: unknown): value is Record { + return typeof value === 'object' && value !== null && !Array.isArray(value) +} + +function stringList(value: unknown, origin: string): string[] { + if (!Array.isArray(value) || !value.every((item: unknown) => typeof item === 'string')) throw new Error(`${origin}: expected a literal package list`) + return value +} + +function literalDeclaration(file: ts.SourceFile, name: string): unknown { + const read = (node: ts.Expression): unknown => { + if (ts.isStringLiteralLike(node)) return node.text + if (ts.isArrayLiteralExpression(node)) return node.elements.map(read) + if (ts.isObjectLiteralExpression(node)) return Object.fromEntries(node.properties.map((property) => { + if (!ts.isPropertyAssignment(property) || !ts.isIdentifier(property.name) && !ts.isStringLiteralLike(property.name)) { + throw new Error(`${file.fileName}: ${name} requires literal properties`) + } + return [property.name.text, read(property.initializer)] + })) + if (ts.isAsExpression(node) || ts.isSatisfiesExpression(node) || ts.isParenthesizedExpression(node)) return read(node.expression) + throw new Error(`${file.fileName}: ${name} requires literal package declarations`) + } + for (const statement of file.statements) { + if (!ts.isVariableStatement(statement)) continue + for (const declaration of statement.declarationList.declarations) { + if (ts.isIdentifier(declaration.name) && declaration.name.text === name && declaration.initializer !== undefined) { + return read(declaration.initializer) + } + } + } + throw new Error(`${file.fileName}: missing ${name} declaration`) +} + +if (process.argv[1] !== undefined && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + const result = verifyProductUse(resolve(dirname(fileURLToPath(import.meta.url)), '..')) + for (const failure of result.failures) console.error(failure) + if (result.failures.length > 0) process.exitCode = 1 + else console.log(`Product use: ${String(result.defaultPackages.length)} default, ${String(result.optionalPackages.length)} optional packages; ${String(result.sourceCount)} source modules.`) +} diff --git a/scripts/verify-subsystem-pages.ts b/scripts/verify-subsystem-pages.ts index bbe0ff3327..159352e037 100644 --- a/scripts/verify-subsystem-pages.ts +++ b/scripts/verify-subsystem-pages.ts @@ -17,7 +17,6 @@ const root = resolve(import.meta.dirname, '..') export const GROUPS_WITHOUT_SUBSYSTEM_PAGE: Readonly> = { acp: 'Protocol transport entry point; the server package README owns its interoperability contract.', bundle: 'Composition patch carriers whose mounted packages own all runtime contracts.', - hooks: 'External hook-protocol bridges over existing interception points, not a new Harness service.', sdk: 'Out-of-process protocol and client packages whose package READMEs own the SDK contracts.', 'test-support': 'Repository test harnesses; docs/testing.md owns the testing policy they serve.', util: 'Low-level primitives whose business semantics remain with their consuming subsystems.', diff --git a/snapshots/acp/escalation-approved/cordis.yml b/snapshots/acp/escalation-approved/cordis.yml index 08e9986ee3..a0bfa2c372 100644 --- a/snapshots/acp/escalation-approved/cordis.yml +++ b/snapshots/acp/escalation-approved/cordis.yml @@ -71,12 +71,12 @@ - insert: - id: hooks-claude-code - name: '@deepseek-ai/dsh-hooks-claude-code' + name: '@deepseek-ai/dsh-experimental-hooks-claude-code' config: configPath: ./hooks.json - id: hooks-codex - name: '@deepseek-ai/dsh-hooks-codex' + name: '@deepseek-ai/dsh-experimental-hooks-codex' config: configPath: ./codex-hooks.json diff --git a/snapshots/sdk/persistent-tools/cordis.yml b/snapshots/sdk/persistent-tools/cordis.yml index e28f49f0e6..6262d2fb44 100644 --- a/snapshots/sdk/persistent-tools/cordis.yml +++ b/snapshots/sdk/persistent-tools/cordis.yml @@ -108,10 +108,6 @@ name: '@deepseek-ai/dsh-tool-goal' disabled: true -- id: tool-ralph - name: '@deepseek-ai/dsh-tool-ralph' - disabled: true - - id: tool-web name: '@deepseek-ai/dsh-tool-web' disabled: true diff --git a/snapshots/session/headless.snapshot.ts b/snapshots/session/headless.snapshot.ts index 710737735f..c5646c3691 100644 --- a/snapshots/session/headless.snapshot.ts +++ b/snapshots/session/headless.snapshot.ts @@ -1201,9 +1201,7 @@ describe('headless recorded-session snapshots', () => { ...existsSync(join(scenario.dir, 'runtime.cordis.yml')) ? [join(scenario.dir, 'runtime.cordis.yml')] : [], ] const patchRoot = '.snapshot-patches' - const patches = patchSources.map((source, index) => source.endsWith('.snapshot.yml') - ? join(patchRoot, `${String(index)}-${basename(source)}`) - : source) + const patches = patchSources.map((source, index) => join(patchRoot, `${String(index)}-${basename(source)}`)) let actualLogs: SessionLog[] = [] let initialWorkspace: WorkspaceSnapshotEntry[] | undefined @@ -1259,9 +1257,7 @@ describe('headless recorded-session snapshots', () => { if (scenario.manifest.workspace?.parent === 'outside-temp') assertWorkspaceOutsideTemp(cwd) await mkdir(join(cwd, patchRoot), { recursive: true }) patchSources.forEach((source, index) => { - if (source.endsWith('.snapshot.yml')) { - materializeProfilePatch(source, cwd, 'headless', join(cwd, patchRoot), index) - } + materializeProfilePatch(source, cwd, 'headless', join(cwd, patchRoot), index) }) if (mcpDemo !== undefined) { const profileDir = join(cwd, '.dsh/profiles/headless') diff --git a/snapshots/session/pty-tools-sandbox-backend/cordis.snapshot.yml b/snapshots/session/pty-tools-sandbox-backend/cordis.snapshot.yml index a912d7ffbd..73e64267f8 100644 --- a/snapshots/session/pty-tools-sandbox-backend/cordis.snapshot.yml +++ b/snapshots/session/pty-tools-sandbox-backend/cordis.snapshot.yml @@ -9,7 +9,7 @@ - id: pty-snapshot-backend name: './pty-snapshot-backend.mjs' - id: tool-terminal - name: '@deepseek-ai/dsh-tool-terminal' + name: '@deepseek-ai/dsh-experimental-tool-terminal' config: maxResultBytes: 64 - id: llm-replay diff --git a/snapshots/session/pty-tools-sandbox-backend/cordis.yml b/snapshots/session/pty-tools-sandbox-backend/cordis.yml index c8ba76be5a..f9bc660180 100644 --- a/snapshots/session/pty-tools-sandbox-backend/cordis.yml +++ b/snapshots/session/pty-tools-sandbox-backend/cordis.yml @@ -13,4 +13,4 @@ timeoutMs: 2000 disposeGraceMs: 500 - id: tool-terminal - name: '@deepseek-ai/dsh-tool-terminal' + name: '@deepseek-ai/dsh-experimental-tool-terminal' diff --git a/snapshots/session/ralph-loop/cordis.snapshot.yml b/snapshots/session/ralph-loop/cordis.snapshot.yml index b06824b579..d23a9727e4 100644 --- a/snapshots/session/ralph-loop/cordis.snapshot.yml +++ b/snapshots/session/ralph-loop/cordis.snapshot.yml @@ -44,5 +44,9 @@ - id: deepseek-v4-flash - id: deepseek-v4-pro -- id: tool-ralph - disabled: false +- insert: + - id: tool-ralph + name: '@deepseek-ai/dsh-experimental-tool-ralph' + config: + subagentProvider: spawn + maxRounds: 64 diff --git a/snapshots/session/ralph-loop/cordis.yml b/snapshots/session/ralph-loop/cordis.yml index 0f99407597..4767d9f166 100644 --- a/snapshots/session/ralph-loop/cordis.yml +++ b/snapshots/session/ralph-loop/cordis.yml @@ -1,6 +1,7 @@ -# This scenario owns the `ralph` composition. The harness layers the shared -# headless patch (`text-turn/cordis.yml`) underneath, so this file carries only -# what makes the composition different: the shipped base layer carries -# `tool-ralph` disabled, and this is the one scenario that exercises the tool. -- id: tool-ralph - disabled: false +# This scenario adds Ralph over the shared headless composition. +- insert: + - id: tool-ralph + name: '@deepseek-ai/dsh-experimental-tool-ralph' + config: + subagentProvider: spawn + maxRounds: 64 diff --git a/snapshots/session/text-turn/cordis.yml b/snapshots/session/text-turn/cordis.yml index dd4fe733e6..5814ffc142 100644 --- a/snapshots/session/text-turn/cordis.yml +++ b/snapshots/session/text-turn/cordis.yml @@ -67,12 +67,12 @@ - insert: - id: hooks-claude-code - name: '@deepseek-ai/dsh-hooks-claude-code' + name: '@deepseek-ai/dsh-experimental-hooks-claude-code' config: configPath: ./hooks.json - id: hooks-codex - name: '@deepseek-ai/dsh-hooks-codex' + name: '@deepseek-ai/dsh-experimental-hooks-codex' config: configPath: ./codex-hooks.json diff --git a/tsconfig.base.json b/tsconfig.base.json index 4280f79ed1..009ec03dae 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -278,6 +278,7 @@ "@deepseek-ai/dsh-client-ui-skill": ["./packages/client/ui-skill/src"], "@deepseek-ai/dsh-client-ui-subagent": ["./packages/client/ui-subagent/src"], "@deepseek-ai/dsh-experimental-client-ui-agent-team": ["./packages/experimental/client-ui-agent-team/src"], + "@deepseek-ai/dsh-experimental-client-ui-agent-team/client": ["./packages/experimental/client-ui-agent-team/src/client/index.ts"], "@deepseek-ai/dsh-client-ui-settings-plugins": ["./packages/client/ui-settings-plugins/src"], "@deepseek-ai/dsh-client-ui-settings-shell": ["./packages/client/ui-settings-shell/src"], "@deepseek-ai/dsh-client-ui-settings-agent-loop": ["./packages/client/ui-settings-agent-loop/src"], @@ -340,6 +341,15 @@ "@deepseek-ai/dsh-compaction-image-offload/projection": ["./packages/compaction/compaction-image-offload/src/projection.ts"], "@deepseek-ai/dsh-session-format-catalog/message-projections": ["./packages/session/session-format-catalog/src/message-projections.ts"], "@deepseek-ai/dsh-native-command/types": ["./packages/util/native-command/src/types.ts"], + "@deepseek-ai/dsh-experimental-hook-protocol": ["./packages/experimental/hook-protocol/src"], + "@deepseek-ai/dsh-experimental-hooks-claude-code": ["./packages/experimental/hooks-claude-code/src"], + "@deepseek-ai/dsh-experimental-hooks-codex": ["./packages/experimental/hooks-codex/src"], + "@deepseek-ai/dsh-experimental-session-title-all-prompts-llm": ["./packages/experimental/session-title-all-prompts-llm/src"], + "@deepseek-ai/dsh-experimental-skill-badge": ["./packages/experimental/skill-badge/src"], + "@deepseek-ai/dsh-experimental-tool-ralph": ["./packages/experimental/tool-ralph/src"], + "@deepseek-ai/dsh-experimental-tool-terminal": ["./packages/experimental/tool-terminal/src"], + "@deepseek-ai/dsh-experimental-webhook": ["./packages/experimental/webhook/src"], + "@deepseek-ai/dsh-experimental-webhook-github": ["./packages/experimental/webhook-github/src"], // BEGIN generated package aliases — pnpm run gen-tsconfig-paths "@deepseek-ai/dsh-acp": ["./packages/acp/acp/src"], "@deepseek-ai/dsh-acp-app": ["./packages/bundle/acp-app/src"], @@ -387,9 +397,6 @@ "@deepseek-ai/dsh-goal-round-driver": ["./packages/goal/goal-round-driver/src"], "@deepseek-ai/dsh-headless": ["./packages/bundle/headless/src"], "@deepseek-ai/dsh-home-paths": ["./packages/util/home-paths/src"], - "@deepseek-ai/dsh-hook-protocol": ["./packages/hooks/hook-protocol/src"], - "@deepseek-ai/dsh-hooks-claude-code": ["./packages/hooks/hooks-claude-code/src"], - "@deepseek-ai/dsh-hooks-codex": ["./packages/hooks/hooks-codex/src"], "@deepseek-ai/dsh-http-proxy": ["./packages/util/http-proxy/src"], "@deepseek-ai/dsh-jobs": ["./packages/jobs/jobs/src"], "@deepseek-ai/dsh-jobs-local": ["./packages/jobs/jobs-local/src"], @@ -453,14 +460,12 @@ "@deepseek-ai/dsh-session-telemetry": ["./packages/session/session-telemetry/src"], "@deepseek-ai/dsh-session-telemetry-otel": ["./packages/session/session-telemetry-otel/src"], "@deepseek-ai/dsh-session-title": ["./packages/session/session-title/src"], - "@deepseek-ai/dsh-session-title-all-prompts-llm": ["./packages/session/session-title-all-prompts-llm/src"], "@deepseek-ai/dsh-session-title-first-prompt-llm": ["./packages/session/session-title-first-prompt-llm/src"], "@deepseek-ai/dsh-session-title-llm": ["./packages/session/session-title-llm/src"], "@deepseek-ai/dsh-session-turn-outline": ["./packages/session/session-turn-outline/src"], "@deepseek-ai/dsh-settings": ["./packages/settings/settings/src"], "@deepseek-ai/dsh-shell": ["./packages/shell/shell/src"], "@deepseek-ai/dsh-skill": ["./packages/skill/skill/src"], - "@deepseek-ai/dsh-skill-badge": ["./packages/skill/skill-badge/src"], "@deepseek-ai/dsh-skill-filesystem": ["./packages/skill/skill-filesystem/src"], "@deepseek-ai/dsh-skill-office": ["./packages/skill/skill-office/src"], "@deepseek-ai/dsh-spill": ["./packages/spill/spill/src"], @@ -499,14 +504,12 @@ "@deepseek-ai/dsh-tool-lsp": ["./packages/lsp/tool-lsp/src"], "@deepseek-ai/dsh-tool-present": ["./packages/deliverables/tool-present/src"], "@deepseek-ai/dsh-tool-pwsh-persistent": ["./packages/shell/tool-pwsh-persistent/src"], - "@deepseek-ai/dsh-tool-ralph": ["./packages/workflow/tool-ralph/src"], "@deepseek-ai/dsh-tool-schedule": ["./packages/schedule/tool-schedule/src"], "@deepseek-ai/dsh-tool-session-query": ["./packages/session-query/tool-session-query/src"], "@deepseek-ai/dsh-tool-skill": ["./packages/skill/tool-skill/src"], "@deepseek-ai/dsh-tool-str-replace-editor": ["./packages/fs/tool-str-replace-editor/src"], "@deepseek-ai/dsh-tool-subagent": ["./packages/subagent/tool-subagent/src"], "@deepseek-ai/dsh-tool-subagent-control": ["./packages/subagent/tool-subagent-control/src"], - "@deepseek-ai/dsh-tool-terminal": ["./packages/terminal/tool-terminal/src"], "@deepseek-ai/dsh-tool-todo": ["./packages/todo/tool-todo/src"], "@deepseek-ai/dsh-tool-web": ["./packages/web/tool-web/src"], "@deepseek-ai/dsh-tool-workflow": ["./packages/workflow/tool-workflow/src"], @@ -521,8 +524,6 @@ "@deepseek-ai/dsh-web-search-deepseek": ["./packages/web/web-search-deepseek/src"], "@deepseek-ai/dsh-web-search-exa": ["./packages/web/web-search-exa/src"], "@deepseek-ai/dsh-web-search-perplexity": ["./packages/web/web-search-perplexity/src"], - "@deepseek-ai/dsh-webhook": ["./packages/webhook/webhook/src"], - "@deepseek-ai/dsh-webhook-github": ["./packages/webhook/webhook-github/src"], "@deepseek-ai/dsh-win32-process": ["./packages/subprocess/win32-process/src"], "@deepseek-ai/dsh-workflow": ["./packages/workflow/workflow/src"], "@deepseek-ai/dsh-workflow-ptc": ["./packages/workflow/workflow-ptc/src"], diff --git a/tsconfig.host.json b/tsconfig.host.json index 39e0c77935..a5f16c3bb7 100644 --- a/tsconfig.host.json +++ b/tsconfig.host.json @@ -333,7 +333,7 @@ { "path": "./packages/session/tool-working-directory" }, { "path": "./packages/session/session-title-llm" }, { "path": "./packages/session/session-title-first-prompt-llm" }, - { "path": "./packages/session/session-title-all-prompts-llm" }, + { "path": "./packages/experimental/session-title-all-prompts-llm" }, { "path": "./packages/session/session-turn-outline" }, { "path": "./packages/session/session-telemetry" }, { "path": "./packages/identity/anonymous-user-id" }, @@ -362,7 +362,7 @@ { "path": "./packages/core/tools" }, { "path": "./packages/core/agent-tool-presentation" }, { "path": "./packages/skill/skill" }, - { "path": "./packages/skill/skill-badge" }, + { "path": "./packages/experimental/skill-badge" }, { "path": "./packages/skill/skill-filesystem" }, { "path": "./packages/skill/tool-skill" }, { "path": "./packages/interaction/tool-ask-user" }, @@ -381,7 +381,7 @@ { "path": "./packages/terminal/terminal-bash" }, { "path": "./packages/shell/tool-bash-persistent" }, { "path": "./packages/shell/tool-pwsh-persistent" }, - { "path": "./packages/terminal/tool-terminal" }, + { "path": "./packages/experimental/tool-terminal" }, { "path": "./packages/ptc-runtime/ptc-runtime" }, { "path": "./packages/experimental/ptc-runtime-python" }, { "path": "./packages/ptc-runtime/ptc-runtime-node" }, @@ -462,9 +462,9 @@ { "path": "./packages/workflow/workflow" }, { "path": "./packages/workflow/workflow-ptc" }, { "path": "./packages/workflow/tool-workflow" }, - { "path": "./packages/workflow/tool-ralph" }, - { "path": "./packages/webhook/webhook" }, - { "path": "./packages/webhook/webhook-github" }, + { "path": "./packages/experimental/tool-ralph" }, + { "path": "./packages/experimental/webhook" }, + { "path": "./packages/experimental/webhook-github" }, { "path": "./packages/todo/tool-todo" }, { "path": "./packages/plan/plan-mode" }, { "path": "./packages/preset/agent-preset-registry" }, @@ -473,9 +473,9 @@ { "path": "./packages/guard/repeat-tool-reminder" }, { "path": "./packages/extensions/cordis-host-runner" }, { "path": "./packages/extensions/tool-cordis" }, - { "path": "./packages/hooks/hook-protocol" }, - { "path": "./packages/hooks/hooks-claude-code" }, - { "path": "./packages/hooks/hooks-codex" }, + { "path": "./packages/experimental/hook-protocol" }, + { "path": "./packages/experimental/hooks-claude-code" }, + { "path": "./packages/experimental/hooks-codex" }, { "path": "./packages/mcp/mcp-client" }, { "path": "./packages/mcp/mcp-resources" }, { "path": "./packages/host/directory-picker" },