From 3fc35c91ff490e3ad1ad5fed34aa1e3ed7145eec Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Thu, 30 Jul 2026 03:13:49 +0800 Subject: [PATCH] refactor(packages): dissolve ui/ and rename sdk/ to scaffold/ git mv per the regrouping RFC: the five human-collaboration seams and tui join packages/interaction/, app-boot becomes packages/boot/, and jsonrpc joins the renamed scaffold/ (formerly sdk/) as its server half beside client/protocol/create-sdk/helper/scripts/telemetry, whose folders drop the legacy sdk- prefix. Three new group README triplets replace the ui/ and sdk/ ones; tsconfig references/paths/globs, knip keys, vitest globs, gate scripts, catalogs, docs, and the lockfile follow. Adds the four settled FIXME rename markers (dsh-sdk-server, dsh-sdk-telemetry, dsh-sdk-helper, dsh-sdk-scripts). The scaffold folders diverge from their npm names until those renames land, so tsconfig.base.json maps the three affected names explicitly beside the group wildcard. Also repairs two pre-existing stale-path classes the strengthened sweep surfaced: docs/web-styling.md's retired web-ui host package and type-model spec fixture-literal joins. app-boot's three Loader-composition specs time out at the default 5s under full-suite parallel load on this filesystem (pre-existing; pass isolated with --testTimeout=30000); interaction/scaffold/boot suites otherwise green (687 passed). --- ...026-07-27-tui-chat-channel-module-split.md | 2 +- ...-07-27-tui-chat-channel-module-split.zh.md | 2 +- ...-07-24-tui-turn-end-stop-reason-notices.md | 2 +- ...-24-tui-turn-end-stop-reason-notices.zh.md | 2 +- ...17-dedicated-full-screen-tui-front-door.md | 2 +- ...dedicated-full-screen-tui-front-door.zh.md | 2 +- .../feature/2026-07-20-windows-tui-support.md | 2 +- .../2026-07-20-windows-tui-support.zh.md | 2 +- .../2026-07-21-tui-skill-slash-command.md | 2 +- .../2026-07-21-tui-skill-slash-command.zh.md | 2 +- ...-07-27-assistant-timing-header-trailing.md | 2 +- ...-27-assistant-timing-header-trailing.zh.md | 2 +- ...7-26-execa-for-test-subprocess-plumbing.md | 2 +- ...6-execa-for-test-subprocess-plumbing.zh.md | 2 +- ...cutable-sdk-runtime-distribution.i18n.yaml | 4 +-- ...ile-executable-sdk-runtime-distribution.md | 4 +-- ...-executable-sdk-runtime-distribution.zh.md | 4 +-- ...-20-config-hot-reload-resilience.i18n.yaml | 4 +-- ...2026-07-20-config-hot-reload-resilience.md | 2 +- ...6-07-20-config-hot-reload-resilience.zh.md | 2 +- .../2026-07-06-approval-seam.i18n.yaml | 4 +-- .../feature/2026-07-06-approval-seam.md | 4 +-- .../feature/2026-07-06-approval-seam.zh.md | 4 +-- ...nt-persona-tool-filter-and-depth.i18n.yaml | 4 +-- ...-subagent-persona-tool-filter-and-depth.md | 2 +- ...bagent-persona-tool-filter-and-depth.zh.md | 2 +- .../2026-07-16-harness-level-loop.i18n.yaml | 4 +-- .../feature/2026-07-16-harness-level-loop.md | 2 +- .../2026-07-16-harness-level-loop.zh.md | 2 +- ...7-19-plugin-command-registration.i18n.yaml | 4 +-- .../2026-07-19-plugin-command-registration.md | 2 +- ...26-07-19-plugin-command-registration.zh.md | 2 +- ...26-07-20-dsh-cli-personal-config.i18n.yaml | 4 +-- .../2026-07-20-dsh-cli-personal-config.md | 2 +- .../2026-07-20-dsh-cli-personal-config.zh.md | 2 +- ...continuable-background-subagents.i18n.yaml | 4 +-- ...-07-21-continuable-background-subagents.md | 2 +- ...-21-continuable-background-subagents.zh.md | 2 +- ...ipt-sdk-and-sdk-subagent-backend.i18n.yaml | 4 +-- ...typescript-sdk-and-sdk-subagent-backend.md | 4 +-- ...escript-sdk-and-sdk-subagent-backend.zh.md | 4 +-- ...ssion-projection-and-command-log.i18n.yaml | 4 +-- ...7-27-session-projection-and-command-log.md | 2 +- ...7-session-projection-and-command-log.zh.md | 2 +- ...6-07-19-make-jsonrpc-directional.i18n.yaml | 4 +-- .../2026-07-19-make-jsonrpc-directional.md | 6 ++-- .../2026-07-19-make-jsonrpc-directional.zh.md | 6 ++-- AGENTS.md | 4 ++- apps/cli/tsconfig.json | 2 +- docs/architecture.i18n.yaml | 4 +-- docs/architecture.md | 2 +- docs/architecture.zh.md | 2 +- docs/capability-seams.md | 8 ++--- docs/core-data-structures/approval.i18n.yaml | 4 +-- docs/core-data-structures/approval.md | 4 +-- docs/core-data-structures/approval.zh.md | 4 +-- docs/core-data-structures/commands.i18n.yaml | 4 +-- docs/core-data-structures/commands.md | 4 +-- docs/core-data-structures/commands.zh.md | 4 +-- .../user-interaction.i18n.yaml | 4 +-- docs/core-data-structures/user-interaction.md | 4 +-- .../user-interaction.zh.md | 4 +-- docs/testing.i18n.yaml | 4 +-- docs/testing.md | 2 +- docs/testing.zh.md | 2 +- docs/tool-catalog.md | 2 +- knip.json | 8 ++--- packages/README.i18n.yaml | 4 +-- packages/README.md | 5 +-- packages/README.zh.md | 5 +-- packages/acp/acp/tsconfig.json | 2 +- packages/bash/tool-bash/tsconfig.json | 2 +- packages/{sdk => boot}/README.i18n.yaml | 6 ++-- packages/boot/README.md | 9 +++++ packages/boot/README.zh.md | 9 +++++ .../{ui => boot}/app-boot/README.i18n.yaml | 2 +- packages/{ui => boot}/app-boot/README.md | 0 packages/{ui => boot}/app-boot/README.zh.md | 0 packages/{ui => boot}/app-boot/package.json | 0 packages/{ui => boot}/app-boot/src/index.ts | 0 .../{ui => boot}/app-boot/src/invariant.ts | 0 packages/{ui => boot}/app-boot/src/profile.ts | 0 .../app-boot/tests/app-boot.spec.ts | 0 .../app-boot/tests/config-dump.spec.ts | 0 .../app-boot/tests/config-reload.spec.ts | 0 .../app-boot/tests/hmr-config.spec.ts | 0 .../app-boot/tests/profile.spec.ts | 0 .../app-boot/tests/repository-cache.spec.ts | 0 .../app-boot/tests/user-patches.spec.ts | 0 packages/{ui => boot}/app-boot/tsconfig.json | 0 .../{ui => boot}/app-boot/tsdown.config.ts | 0 packages/bundle/README.i18n.yaml | 6 ++++ packages/client/connection/tsconfig.json | 6 ++-- packages/client/runtime/tsconfig.json | 2 +- packages/client/ui-conversation/tsconfig.json | 2 +- packages/client/ui-permission/tsconfig.json | 2 +- packages/client/ui-question/tsconfig.json | 2 +- .../compact/command-compact/tsconfig.json | 2 +- packages/compact/compact/README.i18n.yaml | 4 +-- packages/compact/compact/README.md | 2 +- packages/compact/compact/README.zh.md | 2 +- packages/core/tools/README.i18n.yaml | 4 +-- packages/core/tools/README.md | 2 +- packages/core/tools/README.zh.md | 2 +- packages/core/tools/tsconfig.json | 2 +- .../examples/acp-demo/tests/built-bin.e2e.ts | 2 +- packages/examples/acp-demo/tsconfig.json | 2 +- packages/examples/jsonrpc-demo/tsconfig.json | 2 +- packages/fs/tool-fs/tsconfig.json | 2 +- packages/goal/command-goal/tsconfig.json | 2 +- packages/host/apiproxy/tsconfig.json | 6 ++-- packages/interaction/README.i18n.yaml | 6 ++++ packages/{ui => interaction}/README.md | 6 ++-- packages/{ui => interaction}/README.zh.md | 6 ++-- .../commands/README.i18n.yaml | 2 +- .../{ui => interaction}/commands/README.md | 0 .../{ui => interaction}/commands/README.zh.md | 0 .../{ui => interaction}/commands/package.json | 0 .../{ui => interaction}/commands/src/brand.ts | 0 .../{ui => interaction}/commands/src/index.ts | 0 .../commands/src/invariant.ts | 0 .../commands/tests/commands.spec.ts | 0 .../commands/tests/invariant.spec.ts | 0 .../commands/tsconfig.json | 0 .../interaction/permission/README.i18n.yaml | 6 ++++ .../{ui => interaction}/permission/README.md | 0 .../permission/README.zh.md | 0 .../permission/package.json | 0 .../permission/src/client.ts | 0 .../permission/src/index.ts | 0 .../permission/src/invariant.ts | 0 .../permission/src/types.ts | 0 .../permission/tests/invariant.spec.ts | 0 .../permission/tests/permission.spec.ts | 0 .../permission/tests/projection.spec.ts | 0 .../permission/tsconfig.json | 0 .../tool-ask-user/README.i18n.yaml | 2 +- .../tool-ask-user/README.md | 0 .../tool-ask-user/README.zh.md | 0 .../tool-ask-user/package.json | 0 .../tool-ask-user/src/index.ts | 0 .../tool-ask-user/src/invariant.ts | 0 .../tool-ask-user/tests/tool-ask-user.spec.ts | 0 .../tool-ask-user/tsconfig.json | 0 .../user-approval/README.i18n.yaml | 2 +- .../user-approval/README.md | 0 .../user-approval/README.zh.md | 0 .../user-approval/package.json | 0 .../user-approval/src/index.ts | 0 .../user-approval/src/invariant.ts | 0 .../user-approval/src/types.ts | 0 .../user-approval/tests/approval.spec.ts | 0 .../user-approval/tests/invariant.spec.ts | 0 .../user-approval/tsconfig.json | 0 .../user-approval/tsdown.config.ts | 0 .../user-interaction/README.i18n.yaml | 6 ++++ .../user-interaction/README.md | 0 .../user-interaction/README.zh.md | 0 .../user-interaction/package.json | 0 .../user-interaction/src/index.ts | 0 .../user-interaction/src/invariant.ts | 0 .../user-interaction/src/types.ts | 0 .../tests/user-interaction.spec.ts | 0 .../user-interaction/tsconfig.json | 0 packages/plan/plan-mode/tsconfig.json | 4 +-- packages/{ui => scaffold}/README.i18n.yaml | 6 ++-- packages/{sdk => scaffold}/README.md | 9 ++--- packages/scaffold/README.zh.md | 17 +++++++++ .../client}/README.i18n.yaml | 2 +- .../sdk-client => scaffold/client}/README.md | 0 .../client}/README.zh.md | 0 .../client}/package.json | 0 .../sdk-client => scaffold/client}/src/api.ts | 0 .../client}/src/client.ts | 0 .../client}/src/dispose.ts | 0 .../client}/src/index.ts | 0 .../client}/src/invariant.ts | 0 .../client}/src/types.ts | 0 .../client}/tests/dispose.spec.ts | 0 .../client}/tests/fake-runtime.ts | 0 .../client}/tests/sdk-client.spec.ts | 0 .../client}/tsconfig.json | 2 +- .../create-sdk/README.i18n.yaml | 2 +- .../{sdk => scaffold}/create-sdk/README.md | 0 .../{sdk => scaffold}/create-sdk/README.zh.md | 0 .../{sdk => scaffold}/create-sdk/package.json | 0 .../{sdk => scaffold}/create-sdk/src/args.ts | 0 .../{sdk => scaffold}/create-sdk/src/bin.ts | 0 .../create-sdk/src/command.ts | 0 .../create-sdk/src/create-questions.ts | 0 .../create-sdk/src/create-wizard.ts | 0 .../create-sdk/src/headless.ts | 0 .../{sdk => scaffold}/create-sdk/src/index.ts | 0 .../create-sdk/src/invariant.ts | 0 .../create-sdk/src/project-scaffolder.ts | 0 .../src/templates/assets/created.txt.tpl | 0 .../templates/assets/install-question.txt.tpl | 0 .../src/templates/assets/next-steps.txt.tpl | 0 .../templates/assets/setup-failure.txt.tpl | 0 .../src/templates/assets/usage.txt.tpl | 0 .../src/templates/create-templates.ts | 0 .../create-sdk/tests/built-artifacts.e2e.ts | 4 +-- .../create-sdk/tests/create.snapshot.ts | 0 .../create-sdk/tests/create.spec.ts | 0 .../create-sdk/tests/link-workspace.e2e.ts | 2 +- .../create-sdk/tsconfig.json | 0 .../create-sdk/tsdown.config.ts | 0 .../{sdk => scaffold}/helper/README.i18n.yaml | 2 +- packages/{sdk => scaffold}/helper/README.md | 0 .../{sdk => scaffold}/helper/README.zh.md | 0 .../{sdk => scaffold}/helper/package.json | 0 .../helper/src/documents/cordis-yaml-file.ts | 0 .../helper/src/documents/env-file.ts | 0 .../helper/src/documents/package-json-file.ts | 0 .../src/documents/pnpm-workspace-file.ts | 0 .../helper/src/documents/project-file.ts | 0 .../helper/src/documents/tsconfig-file.ts | 0 .../helper/src/features/builtin/app.ts | 0 .../helper/src/features/builtin/helpers.ts | 0 .../helper/src/features/builtin/index.ts | 0 .../helper/src/features/builtin/provider.ts | 0 .../helper/src/features/builtin/spine.ts | 0 .../helper/src/features/define-feature.ts | 0 .../src/features/feature-configurator.ts | 0 .../helper/src/features/feature.ts | 0 .../helper/src/features/registry.ts | 0 .../helper/src/features/resources.ts | 0 packages/{sdk => scaffold}/helper/src/ids.ts | 0 .../{sdk => scaffold}/helper/src/index.ts | 4 +++ .../{sdk => scaffold}/helper/src/invariant.ts | 0 .../src/package-managers/link-workspace.ts | 0 .../src/package-managers/package-manager.ts | 0 .../src/plugins/local-plugin-blueprint.ts | 0 .../helper/src/project/change-set.ts | 0 .../src/project/npm-dependency-policy.ts | 0 .../src/project/project-edit-session.ts | 0 .../helper/src/project/sdk-project.ts | 2 +- .../helper/src/project/types.ts | 0 .../src/questions/clack-nested-multiselect.ts | 0 .../helper/src/questions/clack-prompt-port.ts | 0 .../src/questions/headless-prompt-port.ts | 0 .../helper/src/questions/prompt-port.ts | 0 .../helper/src/questions/question.ts | 0 .../helper/src/templates/assets/README.md.tpl | 0 .../helper/src/templates/assets/gitignore.tpl | 0 .../helper/src/templates/assets/index.ts.tpl | 0 .../assets/local-plugin-tsdown.config.ts.tpl | 0 .../src/templates/assets/local-plugin.ts.tpl | 0 .../src/templates/assets/local-tool.ts.tpl | 0 .../src/templates/assets/package.json.tpl | 0 .../src/templates/assets/persona.txt.tpl | 0 .../templates/assets/tsconfig.base.json.tpl | 0 .../src/templates/assets/tsdown.config.ts.tpl | 0 .../src/templates/assets/yarnrc.yml.tpl | 0 .../helper/src/templates/project-template.ts | 0 .../helper/src/templates/template-assets.ts | 0 .../helper/src/templates/text-template.ts | 0 .../helper/tests/documents.spec.ts | 0 .../helper/tests/headless-prompt-port.spec.ts | 0 .../helper/tests/project.spec.ts | 0 .../helper/tests/questions.spec.ts | 0 .../{sdk => scaffold}/helper/tsconfig.json | 0 .../{sdk => scaffold}/helper/tsdown.config.ts | 0 packages/scaffold/protocol/README.i18n.yaml | 6 ++++ .../protocol}/README.md | 6 ++-- .../protocol}/README.zh.md | 0 .../protocol}/package.json | 0 .../protocol}/src/index.ts | 0 .../protocol}/src/invariant.ts | 0 .../protocol}/src/transport.ts | 0 .../protocol}/src/types.ts | 0 .../protocol}/tests/transport.spec.ts | 0 .../protocol}/tsconfig.json | 0 .../scripts/README.i18n.yaml | 2 +- packages/{sdk => scaffold}/scripts/README.md | 0 .../{sdk => scaffold}/scripts/README.zh.md | 0 .../{sdk => scaffold}/scripts/package.json | 0 .../{sdk => scaffold}/scripts/src/args.ts | 0 packages/{sdk => scaffold}/scripts/src/bin.ts | 0 .../{sdk => scaffold}/scripts/src/build.ts | 0 .../{sdk => scaffold}/scripts/src/command.ts | 0 .../{sdk => scaffold}/scripts/src/config.ts | 0 .../scripts/src/config/config-workflow.ts | 0 .../scripts/src/create-plugin.ts | 0 .../scripts/src/dev/tsdown-config.ts | 0 packages/scaffold/scripts/src/index.ts | 11 ++++++ .../scripts/src/invariant.ts | 0 .../scripts/src/local-plugin-loader-hooks.ts | 0 .../{sdk => scaffold}/scripts/src/runtime.ts | 0 .../scripts/src/telemetry.ts | 0 .../assets/config-install-failure.txt.tpl | 0 .../src/templates/assets/usage.txt.tpl | 0 .../src/templates/dsh-sdk-templates.ts | 0 .../__snapshots__/config.snapshot.ts.snap | 0 .../scripts/tests/config.snapshot.ts | 0 .../scripts/tests/scripts.spec.ts | 0 .../{sdk => scaffold}/scripts/tsconfig.json | 2 +- .../scripts/tsdown.config.ts | 0 packages/scaffold/server/README.i18n.yaml | 6 ++++ .../{ui/jsonrpc => scaffold/server}/README.md | 2 +- .../jsonrpc => scaffold/server}/README.zh.md | 2 +- .../jsonrpc => scaffold/server}/package.json | 0 .../jsonrpc => scaffold/server}/src/index.ts | 4 +++ .../server}/src/invariant.ts | 0 .../jsonrpc => scaffold/server}/src/server.ts | 0 .../server}/tests/built-scope-carrier.e2e.ts | 2 +- .../server}/tests/plugin-apply.spec.ts | 0 .../server}/tests/plugin-shape.spec.ts | 0 .../server}/tests/server.spec.ts | 0 .../jsonrpc => scaffold/server}/tsconfig.json | 2 +- .../telemetry/README.i18n.yaml | 2 +- .../{sdk => scaffold}/telemetry/README.md | 0 .../{sdk => scaffold}/telemetry/README.zh.md | 0 .../{sdk => scaffold}/telemetry/package.json | 0 .../telemetry/src/anonymous-id.ts | 0 .../telemetry/src/consent-resolver.ts | 0 .../{sdk => scaffold}/telemetry/src/index.ts | 4 +++ .../telemetry/src/invariant.ts | 0 .../telemetry/src/payload.ts | 0 .../telemetry/src/reporter.ts | 0 .../telemetry/src/secret-redactor.ts | 0 .../telemetry/tests/anonymous-id.spec.ts | 0 .../telemetry/tests/consent-resolver.spec.ts | 0 .../telemetry/tests/payload.spec.ts | 0 .../telemetry/tests/reporter.spec.ts | 0 .../telemetry/tests/secret-redactor.spec.ts | 0 .../{sdk => scaffold}/telemetry/tsconfig.json | 0 packages/sdk/README.zh.md | 16 --------- packages/sdk/scripts/src/index.ts | 7 ---- packages/sdk/sdk-protocol/README.i18n.yaml | 6 ---- .../subagent-dsh-sdk/README.i18n.yaml | 4 +-- packages/subagent/subagent-dsh-sdk/README.md | 2 +- .../subagent/subagent-dsh-sdk/README.zh.md | 2 +- .../tests/subagent-dsh-sdk.spec.ts | 2 +- .../subagent/subagent-dsh-sdk/tsconfig.json | 4 +-- .../subagent/subagent-inprocess/tsconfig.json | 2 +- .../typert/generator/tests/type-model.spec.ts | 22 ++++++------ packages/ui/jsonrpc/README.i18n.yaml | 6 ---- packages/ui/permission/README.i18n.yaml | 6 ---- packages/ui/user-interaction/README.i18n.yaml | 6 ---- scripts/gen-cordis-catalog.ts | 10 +++--- scripts/gen-third-party-notices.spec.ts | 2 +- scripts/gen-tool-catalog.ts | 2 +- scripts/run-gates.ts | 2 +- scripts/type-equiv.manifest.json | 36 +++++++++---------- .../verify-package-readme-model-experience.ts | 18 +++++----- tsconfig.base.json | 23 ++++++++---- tsconfig.host.json | 26 +++++++------- vendor/README.md | 8 ++--- vitest.config.ts | 10 +++--- vitest.snapshot.config.ts | 2 +- 351 files changed, 368 insertions(+), 311 deletions(-) rename packages/{sdk => boot}/README.i18n.yaml (57%) create mode 100644 packages/boot/README.md create mode 100644 packages/boot/README.zh.md rename packages/{ui => boot}/app-boot/README.i18n.yaml (81%) rename packages/{ui => boot}/app-boot/README.md (100%) rename packages/{ui => boot}/app-boot/README.zh.md (100%) rename packages/{ui => boot}/app-boot/package.json (100%) rename packages/{ui => boot}/app-boot/src/index.ts (100%) rename packages/{ui => boot}/app-boot/src/invariant.ts (100%) rename packages/{ui => boot}/app-boot/src/profile.ts (100%) rename packages/{ui => boot}/app-boot/tests/app-boot.spec.ts (100%) rename packages/{ui => boot}/app-boot/tests/config-dump.spec.ts (100%) rename packages/{ui => boot}/app-boot/tests/config-reload.spec.ts (100%) rename packages/{ui => boot}/app-boot/tests/hmr-config.spec.ts (100%) rename packages/{ui => boot}/app-boot/tests/profile.spec.ts (100%) rename packages/{ui => boot}/app-boot/tests/repository-cache.spec.ts (100%) rename packages/{ui => boot}/app-boot/tests/user-patches.spec.ts (100%) rename packages/{ui => boot}/app-boot/tsconfig.json (100%) rename packages/{ui => boot}/app-boot/tsdown.config.ts (100%) create mode 100644 packages/interaction/README.i18n.yaml rename packages/{ui => interaction}/README.md (71%) rename packages/{ui => interaction}/README.zh.md (69%) rename packages/{ui => interaction}/commands/README.i18n.yaml (79%) rename packages/{ui => interaction}/commands/README.md (100%) rename packages/{ui => interaction}/commands/README.zh.md (100%) rename packages/{ui => interaction}/commands/package.json (100%) rename packages/{ui => interaction}/commands/src/brand.ts (100%) rename packages/{ui => interaction}/commands/src/index.ts (100%) rename packages/{ui => interaction}/commands/src/invariant.ts (100%) rename packages/{ui => interaction}/commands/tests/commands.spec.ts (100%) rename packages/{ui => interaction}/commands/tests/invariant.spec.ts (100%) rename packages/{ui => interaction}/commands/tsconfig.json (100%) create mode 100644 packages/interaction/permission/README.i18n.yaml rename packages/{ui => interaction}/permission/README.md (100%) rename packages/{ui => interaction}/permission/README.zh.md (100%) rename packages/{ui => interaction}/permission/package.json (100%) rename packages/{ui => interaction}/permission/src/client.ts (100%) rename packages/{ui => interaction}/permission/src/index.ts (100%) rename packages/{ui => interaction}/permission/src/invariant.ts (100%) rename packages/{ui => interaction}/permission/src/types.ts (100%) rename packages/{ui => interaction}/permission/tests/invariant.spec.ts (100%) rename packages/{ui => interaction}/permission/tests/permission.spec.ts (100%) rename packages/{ui => interaction}/permission/tests/projection.spec.ts (100%) rename packages/{ui => interaction}/permission/tsconfig.json (100%) rename packages/{ui => interaction}/tool-ask-user/README.i18n.yaml (79%) rename packages/{ui => interaction}/tool-ask-user/README.md (100%) rename packages/{ui => interaction}/tool-ask-user/README.zh.md (100%) rename packages/{ui => interaction}/tool-ask-user/package.json (100%) rename packages/{ui => interaction}/tool-ask-user/src/index.ts (100%) rename packages/{ui => interaction}/tool-ask-user/src/invariant.ts (100%) rename packages/{ui => interaction}/tool-ask-user/tests/tool-ask-user.spec.ts (100%) rename packages/{ui => interaction}/tool-ask-user/tsconfig.json (100%) rename packages/{ui => interaction}/user-approval/README.i18n.yaml (79%) rename packages/{ui => interaction}/user-approval/README.md (100%) rename packages/{ui => interaction}/user-approval/README.zh.md (100%) rename packages/{ui => interaction}/user-approval/package.json (100%) rename packages/{ui => interaction}/user-approval/src/index.ts (100%) rename packages/{ui => interaction}/user-approval/src/invariant.ts (100%) rename packages/{ui => interaction}/user-approval/src/types.ts (100%) rename packages/{ui => interaction}/user-approval/tests/approval.spec.ts (100%) rename packages/{ui => interaction}/user-approval/tests/invariant.spec.ts (100%) rename packages/{ui => interaction}/user-approval/tsconfig.json (100%) rename packages/{ui => interaction}/user-approval/tsdown.config.ts (100%) create mode 100644 packages/interaction/user-interaction/README.i18n.yaml rename packages/{ui => interaction}/user-interaction/README.md (100%) rename packages/{ui => interaction}/user-interaction/README.zh.md (100%) rename packages/{ui => interaction}/user-interaction/package.json (100%) rename packages/{ui => interaction}/user-interaction/src/index.ts (100%) rename packages/{ui => interaction}/user-interaction/src/invariant.ts (100%) rename packages/{ui => interaction}/user-interaction/src/types.ts (100%) rename packages/{ui => interaction}/user-interaction/tests/user-interaction.spec.ts (100%) rename packages/{ui => interaction}/user-interaction/tsconfig.json (100%) rename packages/{ui => scaffold}/README.i18n.yaml (57%) rename packages/{sdk => scaffold}/README.md (64%) create mode 100644 packages/scaffold/README.zh.md rename packages/{sdk/sdk-client => scaffold/client}/README.i18n.yaml (80%) rename packages/{sdk/sdk-client => scaffold/client}/README.md (100%) rename packages/{sdk/sdk-client => scaffold/client}/README.zh.md (100%) rename packages/{sdk/sdk-client => scaffold/client}/package.json (100%) rename packages/{sdk/sdk-client => scaffold/client}/src/api.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/src/client.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/src/dispose.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/src/index.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/src/invariant.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/src/types.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/tests/dispose.spec.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/tests/fake-runtime.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/tests/sdk-client.spec.ts (100%) rename packages/{sdk/sdk-client => scaffold/client}/tsconfig.json (93%) rename packages/{sdk => scaffold}/create-sdk/README.i18n.yaml (80%) rename packages/{sdk => scaffold}/create-sdk/README.md (100%) rename packages/{sdk => scaffold}/create-sdk/README.zh.md (100%) rename packages/{sdk => scaffold}/create-sdk/package.json (100%) rename packages/{sdk => scaffold}/create-sdk/src/args.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/bin.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/command.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/create-questions.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/create-wizard.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/headless.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/index.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/invariant.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/project-scaffolder.ts (100%) rename packages/{sdk => scaffold}/create-sdk/src/templates/assets/created.txt.tpl (100%) rename packages/{sdk => scaffold}/create-sdk/src/templates/assets/install-question.txt.tpl (100%) rename packages/{sdk => scaffold}/create-sdk/src/templates/assets/next-steps.txt.tpl (100%) rename packages/{sdk => scaffold}/create-sdk/src/templates/assets/setup-failure.txt.tpl (100%) rename packages/{sdk => scaffold}/create-sdk/src/templates/assets/usage.txt.tpl (100%) rename packages/{sdk => scaffold}/create-sdk/src/templates/create-templates.ts (100%) rename packages/{sdk => scaffold}/create-sdk/tests/built-artifacts.e2e.ts (87%) rename packages/{sdk => scaffold}/create-sdk/tests/create.snapshot.ts (100%) rename packages/{sdk => scaffold}/create-sdk/tests/create.spec.ts (100%) rename packages/{sdk => scaffold}/create-sdk/tests/link-workspace.e2e.ts (98%) rename packages/{sdk => scaffold}/create-sdk/tsconfig.json (100%) rename packages/{sdk => scaffold}/create-sdk/tsdown.config.ts (100%) rename packages/{sdk => scaffold}/helper/README.i18n.yaml (80%) rename packages/{sdk => scaffold}/helper/README.md (100%) rename packages/{sdk => scaffold}/helper/README.zh.md (100%) rename packages/{sdk => scaffold}/helper/package.json (100%) rename packages/{sdk => scaffold}/helper/src/documents/cordis-yaml-file.ts (100%) rename packages/{sdk => scaffold}/helper/src/documents/env-file.ts (100%) rename packages/{sdk => scaffold}/helper/src/documents/package-json-file.ts (100%) rename packages/{sdk => scaffold}/helper/src/documents/pnpm-workspace-file.ts (100%) rename packages/{sdk => scaffold}/helper/src/documents/project-file.ts (100%) rename packages/{sdk => scaffold}/helper/src/documents/tsconfig-file.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/builtin/app.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/builtin/helpers.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/builtin/index.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/builtin/provider.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/builtin/spine.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/define-feature.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/feature-configurator.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/feature.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/registry.ts (100%) rename packages/{sdk => scaffold}/helper/src/features/resources.ts (100%) rename packages/{sdk => scaffold}/helper/src/ids.ts (100%) rename packages/{sdk => scaffold}/helper/src/index.ts (86%) rename packages/{sdk => scaffold}/helper/src/invariant.ts (100%) rename packages/{sdk => scaffold}/helper/src/package-managers/link-workspace.ts (100%) rename packages/{sdk => scaffold}/helper/src/package-managers/package-manager.ts (100%) rename packages/{sdk => scaffold}/helper/src/plugins/local-plugin-blueprint.ts (100%) rename packages/{sdk => scaffold}/helper/src/project/change-set.ts (100%) rename packages/{sdk => scaffold}/helper/src/project/npm-dependency-policy.ts (100%) rename packages/{sdk => scaffold}/helper/src/project/project-edit-session.ts (100%) rename packages/{sdk => scaffold}/helper/src/project/sdk-project.ts (99%) rename packages/{sdk => scaffold}/helper/src/project/types.ts (100%) rename packages/{sdk => scaffold}/helper/src/questions/clack-nested-multiselect.ts (100%) rename packages/{sdk => scaffold}/helper/src/questions/clack-prompt-port.ts (100%) rename packages/{sdk => scaffold}/helper/src/questions/headless-prompt-port.ts (100%) rename packages/{sdk => scaffold}/helper/src/questions/prompt-port.ts (100%) rename packages/{sdk => scaffold}/helper/src/questions/question.ts (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/README.md.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/gitignore.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/index.ts.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/local-plugin-tsdown.config.ts.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/local-plugin.ts.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/local-tool.ts.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/package.json.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/persona.txt.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/tsconfig.base.json.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/tsdown.config.ts.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/assets/yarnrc.yml.tpl (100%) rename packages/{sdk => scaffold}/helper/src/templates/project-template.ts (100%) rename packages/{sdk => scaffold}/helper/src/templates/template-assets.ts (100%) rename packages/{sdk => scaffold}/helper/src/templates/text-template.ts (100%) rename packages/{sdk => scaffold}/helper/tests/documents.spec.ts (100%) rename packages/{sdk => scaffold}/helper/tests/headless-prompt-port.spec.ts (100%) rename packages/{sdk => scaffold}/helper/tests/project.spec.ts (100%) rename packages/{sdk => scaffold}/helper/tests/questions.spec.ts (100%) rename packages/{sdk => scaffold}/helper/tsconfig.json (100%) rename packages/{sdk => scaffold}/helper/tsdown.config.ts (100%) create mode 100644 packages/scaffold/protocol/README.i18n.yaml rename packages/{sdk/sdk-protocol => scaffold/protocol}/README.md (90%) rename packages/{sdk/sdk-protocol => scaffold/protocol}/README.zh.md (100%) rename packages/{sdk/sdk-protocol => scaffold/protocol}/package.json (100%) rename packages/{sdk/sdk-protocol => scaffold/protocol}/src/index.ts (100%) rename packages/{sdk/sdk-protocol => scaffold/protocol}/src/invariant.ts (100%) rename packages/{sdk/sdk-protocol => scaffold/protocol}/src/transport.ts (100%) rename packages/{sdk/sdk-protocol => scaffold/protocol}/src/types.ts (100%) rename packages/{sdk/sdk-protocol => scaffold/protocol}/tests/transport.spec.ts (100%) rename packages/{sdk/sdk-protocol => scaffold/protocol}/tsconfig.json (100%) rename packages/{sdk => scaffold}/scripts/README.i18n.yaml (80%) rename packages/{sdk => scaffold}/scripts/README.md (100%) rename packages/{sdk => scaffold}/scripts/README.zh.md (100%) rename packages/{sdk => scaffold}/scripts/package.json (100%) rename packages/{sdk => scaffold}/scripts/src/args.ts (100%) rename packages/{sdk => scaffold}/scripts/src/bin.ts (100%) rename packages/{sdk => scaffold}/scripts/src/build.ts (100%) rename packages/{sdk => scaffold}/scripts/src/command.ts (100%) rename packages/{sdk => scaffold}/scripts/src/config.ts (100%) rename packages/{sdk => scaffold}/scripts/src/config/config-workflow.ts (100%) rename packages/{sdk => scaffold}/scripts/src/create-plugin.ts (100%) rename packages/{sdk => scaffold}/scripts/src/dev/tsdown-config.ts (100%) create mode 100644 packages/scaffold/scripts/src/index.ts rename packages/{sdk => scaffold}/scripts/src/invariant.ts (100%) rename packages/{sdk => scaffold}/scripts/src/local-plugin-loader-hooks.ts (100%) rename packages/{sdk => scaffold}/scripts/src/runtime.ts (100%) rename packages/{sdk => scaffold}/scripts/src/telemetry.ts (100%) rename packages/{sdk => scaffold}/scripts/src/templates/assets/config-install-failure.txt.tpl (100%) rename packages/{sdk => scaffold}/scripts/src/templates/assets/usage.txt.tpl (100%) rename packages/{sdk => scaffold}/scripts/src/templates/dsh-sdk-templates.ts (100%) rename packages/{sdk => scaffold}/scripts/tests/__snapshots__/config.snapshot.ts.snap (100%) rename packages/{sdk => scaffold}/scripts/tests/config.snapshot.ts (100%) rename packages/{sdk => scaffold}/scripts/tests/scripts.spec.ts (100%) rename packages/{sdk => scaffold}/scripts/tsconfig.json (88%) rename packages/{sdk => scaffold}/scripts/tsdown.config.ts (100%) create mode 100644 packages/scaffold/server/README.i18n.yaml rename packages/{ui/jsonrpc => scaffold/server}/README.md (95%) rename packages/{ui/jsonrpc => scaffold/server}/README.zh.md (95%) rename packages/{ui/jsonrpc => scaffold/server}/package.json (100%) rename packages/{ui/jsonrpc => scaffold/server}/src/index.ts (92%) rename packages/{ui/jsonrpc => scaffold/server}/src/invariant.ts (100%) rename packages/{ui/jsonrpc => scaffold/server}/src/server.ts (100%) rename packages/{ui/jsonrpc => scaffold/server}/tests/built-scope-carrier.e2e.ts (98%) rename packages/{ui/jsonrpc => scaffold/server}/tests/plugin-apply.spec.ts (100%) rename packages/{ui/jsonrpc => scaffold/server}/tests/plugin-shape.spec.ts (100%) rename packages/{ui/jsonrpc => scaffold/server}/tests/server.spec.ts (100%) rename packages/{ui/jsonrpc => scaffold/server}/tsconfig.json (93%) rename packages/{sdk => scaffold}/telemetry/README.i18n.yaml (80%) rename packages/{sdk => scaffold}/telemetry/README.md (100%) rename packages/{sdk => scaffold}/telemetry/README.zh.md (100%) rename packages/{sdk => scaffold}/telemetry/package.json (100%) rename packages/{sdk => scaffold}/telemetry/src/anonymous-id.ts (100%) rename packages/{sdk => scaffold}/telemetry/src/consent-resolver.ts (100%) rename packages/{sdk => scaffold}/telemetry/src/index.ts (82%) rename packages/{sdk => scaffold}/telemetry/src/invariant.ts (100%) rename packages/{sdk => scaffold}/telemetry/src/payload.ts (100%) rename packages/{sdk => scaffold}/telemetry/src/reporter.ts (100%) rename packages/{sdk => scaffold}/telemetry/src/secret-redactor.ts (100%) rename packages/{sdk => scaffold}/telemetry/tests/anonymous-id.spec.ts (100%) rename packages/{sdk => scaffold}/telemetry/tests/consent-resolver.spec.ts (100%) rename packages/{sdk => scaffold}/telemetry/tests/payload.spec.ts (100%) rename packages/{sdk => scaffold}/telemetry/tests/reporter.spec.ts (100%) rename packages/{sdk => scaffold}/telemetry/tests/secret-redactor.spec.ts (100%) rename packages/{sdk => scaffold}/telemetry/tsconfig.json (100%) delete mode 100644 packages/sdk/README.zh.md delete mode 100644 packages/sdk/scripts/src/index.ts delete mode 100644 packages/sdk/sdk-protocol/README.i18n.yaml delete mode 100644 packages/ui/jsonrpc/README.i18n.yaml delete mode 100644 packages/ui/permission/README.i18n.yaml delete mode 100644 packages/ui/user-interaction/README.i18n.yaml diff --git a/.agents/notes/archived/architecture/2026-07-27-tui-chat-channel-module-split.md b/.agents/notes/archived/architecture/2026-07-27-tui-chat-channel-module-split.md index 3cf9548d4d..9b2c456d88 100644 --- a/.agents/notes/archived/architecture/2026-07-27-tui-chat-channel-module-split.md +++ b/.agents/notes/archived/architecture/2026-07-27-tui-chat-channel-module-split.md @@ -7,7 +7,7 @@ English | [中文](2026-07-27-tui-chat-channel-module-split.zh.md) ## Problem -`packages/ui/tui/src/index.ts` had grown past 2000 lines. Most of it was one `createTuiChat` factory: a ~1600-line closure holding roughly forty mutable variables and as many nested closures. Model selection, the ask-user-question queue, and session resume were tangled into that single scope, so a reader could not follow any one concern without holding the whole file in their head, and unrelated edits collided. A prior pass had grouped `src/` into `components/`, `session/`, `extension/`, but the entry file itself and the loose top-level input files (`autocomplete.ts`, `file-autocomplete.ts`, `skill-invocation.ts`, `xml-tool-output.ts`) were untouched. +`packages/interaction/tui/src/index.ts` had grown past 2000 lines. Most of it was one `createTuiChat` factory: a ~1600-line closure holding roughly forty mutable variables and as many nested closures. Model selection, the ask-user-question queue, and session resume were tangled into that single scope, so a reader could not follow any one concern without holding the whole file in their head, and unrelated edits collided. A prior pass had grouped `src/` into `components/`, `session/`, `extension/`, but the entry file itself and the loose top-level input files (`autocomplete.ts`, `file-autocomplete.ts`, `skill-invocation.ts`, `xml-tool-output.ts`) were untouched. ## Decision diff --git a/.agents/notes/archived/architecture/2026-07-27-tui-chat-channel-module-split.zh.md b/.agents/notes/archived/architecture/2026-07-27-tui-chat-channel-module-split.zh.md index d5de02bd0f..44e8ffeac4 100644 --- a/.agents/notes/archived/architecture/2026-07-27-tui-chat-channel-module-split.zh.md +++ b/.agents/notes/archived/architecture/2026-07-27-tui-chat-channel-module-split.zh.md @@ -7,7 +7,7 @@ Archived: 2026-08-04 ## Problem -`packages/ui/tui/src/index.ts` 已超过 2000 行,其中绝大部分是单个 `createTuiChat` 工厂:一个约 1600 行的闭包,持有约四十个可变变量以及同等数量的嵌套闭包。模型选择、ask-user-question 队列、会话恢复都缠绕在这一个作用域里,读者无法在不把整份文件装进脑子的前提下理清任何单一关注点,互不相关的改动也会彼此冲突。此前一轮已把 `src/` 归组为 `components/`、`session/`、`extension/`,但入口文件本身以及散落在顶层的输入相关文件(`autocomplete.ts`、`file-autocomplete.ts`、`skill-invocation.ts`、`xml-tool-output.ts`)未动。 +`packages/interaction/tui/src/index.ts` 已超过 2000 行,其中绝大部分是单个 `createTuiChat` 工厂:一个约 1600 行的闭包,持有约四十个可变变量以及同等数量的嵌套闭包。模型选择、ask-user-question 队列、会话恢复都缠绕在这一个作用域里,读者无法在不把整份文件装进脑子的前提下理清任何单一关注点,互不相关的改动也会彼此冲突。此前一轮已把 `src/` 归组为 `components/`、`session/`、`extension/`,但入口文件本身以及散落在顶层的输入相关文件(`autocomplete.ts`、`file-autocomplete.ts`、`skill-invocation.ts`、`xml-tool-output.ts`)未动。 ## Decision diff --git a/.agents/notes/archived/bug-fix/2026-07-24-tui-turn-end-stop-reason-notices.md b/.agents/notes/archived/bug-fix/2026-07-24-tui-turn-end-stop-reason-notices.md index 62784ed7cd..998e9dfcdc 100644 --- a/.agents/notes/archived/bug-fix/2026-07-24-tui-turn-end-stop-reason-notices.md +++ b/.agents/notes/archived/bug-fix/2026-07-24-tui-turn-end-stop-reason-notices.md @@ -11,7 +11,7 @@ The TUI rendered transcript notices for `error`, `aborted`, `max-tokens`, `rejec ## Decision -The `turn/end` case in `packages/ui/tui/src/index.ts` switches on the reason's discriminant and covers every kind: `completed` stays silent because the settled assistant message and its `Completed` timing header already present that outcome; `disposed` appends `Turn stopped: the agent was disposed.`; and the merge-extensible default appends `Turn ended: .` so an unknown plugin-added outcome still names why the agent stopped. All other kinds keep their existing notices. +The `turn/end` case in `packages/interaction/tui/src/index.ts` switches on the reason's discriminant and covers every kind: `completed` stays silent because the settled assistant message and its `Completed` timing header already present that outcome; `disposed` appends `Turn stopped: the agent was disposed.`; and the merge-extensible default appends `Turn ended: .` so an unknown plugin-added outcome still names why the agent stopped. All other kinds keep their existing notices. ## Alternatives considered diff --git a/.agents/notes/archived/bug-fix/2026-07-24-tui-turn-end-stop-reason-notices.zh.md b/.agents/notes/archived/bug-fix/2026-07-24-tui-turn-end-stop-reason-notices.zh.md index 162ba4ed44..ad53755259 100644 --- a/.agents/notes/archived/bug-fix/2026-07-24-tui-turn-end-stop-reason-notices.zh.md +++ b/.agents/notes/archived/bug-fix/2026-07-24-tui-turn-end-stop-reason-notices.zh.md @@ -11,7 +11,7 @@ TUI 会为 `error`、`aborted`、`max-tokens`、`rejected`、`interrupted` 这 ## 决策 -`packages/ui/tui/src/index.ts` 中的 `turn/end` 分支按 reason 的判别字段做 switch,覆盖每一种 kind:`completed` 保持沉默,因为已定稿的助手消息及其 `Completed` 计时头部已经呈现了这一结果;`disposed` 追加 `Turn stopped: the agent was disposed.`;merge 扩展的 default 分支追加 `Turn ended: .`,让未知的插件新增结果仍能点明 agent 停止的原因。其余各 kind 保留现有通知。 +`packages/interaction/tui/src/index.ts` 中的 `turn/end` 分支按 reason 的判别字段做 switch,覆盖每一种 kind:`completed` 保持沉默,因为已定稿的助手消息及其 `Completed` 计时头部已经呈现了这一结果;`disposed` 追加 `Turn stopped: the agent was disposed.`;merge 扩展的 default 分支追加 `Turn ended: .`,让未知的插件新增结果仍能点明 agent 停止的原因。其余各 kind 保留现有通知。 ## 备选方案 diff --git a/.agents/notes/archived/feature/2026-07-17-dedicated-full-screen-tui-front-door.md b/.agents/notes/archived/feature/2026-07-17-dedicated-full-screen-tui-front-door.md index 1a04e738a2..184a05ed23 100644 --- a/.agents/notes/archived/feature/2026-07-17-dedicated-full-screen-tui-front-door.md +++ b/.agents/notes/archived/feature/2026-07-17-dedicated-full-screen-tui-front-door.md @@ -15,7 +15,7 @@ The interactive channel must remain a Cordis plugin over the same agent, session ## Decision -DeepSeek Harness ships [`@deepseek-ai/dsh-tui`](../../../../packages/ui/tui/README.md) as a dedicated Cordis plugin. It owns terminal input and presentation only; agent lifecycle, session persistence, tool execution, and the model-facing question tool remain separate composition entries. The plugin requires both stdin and stdout to be TTYs and fails instead of silently changing to line-oriented behavior. +DeepSeek Harness ships [`@deepseek-ai/dsh-tui`](../../../../packages/interaction/tui/README.md) as a dedicated Cordis plugin. It owns terminal input and presentation only; agent lifecycle, session persistence, tool execution, and the model-facing question tool remain separate composition entries. The plugin requires both stdin and stdout to be TTYs and fails instead of silently changing to line-oriented behavior. The package is a terminal front door, not a complete application. A host mounts `@deepseek-ai/dsh-tui` before its configured agent and composes the backends, tools, and policies around it. The product CLI currently ships no terminal composition; non-interactive tasks use headless mode, Web owns the installed human surface, and ACP remains a separate automation protocol. diff --git a/.agents/notes/archived/feature/2026-07-17-dedicated-full-screen-tui-front-door.zh.md b/.agents/notes/archived/feature/2026-07-17-dedicated-full-screen-tui-front-door.zh.md index 75fc3d47aa..6ac3eefa51 100644 --- a/.agents/notes/archived/feature/2026-07-17-dedicated-full-screen-tui-front-door.zh.md +++ b/.agents/notes/archived/feature/2026-07-17-dedicated-full-screen-tui-front-door.zh.md @@ -15,7 +15,7 @@ Archived: 2026-08-04 ## 决策 -DeepSeek Harness 将 [`@deepseek-ai/dsh-tui`](../../../../packages/ui/tui/README.md) 作为独立的 Cordis 插件交付。该插件只负责终端输入与呈现;agent 生命周期、会话持久化、工具执行以及模型可见的提问工具仍由不同组合项负责。插件要求 stdin 和 stdout 均为 TTY;条件不满足时会失败,不会静默切换为逐行输出。 +DeepSeek Harness 将 [`@deepseek-ai/dsh-tui`](../../../../packages/interaction/tui/README.md) 作为独立的 Cordis 插件交付。该插件只负责终端输入与呈现;agent 生命周期、会话持久化、工具执行以及模型可见的提问工具仍由不同组合项负责。插件要求 stdin 和 stdout 均为 TTY;条件不满足时会失败,不会静默切换为逐行输出。 该包是终端入口,而不是完整应用。宿主在已配置 agent 之前挂载 `@deepseek-ai/dsh-tui`,并围绕它组合后端、工具和策略。产品 CLI 目前不交付终端组合;非交互任务使用 headless 模式,Web 是已安装产品中面向人的界面,而 ACP 仍是独立的自动化协议。 diff --git a/.agents/notes/archived/feature/2026-07-20-windows-tui-support.md b/.agents/notes/archived/feature/2026-07-20-windows-tui-support.md index 9308df7fb4..2c8e92671f 100644 --- a/.agents/notes/archived/feature/2026-07-20-windows-tui-support.md +++ b/.agents/notes/archived/feature/2026-07-20-windows-tui-support.md @@ -13,7 +13,7 @@ The TUI platform contract must follow the runtime shipped to users rather than t ## Decision -[`@deepseek-ai/dsh-tui`](../../../../packages/ui/tui/README.md) supports interactive terminals on Windows as well as macOS and Linux. The product continues to use pi-tui's `ProcessTerminal`; on Windows it enables virtual-terminal input after raw mode and avoids the Unix-only `SIGWINCH` refresh. DeepSeek Harness adds no platform rejection or reduced Windows mode. +[`@deepseek-ai/dsh-tui`](../../../../packages/interaction/tui/README.md) supports interactive terminals on Windows as well as macOS and Linux. The product continues to use pi-tui's `ProcessTerminal`; on Windows it enables virtual-terminal input after raw mode and avoids the Unix-only `SIGWINCH` refresh. DeepSeek Harness adds no platform rejection or reduced Windows mode. The real Loader smoke selects a native pseudo-terminal boundary by host. macOS and Linux retain the Python POSIX PTY driver. Windows uses `node-pty` and ConPTY. Both drivers receive the same launch command, environment, terminal dimensions, marker-gated input actions, timeout, expected exit code, and output assertions, and all three smoke scenarios run on every supported platform. diff --git a/.agents/notes/archived/feature/2026-07-20-windows-tui-support.zh.md b/.agents/notes/archived/feature/2026-07-20-windows-tui-support.zh.md index 8b4a1eb4ce..cb5d05da2b 100644 --- a/.agents/notes/archived/feature/2026-07-20-windows-tui-support.zh.md +++ b/.agents/notes/archived/feature/2026-07-20-windows-tui-support.zh.md @@ -13,7 +13,7 @@ TUI 平台契约必须以交付给用户的运行时为准,而不是取决于 ## 决策 -[`@deepseek-ai/dsh-tui`](../../../../packages/ui/tui/README.md) 在 Windows、macOS 和 Linux 上均支持交互式终端。产品继续使用 pi-tui 的 `ProcessTerminal`;在 Windows 上,它会在进入原始模式后启用虚拟终端输入,并避开仅适用于 Unix 的 `SIGWINCH` 刷新。DeepSeek Harness 不增加平台拒绝逻辑,也不采用功能受限的 Windows 模式。 +[`@deepseek-ai/dsh-tui`](../../../../packages/interaction/tui/README.md) 在 Windows、macOS 和 Linux 上均支持交互式终端。产品继续使用 pi-tui 的 `ProcessTerminal`;在 Windows 上,它会在进入原始模式后启用虚拟终端输入,并避开仅适用于 Unix 的 `SIGWINCH` 刷新。DeepSeek Harness 不增加平台拒绝逻辑,也不采用功能受限的 Windows 模式。 真实 Loader 冒烟测试根据宿主选择原生伪终端边界。macOS 和 Linux 继续使用 Python POSIX PTY 驱动,Windows 则使用 `node-pty` 和 ConPTY。两种驱动接收相同的启动命令、环境、终端尺寸、以标记为触发条件的输入动作、超时、预期退出码和输出断言;3 个冒烟场景都会在每个受支持平台上运行。 diff --git a/.agents/notes/archived/feature/2026-07-21-tui-skill-slash-command.md b/.agents/notes/archived/feature/2026-07-21-tui-skill-slash-command.md index e151f92d0d..038d12a561 100644 --- a/.agents/notes/archived/feature/2026-07-21-tui-skill-slash-command.md +++ b/.agents/notes/archived/feature/2026-07-21-tui-skill-slash-command.md @@ -11,7 +11,7 @@ The [skill system](2026-07-05-skill-system.md) shipped with model-initiated load ## Decision -The [`@deepseek-ai/dsh-tui`](../../../../packages/ui/tui/README.md) front door owns a `/skill: [instructions]` command. On submit it loads the named skill and delivers one text block as a user turn — sent with `agent.send()` while idle and `agent.steer()` while running, the same rule as ordinary editor input. The block is `renderSkillInvocation(skill, instructions)`: a `` element wrapping the skill body, preceded by one resource-base line when the provider exposes one, with the user's trailing text appended after a blank line. The command is a TUI-only affordance; it adds no model-facing tool. Its visibility and loading policy comes from the shared [independent model and user skill invocation policy](2026-07-28-skill-invocation-policy.md). +The [`@deepseek-ai/dsh-tui`](../../../../packages/interaction/tui/README.md) front door owns a `/skill: [instructions]` command. On submit it loads the named skill and delivers one text block as a user turn — sent with `agent.send()` while idle and `agent.steer()` while running, the same rule as ordinary editor input. The block is `renderSkillInvocation(skill, instructions)`: a `` element wrapping the skill body, preceded by one resource-base line when the provider exposes one, with the user's trailing text appended after a blank line. The command is a TUI-only affordance; it adds no model-facing tool. Its visibility and loading policy comes from the shared [independent model and user skill invocation policy](2026-07-28-skill-invocation-policy.md). The TUI reads the skill service through `ctx.get('skills')`, not a declared injection, because skills mount conditionally: a deployment without the registry keeps a working front door, and `/skill:` there reports that skills are unavailable rather than failing to mount. `createTuiChat` is synchronous while `ctx.skills.list()` is async, so autocomplete seeds the static slash commands immediately and rebuilds the provider with `skill:` entries once the catalog resolves; a resolution that arrives after disposal is dropped, and a rejected lookup keeps the base commands. diff --git a/.agents/notes/archived/feature/2026-07-21-tui-skill-slash-command.zh.md b/.agents/notes/archived/feature/2026-07-21-tui-skill-slash-command.zh.md index ac1c4da948..af01642c07 100644 --- a/.agents/notes/archived/feature/2026-07-21-tui-skill-slash-command.zh.md +++ b/.agents/notes/archived/feature/2026-07-21-tui-skill-slash-command.zh.md @@ -11,7 +11,7 @@ Archived: 2026-08-04 ## Decision -[`@deepseek-ai/dsh-tui`](../../../../packages/ui/tui/README.md) 前门拥有一条 `/skill: [instructions]` 命令。提交时它加载指定的 skill,并投递一个文本块作为用户轮次——空闲时用 `agent.send()` 发送、运行中用 `agent.steer()` 中途引导,与普通编辑器输入遵循同一规则。该文本块由 `renderSkillInvocation(skill, instructions)` 生成:一个包裹 skill 正文的 `` 元素,当提供方暴露资源基址时在其前加一行资源基址行,用户尾随的文本在空行之后追加。该命令是 TUI 独有的功能;它不新增任何面向模型的工具。其可见性和加载策略来自共享的[模型与用户独立 skill 调用策略](2026-07-28-skill-invocation-policy.md)。 +[`@deepseek-ai/dsh-tui`](../../../../packages/interaction/tui/README.md) 前门拥有一条 `/skill: [instructions]` 命令。提交时它加载指定的 skill,并投递一个文本块作为用户轮次——空闲时用 `agent.send()` 发送、运行中用 `agent.steer()` 中途引导,与普通编辑器输入遵循同一规则。该文本块由 `renderSkillInvocation(skill, instructions)` 生成:一个包裹 skill 正文的 `` 元素,当提供方暴露资源基址时在其前加一行资源基址行,用户尾随的文本在空行之后追加。该命令是 TUI 独有的功能;它不新增任何面向模型的工具。其可见性和加载策略来自共享的[模型与用户独立 skill 调用策略](2026-07-28-skill-invocation-policy.md)。 TUI 通过 `ctx.get('skills')` 读取 skill 服务,而非声明式注入,因为 skill 是条件挂载的:没有注册表的部署仍保有可用的前门,此时 `/skill:` 会报告 skill 不可用,而不是挂载失败。`createTuiChat` 是同步的,而 `ctx.skills.list()` 是异步的,所以自动补全先立即种入静态斜杠命令,待目录解析完成后再用 `skill:` 条目重建 provider(提供方);在 dispose(资源释放)之后才到达的解析结果会被丢弃,而被拒绝的查找会保留基础命令。 diff --git a/.agents/notes/archived/feature/2026-07-27-assistant-timing-header-trailing.md b/.agents/notes/archived/feature/2026-07-27-assistant-timing-header-trailing.md index 2ef926cff9..ff4a310f08 100644 --- a/.agents/notes/archived/feature/2026-07-27-assistant-timing-header-trailing.md +++ b/.agents/notes/archived/feature/2026-07-27-assistant-timing-header-trailing.md @@ -13,7 +13,7 @@ The TUI assistant message opened with a single header line joining the `Assistan **Split the label from the timing; render the timing as the message's trailing line.** -`AssistantMessageComponent` (packages/ui/tui/src/index.ts) now emits the bold `Assistant` label as the first line and appends the dim timing string (already assembled by `StreamingAssistantComponent.rebuild()` as `header`, including the `· Completed …` suffix when settled) as the last child, after reasoning and text. The timing content, bucket-hiding, and completion-time behavior are unchanged — only its position moved from the top to the bottom of the message. +`AssistantMessageComponent` (packages/interaction/tui/src/index.ts) now emits the bold `Assistant` label as the first line and appends the dim timing string (already assembled by `StreamingAssistantComponent.rebuild()` as `header`, including the `· Completed …` suffix when settled) as the last child, after reasoning and text. The timing content, bucket-hiding, and completion-time behavior are unchanged — only its position moved from the top to the bottom of the message. ## Alternatives considered diff --git a/.agents/notes/archived/feature/2026-07-27-assistant-timing-header-trailing.zh.md b/.agents/notes/archived/feature/2026-07-27-assistant-timing-header-trailing.zh.md index 282ac1e65b..08ced9603d 100644 --- a/.agents/notes/archived/feature/2026-07-27-assistant-timing-header-trailing.zh.md +++ b/.agents/notes/archived/feature/2026-07-27-assistant-timing-header-trailing.zh.md @@ -13,7 +13,7 @@ TUI 的助手消息此前以一行开头,把 `Assistant` 标签和步骤计时 **把标签与计时拆开;计时作为消息的末行渲染。** -`AssistantMessageComponent`(packages/ui/tui/src/index.ts)现在把加粗的 `Assistant` 标签作为首行,并把暗色的计时串(仍由 `StreamingAssistantComponent.rebuild()` 组装为 `header`,settled 时含 `· Completed …` 后缀)作为最后一个子节点,追加在 reasoning 与正文之后。计时内容、隐藏零值桶以及完成时间的行为均不变——仅位置从消息顶部移到底部。 +`AssistantMessageComponent`(packages/interaction/tui/src/index.ts)现在把加粗的 `Assistant` 标签作为首行,并把暗色的计时串(仍由 `StreamingAssistantComponent.rebuild()` 组装为 `header`,settled 时含 `· Completed …` 后缀)作为最后一个子节点,追加在 reasoning 与正文之后。计时内容、隐藏零值桶以及完成时间的行为均不变——仅位置从消息顶部移到底部。 ## Alternatives considered diff --git a/.agents/notes/archived/testing/2026-07-26-execa-for-test-subprocess-plumbing.md b/.agents/notes/archived/testing/2026-07-26-execa-for-test-subprocess-plumbing.md index ca5edc50bf..76cc213ba8 100644 --- a/.agents/notes/archived/testing/2026-07-26-execa-for-test-subprocess-plumbing.md +++ b/.agents/notes/archived/testing/2026-07-26-execa-for-test-subprocess-plumbing.md @@ -11,7 +11,7 @@ Roughly ten e2e/smoke files re-derived the same spawn-collect-timeout choreograp Two related test-infra hand-rolls compounded the case: -- `packages/support/llm-mock-server/src/cli.ts` hand-tokenized 17 value-taking `--flag value` options plus boolean flags (~45–60 lines of loop and value-extraction helpers) where the `node:util` `parseArgs` builtin is already the repo idiom (`cli-demo`, `acp-demo`, `verify-runtime-closure.ts`, `packages/sdk/scripts`). +- `packages/support/llm-mock-server/src/cli.ts` hand-tokenized 17 value-taking `--flag value` options plus boolean flags (~45–60 lines of loop and value-extraction helpers) where the `node:util` `parseArgs` builtin is already the repo idiom (`cli-demo`, `acp-demo`, `verify-runtime-closure.ts`, `packages/scaffold/scripts`). - `apps/web/tests/smoke-real.e2e.ts` and `apps/web/tests/scaffold.ts` carried two verbatim copies of a regex `.env` parser (~20 lines) where the `process.loadEnvFile` builtin has exactly the required no-override semantics — and the vitest e2e/snapshot/web configs already load root `.env` with it before these files run, making the copies dead. - The snapshot harness hand-rolled three poll-until-deadline loops (`waitForPersistedTurnStart`/`waitForPersistedTurnEnd`/`waitForWorkspaceFile` in `packages/support/acp-snapshot/src/harness.ts`, ~55 lines) plus `waitForFile` in `crash-recovery.e2e.ts`, where `vi.waitFor`/`expect.poll` cover the shape — vitest is already a runtime dependency of `dsh-acp-snapshot`, so this adds nothing. diff --git a/.agents/notes/archived/testing/2026-07-26-execa-for-test-subprocess-plumbing.zh.md b/.agents/notes/archived/testing/2026-07-26-execa-for-test-subprocess-plumbing.zh.md index 186e5cd560..f597fd1e08 100644 --- a/.agents/notes/archived/testing/2026-07-26-execa-for-test-subprocess-plumbing.zh.md +++ b/.agents/notes/archived/testing/2026-07-26-execa-for-test-subprocess-plumbing.zh.md @@ -11,7 +11,7 @@ Archived: 2026-08-07 另有两处相关的测试基础设施手写代码进一步强化了替换的理由: -- `packages/support/llm-mock-server/src/cli.ts` 曾手工逐个切分 17 个带值的 `--flag value` 选项外加若干布尔标志(约 45–60 行的循环与取值辅助函数),而 `node:util` 内置的 `parseArgs` 早已是本仓库的惯用写法(`cli-demo`、`acp-demo`、`verify-runtime-closure.ts`、`packages/sdk/scripts`)。 +- `packages/support/llm-mock-server/src/cli.ts` 曾手工逐个切分 17 个带值的 `--flag value` 选项外加若干布尔标志(约 45–60 行的循环与取值辅助函数),而 `node:util` 内置的 `parseArgs` 早已是本仓库的惯用写法(`cli-demo`、`acp-demo`、`verify-runtime-closure.ts`、`packages/scaffold/scripts`)。 - `apps/web/tests/smoke-real.e2e.ts` 与 `apps/web/tests/scaffold.ts` 曾携带两份逐字相同的正则 `.env` 解析器拷贝(约 20 行),而内置的 `process.loadEnvFile` 恰好具备所需的「不覆盖已有值」语义;并且 vitest 的 e2e/snapshot/web 配置在这些文件运行之前就已用它加载了根 `.env`,这两份拷贝实为死代码。 - 快照 harness 曾手写三个「轮询直到截止时间」的循环(`packages/support/acp-snapshot/src/harness.ts` 中的 `waitForPersistedTurnStart`/`waitForPersistedTurnEnd`/`waitForWorkspaceFile`,约 55 行),外加 `crash-recovery.e2e.ts` 中的 `waitForFile`,而 `vi.waitFor`/`expect.poll` 正好覆盖这种形态;vitest 本来就是 `dsh-acp-snapshot` 的运行时依赖,因此这不新增任何东西。 diff --git a/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml index 7a0b74dfaf..08d8319d33 100644 --- a/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md -2026-07-10-single-file-executable-sdk-runtime-distribution.md: f3da981c478ef08672a82f23ab9cd42e0f38ebab -2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: 5a8e15aab79875bdb08e6347199924c4215a2705 +2026-07-10-single-file-executable-sdk-runtime-distribution.md: fe09e1b83f4f0a9f867f78351f643b1bd26d7c9d +2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: ee49d7ea8fade9d3e323e8c6921479b8053809af diff --git a/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md b/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md index f3da981c47..fe09e1b83f 100644 --- a/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md +++ b/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md @@ -27,8 +27,8 @@ Terminology reminder: pkg's `/snapshot` VFS has nothing to do with this repo's t The deterministic protocol implementation (`server.ts` / `transport.ts`) lands as two packages on the existing `acp/acp` + `examples/acp-demo` pattern — the serving surface is itself a plugin: -- [`packages/ui/jsonrpc`](../../../../packages/ui/jsonrpc/README.md) (`@deepseek-ai/dsh-jsonrpc`): the pure protocol plugin; on apply it mounts `HarnessSdkServer` plus a line-delimited JSON-RPC transport on the process stdio, with disposal through `ctx.effect()`. Whether to serve is decided by `cordis.yml`; a yml that does not mount it is a legitimate process that does not serve. Protocol-level exit belongs to the plugin (after answering and flushing the `shutdown` response it disposes the root runtime so persistence drains, then `exit(0)`; an HMR-style unload only stops the service without exiting the process). -- [`packages/examples/jsonrpc-demo`](../../../../packages/examples/jsonrpc-demo/README.md) (`@deepseek-ai/dsh-jsonrpc-demo`): a thin app bin — `installFailLoud` + `loadEnv` + config discovery + `boot()` from [`dsh-app-boot`](../../../../packages/ui/app-boot/src/index.ts), done once boot completes; the server is brought up by the `dsh-jsonrpc` entry in the yml. Its only dependency is app-boot. Process-level exit belongs to the bin (stdin EOF/SIGTERM → dispose then 0, SIGINT → 130). +- [`packages/scaffold/server`](../../../../packages/scaffold/server/README.md) (`@deepseek-ai/dsh-jsonrpc`): the pure protocol plugin; on apply it mounts `HarnessSdkServer` plus a line-delimited JSON-RPC transport on the process stdio, with disposal through `ctx.effect()`. Whether to serve is decided by `cordis.yml`; a yml that does not mount it is a legitimate process that does not serve. Protocol-level exit belongs to the plugin (after answering and flushing the `shutdown` response it disposes the root runtime so persistence drains, then `exit(0)`; an HMR-style unload only stops the service without exiting the process). +- [`packages/examples/jsonrpc-demo`](../../../../packages/examples/jsonrpc-demo/README.md) (`@deepseek-ai/dsh-jsonrpc-demo`): a thin app bin — `installFailLoud` + `loadEnv` + config discovery + `boot()` from [`dsh-app-boot`](../../../../packages/boot/app-boot/src/index.ts), done once boot completes; the server is brought up by the `dsh-jsonrpc` entry in the yml. Its only dependency is app-boot. Process-level exit belongs to the bin (stdin EOF/SIGTERM → dispose then 0, SIGINT → 130). Config discovery has two channels and fails loudly when both are missing: the `DSH_CORDIS_CONFIG` environment variable first (the SDK client convention), then an argv positional argument; no default path and no built-in fallback whatsoever — "the plugins actually booted are decided by an external cordis.yml" is a hard semantic. diff --git a/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md b/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md index 5a8e15aab7..ee49d7ea8f 100644 --- a/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md +++ b/.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md @@ -27,8 +27,8 @@ exe 使用 [@yao-pkg/pkg](https://github.com/yao-pkg/pkg)(vercel/pkg 归档后 确定性协议实现(`server.ts` / `transport.ts`)按 `acp/acp` + `examples/acp-demo` 的既有模式落为两包——对外服务接口本身也是插件: -- [`packages/ui/jsonrpc`](../../../../packages/ui/jsonrpc/README.md)(`@deepseek-ai/dsh-jsonrpc`):纯协议插件;执行 `apply` 时,在进程 stdio 上挂载 `HarnessSdkServer` 与按行传输的 JSON-RPC 层,资源释放走 `ctx.effect()`。是否提供服务由 `cordis.yml` 决定;未挂载该插件的配置会启动一个不提供此服务的合法进程。协议级退出归插件所有(应答并刷新 `shutdown` 响应后 dispose 根运行时以排空持久化,再调用 `exit(0)`;HMR 式卸载只停止服务,不退出进程)。 -- [`packages/examples/jsonrpc-demo`](../../../../packages/examples/jsonrpc-demo/README.md)(`@deepseek-ai/dsh-jsonrpc-demo`):轻量应用入口——`installFailLoud` + `loadEnv` + 配置发现 + [`dsh-app-boot`](../../../../packages/ui/app-boot/src/index.ts) 的 `boot()`;`boot()` 完成后入口即完成,服务器由 `cordis.yml` 中的 `dsh-jsonrpc` 条目启动。它只依赖 `app-boot`。进程级退出归 `bin` 所有(stdin EOF/SIGTERM → dispose 后返回 0,SIGINT → 130)。 +- [`packages/scaffold/server`](../../../../packages/scaffold/server/README.md)(`@deepseek-ai/dsh-jsonrpc`):纯协议插件;执行 `apply` 时,在进程 stdio 上挂载 `HarnessSdkServer` 与按行传输的 JSON-RPC 层,资源释放走 `ctx.effect()`。是否提供服务由 `cordis.yml` 决定;未挂载该插件的配置会启动一个不提供此服务的合法进程。协议级退出归插件所有(应答并刷新 `shutdown` 响应后 dispose 根运行时以排空持久化,再调用 `exit(0)`;HMR 式卸载只停止服务,不退出进程)。 +- [`packages/examples/jsonrpc-demo`](../../../../packages/examples/jsonrpc-demo/README.md)(`@deepseek-ai/dsh-jsonrpc-demo`):轻量应用入口——`installFailLoud` + `loadEnv` + 配置发现 + [`dsh-app-boot`](../../../../packages/boot/app-boot/src/index.ts) 的 `boot()`;`boot()` 完成后入口即完成,服务器由 `cordis.yml` 中的 `dsh-jsonrpc` 条目启动。它只依赖 `app-boot`。进程级退出归 `bin` 所有(stdin EOF/SIGTERM → dispose 后返回 0,SIGINT → 130)。 配置发现有两个通道,均缺失时立即报错:优先使用 `DSH_CORDIS_CONFIG` 环境变量(SDK 客户端约定),其次使用 argv 位置参数;没有默认路径或内置回退——「实际启动的插件由外部 `cordis.yml` 决定」是硬语义。 diff --git a/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.i18n.yaml index 6f4a6d363d..6e2c9a635d 100644 --- a/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.md -2026-07-20-config-hot-reload-resilience.md: 0f15bb0aaacb6e06c416cbe35b44155279497eee -2026-07-20-config-hot-reload-resilience.zh.md: 8a185c1915b5247150d8bb1dd5c42d69bd4f2a35 +2026-07-20-config-hot-reload-resilience.md: 2b98ee73e1c7734da9c0ae6df5e3de1af6a5cbeb +2026-07-20-config-hot-reload-resilience.zh.md: 4ddf1f07f4ff5449f3bd91aa2b38f6045eb4e1c6 diff --git a/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.md b/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.md index 0f15bb0aaa..2b98ee73e1 100644 --- a/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.md +++ b/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.md @@ -38,4 +38,4 @@ HMR contains live refresh rejection. Its `registerConfig(filename, refresh)` met ## Testing -`packages/ui/app-boot/tests/config-reload.spec.ts` boots real temporary Loader/Include trees and covers parse and shape rejection, import-before-dispose, plugin/config restoration, multi-entry rollback, ancestor disablement, overlay convergence, option identity, failed direct-update persistence, and failed programmatic moves. `packages/ui/app-boot/tests/hmr-config.spec.ts` covers existing and missing exact paths, add/change/removal, serialized coalescing, disposal drainage, non-`Error` normalization, failure broadcast, and rejecting-observer containment. `packages/host/webserver/tests/webserver.spec.ts` proves a service-gated startup failure rejects Loader composition with its bind diagnostic, `packages/typert/loader/tests/loader.spec.ts` exercises awaited programmatic removal through a real Loader consumer, and the ACP `pty-tools` snapshot guards concurrent composition from reordering equal-priority prompt sections. +`packages/boot/app-boot/tests/config-reload.spec.ts` boots real temporary Loader/Include trees and covers parse and shape rejection, import-before-dispose, plugin/config restoration, multi-entry rollback, ancestor disablement, overlay convergence, option identity, failed direct-update persistence, and failed programmatic moves. `packages/boot/app-boot/tests/hmr-config.spec.ts` covers existing and missing exact paths, add/change/removal, serialized coalescing, disposal drainage, non-`Error` normalization, failure broadcast, and rejecting-observer containment. `packages/host/webserver/tests/webserver.spec.ts` proves a service-gated startup failure rejects Loader composition with its bind diagnostic, `packages/typert/loader/tests/loader.spec.ts` exercises awaited programmatic removal through a real Loader consumer, and the ACP `pty-tools` snapshot guards concurrent composition from reordering equal-priority prompt sections. diff --git a/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.zh.md b/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.zh.md index 8a185c1915..4ddf1f07f4 100644 --- a/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.zh.md +++ b/.agents/notes/implemented/bug-fix/2026-07-20-config-hot-reload-resilience.zh.md @@ -38,4 +38,4 @@ HMR 收容实时刷新 rejection。其 `registerConfig(filename, refresh)` 方 ## Testing -`packages/ui/app-boot/tests/config-reload.spec.ts` 启动真实的临时 Loader/Include 树,并覆盖对解析和形状错误的拒绝、先导入再 dispose、插件/配置恢复、多配置项回滚、祖先禁用、overlay 收敛、option 对象身份、失败的直接更新不持久化以及失败的程序化移动。`packages/ui/app-boot/tests/hmr-config.spec.ts` 覆盖现有和缺失的确切路径、添加/变更/移除、串行化合并、dispose 排空、非 `Error` 值的规范化、失败广播以及对发生 rejection 的观察者的收容。`packages/host/webserver/tests/webserver.spec.ts` 证明受服务门控的启动失败会让 Loader 组合以其 bind 诊断 reject;`packages/typert/loader/tests/loader.spec.ts` 则通过真实 Loader 消费方演练可等待的程序化移除;ACP(Agent Client Protocol)的 `pty-tools` 快照会防止并发组合改变同优先级提示词段的顺序。 +`packages/boot/app-boot/tests/config-reload.spec.ts` 启动真实的临时 Loader/Include 树,并覆盖对解析和形状错误的拒绝、先导入再 dispose、插件/配置恢复、多配置项回滚、祖先禁用、overlay 收敛、option 对象身份、失败的直接更新不持久化以及失败的程序化移动。`packages/boot/app-boot/tests/hmr-config.spec.ts` 覆盖现有和缺失的确切路径、添加/变更/移除、串行化合并、dispose 排空、非 `Error` 值的规范化、失败广播以及对发生 rejection 的观察者的收容。`packages/host/webserver/tests/webserver.spec.ts` 证明受服务门控的启动失败会让 Loader 组合以其 bind 诊断 reject;`packages/typert/loader/tests/loader.spec.ts` 则通过真实 Loader 消费方演练可等待的程序化移除;ACP(Agent Client Protocol)的 `pty-tools` 快照会防止并发组合改变同优先级提示词段的顺序。 diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml b/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml index fa097ae230..b5c6343382 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-06-approval-seam.md -2026-07-06-approval-seam.md: ae143a41302b7bcd6029345fa91ca4eda837c141 -2026-07-06-approval-seam.zh.md: 2f95f67ecd33b4c659e56d5f3cc6168bf01e35ce +2026-07-06-approval-seam.md: a286e07d51a70232f9aab0af5d8a19622cd222d4 +2026-07-06-approval-seam.zh.md: 6656cfe46de663f0e89eacc78dcfb3425812f9e0 diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.md b/.agents/notes/implemented/feature/2026-07-06-approval-seam.md index ae143a4130..a286e07d51 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.md +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.md @@ -12,7 +12,7 @@ The routing problem is ownership: a permission request must reach the channel th ## Decision -One package, `dsh-user-approval` (`packages/ui/user-approval`), owns the vocabulary and the `ctx.approval` service — the mechanism. The policy — who answers, and whether a session is asked at all — lives outside it: answerers are `approval/request` waterfall listeners registered by channel-owning plugins (the ACP bridge, host adapters, and test scripts), and a per-session policy tier can decide before a channel is involved. Consumers (`dsh-tools`' ask routing and the sandbox escalation gate) resolve a question to a closed outcome and derive their own tool results from it. This is deliberately one package, not the capability-seam three (see Alternatives). +One package, `dsh-user-approval` (`packages/interaction/user-approval`), owns the vocabulary and the `ctx.approval` service — the mechanism. The policy — who answers, and whether a session is asked at all — lives outside it: answerers are `approval/request` waterfall listeners registered by channel-owning plugins (the ACP bridge, host adapters, and test scripts), and a per-session policy tier can decide before a channel is involved. Consumers (`dsh-tools`' ask routing and the sandbox escalation gate) resolve a question to a closed outcome and derive their own tool results from it. This is deliberately one package, not the capability-seam three (see Alternatives). ### How a deployment uses it @@ -95,7 +95,7 @@ Snapshots record allowed and rejected sandbox escalation through `session/reques - **A single registered provider instead of waterfall listeners** — rejected: a `registerProvider()` surface forces every composition question — allowlist pre-filters, external hook deciders, scripted test answers, a policy gate in front of a human — inside one provider implementation. The waterfall gets composition, fail-closed absence, and HMR disposal from machinery the runtime already has; the seam's JSDoc pins the single-decision-slot convention instead of inventing a provider registry. - **An inline `tools/pre-execute` permission gate in the ACP bridge** — rejected: prompting for every bridge-owned call hardwires the asking policy into the transport, cannot serve a second asker (sandbox escalation happens after execution starts, with no pre-execute moment), and leaves hook-produced `ask` decisions without a shared mechanism. -- **The generic user-interaction seam (`ctx.userInteraction`)** — rejected as the approval mechanism: the two share a skeleton (route by agent, block for a human, handle absence), but approval's contract is narrower in every dimension that matters: a closed outcome vocabulary instead of free text, a protocol-native prompt attached to a tool call instead of a generic form, mandatory fail-closed absence, and audit events. Approval therefore does not ride the shipped `packages/ui/user-interaction` / `ask_user_question` elicitation path — an elicitation form is not a permission prompt, and a free-text answer is not a closed outcome; sharing provider plumbing stays open if the two ever converge. +- **The generic user-interaction seam (`ctx.userInteraction`)** — rejected as the approval mechanism: the two share a skeleton (route by agent, block for a human, handle absence), but approval's contract is narrower in every dimension that matters: a closed outcome vocabulary instead of free text, a protocol-native prompt attached to a tool call instead of a generic form, mandatory fail-closed absence, and audit events. Approval therefore does not ride the shipped `packages/interaction/user-interaction` / `ask_user_question` elicitation path — an elicitation form is not a permission prompt, and a free-text answer is not a closed outcome; sharing provider plumbing stays open if the two ever converge. - **Static optional injection in `dsh-tools`** — rejected: the vendored cordis `Inject` type has no optional flag — the object form maps service names to intercept config, and a declared inject gates the fiber. `ctx.get('approval')` is the documented opportunistic-consumption pattern (the `tool-bash` owner-token lookup, the loop's persistence probe), reads presence per call, and degrades correctly across HMR without extra machinery. - **The capability-seam three-package split** — rejected: interface/implementation/consumer fits a seam whose implementation is swappable (bash-local vs bash-sandbox). Here the service body is fixed mechanism and the variable part is listeners that live with their owners — splitting would manufacture an implementation package with nothing in it ("don't split preemptively"). - **Offering `allow_always` now** — rejected: the protocol can express it, but honoring it means designing grant storage, scope identity, and revocation (§ Deferred). Advertising an option the harness cannot honor manufactures doomed grants. diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md b/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md index 2f95f67ecd..6656cfe46d 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md @@ -12,7 +12,7 @@ Status: implemented ## 决策 -一个包`dsh-user-approval`(`packages/ui/user-approval`)负责定义词汇表和 `ctx.approval` 服务——即机制。策略——谁来应答、某个会话是否需要被询问——不在其中:应答者是 `approval/request` waterfall 监听器,由拥有通道的插件注册(ACP(Agent Client Protocol)桥、宿主适配器、测试脚本),而每会话的策略层可以在任何通道介入之前做出决定。消费方(`dsh-tools` 的 ask 路由和沙箱升级门禁)将问题解析为一个封闭结果,并从中派生各自的工具结果。刻意设计为一个包,而非能力 seam 的三包拆分(见「替代方案」)。 +一个包`dsh-user-approval`(`packages/interaction/user-approval`)负责定义词汇表和 `ctx.approval` 服务——即机制。策略——谁来应答、某个会话是否需要被询问——不在其中:应答者是 `approval/request` waterfall 监听器,由拥有通道的插件注册(ACP(Agent Client Protocol)桥、宿主适配器、测试脚本),而每会话的策略层可以在任何通道介入之前做出决定。消费方(`dsh-tools` 的 ask 路由和沙箱升级门禁)将问题解析为一个封闭结果,并从中派生各自的工具结果。刻意设计为一个包,而非能力 seam 的三包拆分(见「替代方案」)。 ### 部署如何使用它 @@ -95,7 +95,7 @@ ACP 桥只应答其会话映射所拥有的精确 agent 对象。它携带既有 - **单一注册提供方而非 waterfall 监听器**:否决。`registerProvider()` 接口迫使所有组合问题——允许列表预过滤、外部钩子决策者、脚本化测试应答、人类前面的策略门禁——都塞进一个提供方实现。waterfall 直接复用运行时已有的组合能力、缺失时默认拒绝行为和 HMR(热模块替换)资源释放机制;seam 的 JSDoc 以约定固定单决策槽语义,而非发明一个提供方注册表。 - **在 ACP 桥中内联 `tools/pre-execute` 权限门禁**:否决。对桥拥有的每次调用都弹出提示,会将请求策略硬编码进传输层,无法服务第二个发起方(沙箱升级发生在执行开始之后,没有 pre-execute 时刻),且钩子产生的 `ask` 决策没有共享机制。 -- **通用用户交互 seam(`ctx.userInteraction`)**:否决作为审批机制。二者骨架相似(按 agent 路由、阻塞等待人类、处理缺失),但审批的契约在每个关键维度上都更窄:封闭的结果词汇而非自由文本、附着在工具调用上的协议原生提示而非通用表单、强制的缺失时失败关闭、以及审计事件。因此审批不走已交付的 `packages/ui/user-interaction` / `ask_user_question` 信息征集路径——信息征集表单不是权限提示,自由文本应答不是封闭结果;如果二者将来趋同,共享提供方管道仍然开放。 +- **通用用户交互 seam(`ctx.userInteraction`)**:否决作为审批机制。二者骨架相似(按 agent 路由、阻塞等待人类、处理缺失),但审批的契约在每个关键维度上都更窄:封闭的结果词汇而非自由文本、附着在工具调用上的协议原生提示而非通用表单、强制的缺失时失败关闭、以及审计事件。因此审批不走已交付的 `packages/interaction/user-interaction` / `ask_user_question` 信息征集路径——信息征集表单不是权限提示,自由文本应答不是封闭结果;如果二者将来趋同,共享提供方管道仍然开放。 - **`dsh-tools` 中的静态可选注入**:否决。vendor 的 Cordis `Inject` 类型没有 optional 标志——对象形式将服务名映射到拦截配置,声明的 inject 会阻塞 fiber。`ctx.get('approval')` 是文档化的机会性消费模式(`tool-bash` 的 owner-token 查找、loop 的持久化探测),按调用读取存在性,跨 HMR 正确降级,无需额外机制。 - **能力 seam 的三包拆分**:否决。接口/实现/消费方适合实现可替换的 seam(bash-local vs bash-sandbox)。此处服务体是固定机制,可变部分是留在各自通道拥有者插件中的监听器——拆分只会制造一个空的实现包(「不要预防性拆分」)。 - **现在就提供 `allow_always`**:否决。协议能表达它,但兑现它意味着设计授权存储、作用域标识和撤销(§ 延后)。展示 harness 无法兑现的选项只会制造注定失败的授权。 diff --git a/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml b/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml index 205ce40bb2..b2e1785796 100644 --- a/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md -2026-07-12-subagent-persona-tool-filter-and-depth.md: c690f4701a54272205eedf719fbfe0863bac566c -2026-07-12-subagent-persona-tool-filter-and-depth.zh.md: e14214b16c413eaa05bcea7bcdf9bca996e8d616 +2026-07-12-subagent-persona-tool-filter-and-depth.md: 2c5eaf8829e01536a2de34cc190573ff35e4ab77 +2026-07-12-subagent-persona-tool-filter-and-depth.zh.md: 355db26ecaf57137420798474561d6a7032757cb diff --git a/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md b/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md index c690f4701a..2c5eaf8829 100644 --- a/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md +++ b/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md @@ -53,7 +53,7 @@ The depth limit bounds recursive delegation independently of tool visibility. A The effective parent depth is the greater of durable `SessionHeader.delegationDepth` and runtime `AgentOptions.subagentDepth`. An in-process child records its derived depth in the session header, and resume restores that header, so a restart cannot lower the recursion count. -Every public entry validates the domain rather than relying on one model-facing configuration path. Negative values, fractions, negative zero, non-finite values, unsafe integers, malformed stored parent depth, and derived overflow all reject. A direct `SubagentStartRequest` may omit the cap to leave depth unbounded; loader-resolved `dsh-tool-subagent` configuration instead defaults to `3`, accepts a numeric override, and uses explicit `'provider-managed'` to omit the cap for an out-of-process provider whose deployment owns its recursion budget. Three is a small finite default that still permits a root plus three descendant generations: the [SDK helper's generated subagent entries](../../../../packages/sdk/helper/src/features/builtin/index.ts) and [JSON-RPC example](../../../../examples/jsonrpc-agent/cordis.yml) use that general policy, while the shipped interactive ACP, headless, and REPL examples pin one. A numeric tool cap fails at provider mount when the provider lacks `depthLimit`. +Every public entry validates the domain rather than relying on one model-facing configuration path. Negative values, fractions, negative zero, non-finite values, unsafe integers, malformed stored parent depth, and derived overflow all reject. A direct `SubagentStartRequest` may omit the cap to leave depth unbounded; loader-resolved `dsh-tool-subagent` configuration instead defaults to `3`, accepts a numeric override, and uses explicit `'provider-managed'` to omit the cap for an out-of-process provider whose deployment owns its recursion budget. Three is a small finite default that still permits a root plus three descendant generations: the [SDK helper's generated subagent entries](../../../../packages/scaffold/helper/src/features/builtin/index.ts) and [JSON-RPC example](../../../../examples/jsonrpc-agent/cordis.yml) use that general policy, while the shipped interactive ACP, headless, and REPL examples pin one. A numeric tool cap fails at provider mount when the provider lacks `depthLimit`. A deployment can combine depth and filtering, but the numeric cap does not synthesize a filter. The delegation tool stays visible at the cap because authorization may depend on runtime state; every attempted start checks the calling agent's current durable and runtime depth, and a rejected start returns an errored tool result without publishing a child. A deployment may separately deny delegation tools in children when its visibility policy is static. Neither choice changes the provider's conversation-history behavior. diff --git a/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.zh.md b/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.zh.md index e14214b16c..355db26eca 100644 --- a/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.zh.md +++ b/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.zh.md @@ -53,7 +53,7 @@ subagent 启动有三个独立的组合控制:`persona`、`toolFilter` 和 `ma 有效父级深度取持久 `SessionHeader.delegationDepth` 与运行时 `AgentOptions.subagentDepth` 中的较大值。进程内子 agent 把推导出的深度记录在会话 header 中,恢复时会重新载入该 header,因此重启无法降低递归计数。 -每个公开入口都自行验证值域,而非依赖单一的面向模型配置路径。负值、小数、负零、非有限值、不安全整数、格式错误的存储父级深度以及推导溢出均被拒绝。直接的 `SubagentStartRequest` 可以省略上限,让此机制不约束深度;经 loader 解析的 `dsh-tool-subagent` 配置则默认值为 `3`、接受数值覆盖,并使用显式的 `'provider-managed'` 来省略由进程外提供方部署拥有递归预算时的上限。三是一个较小的有限默认值,仍允许 root 加三代后代:[SDK 辅助函数生成的 subagent 条目](../../../../packages/sdk/helper/src/features/builtin/index.ts)和 [JSON-RPC 示例](../../../../examples/jsonrpc-agent/cordis.yml)采用这项通用策略,而已交付的交互式 ACP、headless 和 REPL 示例固定为一。提供方缺少 `depthLimit` 时,数值工具上限会在提供方挂载阶段失败。 +每个公开入口都自行验证值域,而非依赖单一的面向模型配置路径。负值、小数、负零、非有限值、不安全整数、格式错误的存储父级深度以及推导溢出均被拒绝。直接的 `SubagentStartRequest` 可以省略上限,让此机制不约束深度;经 loader 解析的 `dsh-tool-subagent` 配置则默认值为 `3`、接受数值覆盖,并使用显式的 `'provider-managed'` 来省略由进程外提供方部署拥有递归预算时的上限。三是一个较小的有限默认值,仍允许 root 加三代后代:[SDK 辅助函数生成的 subagent 条目](../../../../packages/scaffold/helper/src/features/builtin/index.ts)和 [JSON-RPC 示例](../../../../examples/jsonrpc-agent/cordis.yml)采用这项通用策略,而已交付的交互式 ACP、headless 和 REPL 示例固定为一。提供方缺少 `depthLimit` 时,数值工具上限会在提供方挂载阶段失败。 部署可以组合深度与过滤,但数值上限不会合成过滤器。委派工具在上限处仍然可见,因为授权可能依赖运行时状态;每次尝试启动都会检查调用方 agent 当前的持久与运行时深度,被拒绝的启动返回错误工具结果,且不发布子 agent。可见性策略固定的部署可以另外在子 agent 中 deny 委派工具。两种选择都不改变提供方的对话历史行为。 diff --git a/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.i18n.yaml b/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.i18n.yaml index 673e4869af..a54f2e9496 100644 --- a/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-16-harness-level-loop.md -2026-07-16-harness-level-loop.md: 36a567204ee1082d48126369ee0b7277c9f24ca8 -2026-07-16-harness-level-loop.zh.md: cb8d29b4c77848613a6718ea3a343b0ee3294ea4 +2026-07-16-harness-level-loop.md: f37bea0842b3f40bf07c6660ad758d84ece23f1b +2026-07-16-harness-level-loop.zh.md: 0ec2dc2294c1adf8b7f6f810bfaffa7e08c19ed2 diff --git a/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.md b/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.md index 36a567204e..f37bea0842 100644 --- a/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.md +++ b/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.md @@ -38,7 +38,7 @@ Time-based `/loop` or scheduled execution is a third policy and is not implement | `@deepseek-ai/dsh-goal` | `packages/goal/goal/`, domain service | Owns `GoalId`, compare-and-set `GoalRef`, `GoalSnapshot`, four-state `GoalPhase`, structured `GoalBlockReason`, process-local `GoalActivation`, replay folding, and `get`, `create`, `edit`, `pause`, `resume`, `complete`, `block`, `clear`, and `disarm` verbs. | | `@deepseek-ai/dsh-tool-goal` | `packages/goal/tool-goal/`, model-facing consumer | Registers exclusive `get_goal`, `create_goal`, and `update_goal`; authenticates live turn provenance and narrows autonomous-round authority to completion or blocking reports with machine-routable reason codes. | | `@deepseek-ai/dsh-goal-session` | `packages/goal/goal-session/`, continuation policy | Reserves, fences, admits, attributes, settles, cancels, and quiescently drains same-session goal rounds without importing the concrete loop. | -| `@deepseek-ai/dsh-commands` | `packages/ui/commands/`, UI registry | Owns `CommandDefinition`, discovery, scoped registration, direct dispatch, `CommandResult`, and request cancellation for human-only commands. | +| `@deepseek-ai/dsh-commands` | `packages/interaction/commands/`, UI registry | Owns `CommandDefinition`, discovery, scoped registration, direct dispatch, `CommandResult`, and request cancellation for human-only commands. | | `@deepseek-ai/dsh-command-goal` | `packages/goal/command-goal/`, human-command producer | Registers `/goal` status, creation, edit, pause, resume, and clear over the goal domain for TUI. | | `@deepseek-ai/dsh-tool-ralph` | `packages/workflow/tool-ralph/`, fixed workflow consumer | Registers `ralph({ objective, maxRounds? })`, validates the fresh structured provider and bounded `RalphRoundReport`, and returns `complete`, `blocked`, or `budget-limited`. | diff --git a/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.zh.md b/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.zh.md index cb8d29b4c7..0ec2dc2294 100644 --- a/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.zh.md +++ b/.agents/notes/implemented/feature/2026-07-16-harness-level-loop.zh.md @@ -38,7 +38,7 @@ Status: implemented | `@deepseek-ai/dsh-goal` | `packages/goal/goal/`,领域服务 | 拥有 `GoalId`、比较并交换 `GoalRef`、`GoalSnapshot`、四状态 `GoalPhase`、结构化 `GoalBlockReason`、进程本地 `GoalActivation`、重放折叠,以及 `get`、`create`、`edit`、`pause`、`resume`、`complete`、`block`、`clear` 与 `disarm` 动词。 | | `@deepseek-ai/dsh-tool-goal` | `packages/goal/tool-goal/`,面向模型消费方 | 注册互斥的 `get_goal`、`create_goal` 与 `update_goal`;认证实时 Turn 来源,并把自治 Round 权限收窄到带机器可路由原因代码的完成或阻塞报告。 | | `@deepseek-ai/dsh-goal-session` | `packages/goal/goal-session/`,续行策略 | 在不导入具体 loop 的情况下,预留、设围栏、接纳、归属、结算、取消并排空同会话 Goal Round,直至完全停稳。 | -| `@deepseek-ai/dsh-commands` | `packages/ui/commands/`,UI 注册表 | 拥有面向人类专用命令的 `CommandDefinition`、发现、作用域注册、直接分发、`CommandResult` 与请求取消。 | +| `@deepseek-ai/dsh-commands` | `packages/interaction/commands/`,UI 注册表 | 拥有面向人类专用命令的 `CommandDefinition`、发现、作用域注册、直接分发、`CommandResult` 与请求取消。 | | `@deepseek-ai/dsh-command-goal` | `packages/goal/command-goal/`,人类命令生产方 | 为 TUI 注册构建在目标领域之上的 `/goal` 状态、创建、编辑、暂停、恢复与清除。 | | `@deepseek-ai/dsh-tool-ralph` | `packages/workflow/tool-ralph/`,固定工作流消费方 | 注册 `ralph({ objective, maxRounds? })`,验证全新结构化 provider 与有界 `RalphRoundReport`,并返回 `complete`、`blocked` 或 `budget-limited`。 | diff --git a/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.i18n.yaml b/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.i18n.yaml index c3bbbe1d22..e58d618cf3 100644 --- a/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md -2026-07-19-plugin-command-registration.md: 5233ce511dc9798733513ccbf6824f3e1b68d2e6 -2026-07-19-plugin-command-registration.zh.md: 7f41b9d2d00373901b51e3338fa51e1cadf886a9 +2026-07-19-plugin-command-registration.md: c8f0f2772a41948e9eb257a16f40194518c568f9 +2026-07-19-plugin-command-registration.zh.md: 94853393f5f71b29cfbd8da5443b3d73ded20e92 diff --git a/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md b/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md index 5233ce511d..c8f0f2772a 100644 --- a/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md +++ b/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md @@ -12,7 +12,7 @@ A shared mechanism must remain a UI concern rather than a model tool or agent-lo ## Decision -`@deepseek-ai/dsh-commands` in `packages/ui/commands/` is the product command registry. The TUI app bundle mounts it beside its consuming front door; the [automation-only ACP app](../simplification/2026-07-23-acp-automation-only-protocol.md) and the executor-less, UI-less agent spine omit it. TUI injects the service, while command producers depend only on the registry and any domain they operate. +`@deepseek-ai/dsh-commands` in `packages/interaction/commands/` is the product command registry. The TUI app bundle mounts it beside its consuming front door; the [automation-only ACP app](../simplification/2026-07-23-acp-automation-only-protocol.md) and the executor-less, UI-less agent spine omit it. TUI injects the service, while command producers depend only on the registry and any domain they operate. ### Registry contract diff --git a/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.zh.md b/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.zh.md index 7f41b9d2d0..94853393f5 100644 --- a/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.zh.md +++ b/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.zh.md @@ -12,7 +12,7 @@ TUI 拥有斜杠命令。如果命令名、帮助文本、自动补全、分派 ## 决策 -位于 `packages/ui/commands/` 的 `@deepseek-ai/dsh-commands` 是产品命令注册表。TUI 应用 bundle(组合包)把它挂载在消费该服务的入口旁;[仅面向自动化的 ACP(Agent Client Protocol)应用](../simplification/2026-07-23-acp-automation-only-protocol.md)和无执行器、无 UI 的智能体 spine(主干)都省略该服务。TUI 注入该服务,命令生产者只依赖注册表及其操作的领域。 +位于 `packages/interaction/commands/` 的 `@deepseek-ai/dsh-commands` 是产品命令注册表。TUI 应用 bundle(组合包)把它挂载在消费该服务的入口旁;[仅面向自动化的 ACP(Agent Client Protocol)应用](../simplification/2026-07-23-acp-automation-only-protocol.md)和无执行器、无 UI 的智能体 spine(主干)都省略该服务。TUI 注入该服务,命令生产者只依赖注册表及其操作的领域。 ### 注册表契约 diff --git a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.i18n.yaml b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.i18n.yaml index ee99911ee8..0cf926921b 100644 --- a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md -2026-07-20-dsh-cli-personal-config.md: 2a8ae4b235823b4493d2f082d37b85806f45b662 -2026-07-20-dsh-cli-personal-config.zh.md: d8ff6c4fcc5da8f1db6f030e990118e30ae6fe41 +2026-07-20-dsh-cli-personal-config.md: c00432ba2b75cc42caf23e405c24acb33d839e7a +2026-07-20-dsh-cli-personal-config.zh.md: b33a7fa321ca04f41e47386544ffc0f268a8b1b6 diff --git a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md index 2a8ae4b235..c00432ba2b 100644 --- a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md +++ b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md @@ -48,4 +48,4 @@ The TUI and Web register the exact personal path through Cordis HMR after boot. ## Testing -`packages/ui/app-boot/tests/user-patches.spec.ts` pins parsing, startup application, exact-path add/failure/recovery/removal, last-good rollback, failure broadcast, and preservation of app-owned patches. `apps/cli/tests/built-bin.e2e.ts` boots the real dsh bin over a profile and exercises the live patch layer end to end. Test launchers isolate `$DSH_HOME`, so a developer's real overlay cannot leak into fixtures. +`packages/boot/app-boot/tests/user-patches.spec.ts` pins parsing, startup application, exact-path add/failure/recovery/removal, last-good rollback, failure broadcast, and preservation of app-owned patches. `apps/cli/tests/built-bin.e2e.ts` boots the real dsh bin over a profile and exercises the live patch layer end to end. Test launchers isolate `$DSH_HOME`, so a developer's real overlay cannot leak into fixtures. diff --git a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.zh.md b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.zh.md index d8ff6c4fcc..b33a7fa321 100644 --- a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.zh.md +++ b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.zh.md @@ -48,4 +48,4 @@ TUI 和 Web 启动后通过 Cordis HMR(热模块替换)注册确切的个人 ## Testing -`packages/ui/app-boot/tests/user-patches.spec.ts` 固定解析、启动时应用、确切路径的新增/失败/恢复/移除、最后可用状态回滚、失败广播以及应用自有 patch 的保留。`apps/cli/tests/built-bin.e2e.ts` 启动真实 dsh bin 并基于 profile 端到端验证实时 patch 层。测试启动器会隔离 `$DSH_HOME`,因此开发者的真实 overlay 不会泄漏进 fixture。 +`packages/boot/app-boot/tests/user-patches.spec.ts` 固定解析、启动时应用、确切路径的新增/失败/恢复/移除、最后可用状态回滚、失败广播以及应用自有 patch 的保留。`apps/cli/tests/built-bin.e2e.ts` 启动真实 dsh bin 并基于 profile 端到端验证实时 patch 层。测试启动器会隔离 `$DSH_HOME`,因此开发者的真实 overlay 不会泄漏进 fixture。 diff --git a/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.i18n.yaml b/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.i18n.yaml index a7d065d42d..1d93b7f440 100644 --- a/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.md -2026-07-21-continuable-background-subagents.md: 6bbbfb25fb24eba95de888c9d23c79e24fc8535b -2026-07-21-continuable-background-subagents.zh.md: e23fbe67cc2d16a2c01a1b7ed4884008f8932dd4 +2026-07-21-continuable-background-subagents.md: e37abdd798242bc1086754e86a85ef46c08e59a3 +2026-07-21-continuable-background-subagents.zh.md: 799e1914bdeb571dc697652081be6b0170768655 diff --git a/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.md b/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.md index 6bbbfb25fb..e37abdd798 100644 --- a/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.md +++ b/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.md @@ -112,7 +112,7 @@ Task records and active-run associations are process-local. Persistence makes th - `packages/subagent/subagent-inprocess/tests/subagent-inprocess.spec.ts` pins the continuable durability boundary: an absent or detached flush listener and a permanent listener failure reject with `DURABILITY_FAILED`, a transient loop-checkpoint failure can succeed on the final confirmation, cancellation owns either final-checkpoint outcome, resume also confirms durability, and foreground runs remain best-effort. `packages/subagent/subagent/tests/continuation.spec.ts` drives the real stack (agent loop, JSONL persistence, spawn/fork providers, Task service, and `ctx.subagents`) keylessly: initial and resumed activations create fresh Tasks and dispose their runs before terminal; the descriptor event is pre-turn, model-hidden, versioned, durable under the service-allocated child id, and survives blocked or throwing initial prompt admission; cancellation, steering, cold follow-up, authorization, ownership conflicts, and resume races retain the contracts described above. - `packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts` pins the `send_message` schema, coordinator attribution, both route renderings, the not-delivered failure, the no-agent rejection, and HMR disposal. - `packages/subagent/tool-subagent/tests/tool-subagent.spec.ts` covers the configured background route: continuable mode requires a resumable provider and returns both ids without requiring `send_message`, while one-shot mode keeps the plain Task acknowledgement even when the provider can resume. -- `packages/sdk/helper/tests/project.spec.ts` pins the Task service and model-facing Task controls in generated spawn and fork compositions. +- `packages/scaffold/helper/tests/project.spec.ts` pins the Task service and model-facing Task controls in generated spawn and fork compositions. - The keyless ACP snapshot scenario `subagent-continuable` (examples/acp-agent) pins the model-visible transcript: the two-id acknowledgement, a final durability-confirmation failure rendered through `task_output` without unconfirmed child output, and a `send_message` follow-up whose started Task fails with the id unavailable. ## Consequences diff --git a/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.zh.md b/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.zh.md index e23fbe67cc..799e1914bd 100644 --- a/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.zh.md +++ b/.agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.zh.md @@ -112,7 +112,7 @@ Task 记录和活跃 run 关联都位于进程内。持久化使 child 会话可 - `packages/subagent/subagent-inprocess/tests/subagent-inprocess.spec.ts` 固定可继续执行的持久性边界:缺少 flush 监听器、flush 监听器已脱离或监听器持续失败时,均会以 `DURABILITY_FAILED` 拒绝;循环检查点的瞬时失败可在最终确认成功后继续完成,发生取消时最终检查点无论成功还是失败都由取消优先决定结果,resume 同样会确认持久性,而前台运行仍采用尽力而为策略。`packages/subagent/subagent/tests/continuation.spec.ts` 以无密钥方式驱动真实栈(agent loop、JSONL 持久化、spawn/fork 提供方、Task 服务和 `ctx.subagents`):初始及恢复后的激活都会创建新 Task,并在进入终态前 dispose 各自的 run;描述符事件位于轮次前、对模型隐藏、带版本、在服务分配的 child id 下持久化,并在初始 prompt admission 阻止请求或抛出异常时仍保留;取消、steering、cold follow-up、授权、所有权冲突与 resume 竞态保留上述契约。 - `packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts` 固定 `send_message` 的 schema、coordinator 来源标记、两种路由渲染、未送达失败、无 agent 时的拒绝,以及 HMR(热模块替换)dispose。 - `packages/subagent/tool-subagent/tests/tool-subagent.spec.ts` 覆盖配置的后台路由:可继续模式要求提供方可恢复,并在不要求 `send_message` 的情况下返回两个 id;即使提供方可以恢复,一次性模式仍保持普通的 Task 确认消息。 -- `packages/sdk/helper/tests/project.spec.ts` 固定生成的 spawn 与 fork 组合中的 Task 服务及面向模型的 Task 控制工具。 +- `packages/scaffold/helper/tests/project.spec.ts` 固定生成的 spawn 与 fork 组合中的 Task 服务及面向模型的 Task 控制工具。 - 无密钥 ACP 快照场景 `subagent-continuable`(examples/acp-agent)固定模型可见的 transcript:双 id 确认消息、最终持久性确认失败(该失败通过 `task_output` 呈现,且不包含未经确认的 child 输出),以及一次 `send_message` 后续操作——其已启动的 Task 会带着「id 不可用」失败。 ## 影响 diff --git a/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.i18n.yaml b/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.i18n.yaml index 6018cb1305..38dc165e7f 100644 --- a/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md -2026-07-27-typescript-sdk-and-sdk-subagent-backend.md: 96ffd772810a7908ff452967aa0be0e540bc2d8c -2026-07-27-typescript-sdk-and-sdk-subagent-backend.zh.md: 74ae4b81807d1267dc19f30d2bb51e50a775c4be +2026-07-27-typescript-sdk-and-sdk-subagent-backend.md: c5c6c4eac053e9a3adfa2a2a441ac492ba3391ac +2026-07-27-typescript-sdk-and-sdk-subagent-backend.zh.md: 643ec36134a1ebe940da5de5b373fa0c25afcd42 diff --git a/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md b/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md index 96ffd77281..c5c6c4eac0 100644 --- a/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md +++ b/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md @@ -12,8 +12,8 @@ The stdio JSON-RPC serving surface (`@deepseek-ai/dsh-jsonrpc`, the [single-exe Three packages, layered exactly like the existing Python stack, plus one seam registration: -- **`@deepseek-ai/dsh-sdk-protocol`** (`packages/sdk/sdk-protocol/`) — the wire made shared and nominal. `JsonRpcLineTransport` moves here verbatim from `dsh-jsonrpc` (which now imports it), and `types.ts` names every payload the server speaks: `InitializeParams/Result`, `SessionPromptParams/Result`, the four notification payloads, and the `HarnessSdkRequestMap`/`HarnessSdkNotificationMap` indexes. The package root explicitly exports that complete interface and provides no source-module deep imports. The server's `notify()` call sites are typed against these named payloads, so server drift breaks compilation, not clients. One behavioral change: an error response now rejects with `JsonRpcResponseError` carrying the wire `code`/`data` (the Python client already preserved these; the old transport threw a bare `Error` with only the message). -- **`@deepseek-ai/dsh-sdk-client`** (`packages/sdk/sdk-client/`) — the TypeScript twin of `python/sdk`: `HarnessClient` (spawn, frame, fan out notifications, typed error surfaces, close-to-quiescence via the shared dispose ladder) under `DeepSeekHarness`/`HarnessSession` (lazy start, memoized `initialize`, `run()` pairing one `session/prompt` with its `session.finished`). Its package-root consumer interface explicitly exports both client layers, caller-facing types, and the protocol-owned `JsonRpcResponseError`; source modules, normalization helpers, and the notification producer stay internal. `TurnResult.events` contains only the root session's typed events, while `notifications` retains session ids across the root and descendants discovered from `subagent.started`; session-tree scoping is client-side, mirroring `client.py`. Deliberate asymmetries with Python: the launch spec is explicit `command`/`args` (no bundled-runtime resolution — that is a distribution concern with no TS consumer yet); `env` replaces rather than merges (callers own credential policy; `scrubbedParentEnv` from the subprocess seam is one import away); `TurnResult` carries the structured `reason` (Python exposes only `status`); teardown walks a private stdin-EOF → SIGTERM → SIGKILL ladder to actual exit (the client runs outside any harness context, so it cannot ride `ctx.subprocess`). +- **`@deepseek-ai/dsh-sdk-protocol`** (`packages/scaffold/protocol/`) — the wire made shared and nominal. `JsonRpcLineTransport` moves here verbatim from `dsh-jsonrpc` (which now imports it), and `types.ts` names every payload the server speaks: `InitializeParams/Result`, `SessionPromptParams/Result`, the four notification payloads, and the `HarnessSdkRequestMap`/`HarnessSdkNotificationMap` indexes. The package root explicitly exports that complete interface and provides no source-module deep imports. The server's `notify()` call sites are typed against these named payloads, so server drift breaks compilation, not clients. One behavioral change: an error response now rejects with `JsonRpcResponseError` carrying the wire `code`/`data` (the Python client already preserved these; the old transport threw a bare `Error` with only the message). +- **`@deepseek-ai/dsh-sdk-client`** (`packages/scaffold/client/`) — the TypeScript twin of `python/sdk`: `HarnessClient` (spawn, frame, fan out notifications, typed error surfaces, close-to-quiescence via the shared dispose ladder) under `DeepSeekHarness`/`HarnessSession` (lazy start, memoized `initialize`, `run()` pairing one `session/prompt` with its `session.finished`). Its package-root consumer interface explicitly exports both client layers, caller-facing types, and the protocol-owned `JsonRpcResponseError`; source modules, normalization helpers, and the notification producer stay internal. `TurnResult.events` contains only the root session's typed events, while `notifications` retains session ids across the root and descendants discovered from `subagent.started`; session-tree scoping is client-side, mirroring `client.py`. Deliberate asymmetries with Python: the launch spec is explicit `command`/`args` (no bundled-runtime resolution — that is a distribution concern with no TS consumer yet); `env` replaces rather than merges (callers own credential policy; `scrubbedParentEnv` from the subprocess seam is one import away); `TurnResult` carries the structured `reason` (Python exposes only `status`); teardown walks a private stdin-EOF → SIGTERM → SIGKILL ladder to actual exit (the client runs outside any harness context, so it cannot ride `ctx.subprocess`). - **`@deepseek-ai/dsh-subagent-dsh-sdk`** (`packages/subagent/subagent-dsh-sdk/`) — the second out-of-process `SubagentProvider`, structured as `subagent-acp`'s sibling: same all-false capabilities and `inheritsParentContext: false`, same publish-after-handshake ownership transaction, same result-never-rejects flattening through an `onError` sink, same parent-namespace run id. The child answer is read from streamed `session.event`s — the last complete `assistant/message`, else accumulated `text-delta` chunks, so partial answers survive cancellation. Stop reasons map from the child's structured `TurnEndReason` (`completed`/`max-tokens`/`aborted` pass through; everything else, including a settled-without-turn child, is `error`). Its `provider`/`model` config feeds the child's `initialize`; `env` is where deployments pass the child's own key and `DSH_CORDIS_CONFIG`. - **The subagent seam grows `out-of-process.ts`**: the provider-side vocabulary both out-of-process backends share — `NO_START_CAPABILITIES`, timing-bound validation, child cwd resolution (config override, else the delegating parent session's workspace), the never-reject `settleRunResult`, and the `subprocessRunHandle` publication. Process mechanics (spawn, env scrub, tree-scoped teardown) live in the `dsh-subprocess` seam; `subagent-acp` spawns through `ctx.subprocess`, while this backend spawns through the SDK client (the subprocess README's documented exception for SDK-managed transports) and applies the seam's `scrubbedParentEnv()` itself. diff --git a/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.zh.md b/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.zh.md index 74ae4b8180..643ec36134 100644 --- a/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.zh.md +++ b/.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.zh.md @@ -12,8 +12,8 @@ stdio JSON-RPC 对外服务接口(`@deepseek-ai/dsh-jsonrpc`,见[单文件 三个包,分层与既有 Python 栈完全一致,外加一个 seam 注册: -- **`@deepseek-ai/dsh-sdk-protocol`**(`packages/sdk/sdk-protocol/`)—— 把线协议做成共享且具名。`JsonRpcLineTransport` 从 `dsh-jsonrpc` 原样移入(后者现在导入它),`types.ts` 为服务器所说的每个载荷命名:`InitializeParams/Result`、`SessionPromptParams/Result`、四个通知载荷,以及 `HarnessSdkRequestMap`/`HarnessSdkNotificationMap` 索引。该包根显式导出这一完整接口,且不提供指向源模块的深层导入。服务器的 `notify()` 调用点以这些具名载荷标注类型,服务器漂移会先破坏编译而不是破坏客户端。一处行为变化:错误响应现在以携带线上 `code`/`data` 的 `JsonRpcResponseError` 拒绝(Python 客户端本就保留这些;旧传输只抛携带消息的裸 `Error`)。 -- **`@deepseek-ai/dsh-sdk-client`**(`packages/sdk/sdk-client/`)—— `python/sdk` 的 TypeScript 孪生:`HarnessClient`(spawn、分帧、通知扇出、有类型的错误表面、经共享 dispose(资源释放)阶梯关闭至完全停稳)之上是 `DeepSeekHarness`/`HarnessSession`(惰性启动、记忆化 `initialize`、`run()` 把一个 `session/prompt` 与其 `session.finished` 配对)。其包根消费方接口显式导出两层客户端、面向调用方的类型,以及协议包所拥有的 `JsonRpcResponseError`;源模块、规范化辅助函数和通知投递端都保留为内部实现。`TurnResult.events` 只包含根会话的类型化事件,而 `notifications` 则保留根会话及从 `subagent.started` 发现的后代各自的会话 id;基于 `subagent.started` 血缘边的会话树范围限定在客户端完成,镜像 `client.py`。与 Python 的刻意不对称:启动规格是显式 `command`/`args`(无捆绑运行时解析——那是尚无 TS 消费方的发行问题);`env` 整体替换而非合并(凭据策略归调用方;subprocess seam 的 `scrubbedParentEnv` 一个 import 即得);`TurnResult` 携带结构化 `reason`(Python 只暴露 `status`);拆除走私有的 stdin-EOF → SIGTERM → SIGKILL 阶梯直到真正退出(客户端运行在任何 harness 上下文之外,无法搭乘 `ctx.subprocess`)。 +- **`@deepseek-ai/dsh-sdk-protocol`**(`packages/scaffold/protocol/`)—— 把线协议做成共享且具名。`JsonRpcLineTransport` 从 `dsh-jsonrpc` 原样移入(后者现在导入它),`types.ts` 为服务器所说的每个载荷命名:`InitializeParams/Result`、`SessionPromptParams/Result`、四个通知载荷,以及 `HarnessSdkRequestMap`/`HarnessSdkNotificationMap` 索引。该包根显式导出这一完整接口,且不提供指向源模块的深层导入。服务器的 `notify()` 调用点以这些具名载荷标注类型,服务器漂移会先破坏编译而不是破坏客户端。一处行为变化:错误响应现在以携带线上 `code`/`data` 的 `JsonRpcResponseError` 拒绝(Python 客户端本就保留这些;旧传输只抛携带消息的裸 `Error`)。 +- **`@deepseek-ai/dsh-sdk-client`**(`packages/scaffold/client/`)—— `python/sdk` 的 TypeScript 孪生:`HarnessClient`(spawn、分帧、通知扇出、有类型的错误表面、经共享 dispose(资源释放)阶梯关闭至完全停稳)之上是 `DeepSeekHarness`/`HarnessSession`(惰性启动、记忆化 `initialize`、`run()` 把一个 `session/prompt` 与其 `session.finished` 配对)。其包根消费方接口显式导出两层客户端、面向调用方的类型,以及协议包所拥有的 `JsonRpcResponseError`;源模块、规范化辅助函数和通知投递端都保留为内部实现。`TurnResult.events` 只包含根会话的类型化事件,而 `notifications` 则保留根会话及从 `subagent.started` 发现的后代各自的会话 id;基于 `subagent.started` 血缘边的会话树范围限定在客户端完成,镜像 `client.py`。与 Python 的刻意不对称:启动规格是显式 `command`/`args`(无捆绑运行时解析——那是尚无 TS 消费方的发行问题);`env` 整体替换而非合并(凭据策略归调用方;subprocess seam 的 `scrubbedParentEnv` 一个 import 即得);`TurnResult` 携带结构化 `reason`(Python 只暴露 `status`);拆除走私有的 stdin-EOF → SIGTERM → SIGKILL 阶梯直到真正退出(客户端运行在任何 harness 上下文之外,无法搭乘 `ctx.subprocess`)。 - **`@deepseek-ai/dsh-subagent-dsh-sdk`**(`packages/subagent/subagent-dsh-sdk/`)—— 第二个进程外 `SubagentProvider`,采用与 `subagent-acp` 对等的结构:同样的全 false 能力与 `inheritsParentContext: false`,同样的握手后发布所有权事务,同样通过 `onError` sink 将结果归一为绝不拒绝,同样的父命名空间 run id。子答案从流式 `session.event` 读取——最后一条完整 `assistant/message`,否则累积的 `text-delta` 块,部分答案在取消时得以保留。停止原因由子进程的结构化 `TurnEndReason` 映射(`completed`/`max-tokens`/`aborted` 直通;其余一切、包括未运行任何轮次便已结束的子进程,都是 `error`)。其 `provider`/`model` 配置喂给子进程的 `initialize`;`env` 是部署传入子进程自有密钥与 `DSH_CORDIS_CONFIG` 的地方。 - **subagent seam 新增 `out-of-process.ts`**:两个进程外后端共享的 provider 侧词汇——`NO_START_CAPABILITIES`、时限校验、子进程 cwd 解析(配置覆盖、否则发起委托的父会话工作区)、绝不拒绝的 `settleRunResult`、以及 `subprocessRunHandle` 发布。进程机制(spawn、环境清理、进程树清理)属于 `dsh-subprocess` seam;`subagent-acp` 经 `ctx.subprocess` spawn 子进程,本后端则经 SDK 客户端 spawn 子进程(subprocess README 记载的 SDK 托管传输例外)并自行应用该 seam 的 `scrubbedParentEnv()`。 diff --git a/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml b/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml index 7adc61691c..0fe388a3dc 100644 --- a/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml +++ b/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md -2026-07-27-session-projection-and-command-log.md: 8226325d4cd4047c3a9c41eb9427082c59753dd5 -2026-07-27-session-projection-and-command-log.zh.md: b55704f28799008b5e2323d846696e4768fcd6d6 +2026-07-27-session-projection-and-command-log.md: 2fc463ab6e65998c19b0a0fce186c7eb17dacbf6 +2026-07-27-session-projection-and-command-log.zh.md: 89877d3aabcd074863f912b334c927268014e4d8 diff --git a/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md b/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md index 8226325d4c..2fc463ab6e 100644 --- a/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md +++ b/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md @@ -123,7 +123,7 @@ Two log-only (non-surface, model-invisible) events, mirroring the `tool/call`/`t 'command/done': { commandId: string; kind: 'success' | 'error'; text?: string } ``` -The host command executor (`packages/ui/commands`) appends `command/run` before invoking the handler and `command/done` at settlement — direct standalone appends on the receiving agent's session, in the same shape as every other plugin-owned log-only event after the [synthetic-turn removal](../../implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md): no turn wraps them (turns describe model-loop executions only), persistence drains them at ordinary checkpoints, and the commands package's own invariant companion enforces the run/done pairing. The payload is structured — `name` and, by default, `args` are the parser's own split (`parseCommand`'s name and rawInput), so a consumer (a projection unit folding its own command records, a rich command card) never re-parses a line. A definition sets `recordInput: false` when its authoritative domain event owns the payload; `command/run` then omits `args` rather than duplicating it. `text` is the handler's verbatim outcome — factual data of the same nature as `tool/result.content`, not presentation (how it is laid out remains client-computed at render time, satisfying the "presentation never enters the log" red line). Domains that want the model to know the outcome keep doing what they do today (plan's narration, goal's inject) — that is a domain decision, unchanged. +The host command executor (`packages/interaction/commands`) appends `command/run` before invoking the handler and `command/done` at settlement — direct standalone appends on the receiving agent's session, in the same shape as every other plugin-owned log-only event after the [synthetic-turn removal](../../implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md): no turn wraps them (turns describe model-loop executions only), persistence drains them at ordinary checkpoints, and the commands package's own invariant companion enforces the run/done pairing. The payload is structured — `name` and, by default, `args` are the parser's own split (`parseCommand`'s name and rawInput), so a consumer (a projection unit folding its own command records, a rich command card) never re-parses a line. A definition sets `recordInput: false` when its authoritative domain event owns the payload; `command/run` then omits `args` rather than duplicating it. `text` is the handler's verbatim outcome — factual data of the same nature as `tool/result.content`, not presentation (how it is laid out remains client-computed at render time, satisfying the "presentation never enters the log" red line). Domains that want the model to know the outcome keep doing what they do today (plan's narration, goal's inject) — that is a domain decision, unchanged. Because committed events broadcast on the mux stream, refresh persistence, multi-tab sync, and fork/resume recovery all come for free. The `command.execute` RPC degrades to admission — `{ matched, commandId? }`: whether the line resolved, and the minted pairing id when it did, so the issuing client can correlate its request with the flow node the lifecycle events produce. The one-shot notice channel (`runDetached` → `noticeFor`) is retired. diff --git a/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.zh.md b/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.zh.md index b55704f287..89877d3aab 100644 --- a/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.zh.md +++ b/.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.zh.md @@ -123,7 +123,7 @@ type UseProjection = { 'command/done': { commandId: string; kind: 'success' | 'error'; text?: string } ``` -host 侧命令执行器(`packages/ui/commands`)在调用处理器前追加 `command/run`,在结算时追加 `command/done`——在接收 agent 的会话上直接独立追加,与[合成轮次移除](../../implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md)之后所有插件自有 log-only 事件同一形状:没有轮次包裹它们(轮次只描述模型循环执行),持久化在常规检查点排空它们,run/done 配对由 commands 包自己的 invariant 伴生插件把守。载荷是结构化的——`name` 以及默认携带的 `args` 来自解析器自己的切分(`parseCommand` 的 name 与 rawInput),因此消费方(折叠自己命令记录的投影单元、富命令卡片)永远无需重新解析行文本。当载荷由权威领域事件持有时,命令定义会设置 `recordInput: false`;此时 `command/run` 省略 `args`,而不是重复该载荷。`text` 是处理器的原样结果——与 `tool/result.content` 同一性质的事实数据,不是呈现(版式如何编排仍由客户端在渲染时计算,满足「呈现永不入日志」这条红线)。想让模型知道结果的领域继续做它们今天在做的事(plan 的旁白、goal 的注入)——那是领域自己的决定,保持不变。 +host 侧命令执行器(`packages/interaction/commands`)在调用处理器前追加 `command/run`,在结算时追加 `command/done`——在接收 agent 的会话上直接独立追加,与[合成轮次移除](../../implemented/simplification/2026-07-28-remove-synthetic-log-only-turns.md)之后所有插件自有 log-only 事件同一形状:没有轮次包裹它们(轮次只描述模型循环执行),持久化在常规检查点排空它们,run/done 配对由 commands 包自己的 invariant 伴生插件把守。载荷是结构化的——`name` 以及默认携带的 `args` 来自解析器自己的切分(`parseCommand` 的 name 与 rawInput),因此消费方(折叠自己命令记录的投影单元、富命令卡片)永远无需重新解析行文本。当载荷由权威领域事件持有时,命令定义会设置 `recordInput: false`;此时 `command/run` 省略 `args`,而不是重复该载荷。`text` 是处理器的原样结果——与 `tool/result.content` 同一性质的事实数据,不是呈现(版式如何编排仍由客户端在渲染时计算,满足「呈现永不入日志」这条红线)。想让模型知道结果的领域继续做它们今天在做的事(plan 的旁白、goal 的注入)——那是领域自己的决定,保持不变。 由于已提交事件会在 mux 流上广播,刷新后仍在、多标签页同步、fork/恢复后可还原这三件事随之全部自动获得。`command.execute` RPC 退化为准入判定——`{ matched, commandId? }`:该行是否匹配命中,以及命中时新铸的配对 id,发起命令的客户端据此把自己的请求与生命周期事件产出的 flow 节点关联起来。一次性通知通道(`runDetached` → `noticeFor`)就此下线。 diff --git a/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.i18n.yaml b/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.i18n.yaml index cdebeeac5c..71d6fa82b5 100644 --- a/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.i18n.yaml +++ b/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.md -2026-07-19-make-jsonrpc-directional.md: 910b4988aca34dec499b2e34cb2a42042c81b0cb -2026-07-19-make-jsonrpc-directional.zh.md: 9810cf758faa078583955ba541e2b2fe9ad9c855 +2026-07-19-make-jsonrpc-directional.md: 945d58a0c989dac2beeb129bfd545fe5674c63cd +2026-07-19-make-jsonrpc-directional.zh.md: 181aab8cd2f2473f0b2694df1dff072fd805e69d diff --git a/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.md b/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.md index 910b4988ac..945d58a0c9 100644 --- a/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.md +++ b/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.md @@ -20,11 +20,11 @@ Return the settled outcome directly from `session/prompt` as `{ status, reason } ## Implementation plan -1. In `packages/ui/jsonrpc/src/server.ts`, replace `SessionPromptResult.accepted` with `status: 'ok' | 'error' | 'aborted'` and the captured `TurnEndReason`. `HarnessSdkServer.prompt()` will return `completed` as `ok`, `aborted` as `aborted`, and every other current or merge-extensible reason as `error`; reaching idle without a `turn/end` remains an invariant error. Remove only `session.finished`, leaving `session.event`, `subagent.started`, and `subagent.finished` unchanged. -2. In `packages/sdk/sdk-protocol/src/transport.ts`, narrow the shared class to the directions with consumers — inbound requests/outbound responses (the server) and outbound requests/inbound responses plus inbound notifications (the TypeScript SDK client) — removing only server-originated `request()` use and client-originated notification dispatch, or split the class into a server-side and client-side transport. Request result, method-not-found, and handler-error responses retain their current behavior and remain ordered after notifications emitted by the awaited handler. +1. In `packages/scaffold/server/src/server.ts`, replace `SessionPromptResult.accepted` with `status: 'ok' | 'error' | 'aborted'` and the captured `TurnEndReason`. `HarnessSdkServer.prompt()` will return `completed` as `ok`, `aborted` as `aborted`, and every other current or merge-extensible reason as `error`; reaching idle without a `turn/end` remains an invariant error. Remove only `session.finished`, leaving `session.event`, `subagent.started`, and `subagent.finished` unchanged. +2. In `packages/scaffold/protocol/src/transport.ts`, narrow the shared class to the directions with consumers — inbound requests/outbound responses (the server) and outbound requests/inbound responses plus inbound notifications (the TypeScript SDK client) — removing only server-originated `request()` use and client-originated notification dispatch, or split the class into a server-side and client-side transport. Request result, method-not-found, and handler-error responses retain their current behavior and remain ordered after notifications emitted by the awaited handler. 3. In `python/sdk/src/deepseek_harness/client.py`, `models.py`, and `__init__.py`, remove `IncomingRequest`, `_requests`, `notify()`, `next_request()`, `respond()`, and `respond_error()`. Add a public validated `SessionPromptResponse` carrying status and reason, return it from `session_prompt()`, and keep an explicit reader guard that ignores unexpected server-request frames instead of allowing them to match a response waiter. 4. In `python/sdk/src/deepseek_harness/api.py`, build `TurnResult.status` and a new `TurnResult.reason` from `SessionPromptResponse`, then delete the `session.finished` branch and second completion loop. Keep the subscription open during the request and preserve `_request_raw()`'s final notification drain so the last `turn/end` event and any subagent notification written before the response are collected before `Session.run()` reconstructs the final assistant message. -5. Replace the symmetric transport-pair cases in `packages/sdk/sdk-protocol/tests/transport.spec.ts` with per-direction coverage, and update `server.spec.ts`, `plugin-apply.spec.ts`, and `built-scope-carrier.e2e.ts` for direct outcomes, ordering, overlap, shutdown, and the narrowed fake; update the TypeScript SDK client (`packages/sdk/sdk-client`) and its suites for response-based settlement. Update `python/sdk/tests/test_client.py` for response-based settlement, unexpected-request-frame handling, callback and concurrency behavior, and the removed public helpers. Update the JSON-RPC and bilingual Python SDK READMEs, export JSDoc and declarations, `scripts/smoke-python-runtime.py`, and the Python single-executable snapshot. +5. Replace the symmetric transport-pair cases in `packages/scaffold/protocol/tests/transport.spec.ts` with per-direction coverage, and update `server.spec.ts`, `plugin-apply.spec.ts`, and `built-scope-carrier.e2e.ts` for direct outcomes, ordering, overlap, shutdown, and the narrowed fake; update the TypeScript SDK client (`packages/scaffold/client`) and its suites for response-based settlement. Update `python/sdk/tests/test_client.py` for response-based settlement, unexpected-request-frame handling, callback and concurrency behavior, and the removed public helpers. Update the JSON-RPC and bilingual Python SDK READMEs, export JSDoc and declarations, `scripts/smoke-python-runtime.py`, and the Python single-executable snapshot. ## Alternatives considered diff --git a/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.zh.md b/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.zh.md index 9810cf758f..181aab8cd2 100644 --- a/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.zh.md +++ b/.agents/notes/proposed/simplification/2026-07-19-make-jsonrpc-directional.zh.md @@ -20,11 +20,11 @@ JSON-RPC 桥接层把两个端点都建模为对称的对等端,但实际协 ## 实施计划 -1. 在 `packages/ui/jsonrpc/src/server.ts` 中,用 `status: 'ok' | 'error' | 'aborted'` 和捕获的 `TurnEndReason` 替换 `SessionPromptResult.accepted`。`HarnessSdkServer.prompt()` 把 `completed` 映射为 `ok`,把 `aborted` 映射为 `aborted`,把其他当前已有或可通过声明合并扩展的原因映射为 `error`;进入空闲状态却没有 `turn/end` 仍视为不变量错误。只删除 `session.finished`,保持 `session.event`、`subagent.started` 和 `subagent.finished` 不变。 -2. 在 `packages/sdk/sdk-protocol/src/transport.ts` 中,把共享类收窄到有消费者的方向——入站请求/出站响应(服务端)与出站请求/入站响应及入站通知(TypeScript SDK 客户端)——只删除服务端发起的 `request()` 用法与客户端发起的通知分发,或把该类拆分为服务端与客户端两个传输。请求结果、方法不存在与处理器错误响应保持原有行为,并继续排在被等待处理器发出的通知之后。 +1. 在 `packages/scaffold/server/src/server.ts` 中,用 `status: 'ok' | 'error' | 'aborted'` 和捕获的 `TurnEndReason` 替换 `SessionPromptResult.accepted`。`HarnessSdkServer.prompt()` 把 `completed` 映射为 `ok`,把 `aborted` 映射为 `aborted`,把其他当前已有或可通过声明合并扩展的原因映射为 `error`;进入空闲状态却没有 `turn/end` 仍视为不变量错误。只删除 `session.finished`,保持 `session.event`、`subagent.started` 和 `subagent.finished` 不变。 +2. 在 `packages/scaffold/protocol/src/transport.ts` 中,把共享类收窄到有消费者的方向——入站请求/出站响应(服务端)与出站请求/入站响应及入站通知(TypeScript SDK 客户端)——只删除服务端发起的 `request()` 用法与客户端发起的通知分发,或把该类拆分为服务端与客户端两个传输。请求结果、方法不存在与处理器错误响应保持原有行为,并继续排在被等待处理器发出的通知之后。 3. 在 `python/sdk/src/deepseek_harness/client.py`、`models.py` 和 `__init__.py` 中,删除 `IncomingRequest`、`_requests`、`notify()`、`next_request()`、`respond()` 和 `respond_error()`。新增公开且经过校验的 `SessionPromptResponse` 来携带状态与原因,由 `session_prompt()` 返回该对象,并保留明确的读取保护:忽略意外的服务端请求帧,避免它们命中响应等待器。 4. 在 `python/sdk/src/deepseek_harness/api.py` 中,根据 `SessionPromptResponse` 构造 `TurnResult.status` 和新增的 `TurnResult.reason`,再删除 `session.finished` 分支与第二个完成循环。请求期间保持订阅打开,并保留 `_request_raw()` 最后的通知排空步骤,确保写在响应前的最后一条 `turn/end` 事件与任何 subagent 通知,都会在 `Session.run()` 重建最终助手消息之前被收集。 -5. 用按方向的覆盖替换 `packages/sdk/sdk-protocol/tests/transport.spec.ts` 中的对称传输对用例,并更新 `server.spec.ts`、`plugin-apply.spec.ts` 和 `built-scope-carrier.e2e.ts`,覆盖直接结果、顺序、重叠、关闭和收窄后的伪实现;同步更新 TypeScript SDK 客户端(`packages/sdk/sdk-client`)及其套件以采用基于响应的结束流程。更新 `python/sdk/tests/test_client.py`,覆盖基于响应的结束流程、意外请求帧处理、回调与并发行为,以及已删除的公开辅助方法。同步更新 JSON-RPC README、双语 Python SDK README、导出 JSDoc 与声明、`scripts/smoke-python-runtime.py` 和 Python 单可执行文件快照。 +5. 用按方向的覆盖替换 `packages/scaffold/protocol/tests/transport.spec.ts` 中的对称传输对用例,并更新 `server.spec.ts`、`plugin-apply.spec.ts` 和 `built-scope-carrier.e2e.ts`,覆盖直接结果、顺序、重叠、关闭和收窄后的伪实现;同步更新 TypeScript SDK 客户端(`packages/scaffold/client`)及其套件以采用基于响应的结束流程。更新 `python/sdk/tests/test_client.py`,覆盖基于响应的结束流程、意外请求帧处理、回调与并发行为,以及已删除的公开辅助方法。同步更新 JSON-RPC README、双语 Python SDK README、导出 JSDoc 与声明、`scripts/smoke-python-runtime.py` 和 Python 单可执行文件快照。 ## 备选方案 diff --git a/AGENTS.md b/AGENTS.md index 7727539bd9..7c9b795ddc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,7 +37,9 @@ packages/ @deepseek-ai/dsh- workspaces at packages/// settings/ user-settings seam + file-backed provider credentials/ credential-reference seam + env-over-.env provider acp/ automation-only Agent Client Protocol server - ui/ JSON-RPC bridge; boot, approval, interaction plugins + interaction/ approval/interaction seams, permission, commands, ask-user tool + boot/ shared app-bin boot glue + scaffold/ project tooling: helper, launcher, initializer, SDK wire protocol + ends examples/ demo bundles (agent-spine + CLI/ACP/JSON-RPC bins) leaves load support/ dev/test infrastructure util/ zero-dependency utilities diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json index 36c4bad6dd..d830e8fba6 100644 --- a/apps/cli/tsconfig.json +++ b/apps/cli/tsconfig.json @@ -18,7 +18,7 @@ "path": "../../vendor/include" }, { - "path": "../../packages/ui/app-boot" + "path": "../../packages/boot/app-boot" }, { "path": "../../packages/bundle/base" diff --git a/docs/architecture.i18n.yaml b/docs/architecture.i18n.yaml index 4d10310333..76491a37fe 100644 --- a/docs/architecture.i18n.yaml +++ b/docs/architecture.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/architecture.md -architecture.md: c14d68c47f6ed0786e8fc0b0650dbc67678250fb -architecture.zh.md: df484762d29e170a5b1ba64f0637c5170c2c5ef4 +architecture.md: cee159452fc536c98a006cfa3ea92e9d21a1e77b +architecture.zh.md: cf10e60a5d5e4fe3f39d72bef3d48fe7c2f3c105 diff --git a/docs/architecture.md b/docs/architecture.md index c14d68c47f..cee159452f 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -163,7 +163,7 @@ Exceptions combine LLM interface/consumer, filesystem policy, web registries, an ### Bundles And Apps -`dsh-agent-spine-demo` bundles a spine and optional goals. App packages own CLI, ACP automation, and JSON-RPC front doors ([README](../packages/examples/agent-spine-demo/README.md), [acp/](../packages/acp/README.md), [ui/](../packages/ui/README.md)). `dsh-jsonrpc-agent` boots external `cordis.yml`; the Python SDK defaults when config is absent ([Python SDK](../python/README.md)). Thin deployments use swappable backends and optional tools ([examples/](../examples/AGENTS.md), [runnable wirings](cookbook/extension-cookbook.md#runnable-wirings), [graph atlas](graph-atlas.md)). +`dsh-agent-spine-demo` bundles a spine and optional goals. App packages own CLI, ACP automation, and JSON-RPC front doors ([README](../packages/examples/agent-spine-demo/README.md), [acp/](../packages/acp/README.md), [interaction/](../packages/interaction/README.md)). `dsh-jsonrpc-agent` boots external `cordis.yml`; the Python SDK defaults when config is absent ([Python SDK](../python/README.md)). Thin deployments use swappable backends and optional tools ([examples/](../examples/AGENTS.md), [runnable wirings](cookbook/extension-cookbook.md#runnable-wirings), [graph atlas](graph-atlas.md)). ### Where New Behavior Goes diff --git a/docs/architecture.zh.md b/docs/architecture.zh.md index df484762d2..cf10e60a5d 100644 --- a/docs/architecture.zh.md +++ b/docs/architecture.zh.md @@ -163,7 +163,7 @@ idle inject: ### 组合包与应用 -`dsh-agent-spine-demo` 组合一套主干和可选目标。应用包负责 CLI(命令行界面)、ACP 自动化入口和 JSON-RPC 入口([README](../packages/examples/agent-spine-demo/README.md)、[acp/](../packages/acp/README.md)、[ui/](../packages/ui/README.md))。`dsh-jsonrpc-agent` 启动外部 `cordis.yml`;Python SDK 在配置缺失时提供默认项([Python SDK](../python/README.md))。轻量部署使用可替换后端和可选工具([examples/](../examples/AGENTS.md)、[可运行接线](cookbook/extension-cookbook.md#runnable-wirings)、[图谱](graph-atlas.md))。 +`dsh-agent-spine-demo` 组合一套主干和可选目标。应用包负责 CLI(命令行界面)、ACP 自动化入口和 JSON-RPC 入口([README](../packages/examples/agent-spine-demo/README.md)、[acp/](../packages/acp/README.md)、[interaction/](../packages/interaction/README.md))。`dsh-jsonrpc-agent` 启动外部 `cordis.yml`;Python SDK 在配置缺失时提供默认项([Python SDK](../python/README.md))。轻量部署使用可替换后端和可选工具([examples/](../examples/AGENTS.md)、[可运行接线](cookbook/extension-cookbook.md#runnable-wirings)、[图谱](graph-atlas.md))。 ### 新行为的归属位置 diff --git a/docs/capability-seams.md b/docs/capability-seams.md index 60a19999f3..c191f6a659 100644 --- a/docs/capability-seams.md +++ b/docs/capability-seams.md @@ -389,10 +389,10 @@ flowchart LR | `ctx.sessionReferences` | `core` | [`session-reference`](../packages/context/session-reference) | - | - | - | Projects bounded current-surface conversation snapshots into durable untrusted message context; host adapters own mention syntax. | | `ctx.sessionTitle` | `seam` | [`session-title`](../packages/session/session-title) | [`session-title-first-message-llm`](../packages/session/session-title-first-message-llm), [`session-title-all-messages-llm`](../packages/session/session-title-all-messages-llm) | - | - | Owns the deterministic fallback, latest-title fold, and sole optional asynchronous provider registration. | | `ctx.systemPrompt` | `core` | [`system-prompt`](../packages/core/system-prompt) | - | [`agent-loop`](../packages/core/agent-loop), [`tools`](../packages/core/tools), [`tool-fs`](../packages/fs/tool-fs), [`tool-pty`](../packages/pty/tool-pty), [`tool-web`](../packages/web/tool-web) | - | Collects prompt sections and model-facing tool schemas for each step. | -| `ctx.tools` | `core` | [`tools`](../packages/core/tools) | - | [`agent-loop`](../packages/core/agent-loop), [`tool-ask-user`](../packages/ui/tool-ask-user), [`tool-bash`](../packages/bash/tool-bash), [`tool-cordis`](../packages/cordis/tool-cordis), [`tool-fs`](../packages/fs/tool-fs), [`tool-pty`](../packages/pty/tool-pty), [`tool-skill`](../packages/skill/tool-skill), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-todo`](../packages/todo/tool-todo), [`tool-web`](../packages/web/tool-web) | - | Registers capabilities, owns Code Mode transport, and routes calls through pre-policy, monotonic guards, around dispatch, post-policy, and final-result observation. | -| `ctx.userInteraction` | `seam` | [`user-interaction`](../packages/ui/user-interaction) | - | [`tool-ask-user`](../packages/ui/tool-ask-user) | - | UI front doors provide the active human-answer provider; tool-ask-user pauses a tool call on the provider-neutral ask() promise. | +| `ctx.tools` | `core` | [`tools`](../packages/core/tools) | - | [`agent-loop`](../packages/core/agent-loop), [`tool-ask-user`](../packages/interaction/tool-ask-user), [`tool-bash`](../packages/bash/tool-bash), [`tool-cordis`](../packages/cordis/tool-cordis), [`tool-fs`](../packages/fs/tool-fs), [`tool-pty`](../packages/pty/tool-pty), [`tool-skill`](../packages/skill/tool-skill), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-todo`](../packages/todo/tool-todo), [`tool-web`](../packages/web/tool-web) | - | Registers capabilities, owns Code Mode transport, and routes calls through pre-policy, monotonic guards, around dispatch, post-policy, and final-result observation. | +| `ctx.userInteraction` | `seam` | [`user-interaction`](../packages/interaction/user-interaction) | - | [`tool-ask-user`](../packages/interaction/tool-ask-user) | - | UI front doors provide the active human-answer provider; tool-ask-user pauses a tool call on the provider-neutral ask() promise. | | `ctx.planMode` | `core` | [`plan-mode`](../packages/plan/plan-mode) | - | - | - | Folds logged plan/mode state, flushes user selections at turn boundaries, renders deployment-owned guidance, registers /plan, and keeps the plan-exit schema stable across transitions. | -| `ctx.commands` | `core` | [`commands`](../packages/ui/commands) | - | - | - | Plugins register direct human commands without sending invocations to the model. | +| `ctx.commands` | `core` | [`commands`](../packages/interaction/commands) | - | - | - | Plugins register direct human commands without sending invocations to the model. | | `ctx.sessionProjections` | `core` | [`session-projection`](../packages/session/session-projection) | - | [`tool-todo`](../packages/todo/tool-todo), [`session-title`](../packages/session/session-title), [`host-apiproxy`](../packages/host/apiproxy) | - | Domains register state-driven fold units; the eager drive keeps per-session watermark states and api-proxy serves baselines and pushes changed values. | | `ctx.sessionProjectionCache` | `core` | [`session-projection-cache`](../packages/session/session-projection-cache) | - | [`host-apiproxy`](../packages/host/apiproxy) | - | Durably checkpoints projection unit states per session (throttled + turn/end/detach mandatory points) and serves the cold-read ladder: cache row + persistence tail replay, so listings never load full logs. | | `ctx.skills` | `seam` | [`skill`](../packages/skill/skill) | [`skill-badge`](../packages/skill/skill-badge), [`skill-local`](../packages/skill/skill-local) | [`tool-skill`](../packages/skill/tool-skill) | - | Merges provider skill catalogs; tool-skill renders the session-prefix catalog and loads complete skill bodies. | @@ -407,7 +407,7 @@ flowchart LR | `ctx.sandbox` | `seam` | [`sandbox`](../packages/sandbox/sandbox) | [`sandbox-local`](../packages/sandbox/sandbox-local) | [`bash-sandbox`](../packages/bash/bash-sandbox), [`pty-local`](../packages/pty/pty-local) | - | Consumers hand over the exact argv they are about to spawn; same-world backends wrap it under a per-call policy and report enforcement. | | `ctx.sandboxPolicy` | `core` | [`sandbox-policy`](../packages/sandbox/sandbox-policy) | - | [`bash-sandbox`](../packages/bash/bash-sandbox), [`fs-sandbox`](../packages/fs/fs-sandbox), [`pty-local`](../packages/pty/pty-local) | - | The one home for the deployment default mode + workspace root; only the sandboxed executor and provider read the service (the tool layers use the pure `sandbox/mode` fold it also exports). Both enforcing families read it so bash and fs cannot confine to different roots. | | `ctx.approval` | `seam` | `approval` | [`acp`](../packages/acp/acp) | [`tools`](../packages/core/tools), [`tool-bash`](../packages/bash/tool-bash) | - | One-shot permission decisions dispatched over the `approval/request` waterfall; answerers are listeners (the ACP bridge for its own agents), absence fails closed to `unavailable`. | -| `ctx.permission` | `core` | [`permission`](../packages/ui/permission) | - | - | - | User-facing preset table (`workspace-write`/`danger-full-access`) bundling the sandbox-mode and approval-policy knobs; a switch writes one `permission/preset` event through to both knob events. | +| `ctx.permission` | `core` | [`permission`](../packages/interaction/permission) | - | - | - | User-facing preset table (`workspace-write`/`danger-full-access`) bundling the sandbox-mode and approval-policy knobs; a switch writes one `permission/preset` event through to both knob events. | | `ctx.codeRuntime` | `seam` | [`code-runtime`](../packages/code-runtime/code-runtime) | [`code-runtime-worker`](../packages/code-runtime/code-runtime-worker) | [`tools`](../packages/core/tools) | - | Runs one model-written program against host-provided async bindings; backends differ by substrate and language (the tool registry consumes it for Code Mode). | | `ctx.fs` | `seam` | [`fs`](../packages/fs/fs) | [`fs-local`](../packages/fs/fs-local), [`fs-sandbox`](../packages/fs/fs-sandbox), [`fs-e2b`](../packages/e2b/fs-e2b) | [`tool-fs`](../packages/fs/tool-fs) | [`fs-policy`](../packages/fs/fs-policy) | tool-fs executes read/write/edit through ctx.fs; fs-sandbox fences mutations by the shared sandbox mode; fs-policy contributes observed-state checks through the fs/* event gate. | | `ctx.compact` | `seam` | [`compact`](../packages/compact/compact) | [`compact-basic`](../packages/compact/compact-basic) | [`compact-basic`](../packages/compact/compact-basic) | - | The basic backend consumes post-step pressure and request-error recovery events; a model-facing compact tool remains deferred. | diff --git a/docs/core-data-structures/approval.i18n.yaml b/docs/core-data-structures/approval.i18n.yaml index 0679cd47bd..975f631805 100644 --- a/docs/core-data-structures/approval.i18n.yaml +++ b/docs/core-data-structures/approval.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/core-data-structures/approval.md -approval.md: f1889b25e2bbbcb157b0bced070b1f157a867504 -approval.zh.md: 48222991312f9ae97c9249f1232b261d2393d282 +approval.md: 8f17f98101950e6413d67fb4cce6befc5aede069 +approval.zh.md: c19285572b667512427b71d4af214acbc2baf334 diff --git a/docs/core-data-structures/approval.md b/docs/core-data-structures/approval.md index f1889b25e2..8f17f98101 100644 --- a/docs/core-data-structures/approval.md +++ b/docs/core-data-structures/approval.md @@ -2,9 +2,9 @@ English | [中文](approval.zh.md) -The user-approval seam of [dsh-user-approval](../../packages/ui/user-approval) answers one question: may this specific action proceed? It owns the shared request/outcome vocabulary, the `ctx.approval` dispatch service, the `approval/request` answerer waterfall, the log-only audit pair, and the per-session `ask`/`never` policy. UI channels may provide human answerers; the [ACP automation bridge](../../packages/acp/acp) provides one-shot machine decisions for its own agents. Callers such as [dsh-tools](../../packages/core/tools) and [dsh-tool-bash](../../packages/bash/tool-bash) consume the closed outcome and fail closed unless it is `allowed-once`. +The user-approval seam of [dsh-user-approval](../../packages/interaction/user-approval) answers one question: may this specific action proceed? It owns the shared request/outcome vocabulary, the `ctx.approval` dispatch service, the `approval/request` answerer waterfall, the log-only audit pair, and the per-session `ask`/`never` policy. UI channels may provide human answerers; the [ACP automation bridge](../../packages/acp/acp) provides one-shot machine decisions for its own agents. Callers such as [dsh-tools](../../packages/core/tools) and [dsh-tool-bash](../../packages/bash/tool-bash) consume the closed outcome and fail closed unless it is `allowed-once`. -Source: [`packages/ui/user-approval/src/index.ts`](../../packages/ui/user-approval/src/index.ts) +Source: [`packages/interaction/user-approval/src/index.ts`](../../packages/interaction/user-approval/src/index.ts) ## Identity and outcome diff --git a/docs/core-data-structures/approval.zh.md b/docs/core-data-structures/approval.zh.md index 4822299131..c19285572b 100644 --- a/docs/core-data-structures/approval.zh.md +++ b/docs/core-data-structures/approval.zh.md @@ -2,9 +2,9 @@ [English](approval.md) | 中文 -[dsh-user-approval](../../packages/ui/user-approval) 的用户审批 seam 回答一个问题:这个具体操作是否可以继续?它拥有共享的请求/结果词汇、`ctx.approval` 分发服务、`approval/request` 应答者 waterfall(瀑布式事件)、仅记录日志的审计事件对,以及按会话的 `ask`/`never` 策略。UI 通道可以提供人类应答者;[ACP(Agent Client Protocol)自动化桥接层](../../packages/acp/acp)为其拥有的 agent(智能体)提供一次性机器决策。调用方如 [dsh-tools](../../packages/core/tools) 和 [dsh-tool-bash](../../packages/bash/tool-bash) 消费闭合的结果,除非结果为 `allowed-once`,否则一律拒绝。 +[dsh-user-approval](../../packages/interaction/user-approval) 的用户审批 seam 回答一个问题:这个具体操作是否可以继续?它拥有共享的请求/结果词汇、`ctx.approval` 分发服务、`approval/request` 应答者 waterfall(瀑布式事件)、仅记录日志的审计事件对,以及按会话的 `ask`/`never` 策略。UI 通道可以提供人类应答者;[ACP(Agent Client Protocol)自动化桥接层](../../packages/acp/acp)为其拥有的 agent(智能体)提供一次性机器决策。调用方如 [dsh-tools](../../packages/core/tools) 和 [dsh-tool-bash](../../packages/bash/tool-bash) 消费闭合的结果,除非结果为 `allowed-once`,否则一律拒绝。 -源码:[`packages/ui/user-approval/src/index.ts`](../../packages/ui/user-approval/src/index.ts) +源码:[`packages/interaction/user-approval/src/index.ts`](../../packages/interaction/user-approval/src/index.ts) ## 标识与结果 diff --git a/docs/core-data-structures/commands.i18n.yaml b/docs/core-data-structures/commands.i18n.yaml index 532151ef70..18df873acc 100644 --- a/docs/core-data-structures/commands.i18n.yaml +++ b/docs/core-data-structures/commands.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/core-data-structures/commands.md -commands.md: 1390f736ff582a997ee710cfd27fce4e7db3461f -commands.zh.md: 53aec9bd138773df7fceb45e5d6c30b7205dd0d9 +commands.md: 83ce9c2498df58110d9a9c2e7d5163a9df813e1c +commands.zh.md: c486f480177c7ff8b35cc846beafac009cea42bb diff --git a/docs/core-data-structures/commands.md b/docs/core-data-structures/commands.md index 1390f736ff..83ce9c2498 100644 --- a/docs/core-data-structures/commands.md +++ b/docs/core-data-structures/commands.md @@ -2,9 +2,9 @@ English | [中文](commands.zh.md) -The human-command seam of [`dsh-commands`](../../packages/ui/commands). Interactive adapters use it to discover and directly execute plugin-owned commands for an exact agent without creating a model message. The [command Agent Note](../../.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md) owns dispatch and lifecycle rationale; the [package README](../../packages/ui/commands/README.md) owns composition and limitations. +The human-command seam of [`dsh-commands`](../../packages/interaction/commands). Interactive adapters use it to discover and directly execute plugin-owned commands for an exact agent without creating a model message. The [command Agent Note](../../.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md) owns dispatch and lifecycle rationale; the [package README](../../packages/interaction/commands/README.md) owns composition and limitations. -Source: [`packages/ui/commands/src/index.ts`](../../packages/ui/commands/src/index.ts) +Source: [`packages/interaction/commands/src/index.ts`](../../packages/interaction/commands/src/index.ts) ## Input metadata diff --git a/docs/core-data-structures/commands.zh.md b/docs/core-data-structures/commands.zh.md index 53aec9bd13..c486f48017 100644 --- a/docs/core-data-structures/commands.zh.md +++ b/docs/core-data-structures/commands.zh.md @@ -2,9 +2,9 @@ [English](commands.md) | 中文 -[`dsh-commands`](../../packages/ui/commands) 的用户命令 seam。交互式适配器用它发现插件拥有的命令,并针对确切的 agent(智能体)直接执行这些命令,而不创建模型消息。[命令 Agent Note](../../.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md) 负责分发与生命周期的决策依据;[包 README](../../packages/ui/commands/README.md) 负责组合方式与限制。 +[`dsh-commands`](../../packages/interaction/commands) 的用户命令 seam。交互式适配器用它发现插件拥有的命令,并针对确切的 agent(智能体)直接执行这些命令,而不创建模型消息。[命令 Agent Note](../../.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md) 负责分发与生命周期的决策依据;[包 README](../../packages/interaction/commands/README.md) 负责组合方式与限制。 -来源:[`packages/ui/commands/src/index.ts`](../../packages/ui/commands/src/index.ts) +来源:[`packages/interaction/commands/src/index.ts`](../../packages/interaction/commands/src/index.ts) ## 输入元数据 diff --git a/docs/core-data-structures/user-interaction.i18n.yaml b/docs/core-data-structures/user-interaction.i18n.yaml index 5480052231..3768cfcf7b 100644 --- a/docs/core-data-structures/user-interaction.i18n.yaml +++ b/docs/core-data-structures/user-interaction.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/core-data-structures/user-interaction.md -user-interaction.md: 73727cbb754f10633d3213f67f7c3c9fdb215500 -user-interaction.zh.md: b6e95af4026e58c63c713d87ee9a86b3712b311f +user-interaction.md: ec22eb28e9554d6454bf2670f73f2e9b199df014 +user-interaction.zh.md: 814f8911e41aecf568f627f76f8239bac4ea719b diff --git a/docs/core-data-structures/user-interaction.md b/docs/core-data-structures/user-interaction.md index 73727cbb75..ec22eb28e9 100644 --- a/docs/core-data-structures/user-interaction.md +++ b/docs/core-data-structures/user-interaction.md @@ -2,9 +2,9 @@ English | [中文](user-interaction.zh.md) -The user-interaction seam of [dsh-user-interaction](../../packages/ui/user-interaction). It is the provider-neutral vocabulary a tool or permission plugin uses when it needs the human to answer before the agent can continue. UI surfaces provide the active `UserInteractionProvider`; the host runtime relays requests to its connected client. +The user-interaction seam of [dsh-user-interaction](../../packages/interaction/user-interaction). It is the provider-neutral vocabulary a tool or permission plugin uses when it needs the human to answer before the agent can continue. UI surfaces provide the active `UserInteractionProvider`; the host runtime relays requests to its connected client. -Source: [`packages/ui/user-interaction/src/index.ts`](../../packages/ui/user-interaction/src/index.ts) +Source: [`packages/interaction/user-interaction/src/index.ts`](../../packages/interaction/user-interaction/src/index.ts) ## Question options diff --git a/docs/core-data-structures/user-interaction.zh.md b/docs/core-data-structures/user-interaction.zh.md index b6e95af402..814f8911e4 100644 --- a/docs/core-data-structures/user-interaction.zh.md +++ b/docs/core-data-structures/user-interaction.zh.md @@ -2,9 +2,9 @@ [English](user-interaction.md) | 中文 -[dsh-user-interaction](../../packages/ui/user-interaction) 的用户交互 seam。它是工具或权限插件需要人类回答后 agent(智能体)才能继续时所使用的、提供方无关的词汇。UI surface 提供活跃的 `UserInteractionProvider`;host 运行时把请求转发给它连接的客户端。 +[dsh-user-interaction](../../packages/interaction/user-interaction) 的用户交互 seam。它是工具或权限插件需要人类回答后 agent(智能体)才能继续时所使用的、提供方无关的词汇。UI surface 提供活跃的 `UserInteractionProvider`;host 运行时把请求转发给它连接的客户端。 -源码:[`packages/ui/user-interaction/src/index.ts`](../../packages/ui/user-interaction/src/index.ts) +源码:[`packages/interaction/user-interaction/src/index.ts`](../../packages/interaction/user-interaction/src/index.ts) ## 问题选项 diff --git a/docs/testing.i18n.yaml b/docs/testing.i18n.yaml index 90970c8c57..0b7cdfdc76 100644 --- a/docs/testing.i18n.yaml +++ b/docs/testing.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/testing.md -testing.md: fecf02fe887aac5c92c739523f10a0562eba6242 -testing.zh.md: a34f56fac72baa9916d5f96e83048ad54cf23d4a +testing.md: 296dd769118cc5498ddb1bb9c41e2c060b2a5bce +testing.zh.md: e9182495fbdbb1458c9ff5b30a9591f8b70f27c5 diff --git a/docs/testing.md b/docs/testing.md index fecf02fe88..296dd76911 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -32,7 +32,7 @@ An e2e assertion re-runs the command or re-reads the file externally; a keyword - Product-visible plugins require a non-unit REAL-composition test. Hand-built `ctx.plugin(...)` suites are insufficient: boot test-only `cordis.yml` through Loader and app/process, mock only external/nondeterministic boundaries, and assert model-visible request/log, durable state, or user-visible output. Keep opt-ins out of shipped defaults. - A guard only guards if the regression actually fails it. For a plugin without `inject` (bundle/composition plugins), a Loader smoke stays green under a broken export shape — add an explicit `expect('default' in mod).toBe(false)` plus an `unwrapExports` round-trip assertion, and prove it: introduce the regression, watch red, revert. -- "Real entry path" means the published artifact: a package `bin` runs built `lib/bin.js` under plain `node`, exposing failures tsx masks (settle races, module resolution, swallowed load failures). The same applies to non-index runtime entries (the worker-thread sibling `lib/worker.cjs`) and singleton modules shared across bundles (`packages/ui/jsonrpc/tests/built-scope-carrier.e2e.ts`). Keep the built-artifact smokes green (`packages/ui/*/tests/built-bin.e2e.ts`, `packages/code-runtime/code-runtime-worker/tests/built-lib.e2e.ts`), and assert a genuinely-missing config exits non-zero. +- "Real entry path" means the published artifact: a package `bin` runs built `lib/bin.js` under plain `node`, exposing failures tsx masks (settle races, module resolution, swallowed load failures). The same applies to non-index runtime entries (the worker-thread sibling `lib/worker.cjs`) and singleton modules shared across bundles (`packages/scaffold/server/tests/built-scope-carrier.e2e.ts`). Keep the built-artifact smokes green (`packages/examples/*/tests/built-bin.e2e.ts`, `packages/code-runtime/code-runtime-worker/tests/built-lib.e2e.ts`), and assert a genuinely-missing config exits non-zero. ## Test resolution: source plane only diff --git a/docs/testing.zh.md b/docs/testing.zh.md index a34f56fac7..e9182495fb 100644 --- a/docs/testing.zh.md +++ b/docs/testing.zh.md @@ -32,7 +32,7 @@ e2e 断言应重新运行命令或从外部重新读取文件;对 agent 自身 - 产品可见的插件必须有一个非单元的真实组合测试。手动构建的 `ctx.plugin(...)` 套件不够:通过 Loader 和 app/process 启动仅用于测试的 `cordis.yml`,只 mock 外部/不确定边界,断言模型可见的请求/日志、持久状态或用户可见输出。不要把 opt-in 选项混入交付默认值。 - 一个守卫只有在回归真的能让它失败时才有效。对于没有 `inject` 的插件(bundle/组合插件),Loader 冒烟测试在导出形状损坏时仍然绿着——需要添加显式的 `expect('default' in mod).toBe(false)` 加 `unwrapExports` 往返断言,并证明它有效:引入回归、观察变红、回退。 -- 「真实入口路径」指已发布的产物:包的 `bin` 所运行的是构建后的 `lib/bin.js`,并由普通 `node` 执行,从而暴露 tsx 会掩盖的失败(等待稳定时的竞态、模块解析、被吞掉的加载失败)。同样的规则适用于非 index 运行时入口(worker-thread 的同级文件 `lib/worker.cjs`),也适用于多个 bundle 共享的单例模块(`packages/ui/jsonrpc/tests/built-scope-carrier.e2e.ts`)。保持构建产物冒烟测试绿色(`packages/ui/*/tests/built-bin.e2e.ts`、`packages/code-runtime/code-runtime-worker/tests/built-lib.e2e.ts`),并断言真正缺失的配置以非零状态退出。 +- 「真实入口路径」指已发布的产物:包的 `bin` 所运行的是构建后的 `lib/bin.js`,并由普通 `node` 执行,从而暴露 tsx 会掩盖的失败(等待稳定时的竞态、模块解析、被吞掉的加载失败)。同样的规则适用于非 index 运行时入口(worker-thread 的同级文件 `lib/worker.cjs`),也适用于多个 bundle 共享的单例模块(`packages/scaffold/server/tests/built-scope-carrier.e2e.ts`)。保持构建产物冒烟测试绿色(`packages/examples/*/tests/built-bin.e2e.ts`、`packages/code-runtime/code-runtime-worker/tests/built-lib.e2e.ts`),并断言真正缺失的配置以非零状态退出。 ## 测试解析:仅限源码 diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index adb73f104d..0cb985d07d 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -107,7 +107,7 @@ Ask the user a concise question when you need confirmation, a choice, or missing } ``` -Source: [`packages/ui/tool-ask-user/src/index.ts`](../packages/ui/tool-ask-user/src/index.ts) +Source: [`packages/interaction/tool-ask-user/src/index.ts`](../packages/interaction/tool-ask-user/src/index.ts) ask_user_question pauses the tool call until the active UI provider returns a human answer. diff --git a/knip.json b/knip.json index 0e82064200..63db33e51c 100644 --- a/knip.json +++ b/knip.json @@ -513,7 +513,7 @@ "tests/**/*.ts" ] }, - "packages/ui/jsonrpc": { + "packages/scaffold/server": { "entry": [ "tests/**/*.spec.ts", "tests/**/*.e2e.ts" @@ -523,7 +523,7 @@ "tests/**/*.ts" ] }, - "packages/ui/commands": { + "packages/interaction/commands": { "entry": [ "tests/**/*.spec.ts" ], @@ -537,7 +537,7 @@ "src/**/*.ts" ] }, - "packages/sdk/create-sdk": { + "packages/scaffold/create-sdk": { "entry": [ "src/bin.ts", "tests/**/*.spec.ts", @@ -549,7 +549,7 @@ "tests/**/*.ts" ] }, - "packages/sdk/scripts": { + "packages/scaffold/scripts": { "entry": [ "src/bin.ts", "tests/**/*.spec.ts", diff --git a/packages/README.i18n.yaml b/packages/README.i18n.yaml index 44dd906b76..68da8ae611 100644 --- a/packages/README.i18n.yaml +++ b/packages/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/README.md -README.md: 9f8b3f936af6392239218d5389c91c87d0f7d1f9 -README.zh.md: 2f4e86cb541a8a34762b36cac57f456de96cac5d +README.md: 198caca8c8b8231ece4d7160c809ba7b881e775c +README.zh.md: bf2bf437796d904d135b610ff2c7a2d4d21b0298 diff --git a/packages/README.md b/packages/README.md index 9f8b3f936a..198caca8c8 100644 --- a/packages/README.md +++ b/packages/README.md @@ -45,9 +45,10 @@ Groups hold `packages///`; names stay `@deepseek-ai/dsh-`. **Gr | [`credentials/`](credentials/README.md) | Credential-reference seam + env-over-`.env` provider | Product — stable surface | | [`storage/`](storage/README.md) | Non-session storage hub + backends + domain form | Product — stable surface | | [`workspace/`](workspace/README.md) | Workspace entity | Product — stable surface | -| [`sdk/`](sdk/README.md) | Project SDK tooling | Product — stable surface | +| [`scaffold/`](scaffold/README.md) | Create/launch/drive project tooling: helper, launcher, initializer, wire protocol with both ends, launcher telemetry | Product — stable surface | | [`acp/`](acp/README.md) | Automation-only Agent Client Protocol server | Product — stable surface | -| [`ui/`](ui/README.md) | JSON-RPC integration, approval/interaction seams, ask-user tool | Product — stable surface | +| [`interaction/`](interaction/README.md) | Human-collaboration plane: approval/interaction seams, permission preset, commands, ask-user tool | Product — stable surface | +| [`boot/`](boot/README.md) | Shared app-bin boot glue | Product — stable surface | | [`host/`](host/README.md) | Web-GUI host half: API gateway + HTTP route server | Product — stable surface | | [`client/`](client/README.md) | Web-GUI browser half: shell, wire, object services, slots, `ui-*` plugins | Product — stable surface | | [`experimental/`](experimental/README.md) | Prototypes and internal plugins | Unreleased | diff --git a/packages/README.zh.md b/packages/README.zh.md index 2f4e86cb54..bf2bf43779 100644 --- a/packages/README.zh.md +++ b/packages/README.zh.md @@ -45,9 +45,10 @@ | [`credentials/`](credentials/README.md) | 凭据引用 seam + 环境叠加 `.env` provider | 产品:稳定表面 | | [`storage/`](storage/README.md) | 非会话存储中枢 + 后端 + 领域形式 | 产品:稳定表面 | | [`workspace/`](workspace/README.md) | Workspace 实体 | 产品:稳定表面 | -| [`sdk/`](sdk/README.md) | 项目 SDK 工具 | 产品:稳定表面 | +| [`scaffold/`](scaffold/README.md) | 创建/启动/驱动项目的工具:helper、启动器、初始化器、带两端的通信协议、启动器 telemetry | 产品:稳定表面 | | [`acp/`](acp/README.md) | 仅面向自动化的 Agent Client Protocol 服务器 | 产品:稳定表面 | -| [`ui/`](ui/README.md) | JSON-RPC 集成、批准/交互 seam、用户问答工具 | 产品:稳定表面 | +| [`interaction/`](interaction/README.md) | 人机协作平面:批准/交互 seam、权限预设、命令、用户问答工具 | 产品:稳定表面 | +| [`boot/`](boot/README.md) | 共享的 app bin 启动粘合层 | 产品:稳定表面 | | [`host/`](host/README.md) | web GUI 宿主半侧:API 网关 + HTTP 路由服务器 | 产品:稳定表面 | | [`client/`](client/README.md) | web GUI 浏览器半侧:shell、协议层、对象服务、slot、`ui-*` 插件 | 产品:稳定表面 | | [`experimental/`](experimental/README.md) | 原型和内部插件 | 未发布 | diff --git a/packages/acp/acp/tsconfig.json b/packages/acp/acp/tsconfig.json index 3109e0eea8..177b3cb3cd 100644 --- a/packages/acp/acp/tsconfig.json +++ b/packages/acp/acp/tsconfig.json @@ -24,7 +24,7 @@ "path": "../../core/agent" }, { - "path": "../../ui/user-approval" + "path": "../../interaction/user-approval" }, { "path": "../../support/invariants" diff --git a/packages/bash/tool-bash/tsconfig.json b/packages/bash/tool-bash/tsconfig.json index b122ed58ca..93cbe93786 100644 --- a/packages/bash/tool-bash/tsconfig.json +++ b/packages/bash/tool-bash/tsconfig.json @@ -39,7 +39,7 @@ "path": "../../bash/bash-env" }, { - "path": "../../ui/user-approval" + "path": "../../interaction/user-approval" }, { "path": "../../sandbox/sandbox" diff --git a/packages/sdk/README.i18n.yaml b/packages/boot/README.i18n.yaml similarity index 57% rename from packages/sdk/README.i18n.yaml rename to packages/boot/README.i18n.yaml index 738a0610ab..151e5e5c08 100644 --- a/packages/sdk/README.i18n.yaml +++ b/packages/boot/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/sdk/README.md -README.md: 3f99d6d45ddc64ac068457b0d03e533d21451a5f -README.zh.md: 003383c5f6238b37893927813959d52d96350c3e +# pnpm run verify-translation-pairing --write packages/boot/README.md +README.md: 7727f4fbab62a930051fd3b92d04513ac9f5d218 +README.zh.md: aa9a56619ee55c3be8feb58881f77c460861b1ac diff --git a/packages/boot/README.md b/packages/boot/README.md new file mode 100644 index 0000000000..7727f4fbab --- /dev/null +++ b/packages/boot/README.md @@ -0,0 +1,9 @@ +# boot/ — shared app-bin boot glue + +English | [中文](README.zh.md) + +The channel-neutral boot library the app bins share. A role-complete single-package group: it belongs to no channel and no assembly — `apps/cli`, the [`scaffold/`](../scaffold/README.md) launcher, and the [`examples/`](../examples/README.md) demo bins all consume it. + +| Package | Role | ctx key | +|---|---|---| +| `app-boot/` | Shared boot glue for the app bins: `.env` loading, fail-loud Loader guards, snapshot-aware config resolution, the settle-the-tree boot sequence | (library for the bins) | diff --git a/packages/boot/README.zh.md b/packages/boot/README.zh.md new file mode 100644 index 0000000000..aa9a56619e --- /dev/null +++ b/packages/boot/README.zh.md @@ -0,0 +1,9 @@ +# boot/:共享的 app bin 启动粘合层 + +[English](README.md) | 中文 + +各 app bin 共享、与通道无关的启动库。一个角色完备的单包组:它不归属任何通道也不归属任何组装——`apps/cli`、[`scaffold/`](../scaffold/README.md) 启动器和 [`examples/`](../examples/README.md) 各演示 bin 都消费它。 + +| 包 | 职责 | ctx 键 | +|---|---|---| +| `app-boot/` | app bin 的共享启动粘合层:加载 `.env`、会明确报错的 Loader 保护机制、感知快照的配置解析,以及等待整棵树停稳的启动序列 | (供各 bin 使用的库) | diff --git a/packages/ui/app-boot/README.i18n.yaml b/packages/boot/app-boot/README.i18n.yaml similarity index 81% rename from packages/ui/app-boot/README.i18n.yaml rename to packages/boot/app-boot/README.i18n.yaml index 24f04a21c1..3ae6f5427c 100644 --- a/packages/ui/app-boot/README.i18n.yaml +++ b/packages/boot/app-boot/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/ui/app-boot/README.md +# pnpm run verify-translation-pairing --write packages/boot/app-boot/README.md README.md: c256b89288e3e384c1dd3e64629a06d7cfef31f6 README.zh.md: 88d1c4ad0ced2f5a6440a1b64e34e738a842f938 diff --git a/packages/ui/app-boot/README.md b/packages/boot/app-boot/README.md similarity index 100% rename from packages/ui/app-boot/README.md rename to packages/boot/app-boot/README.md diff --git a/packages/ui/app-boot/README.zh.md b/packages/boot/app-boot/README.zh.md similarity index 100% rename from packages/ui/app-boot/README.zh.md rename to packages/boot/app-boot/README.zh.md diff --git a/packages/ui/app-boot/package.json b/packages/boot/app-boot/package.json similarity index 100% rename from packages/ui/app-boot/package.json rename to packages/boot/app-boot/package.json diff --git a/packages/ui/app-boot/src/index.ts b/packages/boot/app-boot/src/index.ts similarity index 100% rename from packages/ui/app-boot/src/index.ts rename to packages/boot/app-boot/src/index.ts diff --git a/packages/ui/app-boot/src/invariant.ts b/packages/boot/app-boot/src/invariant.ts similarity index 100% rename from packages/ui/app-boot/src/invariant.ts rename to packages/boot/app-boot/src/invariant.ts diff --git a/packages/ui/app-boot/src/profile.ts b/packages/boot/app-boot/src/profile.ts similarity index 100% rename from packages/ui/app-boot/src/profile.ts rename to packages/boot/app-boot/src/profile.ts diff --git a/packages/ui/app-boot/tests/app-boot.spec.ts b/packages/boot/app-boot/tests/app-boot.spec.ts similarity index 100% rename from packages/ui/app-boot/tests/app-boot.spec.ts rename to packages/boot/app-boot/tests/app-boot.spec.ts diff --git a/packages/ui/app-boot/tests/config-dump.spec.ts b/packages/boot/app-boot/tests/config-dump.spec.ts similarity index 100% rename from packages/ui/app-boot/tests/config-dump.spec.ts rename to packages/boot/app-boot/tests/config-dump.spec.ts diff --git a/packages/ui/app-boot/tests/config-reload.spec.ts b/packages/boot/app-boot/tests/config-reload.spec.ts similarity index 100% rename from packages/ui/app-boot/tests/config-reload.spec.ts rename to packages/boot/app-boot/tests/config-reload.spec.ts diff --git a/packages/ui/app-boot/tests/hmr-config.spec.ts b/packages/boot/app-boot/tests/hmr-config.spec.ts similarity index 100% rename from packages/ui/app-boot/tests/hmr-config.spec.ts rename to packages/boot/app-boot/tests/hmr-config.spec.ts diff --git a/packages/ui/app-boot/tests/profile.spec.ts b/packages/boot/app-boot/tests/profile.spec.ts similarity index 100% rename from packages/ui/app-boot/tests/profile.spec.ts rename to packages/boot/app-boot/tests/profile.spec.ts diff --git a/packages/ui/app-boot/tests/repository-cache.spec.ts b/packages/boot/app-boot/tests/repository-cache.spec.ts similarity index 100% rename from packages/ui/app-boot/tests/repository-cache.spec.ts rename to packages/boot/app-boot/tests/repository-cache.spec.ts diff --git a/packages/ui/app-boot/tests/user-patches.spec.ts b/packages/boot/app-boot/tests/user-patches.spec.ts similarity index 100% rename from packages/ui/app-boot/tests/user-patches.spec.ts rename to packages/boot/app-boot/tests/user-patches.spec.ts diff --git a/packages/ui/app-boot/tsconfig.json b/packages/boot/app-boot/tsconfig.json similarity index 100% rename from packages/ui/app-boot/tsconfig.json rename to packages/boot/app-boot/tsconfig.json diff --git a/packages/ui/app-boot/tsdown.config.ts b/packages/boot/app-boot/tsdown.config.ts similarity index 100% rename from packages/ui/app-boot/tsdown.config.ts rename to packages/boot/app-boot/tsdown.config.ts diff --git a/packages/bundle/README.i18n.yaml b/packages/bundle/README.i18n.yaml index 27e50409cd..5199e0939e 100644 --- a/packages/bundle/README.i18n.yaml +++ b/packages/bundle/README.i18n.yaml @@ -1,6 +1,12 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: +<<<<<<<< HEAD:packages/bundle/README.i18n.yaml # pnpm run verify-translation-pairing --write packages/bundle/README.md README.md: 4759170435a80e85731446cef21d24fff2abed66 README.zh.md: 1ef610a1b7b3c591c9a900e04f2d8096b0b086b9 +======== +# pnpm run verify-translation-pairing --write packages/interaction/tui/README.md +README.md: c81cac891403e5294c4456ce4d4048ecd74666ce +README.zh.md: 01055619f4df460284564f0a1816de366d809e01 +>>>>>>>> a58746f4cc (refactor(packages): dissolve ui/ and rename sdk/ to scaffold/):packages/interaction/tui/README.i18n.yaml diff --git a/packages/client/connection/tsconfig.json b/packages/client/connection/tsconfig.json index 6ff7fbfb25..58c04d18bd 100644 --- a/packages/client/connection/tsconfig.json +++ b/packages/client/connection/tsconfig.json @@ -16,7 +16,7 @@ "path": "../../core/session" }, { - "path": "../../ui/commands" + "path": "../../interaction/commands" }, { "path": "../../util/brand" @@ -28,10 +28,10 @@ "path": "../../host/webserver" }, { - "path": "../../ui/user-approval" + "path": "../../interaction/user-approval" }, { - "path": "../../ui/user-interaction" + "path": "../../interaction/user-interaction" }, { "path": "../../support/invariants" diff --git a/packages/client/runtime/tsconfig.json b/packages/client/runtime/tsconfig.json index 71cfb229a9..867b2f588c 100644 --- a/packages/client/runtime/tsconfig.json +++ b/packages/client/runtime/tsconfig.json @@ -24,7 +24,7 @@ "path": "../../host/apiproxy" }, { - "path": "../../ui/commands" + "path": "../../interaction/commands" }, { "path": "../../compact/compact" diff --git a/packages/client/ui-conversation/tsconfig.json b/packages/client/ui-conversation/tsconfig.json index 0505786841..89d0067caf 100644 --- a/packages/client/ui-conversation/tsconfig.json +++ b/packages/client/ui-conversation/tsconfig.json @@ -51,7 +51,7 @@ "path": "../../support/invariants" }, { - "path": "../../ui/permission" + "path": "../../interaction/permission" } ], "exclude": [ diff --git a/packages/client/ui-permission/tsconfig.json b/packages/client/ui-permission/tsconfig.json index 32f84d6a2d..bfc71e2e3c 100644 --- a/packages/client/ui-permission/tsconfig.json +++ b/packages/client/ui-permission/tsconfig.json @@ -39,7 +39,7 @@ "path": "../web-react" }, { - "path": "../../ui/permission" + "path": "../../interaction/permission" }, { "path": "../../support/invariants" diff --git a/packages/client/ui-question/tsconfig.json b/packages/client/ui-question/tsconfig.json index 6b5b0acc3a..1b920ce207 100644 --- a/packages/client/ui-question/tsconfig.json +++ b/packages/client/ui-question/tsconfig.json @@ -30,7 +30,7 @@ "path": "../ui-slots" }, { - "path": "../../ui/tool-ask-user" + "path": "../../interaction/tool-ask-user" }, { "path": "../../support/invariants" diff --git a/packages/compact/command-compact/tsconfig.json b/packages/compact/command-compact/tsconfig.json index f99f2b98b4..c1040bf92a 100644 --- a/packages/compact/command-compact/tsconfig.json +++ b/packages/compact/command-compact/tsconfig.json @@ -15,7 +15,7 @@ "path": "../../../vendor/cordis" }, { - "path": "../../ui/commands" + "path": "../../interaction/commands" }, { "path": "../compact" diff --git a/packages/compact/compact/README.i18n.yaml b/packages/compact/compact/README.i18n.yaml index 6463edbc33..1ab398842f 100644 --- a/packages/compact/compact/README.i18n.yaml +++ b/packages/compact/compact/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/compact/compact/README.md -README.md: cd2404cda8d8702ca0400d3f23d9e1fe041495a1 -README.zh.md: ed6ccc630118dc1bd6d6ea761beefafadb4bd48f +README.md: 5703540435b976cfc03987edca28e2b5cd24ae0d +README.zh.md: 434b9bfa3d0d7f21fc262929ac72ff5ab15d5057 diff --git a/packages/compact/compact/README.md b/packages/compact/compact/README.md index cd2404cda8..5703540435 100644 --- a/packages/compact/compact/README.md +++ b/packages/compact/compact/README.md @@ -68,7 +68,7 @@ Subclass `CompactService`, implement `compactIfNeeded`, `compactNow`, and `compa ## Recognizing a checkpoint outside the host program (`./checkpoint`) -`COMPACT_CHECKPOINT_SOURCE` and `isCompactCheckpointSource()` are declared on the `@deepseek-ai/dsh-compact/checkpoint` subpath and re-exported from the root, so host-side consumers keep reading them from the root. The leaf imports no cordis and declares no module augmentation (the [`dsh-commands/brand`](../../ui/commands/README.md) shape), which is what lets a client or wire program name the checkpoint source: the package **root** cannot enter such a program at all, because it reaches `dsh-session`'s root and that `Context` merge declares the host `sessions` service against the client's own (`TS2717` — one program per side, per [development.md](../../../docs/development.md#typescript-project-layout)). The web client's transcript adapter pins its plugin literal to this leaf with a type-only import, so renaming the plugin id here is a compile error there. +`COMPACT_CHECKPOINT_SOURCE` and `isCompactCheckpointSource()` are declared on the `@deepseek-ai/dsh-compact/checkpoint` subpath and re-exported from the root, so host-side consumers keep reading them from the root. The leaf imports no cordis and declares no module augmentation (the [`dsh-commands/brand`](../../interaction/commands/README.md) shape), which is what lets a client or wire program name the checkpoint source: the package **root** cannot enter such a program at all, because it reaches `dsh-session`'s root and that `Context` merge declares the host `sessions` service against the client's own (`TS2717` — one program per side, per [development.md](../../../docs/development.md#typescript-project-layout)). The web client's transcript adapter pins its plugin literal to this leaf with a type-only import, so renaming the plugin id here is a compile error there. ## Model Experience diff --git a/packages/compact/compact/README.zh.md b/packages/compact/compact/README.zh.md index ed6ccc6301..434b9bfa3d 100644 --- a/packages/compact/compact/README.zh.md +++ b/packages/compact/compact/README.zh.md @@ -68,7 +68,7 @@ ## 在 host 程序之外识别检查点(`./checkpoint`) -`COMPACT_CHECKPOINT_SOURCE` 与 `isCompactCheckpointSource()` 声明在 `@deepseek-ai/dsh-compact/checkpoint` 子路径上,并由包根重新导出,因此 host 侧消费方仍从根读取它们。该叶子不导入 cordis、也不声明任何模块增强(即 [`dsh-commands/brand`](../../ui/commands/README.md) 的形状),这正是客户端或 wire 程序能够命名该检查点来源的原因:包的**根**根本无法进入这类程序,因为它会到达 `dsh-session` 的根,而那处 `Context` 合并会让 host 的 `sessions` 服务与客户端自己的冲突(`TS2717`——每侧一个程序,见 [development.md](../../../docs/development.md#typescript-project-layout))。Web 客户端的对话记录适配器用仅类型导入把它的插件字面量钉在该叶子上,因此在此处改插件 id 会让那边编译失败。 +`COMPACT_CHECKPOINT_SOURCE` 与 `isCompactCheckpointSource()` 声明在 `@deepseek-ai/dsh-compact/checkpoint` 子路径上,并由包根重新导出,因此 host 侧消费方仍从根读取它们。该叶子不导入 cordis、也不声明任何模块增强(即 [`dsh-commands/brand`](../../interaction/commands/README.md) 的形状),这正是客户端或 wire 程序能够命名该检查点来源的原因:包的**根**根本无法进入这类程序,因为它会到达 `dsh-session` 的根,而那处 `Context` 合并会让 host 的 `sessions` 服务与客户端自己的冲突(`TS2717`——每侧一个程序,见 [development.md](../../../docs/development.md#typescript-project-layout))。Web 客户端的对话记录适配器用仅类型导入把它的插件字面量钉在该叶子上,因此在此处改插件 id 会让那边编译失败。 ## 模型体验 diff --git a/packages/core/tools/README.i18n.yaml b/packages/core/tools/README.i18n.yaml index c1bd91ce2b..e8157eed7e 100644 --- a/packages/core/tools/README.i18n.yaml +++ b/packages/core/tools/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/core/tools/README.md -README.md: 81cc57983d83fd19468017b217d4db9978f4e228 -README.zh.md: 9f875bd80a03d1d0f78625ee98eeaad9d118f871 +README.md: fd5cb85540e42e62de28f96bf59890da9561f51e +README.zh.md: 5911b25b1d77710077063a643a29e500e4da8e95 diff --git a/packages/core/tools/README.md b/packages/core/tools/README.md index 81cc57983d..fd5cb85540 100644 --- a/packages/core/tools/README.md +++ b/packages/core/tools/README.md @@ -45,7 +45,7 @@ The live registry pipeline has three transformable waterfalls, then the definiti - `ToolExecution` — the readonly pipeline view: immutable `{ token, callId, name, arguments, signal, agent?, parent? }`; the registry separately retains and re-fuses the original caller signal. `ToolDispatchExecution` is the `tools/execute`-only view whose required signal is mutable, so a wrapper may replace and restore it but cannot delete it. A nested call's `parent` is a `ToolExecutionToken`, not an execution object. - `ToolRunContext` — the execution passed to a tool body, extending `ToolExecution` with `deferContext(context)`. It defers one context until the tool's final result reaches the loop — typically a nested-dispatch context ferried by a composite tool, or a fresh plugin-sourced instruction minted by a leaf tool (`tool-goal`'s wrap-up) — even when the tool later throws or cancellation wins; it never injects immediately. - `ToolExecutionResult` — discriminated execution-local outcome. Success is `{ isError:false, value:JsonValue, content, meta?, additionalContexts? }`; failure is `{ isError:true, error:{ message, info? }, content, meta?, additionalContexts? }` and has no value. Call identity stays on the immutable `ToolExecution`. The registry snapshots, validates, and freezes the canonical value before rendering, then materializes the durable presentation fields before final observation. `ToolFailure.info` carries an internal `{ name, code }` for a `HarnessError`; `additionalContexts` preserves every deferred or post-execute identified `UserMessage` for the loop's post-result FIFO. -- `PreToolDecision` — `{kind:'allow'}` | `{kind:'deny', reason}` | `{kind:'ask', reason?}`. Input rewrite is deliberately not offered; `ask` is serviced by [`ctx.approval`](../../ui/user-approval/README.md) when mounted and otherwise degrades to deny. +- `PreToolDecision` — `{kind:'allow'}` | `{kind:'deny', reason}` | `{kind:'ask', reason?}`. Input rewrite is deliberately not offered; `ask` is serviced by [`ctx.approval`](../../interaction/user-approval/README.md) when mounted and otherwise degrades to deny. - `PostToolDecision` — accept may replace `content` or `value`, never both, and may attach `additionalContexts`; block turns feedback into a valueless failure. Content replacement preserves the canonical value and metadata. Value replacement is revalidated and rerenders content/metadata. Accept preserves tool-deferred contexts before decision contexts; block discards tool-deferred contexts and exposes only contexts explicitly supplied by the blocking decision. - `ToolGuard` — `(execution) => string | undefined`; the returned string is a final monotonic denial reason evaluated after the reorderable pre-execute waterfall and before dispatch. - `ToolCallView` / `ToolResultView` — provider-neutral `card`-tagged render intents a tool returns from `presentCall` / `presentResult` to own how a UI renders ITS calls (see "Tool-owned UI presentation"). diff --git a/packages/core/tools/README.zh.md b/packages/core/tools/README.zh.md index 9f875bd80a..5911b25b1d 100644 --- a/packages/core/tools/README.zh.md +++ b/packages/core/tools/README.zh.md @@ -45,7 +45,7 @@ tools: - `ToolExecution`:只读流水线视图:不可变的 `{ token, callId, name, arguments, signal, agent?, parent? }`;注册表会另行保留并重新融合调用方的原始信号。`ToolDispatchExecution` 是仅供 `tools/execute` 使用的视图,其必填信号可变,因此包装层可以替换并还原它,但不能删除它。嵌套调用的 `parent` 是 `ToolExecutionToken`,而不是执行对象。 - `ToolRunContext`:传给工具主体的执行上下文,在 `ToolExecution` 基础上增加 `deferContext(context)`。它把一条上下文推迟到该工具的最终结果抵达循环时——通常是组合工具转运的嵌套分发上下文,也可以是叶子工具铸造的全新插件来源指令(如 `tool-goal` 的收尾注入)——即使工具后来抛出或取消胜出也不例外;该方法绝不会立即注入上下文。 - `ToolExecutionResult`:可辨识的执行局部结果。成功形态为 `{ isError:false, value:JsonValue, content, meta?, additionalContexts? }`;失败形态为 `{ isError:true, error:{ message, info? }, content, meta?, additionalContexts? }`,且不含值。调用身份保留在不可变的 `ToolExecution` 上。注册表会在呈现前快照、验证并冻结规范值,随后在最终观测前实体化持久呈现字段。`ToolFailure.info` 携带内部的 `{ name, code }`,用于表示 `HarnessError`;`additionalContexts` 会保留每个通过延迟或 post-execute 加入且带标识的 `UserMessage`,供循环在结果后按 FIFO 顺序处理。 -- `PreToolDecision`:`{kind:'allow'}` | `{kind:'deny', reason}` | `{kind:'ask', reason?}`。该类型有意不提供输入改写;`ask` 在挂载 [`ctx.approval`](../../ui/user-approval/README.md) 时由它处理,否则退化为拒绝。 +- `PreToolDecision`:`{kind:'allow'}` | `{kind:'deny', reason}` | `{kind:'ask', reason?}`。该类型有意不提供输入改写;`ask` 在挂载 [`ctx.approval`](../../interaction/user-approval/README.md) 时由它处理,否则退化为拒绝。 - `PostToolDecision`:接受决定可以替换 `content` 或 `value`(不能同时替换),并可附加 `additionalContexts`;阻止决定会把反馈变成无值失败。替换内容会保留规范值和元数据。替换值会重新验证,并重新呈现内容/元数据。接受决定会先保留工具延迟的上下文,再附加决定上下文;阻止决定会丢弃工具延迟的上下文,只公开阻止决定显式提供的上下文。 - `ToolGuard`:`(execution) => string | undefined`;返回的字符串是最终单调拒绝理由,在可重排的前置执行 waterfall 之后、分发之前求值。 - `ToolCallView` / `ToolResultView`:提供方无关、带 `card` 标签的呈现意图;工具通过 `presentCall` / `presentResult` 返回该意图,从而拥有 UI 呈现其自身调用的方式(参见「工具拥有的 UI 呈现」)。 diff --git a/packages/core/tools/tsconfig.json b/packages/core/tools/tsconfig.json index 918112d7d0..de5756ecbd 100644 --- a/packages/core/tools/tsconfig.json +++ b/packages/core/tools/tsconfig.json @@ -33,7 +33,7 @@ "path": "../../core/scope" }, { - "path": "../../ui/user-approval" + "path": "../../interaction/user-approval" }, { "path": "../../support/invariants" diff --git a/packages/examples/acp-demo/tests/built-bin.e2e.ts b/packages/examples/acp-demo/tests/built-bin.e2e.ts index d09a0e333d..14b2c3f607 100644 --- a/packages/examples/acp-demo/tests/built-bin.e2e.ts +++ b/packages/examples/acp-demo/tests/built-bin.e2e.ts @@ -33,7 +33,7 @@ const decompress = promisify(zstdDecompress) const dshPackages = [ 'examples/agent-spine-demo', 'core/agent', 'core/session', 'core/system-prompt', 'core/tools', 'core/agent-loop', 'llm/llm', 'bash/bash', - 'bash/bash-local', 'bash/tool-bash', 'subprocess/subprocess', 'subprocess/subprocess-local', 'context/workspace-context', 'support/invariants', 'ui/app-boot', + 'bash/bash-local', 'bash/tool-bash', 'subprocess/subprocess', 'subprocess/subprocess-local', 'context/workspace-context', 'support/invariants', 'boot/app-boot', 'session/session-persistence', 'session/session-checkpoint-policy', 'session/session-persistence-jsonl', 'acp/acp', 'examples/acp-demo', 'util/paths', diff --git a/packages/examples/acp-demo/tsconfig.json b/packages/examples/acp-demo/tsconfig.json index 34b48fc46a..5c7193f1bb 100644 --- a/packages/examples/acp-demo/tsconfig.json +++ b/packages/examples/acp-demo/tsconfig.json @@ -18,7 +18,7 @@ "path": "../../../vendor/loader" }, { - "path": "../../ui/app-boot" + "path": "../../boot/app-boot" }, { "path": "../../acp/acp" diff --git a/packages/examples/jsonrpc-demo/tsconfig.json b/packages/examples/jsonrpc-demo/tsconfig.json index aba279d405..061bbf68c3 100644 --- a/packages/examples/jsonrpc-demo/tsconfig.json +++ b/packages/examples/jsonrpc-demo/tsconfig.json @@ -15,7 +15,7 @@ "path": "../../../vendor/loader" }, { - "path": "../../ui/app-boot" + "path": "../../boot/app-boot" }, { "path": "../../support/invariants" diff --git a/packages/fs/tool-fs/tsconfig.json b/packages/fs/tool-fs/tsconfig.json index fb420b553c..a3f128143c 100644 --- a/packages/fs/tool-fs/tsconfig.json +++ b/packages/fs/tool-fs/tsconfig.json @@ -40,7 +40,7 @@ "path": "../../sandbox/sandbox-policy" }, { - "path": "../../ui/user-approval" + "path": "../../interaction/user-approval" } ] } diff --git a/packages/goal/command-goal/tsconfig.json b/packages/goal/command-goal/tsconfig.json index 8b03235814..488c576922 100644 --- a/packages/goal/command-goal/tsconfig.json +++ b/packages/goal/command-goal/tsconfig.json @@ -15,7 +15,7 @@ "path": "../../../vendor/cordis" }, { - "path": "../../ui/commands" + "path": "../../interaction/commands" }, { "path": "../goal" diff --git a/packages/host/apiproxy/tsconfig.json b/packages/host/apiproxy/tsconfig.json index 58c63f5669..64d7944892 100644 --- a/packages/host/apiproxy/tsconfig.json +++ b/packages/host/apiproxy/tsconfig.json @@ -66,13 +66,13 @@ "path": "../../skill/skill" }, { - "path": "../../ui/commands" + "path": "../../interaction/commands" }, { - "path": "../../ui/user-approval" + "path": "../../interaction/user-approval" }, { - "path": "../../ui/user-interaction" + "path": "../../interaction/user-interaction" }, { "path": "../../workspace/workspace" diff --git a/packages/interaction/README.i18n.yaml b/packages/interaction/README.i18n.yaml new file mode 100644 index 0000000000..2555e896a1 --- /dev/null +++ b/packages/interaction/README.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/interaction/README.md +README.md: 506b47753fc9250f9f7bd971265421ad46a106b2 +README.zh.md: 34d336f3d3c10deab166d5c13bb86c13ee9bced0 diff --git a/packages/ui/README.md b/packages/interaction/README.md similarity index 71% rename from packages/ui/README.md rename to packages/interaction/README.md index 15754410a4..506b47753f 100644 --- a/packages/ui/README.md +++ b/packages/interaction/README.md @@ -1,8 +1,8 @@ -# ui/ — human and SDK-client integration surfaces +# interaction/ — the human-collaboration plane English | [中文](README.zh.md) -Human-facing channels and the out-of-process SDK server. These are **product** packages: real interfaces that a person or SDK client drives. +The seams through which a human collaborates with a running agent — questions, approvals, permission presets, commands. These are **product** packages: real interfaces a person drives. | Package | Role | ctx key | |---|---|---| @@ -11,7 +11,5 @@ Human-facing channels and the out-of-process SDK server. These are **product** p | [`permission/`](permission/README.md) | Presents and persists user-facing permission presets. | `ctx.permission` | | [`user-interaction/`](user-interaction/README.md) | Defines the provider-neutral human question/answer seam. | `ctx.userInteraction` | | [`tool-ask-user/`](tool-ask-user/README.md) | Exposes human questions to the model. | (registers on `ctx.tools`) | -| [`jsonrpc/`](jsonrpc/README.md) | Serves out-of-process SDK clients over stdio JSON-RPC. | (drives `ctx.agents`) | -| [`app-boot/`](app-boot/README.md) | Provides shared boot support for application launchers. | (library for the bins) | These packages integrate through existing agent and session contracts rather than changing the loop. Interactive applications provide the concrete command, approval, and question adapters; automation uses [`acp/`](../acp/README.md), and runnable demo bundles live under [`examples/`](../examples/README.md). The product [`dsh`](../../apps/cli/README.md) CLI composes these packages directly. diff --git a/packages/ui/README.zh.md b/packages/interaction/README.zh.md similarity index 69% rename from packages/ui/README.zh.md rename to packages/interaction/README.zh.md index 4023b80085..34d336f3d3 100644 --- a/packages/ui/README.zh.md +++ b/packages/interaction/README.zh.md @@ -1,8 +1,8 @@ -# ui/:面向用户和 SDK 客户端的集成接口 +# interaction/:人机协作平面 [English](README.md) | 中文 -面向用户的通道和进程外 SDK 服务器。这些是**产品**包:由用户或 SDK 客户端直接操作的真实接口。 +人与运行中的 agent(智能体)协作所经由的各个 seam——提问、审批、权限预设、命令。这些是**产品**包(package):由用户直接操作的真实接口。 | 包 | 职责 | ctx 键 | |---|---|---| @@ -11,7 +11,5 @@ | [`permission/`](permission/README.md) | 呈现并持久化面向用户的权限预设。 | `ctx.permission` | | [`user-interaction/`](user-interaction/README.md) | 定义与提供方无关的用户问答 seam。 | `ctx.userInteraction` | | [`tool-ask-user/`](tool-ask-user/README.md) | 向模型公开用户问题。 | (注册到 `ctx.tools`) | -| [`jsonrpc/`](jsonrpc/README.md) | 通过 stdio JSON-RPC 为进程外 SDK 客户端提供服务。 | (驱动 `ctx.agents`) | -| [`app-boot/`](app-boot/README.md) | 为应用启动器提供共享启动支持。 | (供各 bin 使用的库) | 这些包通过现有的 agent(智能体)和会话契约集成,而不改变循环。交互式应用提供具体的命令、审批和提问适配器;自动化使用 [`acp/`](../acp/README.md),可运行的演示组合包位于 [`examples/`](../examples/README.md)。产品 [`dsh`](../../apps/cli/README.md) CLI(命令行界面)直接组合这些包。 diff --git a/packages/ui/commands/README.i18n.yaml b/packages/interaction/commands/README.i18n.yaml similarity index 79% rename from packages/ui/commands/README.i18n.yaml rename to packages/interaction/commands/README.i18n.yaml index be55a19ca3..967fa0d4ef 100644 --- a/packages/ui/commands/README.i18n.yaml +++ b/packages/interaction/commands/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/ui/commands/README.md +# pnpm run verify-translation-pairing --write packages/interaction/commands/README.md README.md: 1709bdcdce4e43d98cfea5ff3972ab95bfd3c33b README.zh.md: 569f2aa8293793b26d63ee16e3ea7600e04a8397 diff --git a/packages/ui/commands/README.md b/packages/interaction/commands/README.md similarity index 100% rename from packages/ui/commands/README.md rename to packages/interaction/commands/README.md diff --git a/packages/ui/commands/README.zh.md b/packages/interaction/commands/README.zh.md similarity index 100% rename from packages/ui/commands/README.zh.md rename to packages/interaction/commands/README.zh.md diff --git a/packages/ui/commands/package.json b/packages/interaction/commands/package.json similarity index 100% rename from packages/ui/commands/package.json rename to packages/interaction/commands/package.json diff --git a/packages/ui/commands/src/brand.ts b/packages/interaction/commands/src/brand.ts similarity index 100% rename from packages/ui/commands/src/brand.ts rename to packages/interaction/commands/src/brand.ts diff --git a/packages/ui/commands/src/index.ts b/packages/interaction/commands/src/index.ts similarity index 100% rename from packages/ui/commands/src/index.ts rename to packages/interaction/commands/src/index.ts diff --git a/packages/ui/commands/src/invariant.ts b/packages/interaction/commands/src/invariant.ts similarity index 100% rename from packages/ui/commands/src/invariant.ts rename to packages/interaction/commands/src/invariant.ts diff --git a/packages/ui/commands/tests/commands.spec.ts b/packages/interaction/commands/tests/commands.spec.ts similarity index 100% rename from packages/ui/commands/tests/commands.spec.ts rename to packages/interaction/commands/tests/commands.spec.ts diff --git a/packages/ui/commands/tests/invariant.spec.ts b/packages/interaction/commands/tests/invariant.spec.ts similarity index 100% rename from packages/ui/commands/tests/invariant.spec.ts rename to packages/interaction/commands/tests/invariant.spec.ts diff --git a/packages/ui/commands/tsconfig.json b/packages/interaction/commands/tsconfig.json similarity index 100% rename from packages/ui/commands/tsconfig.json rename to packages/interaction/commands/tsconfig.json diff --git a/packages/interaction/permission/README.i18n.yaml b/packages/interaction/permission/README.i18n.yaml new file mode 100644 index 0000000000..b5883174dc --- /dev/null +++ b/packages/interaction/permission/README.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/interaction/permission/README.md +README.md: 814085ed6f2c9650854f377e1c97e442fc4211a4 +README.zh.md: 36880d6b8c3f0b39b88db1abb02534f30e3355fa diff --git a/packages/ui/permission/README.md b/packages/interaction/permission/README.md similarity index 100% rename from packages/ui/permission/README.md rename to packages/interaction/permission/README.md diff --git a/packages/ui/permission/README.zh.md b/packages/interaction/permission/README.zh.md similarity index 100% rename from packages/ui/permission/README.zh.md rename to packages/interaction/permission/README.zh.md diff --git a/packages/ui/permission/package.json b/packages/interaction/permission/package.json similarity index 100% rename from packages/ui/permission/package.json rename to packages/interaction/permission/package.json diff --git a/packages/ui/permission/src/client.ts b/packages/interaction/permission/src/client.ts similarity index 100% rename from packages/ui/permission/src/client.ts rename to packages/interaction/permission/src/client.ts diff --git a/packages/ui/permission/src/index.ts b/packages/interaction/permission/src/index.ts similarity index 100% rename from packages/ui/permission/src/index.ts rename to packages/interaction/permission/src/index.ts diff --git a/packages/ui/permission/src/invariant.ts b/packages/interaction/permission/src/invariant.ts similarity index 100% rename from packages/ui/permission/src/invariant.ts rename to packages/interaction/permission/src/invariant.ts diff --git a/packages/ui/permission/src/types.ts b/packages/interaction/permission/src/types.ts similarity index 100% rename from packages/ui/permission/src/types.ts rename to packages/interaction/permission/src/types.ts diff --git a/packages/ui/permission/tests/invariant.spec.ts b/packages/interaction/permission/tests/invariant.spec.ts similarity index 100% rename from packages/ui/permission/tests/invariant.spec.ts rename to packages/interaction/permission/tests/invariant.spec.ts diff --git a/packages/ui/permission/tests/permission.spec.ts b/packages/interaction/permission/tests/permission.spec.ts similarity index 100% rename from packages/ui/permission/tests/permission.spec.ts rename to packages/interaction/permission/tests/permission.spec.ts diff --git a/packages/ui/permission/tests/projection.spec.ts b/packages/interaction/permission/tests/projection.spec.ts similarity index 100% rename from packages/ui/permission/tests/projection.spec.ts rename to packages/interaction/permission/tests/projection.spec.ts diff --git a/packages/ui/permission/tsconfig.json b/packages/interaction/permission/tsconfig.json similarity index 100% rename from packages/ui/permission/tsconfig.json rename to packages/interaction/permission/tsconfig.json diff --git a/packages/ui/tool-ask-user/README.i18n.yaml b/packages/interaction/tool-ask-user/README.i18n.yaml similarity index 79% rename from packages/ui/tool-ask-user/README.i18n.yaml rename to packages/interaction/tool-ask-user/README.i18n.yaml index bbd0ba0561..f88c303525 100644 --- a/packages/ui/tool-ask-user/README.i18n.yaml +++ b/packages/interaction/tool-ask-user/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/ui/tool-ask-user/README.md +# pnpm run verify-translation-pairing --write packages/interaction/tool-ask-user/README.md README.md: 7af356263ea6582a081e7c6de22fd317ca8b96df README.zh.md: 3f7b814b83c8c6957a4b2574ee69e87d45f65ae6 diff --git a/packages/ui/tool-ask-user/README.md b/packages/interaction/tool-ask-user/README.md similarity index 100% rename from packages/ui/tool-ask-user/README.md rename to packages/interaction/tool-ask-user/README.md diff --git a/packages/ui/tool-ask-user/README.zh.md b/packages/interaction/tool-ask-user/README.zh.md similarity index 100% rename from packages/ui/tool-ask-user/README.zh.md rename to packages/interaction/tool-ask-user/README.zh.md diff --git a/packages/ui/tool-ask-user/package.json b/packages/interaction/tool-ask-user/package.json similarity index 100% rename from packages/ui/tool-ask-user/package.json rename to packages/interaction/tool-ask-user/package.json diff --git a/packages/ui/tool-ask-user/src/index.ts b/packages/interaction/tool-ask-user/src/index.ts similarity index 100% rename from packages/ui/tool-ask-user/src/index.ts rename to packages/interaction/tool-ask-user/src/index.ts diff --git a/packages/ui/tool-ask-user/src/invariant.ts b/packages/interaction/tool-ask-user/src/invariant.ts similarity index 100% rename from packages/ui/tool-ask-user/src/invariant.ts rename to packages/interaction/tool-ask-user/src/invariant.ts diff --git a/packages/ui/tool-ask-user/tests/tool-ask-user.spec.ts b/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts similarity index 100% rename from packages/ui/tool-ask-user/tests/tool-ask-user.spec.ts rename to packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts diff --git a/packages/ui/tool-ask-user/tsconfig.json b/packages/interaction/tool-ask-user/tsconfig.json similarity index 100% rename from packages/ui/tool-ask-user/tsconfig.json rename to packages/interaction/tool-ask-user/tsconfig.json diff --git a/packages/ui/user-approval/README.i18n.yaml b/packages/interaction/user-approval/README.i18n.yaml similarity index 79% rename from packages/ui/user-approval/README.i18n.yaml rename to packages/interaction/user-approval/README.i18n.yaml index cf9c8e1fce..36188334e7 100644 --- a/packages/ui/user-approval/README.i18n.yaml +++ b/packages/interaction/user-approval/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/ui/user-approval/README.md +# pnpm run verify-translation-pairing --write packages/interaction/user-approval/README.md README.md: 7b87a75d1c7c43874c484bc11f8deed45cb523ce README.zh.md: 3c02f8d673a62c3ee954da26f6341b433032a88c diff --git a/packages/ui/user-approval/README.md b/packages/interaction/user-approval/README.md similarity index 100% rename from packages/ui/user-approval/README.md rename to packages/interaction/user-approval/README.md diff --git a/packages/ui/user-approval/README.zh.md b/packages/interaction/user-approval/README.zh.md similarity index 100% rename from packages/ui/user-approval/README.zh.md rename to packages/interaction/user-approval/README.zh.md diff --git a/packages/ui/user-approval/package.json b/packages/interaction/user-approval/package.json similarity index 100% rename from packages/ui/user-approval/package.json rename to packages/interaction/user-approval/package.json diff --git a/packages/ui/user-approval/src/index.ts b/packages/interaction/user-approval/src/index.ts similarity index 100% rename from packages/ui/user-approval/src/index.ts rename to packages/interaction/user-approval/src/index.ts diff --git a/packages/ui/user-approval/src/invariant.ts b/packages/interaction/user-approval/src/invariant.ts similarity index 100% rename from packages/ui/user-approval/src/invariant.ts rename to packages/interaction/user-approval/src/invariant.ts diff --git a/packages/ui/user-approval/src/types.ts b/packages/interaction/user-approval/src/types.ts similarity index 100% rename from packages/ui/user-approval/src/types.ts rename to packages/interaction/user-approval/src/types.ts diff --git a/packages/ui/user-approval/tests/approval.spec.ts b/packages/interaction/user-approval/tests/approval.spec.ts similarity index 100% rename from packages/ui/user-approval/tests/approval.spec.ts rename to packages/interaction/user-approval/tests/approval.spec.ts diff --git a/packages/ui/user-approval/tests/invariant.spec.ts b/packages/interaction/user-approval/tests/invariant.spec.ts similarity index 100% rename from packages/ui/user-approval/tests/invariant.spec.ts rename to packages/interaction/user-approval/tests/invariant.spec.ts diff --git a/packages/ui/user-approval/tsconfig.json b/packages/interaction/user-approval/tsconfig.json similarity index 100% rename from packages/ui/user-approval/tsconfig.json rename to packages/interaction/user-approval/tsconfig.json diff --git a/packages/ui/user-approval/tsdown.config.ts b/packages/interaction/user-approval/tsdown.config.ts similarity index 100% rename from packages/ui/user-approval/tsdown.config.ts rename to packages/interaction/user-approval/tsdown.config.ts diff --git a/packages/interaction/user-interaction/README.i18n.yaml b/packages/interaction/user-interaction/README.i18n.yaml new file mode 100644 index 0000000000..f467aaf4e1 --- /dev/null +++ b/packages/interaction/user-interaction/README.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/interaction/user-interaction/README.md +README.md: d234d6677bdd772f1bbd2c979c0d41f90aef5c32 +README.zh.md: c89210b6955a661313ca9e0e82e43da5a4d1db79 diff --git a/packages/ui/user-interaction/README.md b/packages/interaction/user-interaction/README.md similarity index 100% rename from packages/ui/user-interaction/README.md rename to packages/interaction/user-interaction/README.md diff --git a/packages/ui/user-interaction/README.zh.md b/packages/interaction/user-interaction/README.zh.md similarity index 100% rename from packages/ui/user-interaction/README.zh.md rename to packages/interaction/user-interaction/README.zh.md diff --git a/packages/ui/user-interaction/package.json b/packages/interaction/user-interaction/package.json similarity index 100% rename from packages/ui/user-interaction/package.json rename to packages/interaction/user-interaction/package.json diff --git a/packages/ui/user-interaction/src/index.ts b/packages/interaction/user-interaction/src/index.ts similarity index 100% rename from packages/ui/user-interaction/src/index.ts rename to packages/interaction/user-interaction/src/index.ts diff --git a/packages/ui/user-interaction/src/invariant.ts b/packages/interaction/user-interaction/src/invariant.ts similarity index 100% rename from packages/ui/user-interaction/src/invariant.ts rename to packages/interaction/user-interaction/src/invariant.ts diff --git a/packages/ui/user-interaction/src/types.ts b/packages/interaction/user-interaction/src/types.ts similarity index 100% rename from packages/ui/user-interaction/src/types.ts rename to packages/interaction/user-interaction/src/types.ts diff --git a/packages/ui/user-interaction/tests/user-interaction.spec.ts b/packages/interaction/user-interaction/tests/user-interaction.spec.ts similarity index 100% rename from packages/ui/user-interaction/tests/user-interaction.spec.ts rename to packages/interaction/user-interaction/tests/user-interaction.spec.ts diff --git a/packages/ui/user-interaction/tsconfig.json b/packages/interaction/user-interaction/tsconfig.json similarity index 100% rename from packages/ui/user-interaction/tsconfig.json rename to packages/interaction/user-interaction/tsconfig.json diff --git a/packages/plan/plan-mode/tsconfig.json b/packages/plan/plan-mode/tsconfig.json index 6fa3cffbbc..4dde8fda45 100644 --- a/packages/plan/plan-mode/tsconfig.json +++ b/packages/plan/plan-mode/tsconfig.json @@ -27,10 +27,10 @@ "path": "../../core/system-prompt" }, { - "path": "../../ui/user-interaction" + "path": "../../interaction/user-interaction" }, { - "path": "../../ui/commands" + "path": "../../interaction/commands" }, { "path": "../../session/session-projection" diff --git a/packages/ui/README.i18n.yaml b/packages/scaffold/README.i18n.yaml similarity index 57% rename from packages/ui/README.i18n.yaml rename to packages/scaffold/README.i18n.yaml index fba1f95c52..1480a14b69 100644 --- a/packages/ui/README.i18n.yaml +++ b/packages/scaffold/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/ui/README.md -README.md: 15754410a4a81eb3fc898dd55269ddd1637e1dab -README.zh.md: 4023b80085998f57ed321bfda3a0abdd08b70a28 +# pnpm run verify-translation-pairing --write packages/scaffold/README.md +README.md: b166a351a53afe075ecb794fe2bf6f0702a435ae +README.zh.md: 6e2a65ea554487f48563c16e1defa37ef1a5e043 diff --git a/packages/sdk/README.md b/packages/scaffold/README.md similarity index 64% rename from packages/sdk/README.md rename to packages/scaffold/README.md index 3f99d6d45d..b166a351a5 100644 --- a/packages/sdk/README.md +++ b/packages/scaffold/README.md @@ -1,16 +1,17 @@ -# SDK packages +# scaffold/ — create, launch, and drive projects from outside English | [中文](README.zh.md) -This group contains developer tooling for Harness projects and the client stack for driving a Harness runtime from another process. +This group contains developer tooling for Harness projects and the client stack for driving a Harness runtime from another process. Folders are role-named without the legacy `sdk-` prefix; npm names converge on `dsh-sdk-*` through the FIXME-tracked renames in the [regrouping Agent Note](../../.agents/notes/proposed/architecture/2026-07-29-package-regrouping.md). | Package | Role | |---|---| | [`helper/`](helper/README.md) | Provides the shared project-editing domain | | [`scripts/`](scripts/README.md) | Provides the `dsh-sdk` project commands | | [`create-sdk/`](create-sdk/README.md) | Creates new SDK projects | -| [`sdk-protocol/`](sdk-protocol/README.md) | Defines the SDK runtime wire protocol | -| [`sdk-client/`](sdk-client/README.md) | Drives a Harness runtime through the TypeScript client API | +| [`protocol/`](protocol/README.md) | Defines the SDK runtime wire protocol | +| [`client/`](client/README.md) | Drives a Harness runtime through the TypeScript client API | +| [`server/`](server/README.md) | Serves out-of-process SDK clients over stdio JSON-RPC | | [`telemetry/`](telemetry/README.md) | Provides launcher telemetry, consent, and redaction primitives | `@deepseek-ai/create-sdk` follows npm's scoped initializer naming convention; the other packages follow the repository's `@deepseek-ai/dsh-*` convention. See the [developer-project workflow](../../.agents/notes/proposed/feature/2026-07-14-sdk-developer-projects.md), [project-editing architecture](../../.agents/notes/proposed/architecture/2026-07-15-sdk-project-editing-architecture.md), and [TypeScript SDK design](../../.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md). diff --git a/packages/scaffold/README.zh.md b/packages/scaffold/README.zh.md new file mode 100644 index 0000000000..6e2a65ea55 --- /dev/null +++ b/packages/scaffold/README.zh.md @@ -0,0 +1,17 @@ +# scaffold/:从外部创建、启动、驱动项目 + +[English](README.md) | 中文 + +本组包含 Harness 项目的开发者工具,以及从另一进程驱动 Harness 运行时的客户端栈。目录按角色命名,不带遗留的 `sdk-` 前缀;npm 名则经由[重新分组 Agent Note(agent 决策记录)](../../.agents/notes/proposed/architecture/2026-07-29-package-regrouping.md)中 FIXME 跟踪的改名收敛为 `dsh-sdk-*`。 + +| 包 | 职责 | +|---|---| +| [`helper/`](helper/README.md) | 提供共享的项目编辑领域 | +| [`scripts/`](scripts/README.md) | 提供 `dsh-sdk` 项目命令 | +| [`create-sdk/`](create-sdk/README.md) | 创建新的 SDK 项目 | +| [`protocol/`](protocol/README.md) | 定义 SDK 运行时通信协议 | +| [`client/`](client/README.md) | 通过 TypeScript 客户端 API 驱动 Harness 运行时 | +| [`server/`](server/README.md) | 通过 stdio JSON-RPC 为进程外 SDK 客户端提供服务 | +| [`telemetry/`](telemetry/README.md) | 提供启动器 telemetry、同意与脱敏原语 | + +`@deepseek-ai/create-sdk` 遵循 npm 的 scoped initializer 命名约定;其余包遵循仓库的 `@deepseek-ai/dsh-*` 约定。参见[开发者项目工作流](../../.agents/notes/proposed/feature/2026-07-14-sdk-developer-projects.md)、[项目编辑架构](../../.agents/notes/proposed/architecture/2026-07-15-sdk-project-editing-architecture.md)与 [TypeScript SDK 设计](../../.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md)。 diff --git a/packages/sdk/sdk-client/README.i18n.yaml b/packages/scaffold/client/README.i18n.yaml similarity index 80% rename from packages/sdk/sdk-client/README.i18n.yaml rename to packages/scaffold/client/README.i18n.yaml index bff82b8aec..0a71141cd6 100644 --- a/packages/sdk/sdk-client/README.i18n.yaml +++ b/packages/scaffold/client/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/sdk/sdk-client/README.md +# pnpm run verify-translation-pairing --write packages/scaffold/client/README.md README.md: f27ec256330254156c45b136c21308529ea99e3d README.zh.md: bd23762500a4da469839da8ddb50455e3419b553 diff --git a/packages/sdk/sdk-client/README.md b/packages/scaffold/client/README.md similarity index 100% rename from packages/sdk/sdk-client/README.md rename to packages/scaffold/client/README.md diff --git a/packages/sdk/sdk-client/README.zh.md b/packages/scaffold/client/README.zh.md similarity index 100% rename from packages/sdk/sdk-client/README.zh.md rename to packages/scaffold/client/README.zh.md diff --git a/packages/sdk/sdk-client/package.json b/packages/scaffold/client/package.json similarity index 100% rename from packages/sdk/sdk-client/package.json rename to packages/scaffold/client/package.json diff --git a/packages/sdk/sdk-client/src/api.ts b/packages/scaffold/client/src/api.ts similarity index 100% rename from packages/sdk/sdk-client/src/api.ts rename to packages/scaffold/client/src/api.ts diff --git a/packages/sdk/sdk-client/src/client.ts b/packages/scaffold/client/src/client.ts similarity index 100% rename from packages/sdk/sdk-client/src/client.ts rename to packages/scaffold/client/src/client.ts diff --git a/packages/sdk/sdk-client/src/dispose.ts b/packages/scaffold/client/src/dispose.ts similarity index 100% rename from packages/sdk/sdk-client/src/dispose.ts rename to packages/scaffold/client/src/dispose.ts diff --git a/packages/sdk/sdk-client/src/index.ts b/packages/scaffold/client/src/index.ts similarity index 100% rename from packages/sdk/sdk-client/src/index.ts rename to packages/scaffold/client/src/index.ts diff --git a/packages/sdk/sdk-client/src/invariant.ts b/packages/scaffold/client/src/invariant.ts similarity index 100% rename from packages/sdk/sdk-client/src/invariant.ts rename to packages/scaffold/client/src/invariant.ts diff --git a/packages/sdk/sdk-client/src/types.ts b/packages/scaffold/client/src/types.ts similarity index 100% rename from packages/sdk/sdk-client/src/types.ts rename to packages/scaffold/client/src/types.ts diff --git a/packages/sdk/sdk-client/tests/dispose.spec.ts b/packages/scaffold/client/tests/dispose.spec.ts similarity index 100% rename from packages/sdk/sdk-client/tests/dispose.spec.ts rename to packages/scaffold/client/tests/dispose.spec.ts diff --git a/packages/sdk/sdk-client/tests/fake-runtime.ts b/packages/scaffold/client/tests/fake-runtime.ts similarity index 100% rename from packages/sdk/sdk-client/tests/fake-runtime.ts rename to packages/scaffold/client/tests/fake-runtime.ts diff --git a/packages/sdk/sdk-client/tests/sdk-client.spec.ts b/packages/scaffold/client/tests/sdk-client.spec.ts similarity index 100% rename from packages/sdk/sdk-client/tests/sdk-client.spec.ts rename to packages/scaffold/client/tests/sdk-client.spec.ts diff --git a/packages/sdk/sdk-client/tsconfig.json b/packages/scaffold/client/tsconfig.json similarity index 93% rename from packages/sdk/sdk-client/tsconfig.json rename to packages/scaffold/client/tsconfig.json index 567c6582bb..a5456f5ad3 100644 --- a/packages/sdk/sdk-client/tsconfig.json +++ b/packages/scaffold/client/tsconfig.json @@ -21,7 +21,7 @@ "path": "../../core/session" }, { - "path": "../sdk-protocol" + "path": "../protocol" }, { "path": "../../support/invariants" diff --git a/packages/sdk/create-sdk/README.i18n.yaml b/packages/scaffold/create-sdk/README.i18n.yaml similarity index 80% rename from packages/sdk/create-sdk/README.i18n.yaml rename to packages/scaffold/create-sdk/README.i18n.yaml index 27609d9a11..62d5bd3793 100644 --- a/packages/sdk/create-sdk/README.i18n.yaml +++ b/packages/scaffold/create-sdk/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/sdk/create-sdk/README.md +# pnpm run verify-translation-pairing --write packages/scaffold/create-sdk/README.md README.md: aa09236832a50abdcd2b158e0561db26bce19cf6 README.zh.md: a4685e66bc3eb7924dd247a7b6b420f6bcc70990 diff --git a/packages/sdk/create-sdk/README.md b/packages/scaffold/create-sdk/README.md similarity index 100% rename from packages/sdk/create-sdk/README.md rename to packages/scaffold/create-sdk/README.md diff --git a/packages/sdk/create-sdk/README.zh.md b/packages/scaffold/create-sdk/README.zh.md similarity index 100% rename from packages/sdk/create-sdk/README.zh.md rename to packages/scaffold/create-sdk/README.zh.md diff --git a/packages/sdk/create-sdk/package.json b/packages/scaffold/create-sdk/package.json similarity index 100% rename from packages/sdk/create-sdk/package.json rename to packages/scaffold/create-sdk/package.json diff --git a/packages/sdk/create-sdk/src/args.ts b/packages/scaffold/create-sdk/src/args.ts similarity index 100% rename from packages/sdk/create-sdk/src/args.ts rename to packages/scaffold/create-sdk/src/args.ts diff --git a/packages/sdk/create-sdk/src/bin.ts b/packages/scaffold/create-sdk/src/bin.ts similarity index 100% rename from packages/sdk/create-sdk/src/bin.ts rename to packages/scaffold/create-sdk/src/bin.ts diff --git a/packages/sdk/create-sdk/src/command.ts b/packages/scaffold/create-sdk/src/command.ts similarity index 100% rename from packages/sdk/create-sdk/src/command.ts rename to packages/scaffold/create-sdk/src/command.ts diff --git a/packages/sdk/create-sdk/src/create-questions.ts b/packages/scaffold/create-sdk/src/create-questions.ts similarity index 100% rename from packages/sdk/create-sdk/src/create-questions.ts rename to packages/scaffold/create-sdk/src/create-questions.ts diff --git a/packages/sdk/create-sdk/src/create-wizard.ts b/packages/scaffold/create-sdk/src/create-wizard.ts similarity index 100% rename from packages/sdk/create-sdk/src/create-wizard.ts rename to packages/scaffold/create-sdk/src/create-wizard.ts diff --git a/packages/sdk/create-sdk/src/headless.ts b/packages/scaffold/create-sdk/src/headless.ts similarity index 100% rename from packages/sdk/create-sdk/src/headless.ts rename to packages/scaffold/create-sdk/src/headless.ts diff --git a/packages/sdk/create-sdk/src/index.ts b/packages/scaffold/create-sdk/src/index.ts similarity index 100% rename from packages/sdk/create-sdk/src/index.ts rename to packages/scaffold/create-sdk/src/index.ts diff --git a/packages/sdk/create-sdk/src/invariant.ts b/packages/scaffold/create-sdk/src/invariant.ts similarity index 100% rename from packages/sdk/create-sdk/src/invariant.ts rename to packages/scaffold/create-sdk/src/invariant.ts diff --git a/packages/sdk/create-sdk/src/project-scaffolder.ts b/packages/scaffold/create-sdk/src/project-scaffolder.ts similarity index 100% rename from packages/sdk/create-sdk/src/project-scaffolder.ts rename to packages/scaffold/create-sdk/src/project-scaffolder.ts diff --git a/packages/sdk/create-sdk/src/templates/assets/created.txt.tpl b/packages/scaffold/create-sdk/src/templates/assets/created.txt.tpl similarity index 100% rename from packages/sdk/create-sdk/src/templates/assets/created.txt.tpl rename to packages/scaffold/create-sdk/src/templates/assets/created.txt.tpl diff --git a/packages/sdk/create-sdk/src/templates/assets/install-question.txt.tpl b/packages/scaffold/create-sdk/src/templates/assets/install-question.txt.tpl similarity index 100% rename from packages/sdk/create-sdk/src/templates/assets/install-question.txt.tpl rename to packages/scaffold/create-sdk/src/templates/assets/install-question.txt.tpl diff --git a/packages/sdk/create-sdk/src/templates/assets/next-steps.txt.tpl b/packages/scaffold/create-sdk/src/templates/assets/next-steps.txt.tpl similarity index 100% rename from packages/sdk/create-sdk/src/templates/assets/next-steps.txt.tpl rename to packages/scaffold/create-sdk/src/templates/assets/next-steps.txt.tpl diff --git a/packages/sdk/create-sdk/src/templates/assets/setup-failure.txt.tpl b/packages/scaffold/create-sdk/src/templates/assets/setup-failure.txt.tpl similarity index 100% rename from packages/sdk/create-sdk/src/templates/assets/setup-failure.txt.tpl rename to packages/scaffold/create-sdk/src/templates/assets/setup-failure.txt.tpl diff --git a/packages/sdk/create-sdk/src/templates/assets/usage.txt.tpl b/packages/scaffold/create-sdk/src/templates/assets/usage.txt.tpl similarity index 100% rename from packages/sdk/create-sdk/src/templates/assets/usage.txt.tpl rename to packages/scaffold/create-sdk/src/templates/assets/usage.txt.tpl diff --git a/packages/sdk/create-sdk/src/templates/create-templates.ts b/packages/scaffold/create-sdk/src/templates/create-templates.ts similarity index 100% rename from packages/sdk/create-sdk/src/templates/create-templates.ts rename to packages/scaffold/create-sdk/src/templates/create-templates.ts diff --git a/packages/sdk/create-sdk/tests/built-artifacts.e2e.ts b/packages/scaffold/create-sdk/tests/built-artifacts.e2e.ts similarity index 87% rename from packages/sdk/create-sdk/tests/built-artifacts.e2e.ts rename to packages/scaffold/create-sdk/tests/built-artifacts.e2e.ts index 4b2de078c7..827abe06a2 100644 --- a/packages/sdk/create-sdk/tests/built-artifacts.e2e.ts +++ b/packages/scaffold/create-sdk/tests/built-artifacts.e2e.ts @@ -7,8 +7,8 @@ import { describe, expect, it } from 'vitest' const execFileAsync = promisify(execFile) const repoRoot = fileURLToPath(new URL('../../../../', import.meta.url)) -const createBin = join(repoRoot, 'packages/sdk/create-sdk/lib/bin.js') -const scriptsBin = join(repoRoot, 'packages/sdk/scripts/lib/bin.js') +const createBin = join(repoRoot, 'packages/scaffold/create-sdk/lib/bin.js') +const scriptsBin = join(repoRoot, 'packages/scaffold/scripts/lib/bin.js') describe.skipIf(!existsSync(createBin) || !existsSync(scriptsBin))( 'SDK built artifacts', diff --git a/packages/sdk/create-sdk/tests/create.snapshot.ts b/packages/scaffold/create-sdk/tests/create.snapshot.ts similarity index 100% rename from packages/sdk/create-sdk/tests/create.snapshot.ts rename to packages/scaffold/create-sdk/tests/create.snapshot.ts diff --git a/packages/sdk/create-sdk/tests/create.spec.ts b/packages/scaffold/create-sdk/tests/create.spec.ts similarity index 100% rename from packages/sdk/create-sdk/tests/create.spec.ts rename to packages/scaffold/create-sdk/tests/create.spec.ts diff --git a/packages/sdk/create-sdk/tests/link-workspace.e2e.ts b/packages/scaffold/create-sdk/tests/link-workspace.e2e.ts similarity index 98% rename from packages/sdk/create-sdk/tests/link-workspace.e2e.ts rename to packages/scaffold/create-sdk/tests/link-workspace.e2e.ts index b7739acc16..b978c8217e 100644 --- a/packages/sdk/create-sdk/tests/link-workspace.e2e.ts +++ b/packages/scaffold/create-sdk/tests/link-workspace.e2e.ts @@ -17,7 +17,7 @@ import { scaffoldProject } from '../src/project-scaffolder.ts' const execFileAsync = promisify(execFile) const repoRoot = fileURLToPath(new URL('../../../../', import.meta.url)) -const builtScripts = join(repoRoot, 'packages/sdk/scripts/lib/bin.js') +const builtScripts = join(repoRoot, 'packages/scaffold/scripts/lib/bin.js') const temporary: string[] = [] function resolveCorepackHome(): string { diff --git a/packages/sdk/create-sdk/tsconfig.json b/packages/scaffold/create-sdk/tsconfig.json similarity index 100% rename from packages/sdk/create-sdk/tsconfig.json rename to packages/scaffold/create-sdk/tsconfig.json diff --git a/packages/sdk/create-sdk/tsdown.config.ts b/packages/scaffold/create-sdk/tsdown.config.ts similarity index 100% rename from packages/sdk/create-sdk/tsdown.config.ts rename to packages/scaffold/create-sdk/tsdown.config.ts diff --git a/packages/sdk/helper/README.i18n.yaml b/packages/scaffold/helper/README.i18n.yaml similarity index 80% rename from packages/sdk/helper/README.i18n.yaml rename to packages/scaffold/helper/README.i18n.yaml index bb5acbdcc2..a62db5f38a 100644 --- a/packages/sdk/helper/README.i18n.yaml +++ b/packages/scaffold/helper/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/sdk/helper/README.md +# pnpm run verify-translation-pairing --write packages/scaffold/helper/README.md README.md: 416fcab9815e50ca662333eb6925cc37eb0c41c4 README.zh.md: c50ec7aafa03377bd11759c50eeb2422a12fab68 diff --git a/packages/sdk/helper/README.md b/packages/scaffold/helper/README.md similarity index 100% rename from packages/sdk/helper/README.md rename to packages/scaffold/helper/README.md diff --git a/packages/sdk/helper/README.zh.md b/packages/scaffold/helper/README.zh.md similarity index 100% rename from packages/sdk/helper/README.zh.md rename to packages/scaffold/helper/README.zh.md diff --git a/packages/sdk/helper/package.json b/packages/scaffold/helper/package.json similarity index 100% rename from packages/sdk/helper/package.json rename to packages/scaffold/helper/package.json diff --git a/packages/sdk/helper/src/documents/cordis-yaml-file.ts b/packages/scaffold/helper/src/documents/cordis-yaml-file.ts similarity index 100% rename from packages/sdk/helper/src/documents/cordis-yaml-file.ts rename to packages/scaffold/helper/src/documents/cordis-yaml-file.ts diff --git a/packages/sdk/helper/src/documents/env-file.ts b/packages/scaffold/helper/src/documents/env-file.ts similarity index 100% rename from packages/sdk/helper/src/documents/env-file.ts rename to packages/scaffold/helper/src/documents/env-file.ts diff --git a/packages/sdk/helper/src/documents/package-json-file.ts b/packages/scaffold/helper/src/documents/package-json-file.ts similarity index 100% rename from packages/sdk/helper/src/documents/package-json-file.ts rename to packages/scaffold/helper/src/documents/package-json-file.ts diff --git a/packages/sdk/helper/src/documents/pnpm-workspace-file.ts b/packages/scaffold/helper/src/documents/pnpm-workspace-file.ts similarity index 100% rename from packages/sdk/helper/src/documents/pnpm-workspace-file.ts rename to packages/scaffold/helper/src/documents/pnpm-workspace-file.ts diff --git a/packages/sdk/helper/src/documents/project-file.ts b/packages/scaffold/helper/src/documents/project-file.ts similarity index 100% rename from packages/sdk/helper/src/documents/project-file.ts rename to packages/scaffold/helper/src/documents/project-file.ts diff --git a/packages/sdk/helper/src/documents/tsconfig-file.ts b/packages/scaffold/helper/src/documents/tsconfig-file.ts similarity index 100% rename from packages/sdk/helper/src/documents/tsconfig-file.ts rename to packages/scaffold/helper/src/documents/tsconfig-file.ts diff --git a/packages/sdk/helper/src/features/builtin/app.ts b/packages/scaffold/helper/src/features/builtin/app.ts similarity index 100% rename from packages/sdk/helper/src/features/builtin/app.ts rename to packages/scaffold/helper/src/features/builtin/app.ts diff --git a/packages/sdk/helper/src/features/builtin/helpers.ts b/packages/scaffold/helper/src/features/builtin/helpers.ts similarity index 100% rename from packages/sdk/helper/src/features/builtin/helpers.ts rename to packages/scaffold/helper/src/features/builtin/helpers.ts diff --git a/packages/sdk/helper/src/features/builtin/index.ts b/packages/scaffold/helper/src/features/builtin/index.ts similarity index 100% rename from packages/sdk/helper/src/features/builtin/index.ts rename to packages/scaffold/helper/src/features/builtin/index.ts diff --git a/packages/sdk/helper/src/features/builtin/provider.ts b/packages/scaffold/helper/src/features/builtin/provider.ts similarity index 100% rename from packages/sdk/helper/src/features/builtin/provider.ts rename to packages/scaffold/helper/src/features/builtin/provider.ts diff --git a/packages/sdk/helper/src/features/builtin/spine.ts b/packages/scaffold/helper/src/features/builtin/spine.ts similarity index 100% rename from packages/sdk/helper/src/features/builtin/spine.ts rename to packages/scaffold/helper/src/features/builtin/spine.ts diff --git a/packages/sdk/helper/src/features/define-feature.ts b/packages/scaffold/helper/src/features/define-feature.ts similarity index 100% rename from packages/sdk/helper/src/features/define-feature.ts rename to packages/scaffold/helper/src/features/define-feature.ts diff --git a/packages/sdk/helper/src/features/feature-configurator.ts b/packages/scaffold/helper/src/features/feature-configurator.ts similarity index 100% rename from packages/sdk/helper/src/features/feature-configurator.ts rename to packages/scaffold/helper/src/features/feature-configurator.ts diff --git a/packages/sdk/helper/src/features/feature.ts b/packages/scaffold/helper/src/features/feature.ts similarity index 100% rename from packages/sdk/helper/src/features/feature.ts rename to packages/scaffold/helper/src/features/feature.ts diff --git a/packages/sdk/helper/src/features/registry.ts b/packages/scaffold/helper/src/features/registry.ts similarity index 100% rename from packages/sdk/helper/src/features/registry.ts rename to packages/scaffold/helper/src/features/registry.ts diff --git a/packages/sdk/helper/src/features/resources.ts b/packages/scaffold/helper/src/features/resources.ts similarity index 100% rename from packages/sdk/helper/src/features/resources.ts rename to packages/scaffold/helper/src/features/resources.ts diff --git a/packages/sdk/helper/src/ids.ts b/packages/scaffold/helper/src/ids.ts similarity index 100% rename from packages/sdk/helper/src/ids.ts rename to packages/scaffold/helper/src/ids.ts diff --git a/packages/sdk/helper/src/index.ts b/packages/scaffold/helper/src/index.ts similarity index 86% rename from packages/sdk/helper/src/index.ts rename to packages/scaffold/helper/src/index.ts index 85aba58a99..8c8e0db4b9 100644 --- a/packages/sdk/helper/src/index.ts +++ b/packages/scaffold/helper/src/index.ts @@ -1,6 +1,10 @@ /** * Shared domain and infrastructure for DeepSeek Harness SDK project tooling. * + * FIXME: rename to `@deepseek-ai/dsh-sdk-helper` before the first tagged release — + * the current name is indefensibly generic as a published name + * ([regrouping Agent Note](../../../../.agents/notes/proposed/architecture/2026-07-29-package-regrouping.md)). + * * @module @deepseek-ai/dsh-helper */ diff --git a/packages/sdk/helper/src/invariant.ts b/packages/scaffold/helper/src/invariant.ts similarity index 100% rename from packages/sdk/helper/src/invariant.ts rename to packages/scaffold/helper/src/invariant.ts diff --git a/packages/sdk/helper/src/package-managers/link-workspace.ts b/packages/scaffold/helper/src/package-managers/link-workspace.ts similarity index 100% rename from packages/sdk/helper/src/package-managers/link-workspace.ts rename to packages/scaffold/helper/src/package-managers/link-workspace.ts diff --git a/packages/sdk/helper/src/package-managers/package-manager.ts b/packages/scaffold/helper/src/package-managers/package-manager.ts similarity index 100% rename from packages/sdk/helper/src/package-managers/package-manager.ts rename to packages/scaffold/helper/src/package-managers/package-manager.ts diff --git a/packages/sdk/helper/src/plugins/local-plugin-blueprint.ts b/packages/scaffold/helper/src/plugins/local-plugin-blueprint.ts similarity index 100% rename from packages/sdk/helper/src/plugins/local-plugin-blueprint.ts rename to packages/scaffold/helper/src/plugins/local-plugin-blueprint.ts diff --git a/packages/sdk/helper/src/project/change-set.ts b/packages/scaffold/helper/src/project/change-set.ts similarity index 100% rename from packages/sdk/helper/src/project/change-set.ts rename to packages/scaffold/helper/src/project/change-set.ts diff --git a/packages/sdk/helper/src/project/npm-dependency-policy.ts b/packages/scaffold/helper/src/project/npm-dependency-policy.ts similarity index 100% rename from packages/sdk/helper/src/project/npm-dependency-policy.ts rename to packages/scaffold/helper/src/project/npm-dependency-policy.ts diff --git a/packages/sdk/helper/src/project/project-edit-session.ts b/packages/scaffold/helper/src/project/project-edit-session.ts similarity index 100% rename from packages/sdk/helper/src/project/project-edit-session.ts rename to packages/scaffold/helper/src/project/project-edit-session.ts diff --git a/packages/sdk/helper/src/project/sdk-project.ts b/packages/scaffold/helper/src/project/sdk-project.ts similarity index 99% rename from packages/sdk/helper/src/project/sdk-project.ts rename to packages/scaffold/helper/src/project/sdk-project.ts index e9302aa428..41b66fe7d0 100644 --- a/packages/sdk/helper/src/project/sdk-project.ts +++ b/packages/scaffold/helper/src/project/sdk-project.ts @@ -98,7 +98,7 @@ async function detectPackageManager(root: string, manifest: Readonly): string | undefined { const spec = manifest.dependencies?.['@deepseek-ai/dsh-scripts'] - const match = /^(?:file|link|portal):(.+)\/packages\/sdk\/scripts\/?$/.exec(spec ?? '') + const match = /^(?:file|link|portal):(.+)\/packages\/scaffold\/scripts\/?$/.exec(spec ?? '') return match?.[1] ? resolve(root, match[1]) : undefined } diff --git a/packages/sdk/helper/src/project/types.ts b/packages/scaffold/helper/src/project/types.ts similarity index 100% rename from packages/sdk/helper/src/project/types.ts rename to packages/scaffold/helper/src/project/types.ts diff --git a/packages/sdk/helper/src/questions/clack-nested-multiselect.ts b/packages/scaffold/helper/src/questions/clack-nested-multiselect.ts similarity index 100% rename from packages/sdk/helper/src/questions/clack-nested-multiselect.ts rename to packages/scaffold/helper/src/questions/clack-nested-multiselect.ts diff --git a/packages/sdk/helper/src/questions/clack-prompt-port.ts b/packages/scaffold/helper/src/questions/clack-prompt-port.ts similarity index 100% rename from packages/sdk/helper/src/questions/clack-prompt-port.ts rename to packages/scaffold/helper/src/questions/clack-prompt-port.ts diff --git a/packages/sdk/helper/src/questions/headless-prompt-port.ts b/packages/scaffold/helper/src/questions/headless-prompt-port.ts similarity index 100% rename from packages/sdk/helper/src/questions/headless-prompt-port.ts rename to packages/scaffold/helper/src/questions/headless-prompt-port.ts diff --git a/packages/sdk/helper/src/questions/prompt-port.ts b/packages/scaffold/helper/src/questions/prompt-port.ts similarity index 100% rename from packages/sdk/helper/src/questions/prompt-port.ts rename to packages/scaffold/helper/src/questions/prompt-port.ts diff --git a/packages/sdk/helper/src/questions/question.ts b/packages/scaffold/helper/src/questions/question.ts similarity index 100% rename from packages/sdk/helper/src/questions/question.ts rename to packages/scaffold/helper/src/questions/question.ts diff --git a/packages/sdk/helper/src/templates/assets/README.md.tpl b/packages/scaffold/helper/src/templates/assets/README.md.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/README.md.tpl rename to packages/scaffold/helper/src/templates/assets/README.md.tpl diff --git a/packages/sdk/helper/src/templates/assets/gitignore.tpl b/packages/scaffold/helper/src/templates/assets/gitignore.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/gitignore.tpl rename to packages/scaffold/helper/src/templates/assets/gitignore.tpl diff --git a/packages/sdk/helper/src/templates/assets/index.ts.tpl b/packages/scaffold/helper/src/templates/assets/index.ts.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/index.ts.tpl rename to packages/scaffold/helper/src/templates/assets/index.ts.tpl diff --git a/packages/sdk/helper/src/templates/assets/local-plugin-tsdown.config.ts.tpl b/packages/scaffold/helper/src/templates/assets/local-plugin-tsdown.config.ts.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/local-plugin-tsdown.config.ts.tpl rename to packages/scaffold/helper/src/templates/assets/local-plugin-tsdown.config.ts.tpl diff --git a/packages/sdk/helper/src/templates/assets/local-plugin.ts.tpl b/packages/scaffold/helper/src/templates/assets/local-plugin.ts.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/local-plugin.ts.tpl rename to packages/scaffold/helper/src/templates/assets/local-plugin.ts.tpl diff --git a/packages/sdk/helper/src/templates/assets/local-tool.ts.tpl b/packages/scaffold/helper/src/templates/assets/local-tool.ts.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/local-tool.ts.tpl rename to packages/scaffold/helper/src/templates/assets/local-tool.ts.tpl diff --git a/packages/sdk/helper/src/templates/assets/package.json.tpl b/packages/scaffold/helper/src/templates/assets/package.json.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/package.json.tpl rename to packages/scaffold/helper/src/templates/assets/package.json.tpl diff --git a/packages/sdk/helper/src/templates/assets/persona.txt.tpl b/packages/scaffold/helper/src/templates/assets/persona.txt.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/persona.txt.tpl rename to packages/scaffold/helper/src/templates/assets/persona.txt.tpl diff --git a/packages/sdk/helper/src/templates/assets/tsconfig.base.json.tpl b/packages/scaffold/helper/src/templates/assets/tsconfig.base.json.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/tsconfig.base.json.tpl rename to packages/scaffold/helper/src/templates/assets/tsconfig.base.json.tpl diff --git a/packages/sdk/helper/src/templates/assets/tsdown.config.ts.tpl b/packages/scaffold/helper/src/templates/assets/tsdown.config.ts.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/tsdown.config.ts.tpl rename to packages/scaffold/helper/src/templates/assets/tsdown.config.ts.tpl diff --git a/packages/sdk/helper/src/templates/assets/yarnrc.yml.tpl b/packages/scaffold/helper/src/templates/assets/yarnrc.yml.tpl similarity index 100% rename from packages/sdk/helper/src/templates/assets/yarnrc.yml.tpl rename to packages/scaffold/helper/src/templates/assets/yarnrc.yml.tpl diff --git a/packages/sdk/helper/src/templates/project-template.ts b/packages/scaffold/helper/src/templates/project-template.ts similarity index 100% rename from packages/sdk/helper/src/templates/project-template.ts rename to packages/scaffold/helper/src/templates/project-template.ts diff --git a/packages/sdk/helper/src/templates/template-assets.ts b/packages/scaffold/helper/src/templates/template-assets.ts similarity index 100% rename from packages/sdk/helper/src/templates/template-assets.ts rename to packages/scaffold/helper/src/templates/template-assets.ts diff --git a/packages/sdk/helper/src/templates/text-template.ts b/packages/scaffold/helper/src/templates/text-template.ts similarity index 100% rename from packages/sdk/helper/src/templates/text-template.ts rename to packages/scaffold/helper/src/templates/text-template.ts diff --git a/packages/sdk/helper/tests/documents.spec.ts b/packages/scaffold/helper/tests/documents.spec.ts similarity index 100% rename from packages/sdk/helper/tests/documents.spec.ts rename to packages/scaffold/helper/tests/documents.spec.ts diff --git a/packages/sdk/helper/tests/headless-prompt-port.spec.ts b/packages/scaffold/helper/tests/headless-prompt-port.spec.ts similarity index 100% rename from packages/sdk/helper/tests/headless-prompt-port.spec.ts rename to packages/scaffold/helper/tests/headless-prompt-port.spec.ts diff --git a/packages/sdk/helper/tests/project.spec.ts b/packages/scaffold/helper/tests/project.spec.ts similarity index 100% rename from packages/sdk/helper/tests/project.spec.ts rename to packages/scaffold/helper/tests/project.spec.ts diff --git a/packages/sdk/helper/tests/questions.spec.ts b/packages/scaffold/helper/tests/questions.spec.ts similarity index 100% rename from packages/sdk/helper/tests/questions.spec.ts rename to packages/scaffold/helper/tests/questions.spec.ts diff --git a/packages/sdk/helper/tsconfig.json b/packages/scaffold/helper/tsconfig.json similarity index 100% rename from packages/sdk/helper/tsconfig.json rename to packages/scaffold/helper/tsconfig.json diff --git a/packages/sdk/helper/tsdown.config.ts b/packages/scaffold/helper/tsdown.config.ts similarity index 100% rename from packages/sdk/helper/tsdown.config.ts rename to packages/scaffold/helper/tsdown.config.ts diff --git a/packages/scaffold/protocol/README.i18n.yaml b/packages/scaffold/protocol/README.i18n.yaml new file mode 100644 index 0000000000..df0623573b --- /dev/null +++ b/packages/scaffold/protocol/README.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/scaffold/protocol/README.md +README.md: dc42f385f6e7fd6327ca79887d3cf22d7c34ccdf +README.zh.md: a292120be8b5b09aaadb05f9dbc272a51bd74831 diff --git a/packages/sdk/sdk-protocol/README.md b/packages/scaffold/protocol/README.md similarity index 90% rename from packages/sdk/sdk-protocol/README.md rename to packages/scaffold/protocol/README.md index 2d141e6f62..b8420eb19a 100644 --- a/packages/sdk/sdk-protocol/README.md +++ b/packages/scaffold/protocol/README.md @@ -2,7 +2,7 @@ English | [中文](README.zh.md) -The shared wire protocol for the DeepSeek Harness SDK runtime: one newline-delimited JSON-RPC 2.0 transport class plus the named request, result, and notification types both wire ends speak. The package root enumerates the protocol consumer interface; source modules are not exported as deep imports. The server side is the [`dsh-jsonrpc`](../../ui/jsonrpc/README.md) plugin; clients are [`dsh-sdk-client`](../sdk-client/README.md) (TypeScript) and the [Python SDK](../../../python/README.md) (which mirrors these shapes but does not import them). A pure library — no plugin, no Config, no registration. +The shared wire protocol for the DeepSeek Harness SDK runtime: one newline-delimited JSON-RPC 2.0 transport class plus the named request, result, and notification types both wire ends speak. The package root enumerates the protocol consumer interface; source modules are not exported as deep imports. The server side is the [`dsh-jsonrpc`](../../scaffold/server/README.md) plugin; clients are [`dsh-sdk-client`](../client/README.md) (TypeScript) and the [Python SDK](../../../python/README.md) (which mirrors these shapes but does not import them). A pure library — no plugin, no Config, no registration. ## Transport @@ -26,7 +26,7 @@ The shared wire protocol for the DeepSeek Harness SDK runtime: one newline-delim ## Model Experience -None, as this package defines the client-facing wire protocol; the model-visible surfaces belong to the runtime plugins composed behind the serving [`dsh-jsonrpc`](../../ui/jsonrpc/README.md) entry. +None, as this package defines the client-facing wire protocol; the model-visible surfaces belong to the runtime plugins composed behind the serving [`dsh-jsonrpc`](../../scaffold/server/README.md) entry. #### KV Cache effect @@ -35,5 +35,5 @@ None; this package neither assembles nor sends a provider request. ## Known Limitations and Deferred Work - **No protocol-version negotiation** — the handshake carries only `serverInfo.version` (`0.0.1`, unvalidated by clients); pre-release stance, no compatibility promise. -- **No cancel or session-close methods** — a client abandons a turn by closing the runtime process; see the [`dsh-jsonrpc` README](../../ui/jsonrpc/README.md). +- **No cancel or session-close methods** — a client abandons a turn by closing the runtime process; see the [`dsh-jsonrpc` README](../../scaffold/server/README.md). - **Server→client requests are dead capability** — the transport supports them, but the server never sends one; the Python SDK's responder surface exists for future approval flows. diff --git a/packages/sdk/sdk-protocol/README.zh.md b/packages/scaffold/protocol/README.zh.md similarity index 100% rename from packages/sdk/sdk-protocol/README.zh.md rename to packages/scaffold/protocol/README.zh.md diff --git a/packages/sdk/sdk-protocol/package.json b/packages/scaffold/protocol/package.json similarity index 100% rename from packages/sdk/sdk-protocol/package.json rename to packages/scaffold/protocol/package.json diff --git a/packages/sdk/sdk-protocol/src/index.ts b/packages/scaffold/protocol/src/index.ts similarity index 100% rename from packages/sdk/sdk-protocol/src/index.ts rename to packages/scaffold/protocol/src/index.ts diff --git a/packages/sdk/sdk-protocol/src/invariant.ts b/packages/scaffold/protocol/src/invariant.ts similarity index 100% rename from packages/sdk/sdk-protocol/src/invariant.ts rename to packages/scaffold/protocol/src/invariant.ts diff --git a/packages/sdk/sdk-protocol/src/transport.ts b/packages/scaffold/protocol/src/transport.ts similarity index 100% rename from packages/sdk/sdk-protocol/src/transport.ts rename to packages/scaffold/protocol/src/transport.ts diff --git a/packages/sdk/sdk-protocol/src/types.ts b/packages/scaffold/protocol/src/types.ts similarity index 100% rename from packages/sdk/sdk-protocol/src/types.ts rename to packages/scaffold/protocol/src/types.ts diff --git a/packages/sdk/sdk-protocol/tests/transport.spec.ts b/packages/scaffold/protocol/tests/transport.spec.ts similarity index 100% rename from packages/sdk/sdk-protocol/tests/transport.spec.ts rename to packages/scaffold/protocol/tests/transport.spec.ts diff --git a/packages/sdk/sdk-protocol/tsconfig.json b/packages/scaffold/protocol/tsconfig.json similarity index 100% rename from packages/sdk/sdk-protocol/tsconfig.json rename to packages/scaffold/protocol/tsconfig.json diff --git a/packages/sdk/scripts/README.i18n.yaml b/packages/scaffold/scripts/README.i18n.yaml similarity index 80% rename from packages/sdk/scripts/README.i18n.yaml rename to packages/scaffold/scripts/README.i18n.yaml index b148eb76ab..db65cb315f 100644 --- a/packages/sdk/scripts/README.i18n.yaml +++ b/packages/scaffold/scripts/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/sdk/scripts/README.md +# pnpm run verify-translation-pairing --write packages/scaffold/scripts/README.md README.md: 9a696bf5a4de9a80f0741f07a7e753733bc2f998 README.zh.md: cf9fc2cbbe467eb86e89d9eb77e9bc34860b5a3a diff --git a/packages/sdk/scripts/README.md b/packages/scaffold/scripts/README.md similarity index 100% rename from packages/sdk/scripts/README.md rename to packages/scaffold/scripts/README.md diff --git a/packages/sdk/scripts/README.zh.md b/packages/scaffold/scripts/README.zh.md similarity index 100% rename from packages/sdk/scripts/README.zh.md rename to packages/scaffold/scripts/README.zh.md diff --git a/packages/sdk/scripts/package.json b/packages/scaffold/scripts/package.json similarity index 100% rename from packages/sdk/scripts/package.json rename to packages/scaffold/scripts/package.json diff --git a/packages/sdk/scripts/src/args.ts b/packages/scaffold/scripts/src/args.ts similarity index 100% rename from packages/sdk/scripts/src/args.ts rename to packages/scaffold/scripts/src/args.ts diff --git a/packages/sdk/scripts/src/bin.ts b/packages/scaffold/scripts/src/bin.ts similarity index 100% rename from packages/sdk/scripts/src/bin.ts rename to packages/scaffold/scripts/src/bin.ts diff --git a/packages/sdk/scripts/src/build.ts b/packages/scaffold/scripts/src/build.ts similarity index 100% rename from packages/sdk/scripts/src/build.ts rename to packages/scaffold/scripts/src/build.ts diff --git a/packages/sdk/scripts/src/command.ts b/packages/scaffold/scripts/src/command.ts similarity index 100% rename from packages/sdk/scripts/src/command.ts rename to packages/scaffold/scripts/src/command.ts diff --git a/packages/sdk/scripts/src/config.ts b/packages/scaffold/scripts/src/config.ts similarity index 100% rename from packages/sdk/scripts/src/config.ts rename to packages/scaffold/scripts/src/config.ts diff --git a/packages/sdk/scripts/src/config/config-workflow.ts b/packages/scaffold/scripts/src/config/config-workflow.ts similarity index 100% rename from packages/sdk/scripts/src/config/config-workflow.ts rename to packages/scaffold/scripts/src/config/config-workflow.ts diff --git a/packages/sdk/scripts/src/create-plugin.ts b/packages/scaffold/scripts/src/create-plugin.ts similarity index 100% rename from packages/sdk/scripts/src/create-plugin.ts rename to packages/scaffold/scripts/src/create-plugin.ts diff --git a/packages/sdk/scripts/src/dev/tsdown-config.ts b/packages/scaffold/scripts/src/dev/tsdown-config.ts similarity index 100% rename from packages/sdk/scripts/src/dev/tsdown-config.ts rename to packages/scaffold/scripts/src/dev/tsdown-config.ts diff --git a/packages/scaffold/scripts/src/index.ts b/packages/scaffold/scripts/src/index.ts new file mode 100644 index 0000000000..0af3ef0b30 --- /dev/null +++ b/packages/scaffold/scripts/src/index.ts @@ -0,0 +1,11 @@ +/** + * Public DeepSeek Harness SDK runtime entry points. + * + * FIXME: rename to `@deepseek-ai/dsh-sdk-scripts` before the first tagged release — + * the current name is indefensibly generic as a published name + * ([regrouping Agent Note](../../../../.agents/notes/proposed/architecture/2026-07-29-package-regrouping.md)). + * + * @module @deepseek-ai/dsh-scripts + */ + +export { runSDK, startSDK, type SdkBootContext } from './runtime.ts' diff --git a/packages/sdk/scripts/src/invariant.ts b/packages/scaffold/scripts/src/invariant.ts similarity index 100% rename from packages/sdk/scripts/src/invariant.ts rename to packages/scaffold/scripts/src/invariant.ts diff --git a/packages/sdk/scripts/src/local-plugin-loader-hooks.ts b/packages/scaffold/scripts/src/local-plugin-loader-hooks.ts similarity index 100% rename from packages/sdk/scripts/src/local-plugin-loader-hooks.ts rename to packages/scaffold/scripts/src/local-plugin-loader-hooks.ts diff --git a/packages/sdk/scripts/src/runtime.ts b/packages/scaffold/scripts/src/runtime.ts similarity index 100% rename from packages/sdk/scripts/src/runtime.ts rename to packages/scaffold/scripts/src/runtime.ts diff --git a/packages/sdk/scripts/src/telemetry.ts b/packages/scaffold/scripts/src/telemetry.ts similarity index 100% rename from packages/sdk/scripts/src/telemetry.ts rename to packages/scaffold/scripts/src/telemetry.ts diff --git a/packages/sdk/scripts/src/templates/assets/config-install-failure.txt.tpl b/packages/scaffold/scripts/src/templates/assets/config-install-failure.txt.tpl similarity index 100% rename from packages/sdk/scripts/src/templates/assets/config-install-failure.txt.tpl rename to packages/scaffold/scripts/src/templates/assets/config-install-failure.txt.tpl diff --git a/packages/sdk/scripts/src/templates/assets/usage.txt.tpl b/packages/scaffold/scripts/src/templates/assets/usage.txt.tpl similarity index 100% rename from packages/sdk/scripts/src/templates/assets/usage.txt.tpl rename to packages/scaffold/scripts/src/templates/assets/usage.txt.tpl diff --git a/packages/sdk/scripts/src/templates/dsh-sdk-templates.ts b/packages/scaffold/scripts/src/templates/dsh-sdk-templates.ts similarity index 100% rename from packages/sdk/scripts/src/templates/dsh-sdk-templates.ts rename to packages/scaffold/scripts/src/templates/dsh-sdk-templates.ts diff --git a/packages/sdk/scripts/tests/__snapshots__/config.snapshot.ts.snap b/packages/scaffold/scripts/tests/__snapshots__/config.snapshot.ts.snap similarity index 100% rename from packages/sdk/scripts/tests/__snapshots__/config.snapshot.ts.snap rename to packages/scaffold/scripts/tests/__snapshots__/config.snapshot.ts.snap diff --git a/packages/sdk/scripts/tests/config.snapshot.ts b/packages/scaffold/scripts/tests/config.snapshot.ts similarity index 100% rename from packages/sdk/scripts/tests/config.snapshot.ts rename to packages/scaffold/scripts/tests/config.snapshot.ts diff --git a/packages/sdk/scripts/tests/scripts.spec.ts b/packages/scaffold/scripts/tests/scripts.spec.ts similarity index 100% rename from packages/sdk/scripts/tests/scripts.spec.ts rename to packages/scaffold/scripts/tests/scripts.spec.ts diff --git a/packages/sdk/scripts/tsconfig.json b/packages/scaffold/scripts/tsconfig.json similarity index 88% rename from packages/sdk/scripts/tsconfig.json rename to packages/scaffold/scripts/tsconfig.json index d3dacea10b..2230a377ab 100644 --- a/packages/sdk/scripts/tsconfig.json +++ b/packages/scaffold/scripts/tsconfig.json @@ -8,7 +8,7 @@ "references": [ { "path": "../helper" }, { "path": "../telemetry" }, - { "path": "../../ui/app-boot" }, + { "path": "../../boot/app-boot" }, { "path": "../../../vendor/cordis" }, { "path": "../../support/invariants" } ] diff --git a/packages/sdk/scripts/tsdown.config.ts b/packages/scaffold/scripts/tsdown.config.ts similarity index 100% rename from packages/sdk/scripts/tsdown.config.ts rename to packages/scaffold/scripts/tsdown.config.ts diff --git a/packages/scaffold/server/README.i18n.yaml b/packages/scaffold/server/README.i18n.yaml new file mode 100644 index 0000000000..0672ad22a6 --- /dev/null +++ b/packages/scaffold/server/README.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/scaffold/server/README.md +README.md: 7ada4fbe6a53e90fcd45c20d9472cb87dbf6b4cf +README.zh.md: b8362f7762b963ed6caff1b2ba87421152ecb483 diff --git a/packages/ui/jsonrpc/README.md b/packages/scaffold/server/README.md similarity index 95% rename from packages/ui/jsonrpc/README.md rename to packages/scaffold/server/README.md index 9cd4876b52..0afb3a38ec 100644 --- a/packages/ui/jsonrpc/README.md +++ b/packages/scaffold/server/README.md @@ -2,7 +2,7 @@ English | [中文](README.zh.md) -The `jsonrpc` plugin serves newline-delimited JSON-RPC over stdio so out-of-process SDK clients can drive harness agents. [`HarnessSdkServer`](src/server.ts) owns the protocol methods and notifications; the transport and the named wire types live in [`dsh-sdk-protocol`](../../sdk/sdk-protocol/README.md), shared with the client SDKs; [`jsonrpc-demo`](../../examples/jsonrpc-demo/README.md) supplies the surrounding `cordis.yml` application. +The `jsonrpc` plugin serves newline-delimited JSON-RPC over stdio so out-of-process SDK clients can drive harness agents. [`HarnessSdkServer`](src/server.ts) owns the protocol methods and notifications; the transport and the named wire types live in [`dsh-sdk-protocol`](../../scaffold/protocol/README.md), shared with the client SDKs; [`jsonrpc-demo`](../../examples/jsonrpc-demo/README.md) supplies the surrounding `cordis.yml` application. ## Wiring diff --git a/packages/ui/jsonrpc/README.zh.md b/packages/scaffold/server/README.zh.md similarity index 95% rename from packages/ui/jsonrpc/README.zh.md rename to packages/scaffold/server/README.zh.md index a2b979da44..5305434abb 100644 --- a/packages/ui/jsonrpc/README.zh.md +++ b/packages/scaffold/server/README.zh.md @@ -2,7 +2,7 @@ [English](README.md) | 中文 -`jsonrpc` 插件通过 stdio 提供以换行符分隔的 JSON-RPC,使进程外 SDK 客户端能够驱动 harness agent(智能体)。[`HarnessSdkServer`](src/server.ts) 负责协议方法和通知;传输与具名协议类型位于 [`dsh-sdk-protocol`](../../sdk/sdk-protocol/README.md),与客户端 SDK 共享;[`jsonrpc-demo`](../../examples/jsonrpc-demo/README.md) 提供外围的 `cordis.yml` 应用。 +`jsonrpc` 插件通过 stdio 提供以换行符分隔的 JSON-RPC,使进程外 SDK 客户端能够驱动 harness agent(智能体)。[`HarnessSdkServer`](src/server.ts) 负责协议方法和通知;传输与具名协议类型位于 [`dsh-sdk-protocol`](../../scaffold/protocol/README.md),与客户端 SDK 共享;[`jsonrpc-demo`](../../examples/jsonrpc-demo/README.md) 提供外围的 `cordis.yml` 应用。 ## 组装 diff --git a/packages/ui/jsonrpc/package.json b/packages/scaffold/server/package.json similarity index 100% rename from packages/ui/jsonrpc/package.json rename to packages/scaffold/server/package.json diff --git a/packages/ui/jsonrpc/src/index.ts b/packages/scaffold/server/src/index.ts similarity index 92% rename from packages/ui/jsonrpc/src/index.ts rename to packages/scaffold/server/src/index.ts index 423f338877..9985cadfb4 100644 --- a/packages/ui/jsonrpc/src/index.ts +++ b/packages/scaffold/server/src/index.ts @@ -6,6 +6,10 @@ * owns EOF and signal exits. Keep named plugin exports with no default export so * Loader `unwrapExports` preserves `name`, `inject`, `Config`, and `apply`. * + * FIXME: rename to `@deepseek-ai/dsh-sdk-server` before the first tagged release — + * the current name says the wire encoding, not the role; it is the server half of + * the SDK protocol ([regrouping Agent Note](../../../../.agents/notes/proposed/architecture/2026-07-29-package-regrouping.md)). + * * @module @deepseek-ai/dsh-jsonrpc */ diff --git a/packages/ui/jsonrpc/src/invariant.ts b/packages/scaffold/server/src/invariant.ts similarity index 100% rename from packages/ui/jsonrpc/src/invariant.ts rename to packages/scaffold/server/src/invariant.ts diff --git a/packages/ui/jsonrpc/src/server.ts b/packages/scaffold/server/src/server.ts similarity index 100% rename from packages/ui/jsonrpc/src/server.ts rename to packages/scaffold/server/src/server.ts diff --git a/packages/ui/jsonrpc/tests/built-scope-carrier.e2e.ts b/packages/scaffold/server/tests/built-scope-carrier.e2e.ts similarity index 98% rename from packages/ui/jsonrpc/tests/built-scope-carrier.e2e.ts rename to packages/scaffold/server/tests/built-scope-carrier.e2e.ts index 1de16660a8..b3519110b5 100644 --- a/packages/ui/jsonrpc/tests/built-scope-carrier.e2e.ts +++ b/packages/scaffold/server/tests/built-scope-carrier.e2e.ts @@ -36,7 +36,7 @@ const [ load("packages/examples/agent-spine-demo/lib/index.js"), load("packages/subagent/subagent/lib/index.js"), load("packages/session/session-persistence-jsonl/lib/index.js"), - load("packages/ui/jsonrpc/lib/index.js"), + load("packages/scaffold/server/lib/index.js"), load("packages/core/session/lib/index.js"), ]); diff --git a/packages/ui/jsonrpc/tests/plugin-apply.spec.ts b/packages/scaffold/server/tests/plugin-apply.spec.ts similarity index 100% rename from packages/ui/jsonrpc/tests/plugin-apply.spec.ts rename to packages/scaffold/server/tests/plugin-apply.spec.ts diff --git a/packages/ui/jsonrpc/tests/plugin-shape.spec.ts b/packages/scaffold/server/tests/plugin-shape.spec.ts similarity index 100% rename from packages/ui/jsonrpc/tests/plugin-shape.spec.ts rename to packages/scaffold/server/tests/plugin-shape.spec.ts diff --git a/packages/ui/jsonrpc/tests/server.spec.ts b/packages/scaffold/server/tests/server.spec.ts similarity index 100% rename from packages/ui/jsonrpc/tests/server.spec.ts rename to packages/scaffold/server/tests/server.spec.ts diff --git a/packages/ui/jsonrpc/tsconfig.json b/packages/scaffold/server/tsconfig.json similarity index 93% rename from packages/ui/jsonrpc/tsconfig.json rename to packages/scaffold/server/tsconfig.json index 00ac7000e6..56419b6b84 100644 --- a/packages/ui/jsonrpc/tsconfig.json +++ b/packages/scaffold/server/tsconfig.json @@ -27,7 +27,7 @@ "path": "../../core/session" }, { - "path": "../../sdk/sdk-protocol" + "path": "../protocol" }, { "path": "../../subagent/subagent" diff --git a/packages/sdk/telemetry/README.i18n.yaml b/packages/scaffold/telemetry/README.i18n.yaml similarity index 80% rename from packages/sdk/telemetry/README.i18n.yaml rename to packages/scaffold/telemetry/README.i18n.yaml index 1604b40bf4..4d70fce157 100644 --- a/packages/sdk/telemetry/README.i18n.yaml +++ b/packages/scaffold/telemetry/README.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/sdk/telemetry/README.md +# pnpm run verify-translation-pairing --write packages/scaffold/telemetry/README.md README.md: c87735a93e7659f2913f4dd325176a8ae40cf29b README.zh.md: 24d6e72d988f94cdbc6aa01607edbfc105213267 diff --git a/packages/sdk/telemetry/README.md b/packages/scaffold/telemetry/README.md similarity index 100% rename from packages/sdk/telemetry/README.md rename to packages/scaffold/telemetry/README.md diff --git a/packages/sdk/telemetry/README.zh.md b/packages/scaffold/telemetry/README.zh.md similarity index 100% rename from packages/sdk/telemetry/README.zh.md rename to packages/scaffold/telemetry/README.zh.md diff --git a/packages/sdk/telemetry/package.json b/packages/scaffold/telemetry/package.json similarity index 100% rename from packages/sdk/telemetry/package.json rename to packages/scaffold/telemetry/package.json diff --git a/packages/sdk/telemetry/src/anonymous-id.ts b/packages/scaffold/telemetry/src/anonymous-id.ts similarity index 100% rename from packages/sdk/telemetry/src/anonymous-id.ts rename to packages/scaffold/telemetry/src/anonymous-id.ts diff --git a/packages/sdk/telemetry/src/consent-resolver.ts b/packages/scaffold/telemetry/src/consent-resolver.ts similarity index 100% rename from packages/sdk/telemetry/src/consent-resolver.ts rename to packages/scaffold/telemetry/src/consent-resolver.ts diff --git a/packages/sdk/telemetry/src/index.ts b/packages/scaffold/telemetry/src/index.ts similarity index 82% rename from packages/sdk/telemetry/src/index.ts rename to packages/scaffold/telemetry/src/index.ts index 107956fa39..17ea1d02c7 100644 --- a/packages/sdk/telemetry/src/index.ts +++ b/packages/scaffold/telemetry/src/index.ts @@ -7,6 +7,10 @@ * the launcher command dispatch and the helper feature catalog lives outside * this package. * + * FIXME: rename to `@deepseek-ai/dsh-sdk-telemetry` before the first tagged release — + * the current name collides with the `dsh-session-telemetry` family; this is + * launcher-side SDK telemetry ([regrouping Agent Note](../../../../.agents/notes/proposed/architecture/2026-07-29-package-regrouping.md)). + * * @module @deepseek-ai/dsh-telemetry */ diff --git a/packages/sdk/telemetry/src/invariant.ts b/packages/scaffold/telemetry/src/invariant.ts similarity index 100% rename from packages/sdk/telemetry/src/invariant.ts rename to packages/scaffold/telemetry/src/invariant.ts diff --git a/packages/sdk/telemetry/src/payload.ts b/packages/scaffold/telemetry/src/payload.ts similarity index 100% rename from packages/sdk/telemetry/src/payload.ts rename to packages/scaffold/telemetry/src/payload.ts diff --git a/packages/sdk/telemetry/src/reporter.ts b/packages/scaffold/telemetry/src/reporter.ts similarity index 100% rename from packages/sdk/telemetry/src/reporter.ts rename to packages/scaffold/telemetry/src/reporter.ts diff --git a/packages/sdk/telemetry/src/secret-redactor.ts b/packages/scaffold/telemetry/src/secret-redactor.ts similarity index 100% rename from packages/sdk/telemetry/src/secret-redactor.ts rename to packages/scaffold/telemetry/src/secret-redactor.ts diff --git a/packages/sdk/telemetry/tests/anonymous-id.spec.ts b/packages/scaffold/telemetry/tests/anonymous-id.spec.ts similarity index 100% rename from packages/sdk/telemetry/tests/anonymous-id.spec.ts rename to packages/scaffold/telemetry/tests/anonymous-id.spec.ts diff --git a/packages/sdk/telemetry/tests/consent-resolver.spec.ts b/packages/scaffold/telemetry/tests/consent-resolver.spec.ts similarity index 100% rename from packages/sdk/telemetry/tests/consent-resolver.spec.ts rename to packages/scaffold/telemetry/tests/consent-resolver.spec.ts diff --git a/packages/sdk/telemetry/tests/payload.spec.ts b/packages/scaffold/telemetry/tests/payload.spec.ts similarity index 100% rename from packages/sdk/telemetry/tests/payload.spec.ts rename to packages/scaffold/telemetry/tests/payload.spec.ts diff --git a/packages/sdk/telemetry/tests/reporter.spec.ts b/packages/scaffold/telemetry/tests/reporter.spec.ts similarity index 100% rename from packages/sdk/telemetry/tests/reporter.spec.ts rename to packages/scaffold/telemetry/tests/reporter.spec.ts diff --git a/packages/sdk/telemetry/tests/secret-redactor.spec.ts b/packages/scaffold/telemetry/tests/secret-redactor.spec.ts similarity index 100% rename from packages/sdk/telemetry/tests/secret-redactor.spec.ts rename to packages/scaffold/telemetry/tests/secret-redactor.spec.ts diff --git a/packages/sdk/telemetry/tsconfig.json b/packages/scaffold/telemetry/tsconfig.json similarity index 100% rename from packages/sdk/telemetry/tsconfig.json rename to packages/scaffold/telemetry/tsconfig.json diff --git a/packages/sdk/README.zh.md b/packages/sdk/README.zh.md deleted file mode 100644 index 003383c5f6..0000000000 --- a/packages/sdk/README.zh.md +++ /dev/null @@ -1,16 +0,0 @@ -# SDK 包 - -[English](README.md) | 中文 - -本分组包含 Harness 项目的开发者工具,以及从另一个进程驱动 Harness 运行时的客户端栈。 - -| 包 | 职责 | -|---|---| -| [`helper/`](helper/README.md) | 提供共享的项目编辑领域 | -| [`scripts/`](scripts/README.md) | 提供 `dsh-sdk` 项目命令 | -| [`create-sdk/`](create-sdk/README.md) | 创建新的 SDK 项目 | -| [`sdk-protocol/`](sdk-protocol/README.md) | 定义 SDK 运行时协议格式 | -| [`sdk-client/`](sdk-client/README.md) | 通过 TypeScript 客户端 API 驱动 Harness 运行时 | -| [`telemetry/`](telemetry/README.md) | 提供启动器遥测、同意和脱敏原语 | - -`@deepseek-ai/create-sdk` 遵循 npm 的 scoped initializer 命名约定;其他包遵循仓库的 `@deepseek-ai/dsh-*` 约定。参见[开发者项目工作流](../../.agents/notes/proposed/feature/2026-07-14-sdk-developer-projects.md)、[项目编辑架构](../../.agents/notes/proposed/architecture/2026-07-15-sdk-project-editing-architecture.md)和 [TypeScript SDK 设计](../../.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md)。 diff --git a/packages/sdk/scripts/src/index.ts b/packages/sdk/scripts/src/index.ts deleted file mode 100644 index 5180f885c8..0000000000 --- a/packages/sdk/scripts/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Public DeepSeek Harness SDK runtime entry points. - * - * @module @deepseek-ai/dsh-scripts - */ - -export { runSDK, startSDK, type SdkBootContext } from './runtime.ts' diff --git a/packages/sdk/sdk-protocol/README.i18n.yaml b/packages/sdk/sdk-protocol/README.i18n.yaml deleted file mode 100644 index f878b9fd63..0000000000 --- a/packages/sdk/sdk-protocol/README.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/sdk/sdk-protocol/README.md -README.md: 2d141e6f62ac0d324933996c282a2d0380af29f2 -README.zh.md: bc459f8817c9477a451015f7629168e246ee531c diff --git a/packages/subagent/subagent-dsh-sdk/README.i18n.yaml b/packages/subagent/subagent-dsh-sdk/README.i18n.yaml index 3598c77d31..246d702892 100644 --- a/packages/subagent/subagent-dsh-sdk/README.i18n.yaml +++ b/packages/subagent/subagent-dsh-sdk/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/subagent/subagent-dsh-sdk/README.md -README.md: c0e2f4e9ece366e28492e32d97afa533fd948141 -README.zh.md: 4cf6c58fff44b1c11cf0a6c321da2c02d52bb8c9 +README.md: 0bbcfa105ecf024a2492d39d3bf8d28956110050 +README.zh.md: ffb1b8f4cddca4566a20593bdac54801ad8db38f diff --git a/packages/subagent/subagent-dsh-sdk/README.md b/packages/subagent/subagent-dsh-sdk/README.md index c0e2f4e9ec..0bbcfa105e 100644 --- a/packages/subagent/subagent-dsh-sdk/README.md +++ b/packages/subagent/subagent-dsh-sdk/README.md @@ -2,7 +2,7 @@ English | [中文](README.zh.md) -The SDK provider runs each subagent as a complete DeepSeek Harness runtime in a fresh subprocess, driven over stdio JSON-RPC through the [TypeScript SDK client](../../sdk/sdk-client/README.md). It is the second out-of-process backend beside [`subagent-acp`](../subagent-acp/README.md), differing in the wire and the child contract: the ACP backend drives any Agent Client Protocol agent; this backend drives specifically a harness SDK runtime (`dsh-jsonrpc-agent` bin or packaged executable), so the child is a full peer harness — own `cordis.yml`-decided composition, session persistence, model route, and tools. +The SDK provider runs each subagent as a complete DeepSeek Harness runtime in a fresh subprocess, driven over stdio JSON-RPC through the [TypeScript SDK client](../../scaffold/client/README.md). It is the second out-of-process backend beside [`subagent-acp`](../subagent-acp/README.md), differing in the wire and the child contract: the ACP backend drives any Agent Client Protocol agent; this backend drives specifically a harness SDK runtime (`dsh-jsonrpc-agent` bin or packaged executable), so the child is a full peer harness — own `cordis.yml`-decided composition, session persistence, model route, and tools. ## Start and ownership diff --git a/packages/subagent/subagent-dsh-sdk/README.zh.md b/packages/subagent/subagent-dsh-sdk/README.zh.md index 4cf6c58fff..ffb1b8f4cd 100644 --- a/packages/subagent/subagent-dsh-sdk/README.zh.md +++ b/packages/subagent/subagent-dsh-sdk/README.zh.md @@ -2,7 +2,7 @@ [English](README.md) | 中文 -SDK 提供方会在全新的子进程中把每个 subagent 作为完整的 DeepSeek Harness 运行时运行,并经由 [TypeScript SDK 客户端](../../sdk/sdk-client/README.md) 通过 stdio JSON-RPC 驱动。它是 [`subagent-acp`](../subagent-acp/README.md) 之外的第二个进程外后端,差异在协议格式(wire format)和子进程契约:ACP(Agent Client Protocol)后端能驱动任何 Agent Client Protocol agent(智能体);本后端专门驱动 harness SDK 运行时(`dsh-jsonrpc-agent` bin 或打包后的可执行文件),因此子进程是一个完整的对等 harness,拥有由 `cordis.yml` 决定的组合、会话持久化、模型路由和工具。 +SDK 提供方会在全新的子进程中把每个 subagent 作为完整的 DeepSeek Harness 运行时运行,并经由 [TypeScript SDK 客户端](../../scaffold/client/README.md) 通过 stdio JSON-RPC 驱动。它是 [`subagent-acp`](../subagent-acp/README.md) 之外的第二个进程外后端,差异在协议格式(wire format)和子进程契约:ACP(Agent Client Protocol)后端能驱动任何 Agent Client Protocol agent(智能体);本后端专门驱动 harness SDK 运行时(`dsh-jsonrpc-agent` bin 或打包后的可执行文件),因此子进程是一个完整的对等 harness,拥有由 `cordis.yml` 决定的组合、会话持久化、模型路由和工具。 ## 启动与所有权 diff --git a/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts b/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts index 5603e0e9a0..e42a76c90c 100644 --- a/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts +++ b/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts @@ -24,7 +24,7 @@ import { type SdkRunSpec, } from '../src/run.ts' -const fakeRuntime = fileURLToPath(new URL('../../../sdk/sdk-client/tests/fake-runtime.ts', import.meta.url)) +const fakeRuntime = fileURLToPath(new URL('../../../scaffold/client/tests/fake-runtime.ts', import.meta.url)) /** A parent Agent stub. The SDK backend reads exactly one thing off it: the session header's cwd (the workspace its child inherits). */ const fakeParent = { id: 'parent', session: { header: { cwd: process.cwd() } } } as unknown as Agent diff --git a/packages/subagent/subagent-dsh-sdk/tsconfig.json b/packages/subagent/subagent-dsh-sdk/tsconfig.json index 79ff03f1a4..2b9aa29e21 100644 --- a/packages/subagent/subagent-dsh-sdk/tsconfig.json +++ b/packages/subagent/subagent-dsh-sdk/tsconfig.json @@ -27,10 +27,10 @@ "path": "../../core/session" }, { - "path": "../../sdk/sdk-client" + "path": "../../scaffold/client" }, { - "path": "../../sdk/sdk-protocol" + "path": "../../scaffold/protocol" }, { "path": "../subagent" diff --git a/packages/subagent/subagent-inprocess/tsconfig.json b/packages/subagent/subagent-inprocess/tsconfig.json index 22c00b3a94..23406e362e 100644 --- a/packages/subagent/subagent-inprocess/tsconfig.json +++ b/packages/subagent/subagent-inprocess/tsconfig.json @@ -39,7 +39,7 @@ "path": "../../support/invariants" }, { - "path": "../../ui/user-approval" + "path": "../../interaction/user-approval" } ] } diff --git a/packages/typert/generator/tests/type-model.spec.ts b/packages/typert/generator/tests/type-model.spec.ts index 40a91e3ef5..e1b5d99de9 100644 --- a/packages/typert/generator/tests/type-model.spec.ts +++ b/packages/typert/generator/tests/type-model.spec.ts @@ -419,7 +419,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => { it('rejects relative imports across face boundaries', () => { const root = copyFixture('typert-relative-face-') - const sourcePath = join(root, 'packages/client/src/index.ts') + const sourcePath = join(root, 'packages/client', 'src/index.ts') const source = readFileSync(sourcePath, 'utf8') .replace("from '@fixture/host'", "from '../../host/src/index.ts'") writeFileSync(sourcePath, source) @@ -435,7 +435,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => { join(root, 'packages/host/src/private.ts'), 'export interface PrivateHost { readonly value: string }\n', ) - const sourcePath = join(root, 'packages/client/src/index.ts') + const sourcePath = join(root, 'packages/client', 'src/index.ts') const source = readFileSync(sourcePath, 'utf8') .replace( "import type { HostAgent, Payload } from '@fixture/host'", @@ -458,7 +458,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => { join(root, 'packages/host/src/private.ts'), 'export interface PrivateHost { readonly value: string }\n', ) - const sourcePath = join(root, 'packages/client/src/index.ts') + const sourcePath = join(root, 'packages/client', 'src/index.ts') writeFileSync(sourcePath, [ readFileSync(sourcePath, 'utf8'), "export type { PrivateHost } from '@fixture/host/private'", @@ -472,7 +472,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => { it('rejects cross-face namespace re-exports until the model has a namespace target', () => { const root = copyFixture('typert-namespace-reexport-') - const sourcePath = join(root, 'packages/client/src/index.ts') + const sourcePath = join(root, 'packages/client', 'src/index.ts') writeFileSync(sourcePath, [ readFileSync(sourcePath, 'utf8'), "export type * as HostNamespace from '@fixture/host'", @@ -487,10 +487,10 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => { it('ignores cross-face namespace exports that are not package exports', () => { const root = copyFixture('typert-private-namespace-reexport-') writeFileSync( - join(root, 'packages/client/src/internal.ts'), + join(root, 'packages/client', 'src/internal.ts'), "export type * as HiddenHostNamespace from '@fixture/host'\n", ) - const sourcePath = join(root, 'packages/client/src/index.ts') + const sourcePath = join(root, 'packages/client', 'src/index.ts') writeFileSync(sourcePath, [ "import './internal.ts'", readFileSync(sourcePath, 'utf8'), @@ -503,7 +503,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => { it('records public symbols from explicit cross-face star re-exports', () => { const root = copyFixture('typert-star-reexport-') - const sourcePath = join(root, 'packages/client/src/index.ts') + const sourcePath = join(root, 'packages/client', 'src/index.ts') writeFileSync( sourcePath, readFileSync(sourcePath, 'utf8') @@ -1138,7 +1138,7 @@ describe('WorkspaceTypertGenerator', { timeout: 60_000 }, () => { it('rejects a public Typert subpath that points outside the root-level face artifact', () => { const root = copyFixture('typert-artifact-path-') - const manifestPath = join(root, 'packages/client/package.json') + const manifestPath = join(root, 'packages/client', 'package.json') const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as { exports: Record } @@ -1154,7 +1154,7 @@ describe('WorkspaceTypertGenerator', { timeout: 60_000 }, () => { it('rejects absent Typert exports and package file entries', () => { const noSubpathRoot = copyFixture('typert-missing-artifact-export-') - const noSubpathManifest = join(noSubpathRoot, 'packages/client/package.json') + const noSubpathManifest = join(noSubpathRoot, 'packages/client', 'package.json') const noSubpath = JSON.parse(readFileSync(noSubpathManifest, 'utf8')) as Record noSubpath.exports = './lib/index.js' writeFileSync(noSubpathManifest, `${JSON.stringify(noSubpath, null, 2)}\n`) @@ -1163,7 +1163,7 @@ describe('WorkspaceTypertGenerator', { timeout: 60_000 }, () => { ) const invalidSubpathRoot = copyFixture('typert-invalid-artifact-export-') - const invalidSubpathManifest = join(invalidSubpathRoot, 'packages/client/package.json') + const invalidSubpathManifest = join(invalidSubpathRoot, 'packages/client', 'package.json') const invalidSubpath = JSON.parse(readFileSync(invalidSubpathManifest, 'utf8')) as { exports: Record } @@ -1174,7 +1174,7 @@ describe('WorkspaceTypertGenerator', { timeout: 60_000 }, () => { ) const noFilesRoot = copyFixture('typert-missing-artifact-files-') - const noFilesManifest = join(noFilesRoot, 'packages/client/package.json') + const noFilesManifest = join(noFilesRoot, 'packages/client', 'package.json') const noFiles = JSON.parse(readFileSync(noFilesManifest, 'utf8')) as Record delete noFiles.files writeFileSync(noFilesManifest, `${JSON.stringify(noFiles, null, 2)}\n`) diff --git a/packages/ui/jsonrpc/README.i18n.yaml b/packages/ui/jsonrpc/README.i18n.yaml deleted file mode 100644 index d81f54f405..0000000000 --- a/packages/ui/jsonrpc/README.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/ui/jsonrpc/README.md -README.md: 9cd4876b52f9527745b27041eb2555408c73fabd -README.zh.md: a2b979da448c04c0578382889be2ae3ea6076166 diff --git a/packages/ui/permission/README.i18n.yaml b/packages/ui/permission/README.i18n.yaml deleted file mode 100644 index cb48934488..0000000000 --- a/packages/ui/permission/README.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/ui/permission/README.md -README.md: 4f7f560bb81eaad3b6b95b2742432fa252682d5a -README.zh.md: d45f89e243ce2d8f6bb08943fb7e776ced106b5a diff --git a/packages/ui/user-interaction/README.i18n.yaml b/packages/ui/user-interaction/README.i18n.yaml deleted file mode 100644 index 1da849ed9b..0000000000 --- a/packages/ui/user-interaction/README.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/ui/user-interaction/README.md -README.md: cba015e782623b3a5adf018303823577a0b96774 -README.zh.md: a5f944850c5ac4e05da59e8478167eef91796610 diff --git a/scripts/gen-cordis-catalog.ts b/scripts/gen-cordis-catalog.ts index 2c347613e8..08019b567e 100644 --- a/scripts/gen-cordis-catalog.ts +++ b/scripts/gen-cordis-catalog.ts @@ -275,7 +275,7 @@ export const TYPE_LINK_EXEMPTIONS: Readonly> = { ProjectionChangeListener: 'change-feed listener contract is owned by packages/session/session-projection/src/index.ts', ProjectionSnapshot: 'watermark snapshot shape is owned by packages/session/session-projection/src/index.ts', ProjectionCheckpoint: 'persisted checkpoint row map is owned by packages/session/session-projection/src/index.ts', - CommandExecution: 'executor return contract is owned by packages/ui/commands/src/index.ts', + CommandExecution: 'executor return contract is owned by packages/interaction/commands/src/index.ts', TypertContribution: 'registry contribution contract is owned by packages/typert/registry/README.md', TypertFace: 'registry face identity is owned by packages/typert/registry/README.md', TypertPackageFilter: 'registry package query filter is owned by packages/typert/registry/README.md', @@ -295,10 +295,10 @@ export const TYPE_LINK_EXEMPTIONS: Readonly> = { Translate: 'service-local bound translator is owned by packages/client/i18n/src/index.ts', InvariantRegistration: 'service-local lifecycle handle is owned by packages/support/invariants/README.md', InvokeRemoteRequest: 'gateway invocation contract is owned by packages/api/gateway/README.md', - PresetOption: 'deployment menu metadata is owned by packages/ui/permission/README.md', - PresetSpec: 'deployment preset composition is owned by packages/ui/permission/README.md', - KnobState: 'projection unit state shape is owned by packages/ui/permission/README.md', - PermissionSelect: 'permissions projection payload is owned by packages/ui/permission/src/types.ts', + PresetOption: 'deployment menu metadata is owned by packages/interaction/permission/README.md', + PresetSpec: 'deployment preset composition is owned by packages/interaction/permission/README.md', + KnobState: 'projection unit state shape is owned by packages/interaction/permission/README.md', + PermissionSelect: 'permissions projection payload is owned by packages/interaction/permission/src/types.ts', PromptAssembly: 'assembly result is owned by packages/core/system-prompt/README.md', ResumeAgentOptions: 'agent resume contract is owned by packages/core/agent/README.md', Sandbox: 'external E2B SDK handle is owned by packages/e2b/e2b/README.md', diff --git a/scripts/gen-third-party-notices.spec.ts b/scripts/gen-third-party-notices.spec.ts index 8299114ff5..c9b1f41dbf 100644 --- a/scripts/gen-third-party-notices.spec.ts +++ b/scripts/gen-third-party-notices.spec.ts @@ -70,7 +70,7 @@ describe('tierExternalDeps', () => { it('keeps a package runtime when any shipping area declares it, and excludes workspace links', () => { const { manifests, names } = workspace({ 'package.json': { devDependencies: { shared: '^1' } }, - 'packages/ui/tui/package.json': { name: '@deepseek-ai/dsh-tui', dependencies: { shared: '^1', '@deepseek-ai/dsh-cli': 'workspace:^' } }, + 'packages/interaction/tui/package.json': { name: '@deepseek-ai/dsh-tui', dependencies: { shared: '^1', '@deepseek-ai/dsh-cli': 'workspace:^' } }, 'apps/cli/package.json': { name: '@deepseek-ai/dsh-cli' }, }) diff --git a/scripts/gen-tool-catalog.ts b/scripts/gen-tool-catalog.ts index b59aafe5f0..06475808e1 100644 --- a/scripts/gen-tool-catalog.ts +++ b/scripts/gen-tool-catalog.ts @@ -154,7 +154,7 @@ const TOOL_PACKAGES: ToolPackage[] = [ { pkg: '@deepseek-ai/dsh-tool-ask-user', dir: 'tool-ask-user', - source: 'packages/ui/tool-ask-user/src/index.ts', + source: 'packages/interaction/tool-ask-user/src/index.ts', requires: ['ctx.tools', 'ctx.userInteraction'], writes: ['tool/call', 'tool/result after a UI/provider answers the question'], async mount(ctx) { diff --git a/scripts/run-gates.ts b/scripts/run-gates.ts index 258b70f87d..d99889d28b 100644 --- a/scripts/run-gates.ts +++ b/scripts/run-gates.ts @@ -619,7 +619,7 @@ function builtBinSmokeGate(needs: string[] = ['build']): Gate { 'apps/cli/tests/built-bin.e2e.ts', 'packages/examples/acp-demo/tests/built-bin.e2e.ts', 'packages/host/directory-picker-native/tests/built-worker.e2e.ts', - 'packages/ui/jsonrpc/tests/built-scope-carrier.e2e.ts', + 'packages/scaffold/server/tests/built-scope-carrier.e2e.ts', 'packages/subagent/subagent-codex/tests/loader-composition.e2e.ts', 'packages/subagent/subagent-claude-code/tests/loader-composition.e2e.ts', 'packages/api/remotes/tests/built-lib.e2e.ts', diff --git a/scripts/type-equiv.manifest.json b/scripts/type-equiv.manifest.json index e4eaf15398..903172e48f 100644 --- a/scripts/type-equiv.manifest.json +++ b/scripts/type-equiv.manifest.json @@ -234,32 +234,32 @@ { "doc": "docs/core-data-structures/commands.md", "symbol": "CommandInputDescriptor", - "source": "packages/ui/commands/src/index.ts" + "source": "packages/interaction/commands/src/index.ts" }, { "doc": "docs/core-data-structures/commands.md", "symbol": "CommandDefinition", - "source": "packages/ui/commands/src/index.ts" + "source": "packages/interaction/commands/src/index.ts" }, { "doc": "docs/core-data-structures/commands.md", "symbol": "CommandInvocation", - "source": "packages/ui/commands/src/index.ts" + "source": "packages/interaction/commands/src/index.ts" }, { "doc": "docs/core-data-structures/commands.md", "symbol": "CommandResult", - "source": "packages/ui/commands/src/index.ts" + "source": "packages/interaction/commands/src/index.ts" }, { "doc": "docs/core-data-structures/commands.md", "symbol": "CommandDescriptor", - "source": "packages/ui/commands/src/index.ts" + "source": "packages/interaction/commands/src/index.ts" }, { "doc": "docs/core-data-structures/commands.md", "symbol": "ParsedCommand", - "source": "packages/ui/commands/src/index.ts" + "source": "packages/interaction/commands/src/index.ts" }, { "doc": "docs/core-data-structures/system-prompt.md", @@ -733,62 +733,62 @@ { "doc": "docs/core-data-structures/user-interaction.md", "symbol": "AskUserQuestionOption", - "source": "packages/ui/user-interaction/src/types.ts" + "source": "packages/interaction/user-interaction/src/types.ts" }, { "doc": "docs/core-data-structures/user-interaction.md", "symbol": "AskUserQuestionIntent", - "source": "packages/ui/user-interaction/src/types.ts" + "source": "packages/interaction/user-interaction/src/types.ts" }, { "doc": "docs/core-data-structures/user-interaction.md", "symbol": "AskUserQuestionItem", - "source": "packages/ui/user-interaction/src/types.ts" + "source": "packages/interaction/user-interaction/src/types.ts" }, { "doc": "docs/core-data-structures/user-interaction.md", "symbol": "AskUserQuestionRequest", - "source": "packages/ui/user-interaction/src/index.ts" + "source": "packages/interaction/user-interaction/src/index.ts" }, { "doc": "docs/core-data-structures/user-interaction.md", "symbol": "AskUserQuestionAnswerItem", - "source": "packages/ui/user-interaction/src/types.ts" + "source": "packages/interaction/user-interaction/src/types.ts" }, { "doc": "docs/core-data-structures/user-interaction.md", "symbol": "AskUserQuestionAnswer", - "source": "packages/ui/user-interaction/src/types.ts" + "source": "packages/interaction/user-interaction/src/types.ts" }, { "doc": "docs/core-data-structures/user-interaction.md", "symbol": "UserInteractionProvider", - "source": "packages/ui/user-interaction/src/index.ts" + "source": "packages/interaction/user-interaction/src/index.ts" }, { "doc": "docs/core-data-structures/user-interaction.md", "symbol": "UserInteractionError", - "source": "packages/ui/user-interaction/src/index.ts" + "source": "packages/interaction/user-interaction/src/index.ts" }, { "doc": "docs/core-data-structures/approval.md", "symbol": "ApprovalRequestId", - "source": "packages/ui/user-approval/src/types.ts" + "source": "packages/interaction/user-approval/src/types.ts" }, { "doc": "docs/core-data-structures/approval.md", "symbol": "ApprovalOutcome", - "source": "packages/ui/user-approval/src/types.ts" + "source": "packages/interaction/user-approval/src/types.ts" }, { "doc": "docs/core-data-structures/approval.md", "symbol": "ApprovalPolicy", - "source": "packages/ui/user-approval/src/index.ts" + "source": "packages/interaction/user-approval/src/index.ts" }, { "doc": "docs/core-data-structures/approval.md", "symbol": "ApprovalRequest", - "source": "packages/ui/user-approval/src/index.ts" + "source": "packages/interaction/user-approval/src/index.ts" }, { "doc": "docs/core-data-structures/bash.md", diff --git a/scripts/verify-package-readme-model-experience.ts b/scripts/verify-package-readme-model-experience.ts index 5930d39e26..a0eec4960f 100644 --- a/scripts/verify-package-readme-model-experience.ts +++ b/scripts/verify-package-readme-model-experience.ts @@ -103,12 +103,12 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly> = { 'packages/e2b/subprocess-e2b': { kind: 'indirect', reason: 'The remote spawn backend delegates model rendering to consumer seams such as the bash executor family.' }, 'packages/subprocess/subprocess-local': { kind: 'indirect', reason: 'The spawn backend delegates model rendering to consumer seams such as the bash executor family.' }, 'packages/sandbox/sandbox-local': { kind: 'indirect', reason: 'The provider backend delegates model rendering to dsh-bash-sandbox and dsh-tool-bash.' }, - 'packages/sdk/create-sdk': { kind: 'indirect', reason: 'The initializer only writes project files; selected runtime plugins provide the generated project model surface.' }, - 'packages/sdk/helper': { kind: 'none', reason: 'The project domain edits files and registers no live agent or model surface.' }, - 'packages/sdk/scripts': { kind: 'indirect', reason: 'The launcher delegates model context to the loaded project plugin tree.' }, - 'packages/sdk/sdk-client': { kind: 'none', reason: 'Client-process library; the model surface lives in the spawned runtime\'s composed plugins.' }, - 'packages/sdk/sdk-protocol': { kind: 'none', reason: 'Client-facing wire library; the runtime plugins behind the serving entry own the model surface.' }, - 'packages/sdk/telemetry': { kind: 'none', reason: 'The launcher-side reporter sends developer-cycle telemetry and registers no live agent or model surface.' }, + 'packages/scaffold/create-sdk': { kind: 'indirect', reason: 'The initializer only writes project files; selected runtime plugins provide the generated project model surface.' }, + 'packages/scaffold/helper': { kind: 'none', reason: 'The project domain edits files and registers no live agent or model surface.' }, + 'packages/scaffold/scripts': { kind: 'indirect', reason: 'The launcher delegates model context to the loaded project plugin tree.' }, + 'packages/scaffold/client': { kind: 'none', reason: 'Client-process library; the model surface lives in the spawned runtime\'s composed plugins.' }, + 'packages/scaffold/protocol': { kind: 'none', reason: 'Client-facing wire library; the runtime plugins behind the serving entry own the model surface.' }, + 'packages/scaffold/telemetry': { kind: 'none', reason: 'The launcher-side reporter sends developer-cycle telemetry and registers no live agent or model surface.' }, 'packages/session/session-projection': { kind: 'none', reason: 'The projection registry serves client-facing read models of already-logged session state and registers no model surface.' }, 'packages/session/session-projection-cache': { kind: 'none', reason: 'The persisted cache accelerates host-side cold reads of projection state and registers no model surface.' }, 'packages/session-query/session-query': { kind: 'none', reason: 'The trusted query service exposes cloned records only to callers and registers no model surface.' }, @@ -138,10 +138,10 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly> = { 'packages/tasks/tasks': { kind: 'indirect', reason: 'Producer and control-surface plugins own all model rendering over the task registry.' }, 'packages/tasks/tasks-local': { kind: 'indirect', reason: 'The registry backend delegates model rendering to producer plugins and dsh-tool-tasks.' }, 'packages/examples/acp-demo': { kind: 'indirect', reason: 'The app bundle delegates request composition to dsh-agent-spine-demo and dsh-acp.' }, - 'packages/ui/app-boot': { kind: 'indirect', reason: 'Only the loaded plugin tree contributes model context.' }, + 'packages/boot/app-boot': { kind: 'indirect', reason: 'Only the loaded plugin tree contributes model context.' }, 'packages/examples/jsonrpc-demo': { kind: 'indirect', reason: 'Only the externally configured plugin tree contributes model context.' }, - 'packages/ui/permission': { kind: 'indirect', reason: 'The service writes mechanism events rendered by dsh-user-approval and dsh-tool-bash.' }, - 'packages/ui/user-interaction': { kind: 'indirect', reason: 'Model-facing consumers render provider answers and seam errors.' }, + 'packages/interaction/permission': { kind: 'indirect', reason: 'The service writes mechanism events rendered by dsh-user-approval and dsh-tool-bash.' }, + 'packages/interaction/user-interaction': { kind: 'indirect', reason: 'Model-facing consumers render provider answers and seam errors.' }, 'packages/util/timeout': { kind: 'indirect', reason: 'Only timeout consumers render timeout outcomes.' }, 'packages/util/retention': { kind: 'indirect', reason: 'Only retention consumers render retained content and omission metadata.' }, 'packages/util/native-command': { kind: 'none', reason: 'The host-side subprocess runner registers no model surface.' }, diff --git a/tsconfig.base.json b/tsconfig.base.json index e09ab93743..b748020e11 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -70,12 +70,13 @@ "@deepseek-ai/dsh-llm/brand": ["./packages/llm/llm/src/brand.ts"], "@deepseek-ai/dsh-llm-retry/types": ["./packages/llm/llm-retry/src/types.ts"], "@deepseek-ai/dsh-llm/message": ["./packages/llm/llm/src/message.ts"], - "@deepseek-ai/dsh-commands/brand": ["./packages/ui/commands/src/brand.ts"], + "@deepseek-ai/dsh-commands/brand": ["./packages/interaction/commands/src/brand.ts"], "@deepseek-ai/dsh-compact/checkpoint": ["./packages/compact/compact/src/checkpoint.ts"], "@deepseek-ai/dsh-tools/presentation": ["./packages/core/tools/src/presentation.ts"], "@deepseek-ai/dsh-tool-subagent-control/list-agents": ["./packages/subagent/tool-subagent-control/src/list-agents.ts"], - "@deepseek-ai/dsh-user-approval/types": ["./packages/ui/user-approval/src/types.ts"], - "@deepseek-ai/dsh-user-interaction/types": ["./packages/ui/user-interaction/src/types.ts"], + "@deepseek-ai/dsh-user-approval/types": ["./packages/interaction/user-approval/src/types.ts"], + "@deepseek-ai/dsh-user-interaction/types": ["./packages/interaction/user-interaction/src/types.ts"], + "@deepseek-ai/dsh-agent/brand": ["./packages/core/agent/src/brand.ts"], "@deepseek-ai/dsh-agent/invariant": ["./packages/core/agent/src/invariant.ts"], "@deepseek-ai/dsh-scope/invariant": ["./packages/core/scope/src/invariant.ts"], "@deepseek-ai/dsh-agent-loop/invariant": ["./packages/core/agent-loop/src/invariant.ts"], @@ -113,8 +114,9 @@ "./packages/acp/*/src/invariant.ts", "./packages/storage/*/src/invariant.ts", "./packages/workspace/*/src/invariant.ts", - "./packages/sdk/*/src/invariant.ts", - "./packages/ui/*/src/invariant.ts", + "./packages/scaffold/*/src/invariant.ts", + "./packages/interaction/*/src/invariant.ts", + "./packages/boot/*/src/invariant.ts", "./packages/examples/*/src/invariant.ts", "./packages/util/*/src/invariant.ts", "./packages/mcp/*/src/invariant.ts", @@ -179,6 +181,12 @@ "@deepseek-ai/dsh-client-ui-models": ["./packages/client/ui-models/src"], "@deepseek-ai/dsh-client-locale": ["./packages/client/locale/src"], "@deepseek-ai/dsh-client-web": ["./packages/client/web/src"], + // scaffold/ folders are role-named without the sdk- prefix (folder ≠ npm + // suffix), so the generic wildcard cannot map these three; the npm-side + // renames that restore symmetry are FIXME-tracked in the regrouping note. + "@deepseek-ai/dsh-sdk-client": ["./packages/scaffold/client/src"], + "@deepseek-ai/dsh-sdk-protocol": ["./packages/scaffold/protocol/src"], + "@deepseek-ai/dsh-jsonrpc": ["./packages/scaffold/server/src"], "@deepseek-ai/dsh-*": [ "./packages/core/*/src", "./packages/prompt/*/src", @@ -215,8 +223,9 @@ "./packages/acp/*/src", "./packages/storage/*/src", "./packages/workspace/*/src", - "./packages/sdk/*/src", - "./packages/ui/*/src", + "./packages/scaffold/*/src", + "./packages/interaction/*/src", + "./packages/boot/*/src", "./packages/examples/*/src", "./packages/util/*/src", "./packages/mcp/*/src", diff --git a/tsconfig.host.json b/tsconfig.host.json index 0f44c4b7de..c1cc0705cf 100644 --- a/tsconfig.host.json +++ b/tsconfig.host.json @@ -138,7 +138,7 @@ { "path": "./packages/session/session-telemetry-otel" }, { "path": "./packages/core/system-prompt" }, { "path": "./packages/core/agent" }, - { "path": "./packages/ui/commands" }, + { "path": "./packages/interaction/commands" }, { "path": "./packages/goal/goal" }, { "path": "./packages/goal/tool-goal" }, { "path": "./packages/goal/goal-session" }, @@ -147,15 +147,15 @@ { "path": "./packages/context/time-context" }, { "path": "./packages/context/tmux-context" }, { "path": "./packages/context/session-reference" }, - { "path": "./packages/ui/user-interaction" }, - { "path": "./packages/ui/user-approval" }, - { "path": "./packages/ui/permission" }, + { "path": "./packages/interaction/user-interaction" }, + { "path": "./packages/interaction/user-approval" }, + { "path": "./packages/interaction/permission" }, { "path": "./packages/core/tools" }, { "path": "./packages/skill/skill" }, { "path": "./packages/skill/skill-badge" }, { "path": "./packages/skill/skill-local" }, { "path": "./packages/skill/tool-skill" }, - { "path": "./packages/ui/tool-ask-user" }, + { "path": "./packages/interaction/tool-ask-user" }, { "path": "./packages/context/workspace-context" }, { "path": "./packages/core/agent-loop" }, { "path": "./packages/llm/llm-retry" }, @@ -212,8 +212,8 @@ { "path": "./packages/bundle/base" }, { "path": "./packages/bundle/headless" }, { "path": "./packages/bundle/web-app" }, - { "path": "./packages/ui/app-boot" }, - { "path": "./packages/ui/jsonrpc" }, + { "path": "./packages/boot/app-boot" }, + { "path": "./packages/scaffold/server" }, { "path": "./packages/examples/jsonrpc-demo" }, { "path": "./packages/support/llm-replay" }, { "path": "./packages/typert/generator" }, @@ -259,12 +259,12 @@ { "path": "./packages/host/directory-picker-native" }, { "path": "./packages/host/frontend-static" }, { "path": "./packages/host/webserver" }, - { "path": "./packages/sdk/sdk-client" }, - { "path": "./packages/sdk/helper" }, - { "path": "./packages/sdk/sdk-protocol" }, - { "path": "./packages/sdk/scripts" }, - { "path": "./packages/sdk/create-sdk" }, - { "path": "./packages/sdk/telemetry" }, + { "path": "./packages/scaffold/client" }, + { "path": "./packages/scaffold/helper" }, + { "path": "./packages/scaffold/protocol" }, + { "path": "./packages/scaffold/scripts" }, + { "path": "./packages/scaffold/create-sdk" }, + { "path": "./packages/scaffold/telemetry" }, { "path": "./packages/lsp/lsp" }, { "path": "./packages/lsp/lsp-local" }, { "path": "./packages/lsp/tool-lsp" }, diff --git a/vendor/README.md b/vendor/README.md index 4bf1d43f46..02e33ea723 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -37,11 +37,11 @@ Keep this log exhaustive — every divergence from upstream must be listed. 5. **`schemastery/tsdown.config.ts` and `logger-console/tsdown.config.ts`**: ours, not upstream files — per-package build-shape overrides (dual ESM+CJS output; separate node/browser entries) for the repo-root tsdown build. They read the JS emitted under `lib/types` and then write the publish runtime entries under `lib/`. Like the regenerated tsconfigs, they are not part of the upstream sync surface. 6. **`cordis/src/fiber.ts` lifecycle hardening**: locally closes three reentrant disposal gaps. An effect's owner-list wrapper is registered before its setup body runs, so an unload begun from inside setup awaits setup and every collected cleanup; synchronous setup failure removes the wrapper and rolls back collected cleanup. Async cleanup stays owner-visible until quiescence, and Cordis's internal effect composition joins an already-running cleanup while repeated public disposer calls retain their upstream single-shot result. Effect creation is rejected while the owner is `UNLOADING` (while `PENDING` and `LOADING` remain legal), preventing cleanup-time registrations from escaping the unload snapshot. Child fibers register and receive their parent-owned disposer before `internal/plugin` publication, resolve dependency declarations added by that notification before activation, drain effects attached while pending, skip plugin execution when reentrant disposal invalidates the load epoch before its first checkpoint, and contain teardown-notification failures per observer so one callback cannot starve peers or interrupt ownership cleanup. `Fiber.update()` returns its `internal/update` waterfall result, allowing Loader callers to await a restart while preserving synchronous config validation. 7. **`cordis/src/*.ts` JSDoc enrichment**: added `@param`/`@returns` tags and contract documentation (disposal semantics, waterfall veto, bail conditions, error cases) across the public plugin-author surface — `Context` (class, statics, and the `Context` interface properties incl. `root`), `EventsService`, `Fiber`, `RegistryService`, `ReflectService`, `Service`, `LoggerService` and their `declare module './context.ts'` overloads. Comment-only; no code changes. Motivation: the website API-reference generator renders these docs and hard-errors on undocumented members. Retire this entry when the enrichment is upstreamed to the fork. -8. **Transactional Loader/Include config reconciliation**: Loader imports a changed entry name before disposal, awaits lifecycle settlement, and restores the previous plugin or config when candidate application fails. Loader settlement rechecks service-gated fibers after current tasks drain, rejects failures, and leaves fibers with absent dependencies pending. Group updates start candidates concurrently, await every outcome, undo changes and additions on failure, await removal, preserve programmatic option identity, and persist direct or tree-level mutations only after success. Include reads and validates detached candidate content, applies patches to a clone, reconciles the tree, and only then commits its cached content/data; direct refresh failures propagate for the caller to contain. A non-array parse is invalid, patches re-apply on every file or Include-config update, an omitted patch list clears the overlay, and initial content falls back to `initial` only on `ENOENT`. Covered by `packages/ui/app-boot/tests/config-reload.spec.ts` and `packages/host/webserver/tests/webserver.spec.ts`. -9. **`hmr/src/index.ts` exact config watching**: `registerConfig()` watches one absolute config path outside module roots, including a path under missing parents, serializes and coalesces refreshes, and returns an async disposer that closes the watcher and drains active work. Refresh failures are normalized to `Error`, logged, and broadcast through the parallel `hmr/config-update-failed` event; observer failures are contained. Config-file changes discovered by the ordinary HMR watcher use the same serialized path. Covered by `packages/ui/app-boot/tests/hmr-config.spec.ts`. -10. **`loader/src/repository.ts`, `loader/tsdown.config.ts`, and the `@cordisjs/plugin-loader/repository` export**: the Node-only `RepositoryCache` installs one exact dependency specifier through the bundled `pnpm@11.7.0`, single-flights callers, and atomically publishes only a prepared package plus marker under the specifier hash. The subpath stays out of the browser-reachable Loader entry. Identical specifiers permanently reuse that entry; callers change the ref/specifier for another generation. The isolated workspace permits dependency build scripts because a configured repository is executable code, while the child drops ambient credential-shaped variables. Covered by `packages/ui/app-boot/tests/repository-cache.spec.ts`, including a keyless local-Git prepare run through the bundled pnpm. +8. **Transactional Loader/Include config reconciliation**: Loader imports a changed entry name before disposal, awaits lifecycle settlement, and restores the previous plugin or config when candidate application fails. Loader settlement rechecks service-gated fibers after current tasks drain, rejects failures, and leaves fibers with absent dependencies pending. Group updates start candidates concurrently, await every outcome, undo changes and additions on failure, await removal, preserve programmatic option identity, and persist direct or tree-level mutations only after success. Include reads and validates detached candidate content, applies patches to a clone, reconciles the tree, and only then commits its cached content/data; direct refresh failures propagate for the caller to contain. A non-array parse is invalid, patches re-apply on every file or Include-config update, an omitted patch list clears the overlay, and initial content falls back to `initial` only on `ENOENT`. Covered by `packages/boot/app-boot/tests/config-reload.spec.ts` and `packages/host/webserver/tests/webserver.spec.ts`. +9. **`hmr/src/index.ts` exact config watching**: `registerConfig()` watches one absolute config path outside module roots, including a path under missing parents, serializes and coalesces refreshes, and returns an async disposer that closes the watcher and drains active work. Refresh failures are normalized to `Error`, logged, and broadcast through the parallel `hmr/config-update-failed` event; observer failures are contained. Config-file changes discovered by the ordinary HMR watcher use the same serialized path. Covered by `packages/boot/app-boot/tests/hmr-config.spec.ts`. +10. **`loader/src/repository.ts`, `loader/tsdown.config.ts`, and the `@cordisjs/plugin-loader/repository` export**: the Node-only `RepositoryCache` installs one exact dependency specifier through the bundled `pnpm@11.7.0`, single-flights callers, and atomically publishes only a prepared package plus marker under the specifier hash. The subpath stays out of the browser-reachable Loader entry. Identical specifiers permanently reuse that entry; callers change the ref/specifier for another generation. The isolated workspace permits dependency build scripts because a configured repository is executable code, while the child drops ambient credential-shaped variables. Covered by `packages/boot/app-boot/tests/repository-cache.spec.ts`, including a keyless local-Git prepare run through the bundled pnpm. 11. **Vendored Node-compatible TypeScript**: marked erased imports explicitly across `cordis`, `loader`, `include`, `hmr`, and `schemastery` so Node's native TypeScript transform does not request types as runtime exports. Schemastery's source uses an ESM default export and its package declares `type: module`; its built ESM/CJS entries retain explicit `.mjs`/`.cjs` extensions. -12. **`include/src/index.ts` patch-semantics export**: extracted the private `applyPatches` body into the exported pure function `applyEntryPatches(data, patches, warn)` (the method delegates to it) and exported the `!!js` YAML dialect as `entryListSchema`, so `dsh --dump-config` composes and prints exactly what the include would mount without booting a tree. Behavior-preserving for mounting; the extraction exists because config tooling must never reimplement (and drift from) the patch algorithm. `applyEntryPatches` also indexes each `insert`ed entry as it is added, so a later patch in the same list can configure or disable a row an earlier patch inserted; upstream built the id index once before the patch loop, leaving inserted rows silently unpatchable. That matters because `dsh` composes an empty profile root with each bundle's patch layer, the profile's and the home-level `cordis.patch.yml`, and any `--patch` overlays as sibling patch lists at one include level — patches never cross an include boundary, so surface-only rows would otherwise be unreachable from user config. Covered by `packages/ui/app-boot/tests/config-reload.spec.ts`. +12. **`include/src/index.ts` patch-semantics export**: extracted the private `applyPatches` body into the exported pure function `applyEntryPatches(data, patches, warn)` (the method delegates to it) and exported the `!!js` YAML dialect as `entryListSchema`, so `dsh --dump-config` composes and prints exactly what the include would mount without booting a tree. Behavior-preserving for mounting; the extraction exists because config tooling must never reimplement (and drift from) the patch algorithm. `applyEntryPatches` also indexes each `insert`ed entry as it is added, so a later patch in the same list can configure or disable a row an earlier patch inserted; upstream built the id index once before the patch loop, leaving inserted rows silently unpatchable. That matters because `dsh` composes an empty profile root with each bundle's patch layer, the profile's and the home-level `cordis.patch.yml`, and any `--patch` overlays as sibling patch lists at one include level — patches never cross an include boundary, so surface-only rows would otherwise be unreachable from user config. Covered by `packages/boot/app-boot/tests/config-reload.spec.ts`. 13. **`include/src/index.ts` serialized child-tree mutation and `hmr/src/index.ts` main-watcher initial-scan suppression**: every Include child-tree mutation (initial apply, refresh, `internal/update` patch re-application) runs through one per-Include queue, because the group's transactional `update` is not reentrant — two concurrent applies interleave create and rollback on the same entries and strand the Include fiber without ever settling. The HMR main watcher passes `ignoreInitial: true`: the initial scan re-announced files boot had just consumed, and its `add` for a config file refreshed an Include mid-initial-apply; once serialized, a failing initial apply's rollback disposed HMR, whose teardown drain waited on the queued refresh sitting behind that same apply — a deadlock that exited 13 with no diagnostic. `registerConfig()` keeps its own `ignoreInitial: false` watcher because a user patch layer present at registration must apply once. Covered by the patch-overlay boot-failure built-bin case in `apps/cli/tests/built-bin.e2e.ts`. 14. **`include/src/index.ts` `writeTask` type**: widened the optional `writeTask?: NodeJS.Timeout` property to `NodeJS.Timeout | undefined` — the debounced writer assigns `undefined` on flush, which `exactOptionalPropertyTypes` rejects on a plain optional. Type-only; no behavior change. diff --git a/vitest.config.ts b/vitest.config.ts index 29ad406e75..4456782519 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -32,8 +32,8 @@ const windowsUnsupportedPackages = process.platform === 'win32' 'packages/subprocess/*', 'packages/pty/pty-local', 'packages/sandbox/sandbox-local', - 'packages/sdk/create-sdk', - 'packages/sdk/helper', + 'packages/scaffold/create-sdk', + 'packages/scaffold/helper', ] : [] @@ -83,7 +83,7 @@ const processBoundTests = [ 'packages/subprocess/subprocess-local/tests/spawn.spec.ts', 'packages/context/time-context/tests/time-context.spec.ts', 'packages/llm/llm-pi-ai/tests/adapter.spec.ts', - 'packages/ui/app-boot/tests/app-boot.spec.ts', + 'packages/boot/app-boot/tests/app-boot.spec.ts', 'packages/workflow/workflow-workerthread/tests/session.spec.ts', ] @@ -222,8 +222,8 @@ export default defineConfig({ // Projection/command round: executor lifecycle branches and the // registry's drive tails need the same maturing lanes. TODO(gui): // cover and remove with the client test lane above. - 'packages/ui/commands/src/index.ts', - 'packages/ui/commands/src/invariant.ts', + 'packages/interaction/commands/src/index.ts', + 'packages/interaction/commands/src/invariant.ts', 'packages/session/session-projection/src/index.ts', ...windowsUnsupportedPackages.map(path => `${path}/src/**/*.ts`), ...windowsCoverageExclusions, diff --git a/vitest.snapshot.config.ts b/vitest.snapshot.config.ts index 049688a0ec..cf9cae0780 100644 --- a/vitest.snapshot.config.ts +++ b/vitest.snapshot.config.ts @@ -51,7 +51,7 @@ export default defineConfig({ ...(process.env.DSH_EXAMPLE_MODE === 'lib' ? ['apps/web/tests/**/*.snapshot.ts'] : []), 'apps/cli/tests/**/*.snapshot.ts', 'examples/*/tests/**/*.snapshot.ts', - 'packages/sdk/*/tests/**/*.snapshot.ts', + 'packages/scaffold/*/tests/**/*.snapshot.ts', ], // Replay never writes committed outputs and every scenario owns its // mutable runtime state (the subprocess suites use a unique temp dir and