dsh-plugin-guide 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE.md +26 -0
- package/README.es.md +139 -0
- package/README.hi.md +138 -0
- package/README.md +165 -0
- package/README.pt.md +139 -0
- package/README.zh-CN.md +164 -0
- package/SKILL.md +69 -0
- package/cordis.patch.yml +4 -0
- package/guide/links.md +92 -0
- package/guide/plugin-dev-guide.md +429 -0
- package/guide/quick-reference.es.md +176 -0
- package/guide/quick-reference.hi.md +176 -0
- package/guide/quick-reference.md +176 -0
- package/guide/quick-reference.pt.md +176 -0
- package/guide/quick-reference.zh-CN.md +175 -0
- package/index.js +58 -0
- package/package.json +83 -0
- package/references/community-ecosystem.md +201 -0
- package/references/community-repo-deep-dive.md +695 -0
- package/references/cordis-paper-and-community.md +326 -0
- package/references/harness-repo.md +654 -0
- package/references/official-docs/AGENTS.md +149 -0
- package/references/official-docs/BENCHMARK.md +3 -0
- package/references/official-docs/CLAUDE.md +1 -0
- package/references/official-docs/CONTRIBUTING.i18n.yaml +6 -0
- package/references/official-docs/CONTRIBUTING.md +23 -0
- package/references/official-docs/CONTRIBUTING.zh.md +23 -0
- package/references/official-docs/LICENSE +21 -0
- package/references/official-docs/README.i18n.yaml +6 -0
- package/references/official-docs/README.md +35 -0
- package/references/official-docs/README.zh.md +74 -0
- package/references/official-docs/SNAPSHOT.md +16 -0
- package/references/official-docs/THIRD_PARTY_NOTICES.md +192 -0
- package/references/official-docs/docs/AGENTS.md +75 -0
- package/references/official-docs/docs/agent-lifecycle.i18n.yaml +6 -0
- package/references/official-docs/docs/agent-lifecycle.md +82 -0
- package/references/official-docs/docs/agent-lifecycle.zh.md +84 -0
- package/references/official-docs/docs/api-gateway.i18n.yaml +6 -0
- package/references/official-docs/docs/api-gateway.md +164 -0
- package/references/official-docs/docs/api-gateway.zh.md +164 -0
- package/references/official-docs/docs/architecture.i18n.yaml +6 -0
- package/references/official-docs/docs/architecture.md +129 -0
- package/references/official-docs/docs/architecture.zh.md +133 -0
- package/references/official-docs/docs/capability-seams.i18n.yaml +6 -0
- package/references/official-docs/docs/capability-seams.md +471 -0
- package/references/official-docs/docs/capability-seams.zh.md +473 -0
- package/references/official-docs/docs/config-catalog.i18n.yaml +6 -0
- package/references/official-docs/docs/config-catalog.md +3151 -0
- package/references/official-docs/docs/config-catalog.zh.md +3152 -0
- package/references/official-docs/docs/cookbook/adding-a-conversation-node.i18n.yaml +6 -0
- package/references/official-docs/docs/cookbook/adding-a-conversation-node.md +233 -0
- package/references/official-docs/docs/cookbook/adding-a-conversation-node.zh.md +233 -0
- package/references/official-docs/docs/cookbook/adding-a-package.i18n.yaml +6 -0
- package/references/official-docs/docs/cookbook/adding-a-package.md +118 -0
- package/references/official-docs/docs/cookbook/adding-a-package.zh.md +118 -0
- package/references/official-docs/docs/cookbook/adding-a-tool.i18n.yaml +6 -0
- package/references/official-docs/docs/cookbook/adding-a-tool.md +94 -0
- package/references/official-docs/docs/cookbook/adding-a-tool.zh.md +96 -0
- package/references/official-docs/docs/cookbook/adding-a-vendored-package.i18n.yaml +6 -0
- package/references/official-docs/docs/cookbook/adding-a-vendored-package.md +59 -0
- package/references/official-docs/docs/cookbook/adding-a-vendored-package.zh.md +59 -0
- package/references/official-docs/docs/cookbook/adding-an-llm-adapter.i18n.yaml +6 -0
- package/references/official-docs/docs/cookbook/adding-an-llm-adapter.md +43 -0
- package/references/official-docs/docs/cookbook/adding-an-llm-adapter.zh.md +43 -0
- package/references/official-docs/docs/cookbook/extension-cookbook.i18n.yaml +6 -0
- package/references/official-docs/docs/cookbook/extension-cookbook.md +129 -0
- package/references/official-docs/docs/cookbook/extension-cookbook.zh.md +131 -0
- package/references/official-docs/docs/cookbook/maintaining-dsh-code-review.i18n.yaml +6 -0
- package/references/official-docs/docs/cookbook/maintaining-dsh-code-review.md +64 -0
- package/references/official-docs/docs/cookbook/maintaining-dsh-code-review.zh.md +64 -0
- package/references/official-docs/docs/cookbook/responding-to-pr-review-on-a-stack.i18n.yaml +6 -0
- package/references/official-docs/docs/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
- package/references/official-docs/docs/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
- package/references/official-docs/docs/cordis-api/context.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-api/context.md +364 -0
- package/references/official-docs/docs/cordis-api/context.zh.md +366 -0
- package/references/official-docs/docs/cordis-api/events.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-api/events.md +207 -0
- package/references/official-docs/docs/cordis-api/events.zh.md +209 -0
- package/references/official-docs/docs/cordis-api/fiber.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-api/fiber.md +375 -0
- package/references/official-docs/docs/cordis-api/fiber.zh.md +377 -0
- package/references/official-docs/docs/cordis-api/inherited.md +39 -0
- package/references/official-docs/docs/cordis-api/registry.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-api/registry.md +152 -0
- package/references/official-docs/docs/cordis-api/registry.zh.md +154 -0
- package/references/official-docs/docs/cordis-api/service.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-api/service.md +102 -0
- package/references/official-docs/docs/cordis-api/service.zh.md +104 -0
- package/references/official-docs/docs/cordis-primer.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-primer.md +44 -0
- package/references/official-docs/docs/cordis-primer.zh.md +50 -0
- package/references/official-docs/docs/cordis-tutorial/01-first-plugin.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-tutorial/01-first-plugin.md +95 -0
- package/references/official-docs/docs/cordis-tutorial/01-first-plugin.zh.md +95 -0
- package/references/official-docs/docs/cordis-tutorial/02-lifecycle-and-effects.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
- package/references/official-docs/docs/cordis-tutorial/02-lifecycle-and-effects.zh.md +98 -0
- package/references/official-docs/docs/cordis-tutorial/03-services.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-tutorial/03-services.md +98 -0
- package/references/official-docs/docs/cordis-tutorial/03-services.zh.md +98 -0
- package/references/official-docs/docs/cordis-tutorial/04-events.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-tutorial/04-events.md +144 -0
- package/references/official-docs/docs/cordis-tutorial/04-events.zh.md +144 -0
- package/references/official-docs/docs/cordis-tutorial/05-config.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-tutorial/05-config.md +84 -0
- package/references/official-docs/docs/cordis-tutorial/05-config.zh.md +84 -0
- package/references/official-docs/docs/cordis-tutorial/06-composition-and-hmr.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-tutorial/06-composition-and-hmr.md +113 -0
- package/references/official-docs/docs/cordis-tutorial/06-composition-and-hmr.zh.md +113 -0
- package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.md +107 -0
- package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.zh.md +107 -0
- package/references/official-docs/docs/cordis-tutorial/index.i18n.yaml +6 -0
- package/references/official-docs/docs/cordis-tutorial/index.md +60 -0
- package/references/official-docs/docs/cordis-tutorial/index.zh.md +62 -0
- package/references/official-docs/docs/defensive-patterns.i18n.yaml +6 -0
- package/references/official-docs/docs/defensive-patterns.md +33 -0
- package/references/official-docs/docs/defensive-patterns.zh.md +33 -0
- package/references/official-docs/docs/development.i18n.yaml +6 -0
- package/references/official-docs/docs/development.md +171 -0
- package/references/official-docs/docs/development.zh.md +171 -0
- package/references/official-docs/docs/event-producer-consumer.i18n.yaml +6 -0
- package/references/official-docs/docs/event-producer-consumer.md +76 -0
- package/references/official-docs/docs/event-producer-consumer.zh.md +78 -0
- package/references/official-docs/docs/glossary.i18n.yaml +6 -0
- package/references/official-docs/docs/glossary.md +45 -0
- package/references/official-docs/docs/glossary.zh.md +45 -0
- package/references/official-docs/docs/graph-atlas.i18n.yaml +6 -0
- package/references/official-docs/docs/graph-atlas.md +24 -0
- package/references/official-docs/docs/graph-atlas.zh.md +26 -0
- package/references/official-docs/docs/i18n/README.i18n.yaml +6 -0
- package/references/official-docs/docs/i18n/README.md +60 -0
- package/references/official-docs/docs/i18n/README.zh.md +60 -0
- package/references/official-docs/docs/i18n/style-samples.md +87 -0
- package/references/official-docs/docs/i18n/terminology.md +214 -0
- package/references/official-docs/docs/i18n/translation-prompt.md +263 -0
- package/references/official-docs/docs/i18n/translation-rules.i18n.yaml +6 -0
- package/references/official-docs/docs/i18n/translation-rules.md +69 -0
- package/references/official-docs/docs/i18n/translation-rules.zh.md +69 -0
- package/references/official-docs/docs/module-graph.i18n.yaml +6 -0
- package/references/official-docs/docs/module-graph.md +1638 -0
- package/references/official-docs/docs/module-graph.zh.md +1640 -0
- package/references/official-docs/docs/persistence-catalog.i18n.yaml +6 -0
- package/references/official-docs/docs/persistence-catalog.md +944 -0
- package/references/official-docs/docs/persistence-catalog.zh.md +946 -0
- package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.i18n.yaml +6 -0
- package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.md +113 -0
- package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
- package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.i18n.yaml +6 -0
- package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
- package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
- package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.i18n.yaml +6 -0
- package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
- package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
- package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.i18n.yaml +6 -0
- package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
- package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
- package/references/official-docs/docs/postmortem/README.i18n.yaml +6 -0
- package/references/official-docs/docs/postmortem/README.md +18 -0
- package/references/official-docs/docs/postmortem/README.zh.md +18 -0
- package/references/official-docs/docs/rescope.i18n.yaml +6 -0
- package/references/official-docs/docs/rescope.md +53 -0
- package/references/official-docs/docs/rescope.zh.md +53 -0
- package/references/official-docs/docs/subsystems/README.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/README.md +55 -0
- package/references/official-docs/docs/subsystems/README.zh.md +55 -0
- package/references/official-docs/docs/subsystems/approval.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/approval.md +170 -0
- package/references/official-docs/docs/subsystems/approval.zh.md +170 -0
- package/references/official-docs/docs/subsystems/attachment.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/attachment.md +115 -0
- package/references/official-docs/docs/subsystems/attachment.zh.md +115 -0
- package/references/official-docs/docs/subsystems/client-modules.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/client-modules.md +118 -0
- package/references/official-docs/docs/subsystems/client-modules.zh.md +118 -0
- package/references/official-docs/docs/subsystems/code-runtime.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/code-runtime.md +191 -0
- package/references/official-docs/docs/subsystems/code-runtime.zh.md +191 -0
- package/references/official-docs/docs/subsystems/commands.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/commands.md +187 -0
- package/references/official-docs/docs/subsystems/commands.zh.md +187 -0
- package/references/official-docs/docs/subsystems/compaction.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/compaction.md +238 -0
- package/references/official-docs/docs/subsystems/compaction.zh.md +238 -0
- package/references/official-docs/docs/subsystems/core.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/core.md +1070 -0
- package/references/official-docs/docs/subsystems/core.zh.md +1078 -0
- package/references/official-docs/docs/subsystems/credentials.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/credentials.md +133 -0
- package/references/official-docs/docs/subsystems/credentials.zh.md +133 -0
- package/references/official-docs/docs/subsystems/extensions.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/extensions.md +364 -0
- package/references/official-docs/docs/subsystems/extensions.zh.md +364 -0
- package/references/official-docs/docs/subsystems/feedback.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/feedback.md +266 -0
- package/references/official-docs/docs/subsystems/feedback.zh.md +266 -0
- package/references/official-docs/docs/subsystems/filesystem.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/filesystem.md +495 -0
- package/references/official-docs/docs/subsystems/filesystem.zh.md +495 -0
- package/references/official-docs/docs/subsystems/goal.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/goal.md +277 -0
- package/references/official-docs/docs/subsystems/goal.zh.md +277 -0
- package/references/official-docs/docs/subsystems/invariants.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/invariants.md +88 -0
- package/references/official-docs/docs/subsystems/invariants.zh.md +88 -0
- package/references/official-docs/docs/subsystems/jobs.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/jobs.md +290 -0
- package/references/official-docs/docs/subsystems/jobs.zh.md +290 -0
- package/references/official-docs/docs/subsystems/llm-streaming.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/llm-streaming.md +888 -0
- package/references/official-docs/docs/subsystems/llm-streaming.zh.md +894 -0
- package/references/official-docs/docs/subsystems/lsp.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/lsp.md +202 -0
- package/references/official-docs/docs/subsystems/lsp.zh.md +202 -0
- package/references/official-docs/docs/subsystems/permission-presets.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/permission-presets.md +131 -0
- package/references/official-docs/docs/subsystems/permission-presets.zh.md +131 -0
- package/references/official-docs/docs/subsystems/persistence.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/persistence.md +385 -0
- package/references/official-docs/docs/subsystems/persistence.zh.md +385 -0
- package/references/official-docs/docs/subsystems/plan.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/plan.md +87 -0
- package/references/official-docs/docs/subsystems/plan.zh.md +87 -0
- package/references/official-docs/docs/subsystems/sandbox.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/sandbox.md +218 -0
- package/references/official-docs/docs/subsystems/sandbox.zh.md +218 -0
- package/references/official-docs/docs/subsystems/schedule.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/schedule.md +186 -0
- package/references/official-docs/docs/subsystems/schedule.zh.md +186 -0
- package/references/official-docs/docs/subsystems/scope.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/scope.md +59 -0
- package/references/official-docs/docs/subsystems/scope.zh.md +59 -0
- package/references/official-docs/docs/subsystems/session-projection.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/session-projection.md +262 -0
- package/references/official-docs/docs/subsystems/session-projection.zh.md +262 -0
- package/references/official-docs/docs/subsystems/session-query.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/session-query.md +495 -0
- package/references/official-docs/docs/subsystems/session-query.zh.md +495 -0
- package/references/official-docs/docs/subsystems/session-reference.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/session-reference.md +108 -0
- package/references/official-docs/docs/subsystems/session-reference.zh.md +108 -0
- package/references/official-docs/docs/subsystems/session-telemetry.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/session-telemetry.md +194 -0
- package/references/official-docs/docs/subsystems/session-telemetry.zh.md +194 -0
- package/references/official-docs/docs/subsystems/session-title.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/session-title.md +204 -0
- package/references/official-docs/docs/subsystems/session-title.zh.md +204 -0
- package/references/official-docs/docs/subsystems/session.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/session.md +849 -0
- package/references/official-docs/docs/subsystems/session.zh.md +851 -0
- package/references/official-docs/docs/subsystems/settings.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/settings.md +310 -0
- package/references/official-docs/docs/subsystems/settings.zh.md +310 -0
- package/references/official-docs/docs/subsystems/shell.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/shell.md +303 -0
- package/references/official-docs/docs/subsystems/shell.zh.md +303 -0
- package/references/official-docs/docs/subsystems/skills.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/skills.md +331 -0
- package/references/official-docs/docs/subsystems/skills.zh.md +331 -0
- package/references/official-docs/docs/subsystems/spill.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/spill.md +117 -0
- package/references/official-docs/docs/subsystems/spill.zh.md +117 -0
- package/references/official-docs/docs/subsystems/storage.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/storage.md +229 -0
- package/references/official-docs/docs/subsystems/storage.zh.md +229 -0
- package/references/official-docs/docs/subsystems/subagent.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/subagent.md +734 -0
- package/references/official-docs/docs/subsystems/subagent.zh.md +736 -0
- package/references/official-docs/docs/subsystems/subprocess.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/subprocess.md +324 -0
- package/references/official-docs/docs/subsystems/subprocess.zh.md +324 -0
- package/references/official-docs/docs/subsystems/system-prompt.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/system-prompt.md +207 -0
- package/references/official-docs/docs/subsystems/system-prompt.zh.md +207 -0
- package/references/official-docs/docs/subsystems/terminal.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/terminal.md +184 -0
- package/references/official-docs/docs/subsystems/terminal.zh.md +184 -0
- package/references/official-docs/docs/subsystems/token-meter.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/token-meter.md +90 -0
- package/references/official-docs/docs/subsystems/token-meter.zh.md +90 -0
- package/references/official-docs/docs/subsystems/tools.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/tools.md +720 -0
- package/references/official-docs/docs/subsystems/tools.zh.md +720 -0
- package/references/official-docs/docs/subsystems/typert.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/typert.md +336 -0
- package/references/official-docs/docs/subsystems/typert.zh.md +336 -0
- package/references/official-docs/docs/subsystems/user-questions.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/user-questions.md +178 -0
- package/references/official-docs/docs/subsystems/user-questions.zh.md +178 -0
- package/references/official-docs/docs/subsystems/web-server.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/web-server.md +108 -0
- package/references/official-docs/docs/subsystems/web-server.zh.md +108 -0
- package/references/official-docs/docs/subsystems/web.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/web.md +199 -0
- package/references/official-docs/docs/subsystems/web.zh.md +199 -0
- package/references/official-docs/docs/subsystems/workflow.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/workflow.md +278 -0
- package/references/official-docs/docs/subsystems/workflow.zh.md +278 -0
- package/references/official-docs/docs/subsystems/workspace.i18n.yaml +6 -0
- package/references/official-docs/docs/subsystems/workspace.md +228 -0
- package/references/official-docs/docs/subsystems/workspace.zh.md +228 -0
- package/references/official-docs/docs/testing.i18n.yaml +6 -0
- package/references/official-docs/docs/testing.md +49 -0
- package/references/official-docs/docs/testing.zh.md +49 -0
- package/references/official-docs/docs/tool-catalog.i18n.yaml +6 -0
- package/references/official-docs/docs/tool-catalog.md +1873 -0
- package/references/official-docs/docs/tool-catalog.zh.md +1878 -0
- package/references/official-docs/docs/tool-execution-pipeline.i18n.yaml +6 -0
- package/references/official-docs/docs/tool-execution-pipeline.md +62 -0
- package/references/official-docs/docs/tool-execution-pipeline.zh.md +64 -0
- package/references/official-docs/docs/user/develop/basic/config.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/basic/config.md +106 -0
- package/references/official-docs/docs/user/develop/basic/config.zh.md +106 -0
- package/references/official-docs/docs/user/develop/basic/index.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/basic/index.md +144 -0
- package/references/official-docs/docs/user/develop/basic/index.zh.md +144 -0
- package/references/official-docs/docs/user/develop/basic/publish.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/basic/publish.md +183 -0
- package/references/official-docs/docs/user/develop/basic/publish.zh.md +183 -0
- package/references/official-docs/docs/user/develop/basic/tool.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/basic/tool.md +52 -0
- package/references/official-docs/docs/user/develop/basic/tool.zh.md +52 -0
- package/references/official-docs/docs/user/develop/framework/events.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/framework/events.md +143 -0
- package/references/official-docs/docs/user/develop/framework/events.zh.md +143 -0
- package/references/official-docs/docs/user/develop/framework/index.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/framework/index.md +137 -0
- package/references/official-docs/docs/user/develop/framework/index.zh.md +137 -0
- package/references/official-docs/docs/user/develop/framework/service.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/framework/service.md +148 -0
- package/references/official-docs/docs/user/develop/framework/service.zh.md +150 -0
- package/references/official-docs/docs/user/develop/practice/index.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/practice/index.md +155 -0
- package/references/official-docs/docs/user/develop/practice/index.zh.md +155 -0
- package/references/official-docs/docs/user/develop/practice/llm-adapter.i18n.yaml +6 -0
- package/references/official-docs/docs/user/develop/practice/llm-adapter.md +188 -0
- package/references/official-docs/docs/user/develop/practice/llm-adapter.zh.md +188 -0
- package/references/official-docs/docs/user/guide/index.i18n.yaml +6 -0
- package/references/official-docs/docs/user/guide/index.md +30 -0
- package/references/official-docs/docs/user/guide/index.zh.md +30 -0
- package/references/official-docs/docs/user/guide/providers-custom-form.png +0 -0
- package/references/official-docs/docs/user/guide/providers-custom-form.zh.png +0 -0
- package/references/official-docs/docs/user/guide/providers-models-page.png +0 -0
- package/references/official-docs/docs/user/guide/providers-models-page.zh.png +0 -0
- package/references/official-docs/docs/user/guide/providers.i18n.yaml +6 -0
- package/references/official-docs/docs/user/guide/providers.md +98 -0
- package/references/official-docs/docs/user/guide/providers.zh.md +98 -0
- package/references/official-docs/docs/user/guide/python-sdk.i18n.yaml +6 -0
- package/references/official-docs/docs/user/guide/python-sdk.md +104 -0
- package/references/official-docs/docs/user/guide/python-sdk.zh.md +104 -0
- package/references/official-docs/docs/user/index.i18n.yaml +6 -0
- package/references/official-docs/docs/user/index.md +11 -0
- package/references/official-docs/docs/user/index.zh.md +11 -0
- package/references/official-docs/docs/web-styling.i18n.yaml +6 -0
- package/references/official-docs/docs/web-styling.md +25 -0
- package/references/official-docs/docs/web-styling.zh.md +25 -0
- package/references/official-docs/examples/AGENTS.md +20 -0
- package/references/official-docs/packages/AGENTS.md +27 -0
- package/references/official-docs/packages/README.md +69 -0
- package/references/official-docs/vendor/README.md +60 -0
- package/references/official-docs/website-docs.ts +524 -0
- package/references/sources.md +137 -0
- package/references/upstream-cordis.md +594 -0
- package/references/website-pages.md +668 -0
- package/scripts/archive-discussions.ps1 +154 -0
- package/scripts/download-community-articles.ps1 +188 -0
- package/scripts/download-community-repos.ps1 +232 -0
- package/scripts/download-sources.ps1 +195 -0
- package/scripts/gen-topic-snapshot.ps1 +91 -0
- package/scripts/install-skill.ps1 +63 -0
- package/scripts/sync-official-docs.ps1 +130 -0
- package/scripts/verify-kit.ps1 +191 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write docs/cookbook/adding-a-conversation-node.md
|
|
5
|
+
adding-a-conversation-node.md: c1965dc8a3081eebb8c1026ac53d2f7b8964edb7
|
|
6
|
+
adding-a-conversation-node.zh.md: 92445e1432369a4e42cc372b5d5869c3cdeada4a
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Add a Web Client conversation node
|
|
2
|
+
|
|
3
|
+
English | [中文](adding-a-conversation-node.zh.md)
|
|
4
|
+
|
|
5
|
+
This tutorial adds one business-owned row to the Web Client Chat view. The finished plugin correlates a durable Session event family into one Context, incrementally builds business State, publishes typed Step data, and renders a keyed Chat Node without scanning the Session window or other rendered nodes. It assumes the Host already records the events and the client plugin is composed into the Web bundle; external Host-side UIs and additional view targets such as Trajectory are outside this tutorial.
|
|
6
|
+
|
|
7
|
+
The [Conversation Node assembly decision](../../.agents/notes/implemented/architecture/2026-08-09-client-conversation-node-assembly.md) owns the rationale and complete engine model. This guide covers the implementation path.
|
|
8
|
+
|
|
9
|
+
## 1. Design a replayable event family
|
|
10
|
+
|
|
11
|
+
Choose one stable business id before writing the Definition. Every event that contributes to the same Node must carry that id or derive it independently from its own payload; the client must never assign an update to “the latest unfinished” Context.
|
|
12
|
+
|
|
13
|
+
For a review job, the event contract could be:
|
|
14
|
+
|
|
15
|
+
| Event | Role | Required durable facts |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `review/start` | unique start | `reviewId`, Turn/Step coordinates, title |
|
|
18
|
+
| `review/progress` | update | the same `reviewId`, coordinates, replayable progress |
|
|
19
|
+
| `review/end` | update | the same `reviewId`, coordinates, final summary |
|
|
20
|
+
|
|
21
|
+
Use the producer-owned branded id type across the process boundary. Put the `SessionEventMap` merge and payload types on the producer's type-only export, then import that export for side effects from the client package. Each `(kind, id)` may have at most one start event. A single-event business can use the event's stable identity, such as `event.seq`, as its Definition-local id.
|
|
22
|
+
|
|
23
|
+
Incremental events are supported. Prefer whole-value checkpoints when the producer can emit them cheaply, because they remain useful when the start is outside the loaded window. Each delta must carry the stable id and produce deterministic State when replayed in ascending log `seq`; it must not depend on live-only memory. If the current history window contains only updates, the assembler keeps a pending Context and builds no State until an older page supplies the start. If the product must render before the start is loaded, a terminal or checkpoint event must carry enough whole fallback state for the Definition to build that result directly; do not recover it by scanning unrelated events.
|
|
24
|
+
|
|
25
|
+
## 2. Implement the Definition and typed Chat payload
|
|
26
|
+
|
|
27
|
+
The example keeps the producer declarations and client contribution in one block so the complete relationship is visible. In a package family, keep the branded id and `SessionEventMap` declaration with the event producer, and keep the Definition, Chat data merge, and renderer in the client plugin.
|
|
28
|
+
|
|
29
|
+
```ts ignore-check
|
|
30
|
+
import { createElement } from 'react'
|
|
31
|
+
import type { Branded } from '@deepseek-ai/dsh-brand'
|
|
32
|
+
import type {
|
|
33
|
+
ClientContext, ConversationLocation, ConversationNodeContext,
|
|
34
|
+
ConversationNodeDefinition,
|
|
35
|
+
} from '@deepseek-ai/dsh-client-runtime/client'
|
|
36
|
+
import type { ChatNodeViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
|
37
|
+
|
|
38
|
+
type ReviewId = Branded<'ReviewId'>
|
|
39
|
+
|
|
40
|
+
interface ReviewStartData {
|
|
41
|
+
readonly reviewId: ReviewId
|
|
42
|
+
readonly turn: number
|
|
43
|
+
readonly step: number
|
|
44
|
+
readonly title: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface ReviewProgressData {
|
|
48
|
+
readonly reviewId: ReviewId
|
|
49
|
+
readonly turn: number
|
|
50
|
+
readonly step: number
|
|
51
|
+
readonly completed: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface ReviewEndData {
|
|
55
|
+
readonly reviewId: ReviewId
|
|
56
|
+
readonly turn: number
|
|
57
|
+
readonly step: number
|
|
58
|
+
readonly summary: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare module '@deepseek-ai/dsh-session/types' {
|
|
62
|
+
interface SessionEventMap {
|
|
63
|
+
/**
|
|
64
|
+
* Opens one durable review job.
|
|
65
|
+
* @mode emit
|
|
66
|
+
* @param data - stable identity, location, and initial display state.
|
|
67
|
+
*/
|
|
68
|
+
'review/start': ReviewStartData
|
|
69
|
+
/**
|
|
70
|
+
* Records replayable progress for one review job.
|
|
71
|
+
* @mode emit
|
|
72
|
+
* @param data - stable identity, location, and latest progress.
|
|
73
|
+
*/
|
|
74
|
+
'review/progress': ReviewProgressData
|
|
75
|
+
/**
|
|
76
|
+
* Closes one review job with its final summary.
|
|
77
|
+
* @mode emit
|
|
78
|
+
* @param data - stable identity, location, and final display state.
|
|
79
|
+
*/
|
|
80
|
+
'review/end': ReviewEndData
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface ReviewChatData {
|
|
85
|
+
readonly title: string
|
|
86
|
+
readonly completed: number
|
|
87
|
+
readonly status: 'running' | 'completed'
|
|
88
|
+
readonly summary?: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
|
|
92
|
+
interface ChatNodeDataMap {
|
|
93
|
+
'review-job': ReviewChatData
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
declare module '@deepseek-ai/dsh-client-runtime/client' {
|
|
98
|
+
interface ConversationStepDataMap {
|
|
99
|
+
'review-job': ReviewChatData
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface ReviewState extends ReviewChatData {
|
|
104
|
+
readonly turn: number
|
|
105
|
+
readonly step: number
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function locationOf(context: ConversationNodeContext): ConversationLocation {
|
|
109
|
+
return context.start?.location ?? context.matches[0]?.location ?? { kind: 'unresolved' }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function viewData(state: ReviewState): ReviewChatData {
|
|
113
|
+
return {
|
|
114
|
+
title: state.title,
|
|
115
|
+
completed: state.completed,
|
|
116
|
+
status: state.status,
|
|
117
|
+
...state.summary === undefined ? {} : { summary: state.summary },
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const reviewDefinition: ConversationNodeDefinition<ReviewState> = {
|
|
122
|
+
kind: 'review-job',
|
|
123
|
+
target: 'chat',
|
|
124
|
+
match: (event) => {
|
|
125
|
+
if (event.type === 'review/start') {
|
|
126
|
+
return { id: String(event.data.reviewId), role: 'start' }
|
|
127
|
+
}
|
|
128
|
+
if (event.type === 'review/progress' || event.type === 'review/end') {
|
|
129
|
+
return { id: String(event.data.reviewId), role: 'update' }
|
|
130
|
+
}
|
|
131
|
+
return null
|
|
132
|
+
},
|
|
133
|
+
start: (_context, match) => {
|
|
134
|
+
if (match.event.type !== 'review/start') throw new Error('review-job requires review/start')
|
|
135
|
+
return {
|
|
136
|
+
turn: match.event.data.turn,
|
|
137
|
+
step: match.event.data.step,
|
|
138
|
+
title: match.event.data.title,
|
|
139
|
+
completed: 0,
|
|
140
|
+
status: 'running',
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
update: (context, match) => {
|
|
144
|
+
if (match.event.type === 'review/progress') {
|
|
145
|
+
return { ...context.state, completed: match.event.data.completed }
|
|
146
|
+
}
|
|
147
|
+
if (match.event.type === 'review/end') {
|
|
148
|
+
return { ...context.state, completed: 100, status: 'completed', summary: match.event.data.summary }
|
|
149
|
+
}
|
|
150
|
+
return context.state
|
|
151
|
+
},
|
|
152
|
+
publication: match => match.event.type === 'review/progress'
|
|
153
|
+
? 'animation-frame'
|
|
154
|
+
: 'immediate',
|
|
155
|
+
buildLocationData: (context, scope) => {
|
|
156
|
+
if (scope !== 'step' || context.state === undefined) return null
|
|
157
|
+
return {
|
|
158
|
+
kind: 'step',
|
|
159
|
+
turn: context.state.turn,
|
|
160
|
+
step: context.state.step,
|
|
161
|
+
key: 'review-job',
|
|
162
|
+
value: viewData(context.state),
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
buildViewNode: (context) => {
|
|
166
|
+
if (context.state === undefined) return null
|
|
167
|
+
return {
|
|
168
|
+
key: context.key,
|
|
169
|
+
kind: 'review-job',
|
|
170
|
+
id: context.id,
|
|
171
|
+
target: 'chat',
|
|
172
|
+
anchorSeq: context.start?.event.seq ?? context.matches[0]?.event.seq ?? 0,
|
|
173
|
+
location: locationOf(context),
|
|
174
|
+
visibility: 'visible',
|
|
175
|
+
data: viewData(context.state),
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function ReviewNodeView({ node }: ChatNodeViewProps<'review-job'>) {
|
|
181
|
+
const text = node.data.summary ?? `${node.data.title}: ${node.data.completed}%`
|
|
182
|
+
return createElement('p', null, text)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export const inject = ['conversationEvents', 'slots']
|
|
186
|
+
|
|
187
|
+
export function apply(ctx: ClientContext): void {
|
|
188
|
+
ctx.conversationEvents.register(reviewDefinition)
|
|
189
|
+
ctx.slots.inject('conversation.chat.node', () => ctx.slots.register({
|
|
190
|
+
name: 'conversation.chat.node',
|
|
191
|
+
key: 'review-job',
|
|
192
|
+
}, ReviewNodeView))
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`match(event)` is an identity extractor, not a fold: it receives only the current event and returns the Definition-local id and lifecycle role. After a match, the assembler locates the Context by `(kind, id)` and calls `start` once or `update` with the current State. Both functions return the State that the engine adopts; returning a new immutable value is preferred, but a function that mutates and returns the same object has the same adoption semantics.
|
|
197
|
+
|
|
198
|
+
`buildLocationData(context, scope)` optionally publishes Definition-owned data onto an engine-owned Turn or Step. Use declaration merging to give each key a precise value type. Another Node in the same Location can consume that value through its constrained slot hook, such as `useTurnData(key)`, without receiving the Session or scanning `snapshot.chat.nodes`.
|
|
199
|
+
|
|
200
|
+
`target` and `buildViewNode(context)` declare one target-owned rendering contribution and must appear together. Preserve `context.key` as the React-facing identity, choose `anchorSeq` from durable ordering evidence, and return only renderer-ready data. Once a target Node has been published, keep returning the same key; use `visibility: 'hidden'` when it must temporarily leave the visible flow rather than withdrawing it with `null`.
|
|
201
|
+
|
|
202
|
+
## 3. Query an earlier business Context only at start
|
|
203
|
+
|
|
204
|
+
Some Definitions need the latest earlier State of another business kind. `start` receives a `ConversationContextReader`; call `reader.previous<State>(kind)` there instead of accepting a Context collection or scanning events. The reader returns the nearest started Context before the current start `seq` as read-only data.
|
|
205
|
+
|
|
206
|
+
The assembler records that dependency. If an older prepend later supplies a nearer predecessor, closes a previously unknown window gap, or revises the predecessor State, it reruns the dependent Context from `start` and replays its updates in ascending `seq`. The queried Definition remains responsible for writing useful State; the reader exposes no business-specific query methods and grants no mutation authority over another Context.
|
|
207
|
+
|
|
208
|
+
## 4. Understand the three ingestion paths
|
|
209
|
+
|
|
210
|
+
History may be requested from the tail backward one page at a time, but every accepted page is normalized into ascending `seq` before State replay.
|
|
211
|
+
|
|
212
|
+
| Path | Engine work | Definition-visible behavior |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| Replace on open, resync, or gap repair | Rebuild the loaded window, match every event once per Definition, then replay each started Context | `start`, followed by its updates in ascending `seq`; pending update-only Contexts remain without State |
|
|
215
|
+
| Prepend one older page | Match only fresh older events, merge them into Contexts by `(kind, id)`, preserve existing keyed nodes, and replay only affected Contexts and dependencies | A newly found start activates its collected updates; a changed Location or predecessor may rerun the Context |
|
|
216
|
+
| Append one live event | Call each Definition's `match` once, look up the matched Context by key, and update only that Context | One `update` and one requested publication for a matching post-start event; no existing Context scan |
|
|
217
|
+
|
|
218
|
+
With `D` registered Definitions, one incoming event performs `D` current-event matches and constant-time Context-key lookup after a match. Definition code must preserve that property: do not traverse the complete event window, every Context, `context.matches`, or the rendered Node collection on the normal append path. Use State for accumulated facts, Location data for same-Turn/Step sharing, and `reader.previous()` for indexed predecessor dependencies.
|
|
219
|
+
|
|
220
|
+
`publication` controls when changed State is materialized. Use `immediate` for structural or terminal changes, `animation-frame` for high-frequency visible deltas, and `none` when the State change feeds only a later publication. The engine still applies every update in log order; cadence only coalesces view publication.
|
|
221
|
+
|
|
222
|
+
## 5. Verify replay, pagination, and rendering
|
|
223
|
+
|
|
224
|
+
Add focused tests that establish these outcomes:
|
|
225
|
+
|
|
226
|
+
1. A complete window passed through replace produces the expected final State, Location data, Node payload, and `anchorSeq`.
|
|
227
|
+
2. An update-only tail stays pending; prepending the unique start produces the same result as a complete replace.
|
|
228
|
+
3. Initial history followed by live append produces the same result as replaying the combined window.
|
|
229
|
+
4. Prepending an older page adds earlier rows without replacing existing keyed Node values whose data did not change.
|
|
230
|
+
5. Repeated visible deltas preserve `context.key` and publish at most once per animation frame when requested.
|
|
231
|
+
6. The keyed renderer consumes `node.data` and constrained Location hooks only; it does not scan the Session event window, Contexts, or Chat Nodes.
|
|
232
|
+
|
|
233
|
+
Use [`packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts) for streaming and interruption, [`inbox.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/inbox.ts) plus [`message.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/message.ts) for predecessor queries, and [`packages/client/ui-deliverables`](../../packages/client/ui-deliverables) for a Definition that publishes Turn data without creating its own Node.
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# 添加 Web Client Conversation Node
|
|
2
|
+
|
|
3
|
+
[English](adding-a-conversation-node.md) | 中文
|
|
4
|
+
|
|
5
|
+
本教程为 Web Client Chat 视图添加一行由业务自行拥有的内容。完成后的插件会把一个持久 Session 事件族关联成一个 Context,增量构造业务 State,发布类型化 Step 数据,再渲染 keyed Chat Node;整个过程不扫描 Session 窗口或其他已渲染节点。本教程假设 Host 已经记录这些事件,且该 Client 插件已组装进 Web bundle;Host 侧外部 UI 和 Trajectory 等额外视图目标不在本文范围内。
|
|
6
|
+
|
|
7
|
+
[Conversation Node 组装决策](../../.agents/notes/implemented/architecture/2026-08-09-client-conversation-node-assembly.md)记录完整的引擎模型和设计理由;本文只说明实现路径。
|
|
8
|
+
|
|
9
|
+
## 1. 设计可回放的事件族
|
|
10
|
+
|
|
11
|
+
编写 Definition 前先选定稳定的业务 id。构成同一个 Node 的每条事件都必须携带该 id,或只凭自身 payload 独立推导出该 id;Client 绝不能把 update 猜测为属于“最近一个未完成”的 Context。
|
|
12
|
+
|
|
13
|
+
以一个 review job 为例,事件约定可以是:
|
|
14
|
+
|
|
15
|
+
| 事件 | 角色 | 必须持久化的事实 |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `review/start` | 唯一 start | `reviewId`、Turn/Step 坐标、标题 |
|
|
18
|
+
| `review/progress` | update | 相同的 `reviewId`、坐标、可回放进度 |
|
|
19
|
+
| `review/end` | update | 相同的 `reviewId`、坐标、最终摘要 |
|
|
20
|
+
|
|
21
|
+
跨进程边界使用生产方拥有的 branded id 类型。把 `SessionEventMap` 合并和 payload 类型放在生产方的纯类型导出中,再由 Client 包通过仅类型副作用导入该导出。每个 `(kind, id)` 最多只能有一条 start 事件。单事件业务可以把事件自身的稳定身份(例如 `event.seq`)作为 Definition 内部 id。
|
|
22
|
+
|
|
23
|
+
系统支持增量事件。如果生产方能以较低成本发出 whole-value checkpoint,应优先采用,因为 start 位于已加载窗口之外时它仍可直接使用。每条 delta 都必须携带稳定 id,并且按照日志 `seq` 升序回放时能够确定性地产生 State;它不能依赖只存在于实时内存中的状态。如果当前历史窗口只有 update,Assembler 会保留一个 pending Context,并在更早分页补齐 start 前不构造 State。如果产品必须在 start 尚未加载时渲染,terminal 或 checkpoint 事件就必须携带足够的完整 fallback 状态,让 Definition 能直接构造结果;不要通过扫描无关事件恢复它。
|
|
24
|
+
|
|
25
|
+
## 2. 实现 Definition 与类型化 Chat payload
|
|
26
|
+
|
|
27
|
+
为了完整展示关联关系,下面把生产方声明和 Client 贡献写在同一个代码块里。实际的包族中,branded id 与 `SessionEventMap` 声明留在事件生产方,Definition、Chat data 合并与 renderer 留在 Client 插件。
|
|
28
|
+
|
|
29
|
+
```ts ignore-check
|
|
30
|
+
import { createElement } from 'react'
|
|
31
|
+
import type { Branded } from '@deepseek-ai/dsh-brand'
|
|
32
|
+
import type {
|
|
33
|
+
ClientContext, ConversationLocation, ConversationNodeContext,
|
|
34
|
+
ConversationNodeDefinition,
|
|
35
|
+
} from '@deepseek-ai/dsh-client-runtime/client'
|
|
36
|
+
import type { ChatNodeViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
|
37
|
+
|
|
38
|
+
type ReviewId = Branded<'ReviewId'>
|
|
39
|
+
|
|
40
|
+
interface ReviewStartData {
|
|
41
|
+
readonly reviewId: ReviewId
|
|
42
|
+
readonly turn: number
|
|
43
|
+
readonly step: number
|
|
44
|
+
readonly title: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface ReviewProgressData {
|
|
48
|
+
readonly reviewId: ReviewId
|
|
49
|
+
readonly turn: number
|
|
50
|
+
readonly step: number
|
|
51
|
+
readonly completed: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface ReviewEndData {
|
|
55
|
+
readonly reviewId: ReviewId
|
|
56
|
+
readonly turn: number
|
|
57
|
+
readonly step: number
|
|
58
|
+
readonly summary: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare module '@deepseek-ai/dsh-session/types' {
|
|
62
|
+
interface SessionEventMap {
|
|
63
|
+
/**
|
|
64
|
+
* Opens one durable review job.
|
|
65
|
+
* @mode emit
|
|
66
|
+
* @param data - stable identity, location, and initial display state.
|
|
67
|
+
*/
|
|
68
|
+
'review/start': ReviewStartData
|
|
69
|
+
/**
|
|
70
|
+
* Records replayable progress for one review job.
|
|
71
|
+
* @mode emit
|
|
72
|
+
* @param data - stable identity, location, and latest progress.
|
|
73
|
+
*/
|
|
74
|
+
'review/progress': ReviewProgressData
|
|
75
|
+
/**
|
|
76
|
+
* Closes one review job with its final summary.
|
|
77
|
+
* @mode emit
|
|
78
|
+
* @param data - stable identity, location, and final display state.
|
|
79
|
+
*/
|
|
80
|
+
'review/end': ReviewEndData
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface ReviewChatData {
|
|
85
|
+
readonly title: string
|
|
86
|
+
readonly completed: number
|
|
87
|
+
readonly status: 'running' | 'completed'
|
|
88
|
+
readonly summary?: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
|
|
92
|
+
interface ChatNodeDataMap {
|
|
93
|
+
'review-job': ReviewChatData
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
declare module '@deepseek-ai/dsh-client-runtime/client' {
|
|
98
|
+
interface ConversationStepDataMap {
|
|
99
|
+
'review-job': ReviewChatData
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface ReviewState extends ReviewChatData {
|
|
104
|
+
readonly turn: number
|
|
105
|
+
readonly step: number
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function locationOf(context: ConversationNodeContext): ConversationLocation {
|
|
109
|
+
return context.start?.location ?? context.matches[0]?.location ?? { kind: 'unresolved' }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function viewData(state: ReviewState): ReviewChatData {
|
|
113
|
+
return {
|
|
114
|
+
title: state.title,
|
|
115
|
+
completed: state.completed,
|
|
116
|
+
status: state.status,
|
|
117
|
+
...state.summary === undefined ? {} : { summary: state.summary },
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const reviewDefinition: ConversationNodeDefinition<ReviewState> = {
|
|
122
|
+
kind: 'review-job',
|
|
123
|
+
target: 'chat',
|
|
124
|
+
match: (event) => {
|
|
125
|
+
if (event.type === 'review/start') {
|
|
126
|
+
return { id: String(event.data.reviewId), role: 'start' }
|
|
127
|
+
}
|
|
128
|
+
if (event.type === 'review/progress' || event.type === 'review/end') {
|
|
129
|
+
return { id: String(event.data.reviewId), role: 'update' }
|
|
130
|
+
}
|
|
131
|
+
return null
|
|
132
|
+
},
|
|
133
|
+
start: (_context, match) => {
|
|
134
|
+
if (match.event.type !== 'review/start') throw new Error('review-job requires review/start')
|
|
135
|
+
return {
|
|
136
|
+
turn: match.event.data.turn,
|
|
137
|
+
step: match.event.data.step,
|
|
138
|
+
title: match.event.data.title,
|
|
139
|
+
completed: 0,
|
|
140
|
+
status: 'running',
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
update: (context, match) => {
|
|
144
|
+
if (match.event.type === 'review/progress') {
|
|
145
|
+
return { ...context.state, completed: match.event.data.completed }
|
|
146
|
+
}
|
|
147
|
+
if (match.event.type === 'review/end') {
|
|
148
|
+
return { ...context.state, completed: 100, status: 'completed', summary: match.event.data.summary }
|
|
149
|
+
}
|
|
150
|
+
return context.state
|
|
151
|
+
},
|
|
152
|
+
publication: match => match.event.type === 'review/progress'
|
|
153
|
+
? 'animation-frame'
|
|
154
|
+
: 'immediate',
|
|
155
|
+
buildLocationData: (context, scope) => {
|
|
156
|
+
if (scope !== 'step' || context.state === undefined) return null
|
|
157
|
+
return {
|
|
158
|
+
kind: 'step',
|
|
159
|
+
turn: context.state.turn,
|
|
160
|
+
step: context.state.step,
|
|
161
|
+
key: 'review-job',
|
|
162
|
+
value: viewData(context.state),
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
buildViewNode: (context) => {
|
|
166
|
+
if (context.state === undefined) return null
|
|
167
|
+
return {
|
|
168
|
+
key: context.key,
|
|
169
|
+
kind: 'review-job',
|
|
170
|
+
id: context.id,
|
|
171
|
+
target: 'chat',
|
|
172
|
+
anchorSeq: context.start?.event.seq ?? context.matches[0]?.event.seq ?? 0,
|
|
173
|
+
location: locationOf(context),
|
|
174
|
+
visibility: 'visible',
|
|
175
|
+
data: viewData(context.state),
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function ReviewNodeView({ node }: ChatNodeViewProps<'review-job'>) {
|
|
181
|
+
const text = node.data.summary ?? `${node.data.title}: ${node.data.completed}%`
|
|
182
|
+
return createElement('p', null, text)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export const inject = ['conversationEvents', 'slots']
|
|
186
|
+
|
|
187
|
+
export function apply(ctx: ClientContext): void {
|
|
188
|
+
ctx.conversationEvents.register(reviewDefinition)
|
|
189
|
+
ctx.slots.inject('conversation.chat.node', () => ctx.slots.register({
|
|
190
|
+
name: 'conversation.chat.node',
|
|
191
|
+
key: 'review-job',
|
|
192
|
+
}, ReviewNodeView))
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`match(event)` 是身份提取器,不是 fold:它只能收到当前事件,并返回 Definition 内部 id 与生命周期角色。命中后,Assembler 通过 `(kind, id)` 定位 Context,再调用一次 `start`,或把当前 State 交给 `update`。两个函数都必须返回引擎随后采用的 State;推荐返回新的 immutable value,但函数原地修改后返回同一对象时,采用语义也相同。
|
|
197
|
+
|
|
198
|
+
`buildLocationData(context, scope)` 可以把 Definition 拥有的数据发布到引擎拥有的 Turn 或 Step 上。通过 declaration merging 为每个 key 指定精确 value 类型。同一 Location 内的另一个 Node 可以使用受限 slot hook(例如 `useTurnData(key)`)读取该值,无须取得 Session,也无须扫描 `snapshot.chat.nodes`。
|
|
199
|
+
|
|
200
|
+
`target` 与 `buildViewNode(context)` 必须同时声明一项由 target 拥有的渲染贡献。把 `context.key` 保留为 React 侧身份,根据持久排序证据选择 `anchorSeq`,并且只返回 renderer 可以直接使用的数据。某个 target Node 一旦发布,就要继续返回同一个 key;需要暂时离开可见流时使用 `visibility: 'hidden'`,不要改为返回 `null` 撤回它。
|
|
201
|
+
|
|
202
|
+
## 3. 只在 start 时查询更早的业务 Context
|
|
203
|
+
|
|
204
|
+
有些 Definition 需要另一个业务 kind 在当前位置之前的最新 State。`start` 会收到 `ConversationContextReader`;应在这里调用 `reader.previous<State>(kind)`,不要接收 Context 集合或扫描事件。Reader 返回当前 start `seq` 之前最近一个已启动 Context 的只读数据。
|
|
205
|
+
|
|
206
|
+
Assembler 会记录这项依赖。如果后续 older prepend 带来了更近的前序 Context、补齐了原先未知的窗口缺口,或者前序 State 被修订,引擎会从 `start` 重新运行依赖方 Context,并按 `seq` 升序回放其 update。被查询的 Definition 仍负责把有用信息写入自身 State;Reader 不提供业务专用查询方法,也不授予修改其他 Context 的权限。
|
|
207
|
+
|
|
208
|
+
## 4. 理解三条摄入路径
|
|
209
|
+
|
|
210
|
+
历史可能从尾部开始一页一页向前请求,但每个已接收分页都会先按 `seq` 升序归一化,再进入 State 回放。
|
|
211
|
+
|
|
212
|
+
| 路径 | 引擎工作 | Definition 可观察到的行为 |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| open、resync 或 gap repair 时 replace | 重建已加载窗口,每条事件对每个 Definition 匹配一次,再回放每个已有 start 的 Context | 先执行 `start`,再按 `seq` 升序执行其 update;只有 update 的 pending Context 仍没有 State |
|
|
215
|
+
| prepend 一页更早历史 | 只匹配新增的更早事件,按 `(kind, id)` 合并进 Context,保留现有 keyed node,并只重放受影响的 Context 与依赖 | 新发现的 start 会激活已收集 update;Location 或前序依赖变化也可能重跑 Context |
|
|
216
|
+
| append 一条实时事件 | 每个 Definition 各调用一次 `match`,按 key 查找命中的 Context,只更新该 Context | 对 start 之后的匹配事件执行一次 `update` 并请求一次发布;不扫描已有 Context |
|
|
217
|
+
|
|
218
|
+
注册 `D` 个 Definition 时,一条新事件会进行 `D` 次仅当前事件匹配;命中后的 Context key 查询是常数时间。Definition 代码必须维持这个性质:正常 append 热路径不得遍历完整事件窗口、所有 Context、`context.matches` 或已渲染 Node 集合。累计事实放进 State,同 Turn/Step 共享信息放进 Location data,有索引的前序依赖使用 `reader.previous()`。
|
|
219
|
+
|
|
220
|
+
`publication` 控制发生 State 变更后何时物化。结构或 terminal 变化使用 `immediate`,高频可见 delta 使用 `animation-frame`,只为后续发布积累 State 时使用 `none`。引擎仍会按日志顺序应用每条 update;该选项只合并视图发布频率。
|
|
221
|
+
|
|
222
|
+
## 5. 验证回放、分页与渲染
|
|
223
|
+
|
|
224
|
+
添加聚焦测试,证明以下结果:
|
|
225
|
+
|
|
226
|
+
1. 完整窗口通过 replace 后产生预期的最终 State、Location data、Node payload 与 `anchorSeq`。
|
|
227
|
+
2. 只有 update 的尾部窗口保持 pending;prepend 唯一 start 后,结果与完整 replace 相同。
|
|
228
|
+
3. 初始历史后继续实时 append,与回放合并后的完整窗口得到相同结果。
|
|
229
|
+
4. prepend 更早分页只增加更早的行;数据未变化的既有 keyed Node value 不被替换。
|
|
230
|
+
5. 重复的可见 delta 保持 `context.key`,并在请求 `animation-frame` 时每帧最多发布一次。
|
|
231
|
+
6. keyed renderer 只消费 `node.data` 与受限 Location hook,不扫描 Session 事件窗口、Context 或 Chat Node。
|
|
232
|
+
|
|
233
|
+
流式与中断处理可参考 [`packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts),前序查询可参考 [`inbox.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/inbox.ts) 与 [`message.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/message.ts),只发布 Turn data 而不创建自有 Node 的例子见 [`packages/client/ui-deliverables`](../../packages/client/ui-deliverables)。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write docs/cookbook/adding-a-package.md
|
|
5
|
+
adding-a-package.md: a78695735957395c5c900c3294b6778904557f85
|
|
6
|
+
adding-a-package.zh.md: b7a749220fdc1581875851e2e4a7189ba7642b2d
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Cookbook: adding a workspace package
|
|
2
|
+
|
|
3
|
+
English | [中文](adding-a-package.zh.md)
|
|
4
|
+
|
|
5
|
+
The file-by-file checklist for a new `@deepseek-ai/dsh-<name>` package. This checklist is validated against the bash and adapter packages as templates; if it drifts from them, fix it here.
|
|
6
|
+
|
|
7
|
+
## 1. Create the package
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
packages/<group>/<pkg>/
|
|
11
|
+
package.json # copy from packages/core/tools, adjust name/description/deps
|
|
12
|
+
tsconfig.json # extends ../../../tsconfig.base.json, rootDir src,
|
|
13
|
+
# outDir lib/types, references: ../../../vendor/cosmokit,
|
|
14
|
+
# ../../../vendor/cordis (+ ../../../vendor/schemastery if
|
|
15
|
+
# you use Config, + ../../<group>/<dep> for each dsh dep)
|
|
16
|
+
src/index.ts # service default export or plugin (name/inject/apply/Config)
|
|
17
|
+
README.md # service API, events, extension points, design notes,
|
|
18
|
+
# + gated Model Experience context blocks or short form
|
|
19
|
+
# + the gated "Known Limitations and Deferred Work" section
|
|
20
|
+
# (or a whitelist entry in scripts/verify-package-readme-limitations.ts)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Choose an existing group when one matches the package's role (`core`, `llm`, `bash`, `compact`, `subagent`, `todo`, `session-persistence`, `ui`, `util`, or `support`). A new group is allowed, but it is a pure container: no `package.json`, no source files, and packages still sit exactly one level below it.
|
|
24
|
+
|
|
25
|
+
package.json invariants (enforced by `pnpm run constraints` / `scripts/check-workspace-constraints.ts`): `private: true`, a `version` matching the root `package.json`, `type: module`, `main: "lib/index.js"`, `types: "lib/types/index.d.ts"`, `exports["."].types: "./lib/types/index.d.ts"`, `exports["."].default: "./lib/index.js"`, `@deepseek-ai/cordis` in BOTH peerDependencies and devDependencies (same range). Mirror every dsh peer dependency in devDependencies. `@deepseek-ai/schemastery` goes in `dependencies` (it is a runtime validator), matching agent-loop. The `files` list contains exactly `lib/index.js`, `lib/invariant.js`, `lib/types/**/*.d.ts`, and package-specific runtime artifacts recognized by the gate; a package whose runtime export points into the emitted tree also includes `lib/types/**/*.js`. Do not publish `src`, declaration maps, JS maps, or stale root declaration files. CLI app packages with a package `bin` include `lib/bin.js` immediately after `lib/index.js` in `files`.
|
|
26
|
+
|
|
27
|
+
In-package relative imports use explicit `.ts` specifiers in source (for example, `export * from './types.ts'`). The compiler rewrites those to `.js` in emitted JS and leaves explicit `.ts` specifiers in declarations, which standard NodeNext/Node16 TypeScript consumers resolve to the sibling `.d.ts` files.
|
|
28
|
+
|
|
29
|
+
## 2. Register it in the root configs
|
|
30
|
+
|
|
31
|
+
| File | Change |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `tsconfig.base.json` | no edit for an existing group; for a new group, add a `./packages/<group>/*/src` candidate to the `@deepseek-ai/dsh-*` wildcard |
|
|
34
|
+
| `tsconfig.host.json` (Host package) or `tsconfig.client.json` (Client package) | add `{ "path": "./packages/<group>/<pkg>" }` to `references` — an ordinary package belongs to exactly one aggregate, never both. `api/remotes` uses a repository-specific split because the Host generates a contract that the Client consumes in a later phase; new packages must not copy it ([layout](../development.md#typescript-project-layout)) |
|
|
35
|
+
| `knip.json` | only if the package has entrypoints that repository discovery does not already cover |
|
|
36
|
+
|
|
37
|
+
A `packages/client/*` package additionally extends `tsconfig.base.client.json` instead of `tsconfig.base.json`, and a client plugin package declares `dsh.client` in package.json, exports `./client`, and calls the shared tsdown preset (`packages/client/tsdown.client.ts`) — see [packages/client/AGENTS.md](../../packages/client/AGENTS.md) for the client-side contract.
|
|
38
|
+
|
|
39
|
+
Covered automatically by globs or package-manifest discovery — no edits needed: root `package.json` workspaces, `scripts/publint-all.ts`, `tsdown.config.ts`, `.oxlintrc.json`, `scripts/check-workspace-constraints.ts`.
|
|
40
|
+
|
|
41
|
+
## 3. Decide the package topology
|
|
42
|
+
|
|
43
|
+
For a swappable capability, separate Service Definition / Service Provider / Consumer roles into packages when they evolve independently (see docs/architecture.md § "Capability seams" — the shell trio is the template). A single-purpose plugin stays one package.
|
|
44
|
+
|
|
45
|
+
### Name the role that exists
|
|
46
|
+
|
|
47
|
+
Name the stable current responsibility. Do not name the first implementation, a possible future expansion, or the Cordis base class. An interface package names the capability. An implementation package adds the mechanism, protocol, environment, or vendor that distinguishes it. Use `local` only when same-host execution is part of the contract.
|
|
48
|
+
|
|
49
|
+
Use a singular `ctx` key for one engine, runtime, policy, controller, resolver, store, or current configuration. Use a plural key for a registry or a service that owns multiple named members. The class role and key number must agree. Do not reuse one Cordis `Context` key for incompatible host and client declarations. TypeScript declaration merging sees both faces even when they use separate runtime contexts. Add the role suffix when the natural plural already belongs to another face.
|
|
50
|
+
|
|
51
|
+
| Word | Use it when | Do not use it when |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `Controller` | It accepts commands or user intent and changes one existing domain or presentation state. | It executes arbitrary work, owns a provider fleet, or only converts values for display. |
|
|
54
|
+
| `Store` | It owns one data set and mainly offers CRUD, snapshot, or subscription operations for that data. | It validates a state machine, arbitrates authority, dispatches work, or owns provider precedence. A map does not make a class a store. |
|
|
55
|
+
| `Directory` | It exposes entries and metadata for discovery or selection. | Producers register arbitrary implementations into it, or callers execute work through it. |
|
|
56
|
+
| `Presenter` | It is a pure conversion from domain values or tool arguments to render intent. | It performs I/O, subscribes, mutates state, or owns lifecycle. |
|
|
57
|
+
| `Registry` | It owns a dynamic set of named registrations, including lookup, duplicate or precedence rules, lifetime, and disposal. | Its main contract is dispatch, execution, cancellation, policy, or orchestration. |
|
|
58
|
+
| `Runtime` | It runs live work and owns dispatch, cancellation, provider coordination, or operation lifecycle across calls. | It only stores records, returns a catalog, resolves one value, or holds configuration. |
|
|
59
|
+
| `Resolver` | It computes or locates one answer from supplied inputs without owning that answer's lifecycle. | It owns a mutable collection or long-running execution. |
|
|
60
|
+
| `Binder` | It attaches one declared interface to a caller context or lifecycle and returns the bound value. | It owns the value as a collection, controls its domain state, or only converts data. |
|
|
61
|
+
| `Engine` | It implements a domain algorithm or stateful execution model. | It only selects a provider or forwards across a protocol boundary. |
|
|
62
|
+
| `Policy` | It decides what is allowed, selected, limited, or observed. | It performs the mechanism that the decision permits. |
|
|
63
|
+
| `Executor` | It runs one explicit request or resolved specification in one capability. | It owns a broad application lifecycle or provider catalog. |
|
|
64
|
+
| `Gateway` | It adapts a process, network, RPC, or API boundary. | It only registers same-process services or stores metadata. |
|
|
65
|
+
| `Provider` | It supplies one implementation of a capability definition. Add a mechanism or vendor qualifier when several can exist. | It is the capability definition, provider registry, or consumer runtime. |
|
|
66
|
+
| `Backend` | It implements replaceable lower-level persistence, transport, or execution behind a defined interface. | It is a user-facing service or one returned live-resource reference. |
|
|
67
|
+
| `Handle` | It refers to one live resource and controls or observes that resource. | It creates and manages the complete resource pool. |
|
|
68
|
+
| `Config` | It owns one resolved configuration value or one tightly bounded record and its update contract. | It stores a general collection, executes work, or exposes unrelated settings. |
|
|
69
|
+
| `Service` | It owns a cohesive domain service that no sharper role above states honestly. | The name exists only because the class extends Cordis `Service`. |
|
|
70
|
+
|
|
71
|
+
Use `SDK` only for the JSON-RPC client/server protocol used by the supported Python and TypeScript SDKs. DeepSeek Harness itself is an agent harness, not an SDK project. Use the canonical product spelling `Typert`, never `TypeRT` or `typeRT`.
|
|
72
|
+
|
|
73
|
+
## 4. Write the package README
|
|
74
|
+
|
|
75
|
+
Keep package-specific service API, config, events, extension points, and design notes first. The limitations section records durable consumer gaps and non-obvious maintainer constraints owned by this package; ordinary cleanup stays in its source TODO or Agent Note. An indirect Model Experience sentence may name the consumer that surfaces this package's contribution, but it does not restate that consumer's implementation. End a package README with this canonical sequence:
|
|
76
|
+
|
|
77
|
+
````markdown
|
|
78
|
+
## Model Experience
|
|
79
|
+
|
|
80
|
+
### Request context and condition
|
|
81
|
+
|
|
82
|
+
#### What the model sees
|
|
83
|
+
|
|
84
|
+
The exact data-dependent fields, an anchored generated-catalog link, or an introduction to the verbatim literal below.
|
|
85
|
+
|
|
86
|
+
##### Verbatim text for this field, when needed
|
|
87
|
+
|
|
88
|
+
```markdown
|
|
89
|
+
Stable system-prompt prose of any length, or another long non-generated literal, copied exactly from source.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Token effect
|
|
93
|
+
|
|
94
|
+
Fixed, conditional, retained, replaced, capped, or zero-direct token effect.
|
|
95
|
+
|
|
96
|
+
#### KV Cache effect
|
|
97
|
+
|
|
98
|
+
Append-only, prefix-stable, replacing, or independent behavior, including the exact conditions that may invalidate reuse.
|
|
99
|
+
|
|
100
|
+
## Known Limitations and Deferred Work
|
|
101
|
+
|
|
102
|
+
- **Consumer-visible gap** — exact missing operation or case, its consequence, and any maintainer constraint.
|
|
103
|
+
````
|
|
104
|
+
|
|
105
|
+
Fill Model Experience from the implementation. Use one H3 per direct, conditional, capped, lifetime, or auxiliary model-context entry, with the three ordered H4 fields shown above and one prose paragraph under each. Quote stable text owned by the package: system-prompt prose goes in a titled H5 plus `markdown` fence under the field that introduces it—normally `What the model sees`—other short literals stay inline with named placeholders, and other long literals use the same nested form. Summarize only data-dependent or provider-owned text. A tool-schema entry links its anchored section in the generated [tool catalog](../tool-catalog.md) and states only deltas absent there. Keep prompt and schema entries separate when scoping can hide one without the other. In `KV Cache effect`, distinguish append-only growth, a stable repeated prefix, replacement of earlier request tokens, and an independent model request, then name the package-owned changes that can invalidate reuse. “Does not invalidate” means the package preserves an already-reusable prefix; provider cache availability and eviction remain outside the package contract. The [prose standard](../../.agents/skills/dsh-prose-standard/SKILL.md) governs completeness and ownership; the verifier enforces the required section structure.
|
|
106
|
+
|
|
107
|
+
A package with no context effect or one consumer-owned path uses the audited `None, as ` or `Indirectly, through ` sentence in [`SENTENCE_MODEL_EXPERIENCE`](../../scripts/verify-package-readme-model-experience.ts), followed by a `KV Cache effect` H4 and one non-empty paragraph; a model-agnostic generic package may instead join `NO_MODEL_EXPERIENCE_SECTION`. Do not expand either case into a description of another package's work. The limitations [allowlist](../../scripts/verify-package-readme-limitations.ts) is independent. The [Model Experience Agent Note](../../.agents/notes/implemented/process/2026-07-12-package-model-experience-contract.md) records the rationale.
|
|
108
|
+
|
|
109
|
+
## 5. Verify
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
pnpm install # registers the workspace
|
|
113
|
+
pnpm run doc-sync
|
|
114
|
+
pnpm run constraints && pnpm run typecheck && pnpm run lint
|
|
115
|
+
pnpm run build && pnpm run hygiene
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Follow the [repository testing policy](../testing.md) for the behavior-specific checks and coverage required by the new package.
|