dsh-plugin-dev-kb 1.8.0 → 1.8.1
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/CHANGELOG.md +186 -178
- package/README.en.md +172 -172
- package/README.md +183 -183
- package/kb/INDEX.md +236 -234
- package/kb/README.md +88 -88
- package/kb/extra/AGENTS.md +77 -77
- package/kb/extra/deepseek-llm-api-wire-extensions.md +162 -162
- package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +162 -162
- package/kb/extra/defensive-patterns/package-surface.md +233 -232
- package/kb/extra/defensive-patterns/package-surface.zh.md +233 -232
- package/kb/extra/defensive-patterns/remote-and-api.md +117 -117
- package/kb/extra/defensive-patterns/remote-and-api.zh.md +117 -117
- package/kb/extra/development.md +221 -221
- package/kb/extra/development.zh.md +228 -228
- package/kb/extra/event-producer-consumer.md +133 -123
- package/kb/extra/event-producer-consumer.zh.md +135 -125
- package/kb/extra/module-graph.md +1961 -1888
- package/kb/extra/module-graph.zh.md +1963 -1890
- package/kb/extra/persistence-changes/2026-11-05-timeline-priority-notice.md +60 -0
- package/kb/extra/persistence-changes/2026-11-05-timeline-priority-notice.zh.md +60 -0
- package/kb/extra/persistence-changes/README.md +92 -92
- package/kb/extra/persistence-changes/README.zh.md +92 -92
- package/kb/extra/persistence-changes/historical-formats/README.md +75 -75
- package/kb/extra/persistence-changes/historical-formats/README.zh.md +75 -75
- package/kb/extra/persistence-changes/releases/README.md +103 -103
- package/kb/extra/persistence-changes/releases/README.zh.md +103 -103
- package/kb/extra/rescope.md +55 -55
- package/kb/extra/rescope.zh.md +55 -55
- package/kb/extra/subsystems/boot.md +631 -621
- package/kb/extra/subsystems/boot.zh.md +631 -621
- package/kb/extra/subsystems/computer-use.md +179 -137
- package/kb/extra/subsystems/computer-use.zh.md +179 -137
- package/kb/extra/subsystems/extensions.md +387 -384
- package/kb/extra/subsystems/extensions.zh.md +387 -384
- package/kb/extra/subsystems/feedback.md +418 -400
- package/kb/extra/subsystems/feedback.zh.md +418 -400
- package/kb/extra/subsystems/forge.md +2169 -1226
- package/kb/extra/subsystems/forge.zh.md +2171 -1226
- package/kb/extra/subsystems/liveshare.md +167 -158
- package/kb/extra/subsystems/liveshare.zh.md +167 -158
- package/kb/extra/subsystems/mcp.md +237 -234
- package/kb/extra/subsystems/mcp.zh.md +237 -234
- package/kb/extra/subsystems/office-kit.md +122 -0
- package/kb/extra/subsystems/office-kit.zh.md +122 -0
- package/kb/extra/subsystems/working-directory.md +95 -64
- package/kb/extra/subsystems/working-directory.zh.md +95 -64
- package/kb/extra/subsystems/worktrees.md +187 -127
- package/kb/extra/subsystems/worktrees.zh.md +187 -127
- package/kb/extra/upgrade-guide/v0.2.1-alpha.1/python-ptc-sandbox/guide.md +21 -21
- package/kb/extra/upgrade-guide/v0.2.1-alpha.1/python-ptc-sandbox/guide.zh.md +21 -21
- package/kb/extra/upgrade-guide/v0.2.1-rc.4/sandbox-unsupported-policy-error/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.1-rc.4/sandbox-unsupported-policy-error/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-error-builtin-codes/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-error-builtin-codes/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-kit-package/guide.md +34 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-kit-package/guide.zh.md +34 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-operation-tools/guide.md +49 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-operation-tools/guide.zh.md +49 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-skill-resources/guide.md +36 -0
- package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-skill-resources/guide.zh.md +36 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-notification-fields/guide.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-notification-fields/guide.zh.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-remote-provider/guide.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-remote-provider/guide.zh.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/archive-worktrees/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/archive-worktrees/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/attachment-error-codes/guide.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/attachment-error-codes/guide.zh.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-ax-read-limits/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-ax-read-limits/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-hover-ax-only/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-hover-ax-only/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-native-platform/guide.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-native-platform/guide.zh.md +23 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/dsh-doc-skill/guide.md +35 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/dsh-doc-skill/guide.zh.md +35 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-change-request-overview/guide.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-change-request-overview/guide.zh.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-pinned-diff/guide.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-pinned-diff/guide.zh.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-review-reads/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-review-reads/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/package-export-cleanup/guide.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/package-export-cleanup/guide.zh.md +26 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/plugin-update-method/guide.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/plugin-update-method/guide.zh.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-bootstrap-protocol/guide.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-bootstrap-protocol/guide.zh.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-inspect-output/guide.md +48 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-inspect-output/guide.zh.md +48 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-scoped-repl-default/guide.md +45 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-scoped-repl-default/guide.zh.md +45 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/runtime-context-reminders/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/runtime-context-reminders/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/session-append-overloads/guide.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/session-append-overloads/guide.zh.md +17 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/subagent-interrupt-default/guide.md +27 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/subagent-interrupt-default/guide.zh.md +27 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-backend-cleanup-error/guide.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-backend-cleanup-error/guide.zh.md +20 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-bundle-sidebar-backend/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-bundle-sidebar-backend/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-fetch-transport-error-codes/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-fetch-transport-error-codes/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-search-billing/guide.md +41 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-search-billing/guide.zh.md +41 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/window-drag-regions/guide.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.1/window-drag-regions/guide.zh.md +21 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/client-module-metadata/guide.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/client-module-metadata/guide.zh.md +29 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/connection-page-peer/guide.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/connection-page-peer/guide.zh.md +25 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/cordis-root-and-intercept-metadata/guide.md +31 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/cordis-root-and-intercept-metadata/guide.zh.md +31 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-agents-without-preset/guide.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-agents-without-preset/guide.zh.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-macos-provider/guide.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-macos-provider/guide.zh.md +24 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-partial-observations/guide.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-partial-observations/guide.zh.md +19 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/deepseek-files-timeout/guide.md +15 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/deepseek-files-timeout/guide.zh.md +15 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/experimental-tool-error-codes/guide.md +28 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/experimental-tool-error-codes/guide.zh.md +28 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/package-export-cleanup/guide.md +36 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/package-export-cleanup/guide.zh.md +36 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/python-ptc-removal/guide.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/python-ptc-removal/guide.zh.md +22 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/session-status-package/guide.md +31 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/session-status-package/guide.zh.md +31 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/shared-search-filter/guide.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/shared-search-filter/guide.zh.md +18 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/shell-fs-tool-error-codes/guide.md +30 -0
- package/kb/extra/upgrade-guide/v0.2.2-rc.2/shell-fs-tool-error-codes/guide.zh.md +30 -0
- package/kb/extra/web-styling.md +57 -57
- package/kb/extra/web-styling.zh.md +57 -57
- package/kb/meta/search-index.json +4508 -3980
- package/kb/meta/source.json +18 -18
- package/kb/site/develop/practice/llm-adapter.md +192 -192
- package/kb/site/en/develop/practice/llm-adapter.md +192 -192
- package/kb/site/en/guide/desktop-uninstall-cleanup.md +63 -0
- package/kb/site/en/guide/plugin-market.md +153 -151
- package/kb/site/en/guide/providers.md +234 -234
- package/kb/site/en/guide/quickstart.md +35 -34
- package/kb/site/en/reference/capability-seams.md +789 -767
- package/kb/site/en/reference/config-catalog.md +5432 -5128
- package/kb/site/en/reference/cookbook/adding-a-package.md +175 -175
- package/kb/site/en/reference/cookbook/adding-a-tool.md +105 -104
- package/kb/site/en/reference/cookbook/extension-cookbook.md +178 -135
- package/kb/site/en/reference/cordis-api/context.md +373 -369
- package/kb/site/en/reference/cordis-api/fiber.md +457 -433
- package/kb/site/en/reference/cordis-api/inherited.md +44 -44
- package/kb/site/en/reference/cordis-api/service.md +118 -107
- package/kb/site/en/reference/experimental-persistence-catalog.md +36 -23
- package/kb/site/en/reference/index.md +174 -174
- package/kb/site/en/reference/persistence-catalog.md +9453 -9432
- package/kb/site/en/reference/subsystems/compaction.md +288 -288
- package/kb/site/en/reference/subsystems/core.md +1172 -1171
- package/kb/site/en/reference/subsystems/credentials.md +526 -497
- package/kb/site/en/reference/subsystems/filesystem.md +708 -708
- package/kb/site/en/reference/subsystems/index.md +82 -82
- package/kb/site/en/reference/subsystems/llm-streaming.md +1290 -1288
- package/kb/site/en/reference/subsystems/lsp.md +230 -206
- package/kb/site/en/reference/subsystems/persistence.md +451 -432
- package/kb/site/en/reference/subsystems/plan.md +91 -91
- package/kb/site/en/reference/subsystems/ptc-runtime.md +295 -261
- package/kb/site/en/reference/subsystems/sandbox.md +250 -232
- package/kb/site/en/reference/subsystems/session-query.md +525 -515
- package/kb/site/en/reference/subsystems/session-reference.md +231 -229
- package/kb/site/en/reference/subsystems/session.md +1478 -1431
- package/kb/site/en/reference/subsystems/sidebar-right.md +165 -165
- package/kb/site/en/reference/subsystems/skills.md +356 -356
- package/kb/site/en/reference/subsystems/slots.md +235 -231
- package/kb/site/en/reference/subsystems/terminal.md +188 -188
- package/kb/site/en/reference/subsystems/tools.md +902 -891
- package/kb/site/en/reference/subsystems/user-questions.md +330 -327
- package/kb/site/en/reference/subsystems/web-client.md +161 -104
- package/kb/site/en/reference/subsystems/web-server.md +434 -351
- package/kb/site/en/reference/subsystems/web.md +268 -268
- package/kb/site/en/reference/subsystems/workflow.md +287 -282
- package/kb/site/en/reference/subsystems/workspace.md +743 -651
- package/kb/site/en/reference/tool-catalog.md +2867 -2704
- package/kb/site/guide/desktop-uninstall-cleanup.md +63 -0
- package/kb/site/guide/plugin-market.md +153 -151
- package/kb/site/guide/providers.md +234 -234
- package/kb/site/guide/quickstart.md +35 -34
- package/kb/site/reference/capability-seams.md +789 -767
- package/kb/site/reference/config-catalog.md +5432 -5128
- package/kb/site/reference/cookbook/adding-a-package.md +175 -175
- package/kb/site/reference/cookbook/adding-a-tool.md +107 -106
- package/kb/site/reference/cookbook/extension-cookbook.md +182 -139
- package/kb/site/reference/cordis-api/context.md +373 -369
- package/kb/site/reference/cordis-api/fiber.md +459 -435
- package/kb/site/reference/cordis-api/inherited.md +44 -44
- package/kb/site/reference/cordis-api/service.md +118 -107
- package/kb/site/reference/experimental-persistence-catalog.md +36 -23
- package/kb/site/reference/index.md +178 -178
- package/kb/site/reference/persistence-catalog.md +9453 -9432
- package/kb/site/reference/subsystems/compaction.md +288 -288
- package/kb/site/reference/subsystems/core.md +1184 -1183
- package/kb/site/reference/subsystems/credentials.md +526 -497
- package/kb/site/reference/subsystems/filesystem.md +708 -708
- package/kb/site/reference/subsystems/index.md +82 -82
- package/kb/site/reference/subsystems/llm-streaming.md +1296 -1294
- package/kb/site/reference/subsystems/lsp.md +230 -206
- package/kb/site/reference/subsystems/persistence.md +451 -432
- package/kb/site/reference/subsystems/plan.md +91 -91
- package/kb/site/reference/subsystems/ptc-runtime.md +295 -261
- package/kb/site/reference/subsystems/sandbox.md +250 -232
- package/kb/site/reference/subsystems/session-query.md +525 -515
- package/kb/site/reference/subsystems/session-reference.md +231 -229
- package/kb/site/reference/subsystems/session.md +1482 -1435
- package/kb/site/reference/subsystems/sidebar-right.md +165 -165
- package/kb/site/reference/subsystems/skills.md +356 -356
- package/kb/site/reference/subsystems/slots.md +239 -235
- package/kb/site/reference/subsystems/terminal.md +188 -188
- package/kb/site/reference/subsystems/tools.md +902 -891
- package/kb/site/reference/subsystems/user-questions.md +330 -327
- package/kb/site/reference/subsystems/web-client.md +161 -104
- package/kb/site/reference/subsystems/web-server.md +434 -351
- package/kb/site/reference/subsystems/web.md +268 -268
- package/kb/site/reference/subsystems/workflow.md +287 -282
- package/kb/site/reference/subsystems/workspace.md +743 -651
- package/kb/site/reference/tool-catalog.md +2872 -2709
- package/lib/index.js +359 -359
- package/package.json +68 -68
- package/skills/dsh-plugin-dev-kb.md +71 -70
- package/kb/extra/subsystems/office-to-pdf.md +0 -87
- package/kb/extra/subsystems/office-to-pdf.zh.md +0 -87
|
@@ -1,135 +1,178 @@
|
|
|
1
|
-
---
|
|
2
|
-
editSource: "docs/cookbook/extension-cookbook.md"
|
|
3
|
-
rawMarkdownPath: "en/reference/cookbook/extension-cookbook.md"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Cookbook: extension plugin shapes
|
|
7
|
-
|
|
8
|
-
Reference patterns for harness extensions. The snippets omit imports and helper implementations and are not copy-paste-complete. For concrete authoring paths, see the [package checklist](./adding-a-package.md), [first-tool tutorial](../../develop/basic/tool.md), [tool reference](./adding-a-tool.md), [LLM adapter guide](./adding-an-llm-adapter.md), and [Session format version tutorial](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/cookbook/adding-a-session-format-version.md); the [architecture](../index.md) owns the system and extension-point map.
|
|
9
|
-
|
|
10
|
-
## A tool plugin
|
|
11
|
-
|
|
12
|
-
A tool registers on `ctx.tools`. The annotated `defineTool` example (typed `execute` arguments, result construction, the `run_in_background` pattern) lives in [adding-a-tool.md](./adding-a-tool.md) — that guide is the source of truth for tool definitions. Raw JSON-Schema `ToolDefinition`s are also accepted by `ctx.tools.register()` directly (that is how MCP-sourced tools arrive); `defineTool` is the typed helper for first-party tools.
|
|
13
|
-
|
|
14
|
-
## A hook plugin (permission-gate example)
|
|
15
|
-
|
|
16
|
-
This permission gate is one example of a hook plugin. It returns a typed decision from the `tools/pre-execute` gate to allow or deny a call; sandbox, permission, and plan-mode plugins can use this extension point. Hook plugins can intercept other extension points and are not inherently permission gates. A "native hook" is an ordinary Cordis plugin on an interception point; it needs no external protocol.
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
import type { Context } from '@deepseek-ai/cordis'
|
|
20
|
-
import type { PreToolDecision, ToolExecution } from '@deepseek-ai/dsh-tools'
|
|
21
|
-
|
|
22
|
-
declare function isAllowed(exec: ToolExecution): Promise<boolean>
|
|
23
|
-
|
|
24
|
-
export const name = 'permission-gate'
|
|
25
|
-
|
|
26
|
-
export function apply(ctx: Context) {
|
|
27
|
-
ctx.on('tools/pre-execute', async (exec, next): Promise<PreToolDecision> => {
|
|
28
|
-
if (!(await isAllowed(exec))) {
|
|
29
|
-
return { kind: 'deny', reason: 'Denied by policy.' }
|
|
30
|
-
}
|
|
31
|
-
return next()
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
This waterfall is the reorderable policy layer. Use `ctx.tools.guard()` when an invariant needs a monotonic final denial, `tools/execute` when a plugin must wrap the dispatch lifetime (timeouts/retries/metrics; only `exec.signal` is replaceable), `tools/post-execute` for explicit result transformation, and `tools/result` for contained observation of the immutable final outcome. The [adding-a-tool guide](./adding-a-tool.md#execution-policy-and-observation) gives the selection rule.
|
|
37
|
-
|
|
38
|
-
## A UI plugin
|
|
39
|
-
|
|
40
|
-
A UI plugin combines durable `session/event` records (Assistant settlements, turn/step boundaries, and tool activity) with transient `agent/assistant-stream` frames for live token presentation, and drives input back in via `agent.followup()` / `agent.steer()`. A browser plugin contributing a business row to the built-in Web Client instead registers a `ConversationNodeDefinition` and keyed Chat renderer; follow the [Conversation subsystem reference](../subsystems/conversation.md).
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
import type { Context } from '@deepseek-ai/cordis'
|
|
44
|
-
import { brandString } from '@deepseek-ai/dsh-brand'
|
|
45
|
-
import { createUserMessage } from '@deepseek-ai/dsh-llm'
|
|
46
|
-
import type { SessionId } from '@deepseek-ai/dsh-session'
|
|
47
|
-
|
|
48
|
-
declare function render(text: string): void
|
|
49
|
-
declare function onUserInput(handler: (text: string) => void): void
|
|
50
|
-
|
|
51
|
-
export const name = 'my-ui'
|
|
52
|
-
export const inject = ['agents']
|
|
53
|
-
|
|
54
|
-
export function apply(ctx: Context) {
|
|
55
|
-
ctx.on('agent/assistant-stream', ({ frame }) => {
|
|
56
|
-
if (frame.type === 'chunk' && frame.chunk.type === 'text-delta') {
|
|
57
|
-
render(frame.chunk.text)
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
onUserInput(text => ctx.agents.get(brandString<SessionId>('client-session'))?.followup(createUserMessage({
|
|
61
|
-
content: [{ type: 'text', text }],
|
|
62
|
-
source: { kind: 'user' },
|
|
63
|
-
})))
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## An external protocol driver
|
|
68
|
-
|
|
69
|
-
A *protocol driver* adapts a wire peer to `ctx.agents`; it may serve a UI or an automation client. A stdio driver owns stdout, creates or resumes agents through the factory, and maps protocol requests to `followup()` or `cancel()`. A low-level prompt request returns its durable enqueue receipt; it does not acquire a result by correlating `MessageId` with `turn/end`. Publish whole-agent status separately. An automation method may wait from its receipt through the next idle and summarize that explicitly owned interval, while a UI normally keeps observing the open-ended event stream. Tear agents down with `AgentHandle.dispose()` so disposal reaches quiescence.
|
|
70
|
-
|
|
71
|
-
[`packages/acp/acp`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/acp/acp) is the automation-only worked example: it exposes fresh text sessions over Agent Client Protocol JSON-RPC stdio, emits committed assistant text, and registers a one-shot machine permission answerer for agents it owns. Its [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/acp/acp/README.md) defines the exact methods, event order, and lifecycle contract.
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
import type { Context } from '@deepseek-ai/cordis'
|
|
75
|
-
import { expandAssistantStream } from '@deepseek-ai/dsh-llm'
|
|
76
|
-
|
|
77
|
-
export const name = 'my-protocol-bridge'
|
|
78
|
-
export const inject = ['agents', 'sessions', 'sessionPersistence']
|
|
79
|
-
|
|
80
|
-
export function apply(ctx: Context) {
|
|
81
|
-
// Publish every committed Assistant text delta to the client.
|
|
82
|
-
ctx.on('session/event', (_session, event) => {
|
|
83
|
-
if (event.type === 'assistant/message' || event.type === 'assistant/attempt') {
|
|
84
|
-
for (const { chunk } of expandAssistantStream(event.data.stream)) {
|
|
85
|
-
if (chunk.type === 'text-delta') {
|
|
86
|
-
// sendToClient({ kind: 'message_chunk', text: chunk.text })
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
})
|
|
91
|
-
// Inbound "prompt": create/resume an agent, feed it, and return its enqueue receipt.
|
|
92
|
-
// Whole-agent status is a separate notification; no turn end belongs to this prompt.
|
|
93
|
-
// Teardown reaches quiescence via AgentHandle.dispose() (stop + await exit).
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
##
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
1
|
+
---
|
|
2
|
+
editSource: "docs/cookbook/extension-cookbook.md"
|
|
3
|
+
rawMarkdownPath: "en/reference/cookbook/extension-cookbook.md"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cookbook: extension plugin shapes
|
|
7
|
+
|
|
8
|
+
Reference patterns for harness extensions. The snippets omit imports and helper implementations and are not copy-paste-complete. For concrete authoring paths, see the [package checklist](./adding-a-package.md), [first-tool tutorial](../../develop/basic/tool.md), [tool reference](./adding-a-tool.md), [LLM adapter guide](./adding-an-llm-adapter.md), and [Session format version tutorial](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/cookbook/adding-a-session-format-version.md); the [architecture](../index.md) owns the system and extension-point map.
|
|
9
|
+
|
|
10
|
+
## A tool plugin
|
|
11
|
+
|
|
12
|
+
A tool registers on `ctx.tools`. The annotated `defineTool` example (typed `execute` arguments, result construction, the `run_in_background` pattern) lives in [adding-a-tool.md](./adding-a-tool.md) — that guide is the source of truth for tool definitions. Raw JSON-Schema `ToolDefinition`s are also accepted by `ctx.tools.register()` directly (that is how MCP-sourced tools arrive); `defineTool` is the typed helper for first-party tools.
|
|
13
|
+
|
|
14
|
+
## A hook plugin (permission-gate example)
|
|
15
|
+
|
|
16
|
+
This permission gate is one example of a hook plugin. It returns a typed decision from the `tools/pre-execute` gate to allow or deny a call; sandbox, permission, and plan-mode plugins can use this extension point. Hook plugins can intercept other extension points and are not inherently permission gates. A "native hook" is an ordinary Cordis plugin on an interception point; it needs no external protocol.
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
20
|
+
import type { PreToolDecision, ToolExecution } from '@deepseek-ai/dsh-tools'
|
|
21
|
+
|
|
22
|
+
declare function isAllowed(exec: ToolExecution): Promise<boolean>
|
|
23
|
+
|
|
24
|
+
export const name = 'permission-gate'
|
|
25
|
+
|
|
26
|
+
export function apply(ctx: Context) {
|
|
27
|
+
ctx.on('tools/pre-execute', async (exec, next): Promise<PreToolDecision> => {
|
|
28
|
+
if (!(await isAllowed(exec))) {
|
|
29
|
+
return { kind: 'deny', reason: 'Denied by policy.' }
|
|
30
|
+
}
|
|
31
|
+
return next()
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This waterfall is the reorderable policy layer. Use `ctx.tools.guard()` when an invariant needs a monotonic final denial, `tools/execute` when a plugin must wrap the dispatch lifetime (timeouts/retries/metrics; only `exec.signal` is replaceable), `tools/post-execute` for explicit result transformation, and `tools/result` for contained observation of the immutable final outcome. The [adding-a-tool guide](./adding-a-tool.md#execution-policy-and-observation) gives the selection rule.
|
|
37
|
+
|
|
38
|
+
## A UI plugin
|
|
39
|
+
|
|
40
|
+
A UI plugin combines durable `session/event` records (Assistant settlements, turn/step boundaries, and tool activity) with transient `agent/assistant-stream` frames for live token presentation, and drives input back in via `agent.followup()` / `agent.steer()`. A browser plugin contributing a business row to the built-in Web Client instead registers a `ConversationNodeDefinition` and keyed Chat renderer; follow the [Conversation subsystem reference](../subsystems/conversation.md).
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
44
|
+
import { brandString } from '@deepseek-ai/dsh-brand'
|
|
45
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm'
|
|
46
|
+
import type { SessionId } from '@deepseek-ai/dsh-session'
|
|
47
|
+
|
|
48
|
+
declare function render(text: string): void
|
|
49
|
+
declare function onUserInput(handler: (text: string) => void): void
|
|
50
|
+
|
|
51
|
+
export const name = 'my-ui'
|
|
52
|
+
export const inject = ['agents']
|
|
53
|
+
|
|
54
|
+
export function apply(ctx: Context) {
|
|
55
|
+
ctx.on('agent/assistant-stream', ({ frame }) => {
|
|
56
|
+
if (frame.type === 'chunk' && frame.chunk.type === 'text-delta') {
|
|
57
|
+
render(frame.chunk.text)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
onUserInput(text => ctx.agents.get(brandString<SessionId>('client-session'))?.followup(createUserMessage({
|
|
61
|
+
content: [{ type: 'text', text }],
|
|
62
|
+
source: { kind: 'user' },
|
|
63
|
+
})))
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## An external protocol driver
|
|
68
|
+
|
|
69
|
+
A *protocol driver* adapts a wire peer to `ctx.agents`; it may serve a UI or an automation client. A stdio driver owns stdout, creates or resumes agents through the factory, and maps protocol requests to `followup()` or `cancel()`. A low-level prompt request returns its durable enqueue receipt; it does not acquire a result by correlating `MessageId` with `turn/end`. Publish whole-agent status separately. An automation method may wait from its receipt through the next idle and summarize that explicitly owned interval, while a UI normally keeps observing the open-ended event stream. Tear agents down with `AgentHandle.dispose()` so disposal reaches quiescence.
|
|
70
|
+
|
|
71
|
+
[`packages/acp/acp`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/acp/acp) is the automation-only worked example: it exposes fresh text sessions over Agent Client Protocol JSON-RPC stdio, emits committed assistant text, and registers a one-shot machine permission answerer for agents it owns. Its [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/acp/acp/README.md) defines the exact methods, event order, and lifecycle contract.
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
75
|
+
import { expandAssistantStream } from '@deepseek-ai/dsh-llm'
|
|
76
|
+
|
|
77
|
+
export const name = 'my-protocol-bridge'
|
|
78
|
+
export const inject = ['agents', 'sessions', 'sessionPersistence']
|
|
79
|
+
|
|
80
|
+
export function apply(ctx: Context) {
|
|
81
|
+
// Publish every committed Assistant text delta to the client.
|
|
82
|
+
ctx.on('session/event', (_session, event) => {
|
|
83
|
+
if (event.type === 'assistant/message' || event.type === 'assistant/attempt') {
|
|
84
|
+
for (const { chunk } of expandAssistantStream(event.data.stream)) {
|
|
85
|
+
if (chunk.type === 'text-delta') {
|
|
86
|
+
// sendToClient({ kind: 'message_chunk', text: chunk.text })
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
// Inbound "prompt": create/resume an agent, feed it, and return its enqueue receipt.
|
|
92
|
+
// Whole-agent status is a separate notification; no turn end belongs to this prompt.
|
|
93
|
+
// Teardown reaches quiescence via AgentHandle.dispose() (stop + await exit).
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## A forge review extension
|
|
98
|
+
|
|
99
|
+
Change request review opens to plugins through the [forge extension API](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/forge.md#extension-api). A Host plugin registers a filter lens, which keeps some of the files a changes view shows and names the lines it is about:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
103
|
+
import { brandString } from '@deepseek-ai/dsh-brand'
|
|
104
|
+
import type { ForgeLensId } from '@deepseek-ai/dsh-experimental-client-ui-forge'
|
|
105
|
+
|
|
106
|
+
export const name = 'exports-lens'
|
|
107
|
+
export const inject = ['forgePanel']
|
|
108
|
+
|
|
109
|
+
export function apply(ctx: Context) {
|
|
110
|
+
// An effect of this plugin's fiber: unloading the plugin withdraws the lens and aborts its runs.
|
|
111
|
+
ctx.forgePanel.registerLens({
|
|
112
|
+
id: brandString<ForgeLensId>('example/exports'),
|
|
113
|
+
version: '1',
|
|
114
|
+
async classify(input, signal) {
|
|
115
|
+
const files: Record<string, { ranges: { old: []; new: { start: number; end: number }[] } }> = {}
|
|
116
|
+
for (const file of input.files) {
|
|
117
|
+
const lines = (await input.text('new', file.path, signal))?.split('\n') ?? []
|
|
118
|
+
const ranges = lines.flatMap((line, at) => line.startsWith('export') ? [{ start: at + 1, end: at + 1 }] : [])
|
|
119
|
+
if (ranges.length > 0) files[file.path] = { ranges: { old: [], new: ranges } }
|
|
120
|
+
}
|
|
121
|
+
return { files }
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
A Client plugin names that lens and adds line annotations; `notesOf` returns one stable observable per view, and `NoteBody` is a module-scope component that draws one annotation inside the frame the view draws. The forge tests' [fixture plugin](https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/web/tests/fixtures/plugins/fixture-forge-extension/client.js) also uses the toolbar, file menu, comment form, and card slots.
|
|
128
|
+
|
|
129
|
+
```ts ignore-check
|
|
130
|
+
export const inject = ['forgeChanges', 'slots']
|
|
131
|
+
|
|
132
|
+
export function apply(ctx: Context) {
|
|
133
|
+
ctx.effect(() => ctx.forgeChanges.describeLens({ id: brandString<ForgeLensId>('example/exports'), title: () => 'Exports' }))
|
|
134
|
+
ctx.effect(() => ctx.forgeChanges.registerAnnotations({ id: 'example-notes', observe: target => notesOf(target) }))
|
|
135
|
+
ctx.slots.inject('forge.diff.line.annotation', () => ctx.slots.register(
|
|
136
|
+
{ name: 'forge.diff.line.annotation', key: 'example-notes' }, NoteBody))
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Runnable wirings
|
|
141
|
+
|
|
142
|
+
Shipped applications contribute profile layers through `packages/bundle/*/cordis.patch.yml`, and the product `dsh` launcher owns Web, ACP, SDK, and one-shot headless execution through named profiles. Optional user-facing overlays live under `apps/cli/config/examples/`; profile integration tests live under `apps/cli/tests/profiles/`, while package-specific Loader compositions stay with their package tests.
|
|
143
|
+
|
|
144
|
+
## The feature → mechanism map
|
|
145
|
+
|
|
146
|
+
Every product feature maps to a listener on a documented extension point — the microkernel claim made checkable ([microkernel reference](../index.md)). No row modifies the loop.
|
|
147
|
+
|
|
148
|
+
`system-prompt/assemble` is an expert cooperative whole-assembly transform: its returned assembly is authoritative, so listener authors own preserving active PTC mode and structured-output protocol contributions. Prefer `ctx.tools.restrict()` for tool filtering that must stay aligned across presentation, lookup, and execution.
|
|
149
|
+
|
|
150
|
+
| Product feature | Plugin mechanism |
|
|
151
|
+
|---|---|
|
|
152
|
+
| Hook system (user + project level) | listeners on `agent/created`, `agent/pre-step`, `tools/pre-execute`, `tools/post-execute`, and `agent/turn-stopping`; the waterfalls return typed decisions, while `agent/turn-stopping` may steer another step; the `dsh-hooks-claude-code` / `dsh-hooks-codex` bridges map hook config files onto these extension points |
|
|
153
|
+
| `/goal` | `ctx.goals` owns durable state, `dsh-goal-round-driver` schedules same-session rounds through the public `Agent`, and separate command/tool producers expose human/model control |
|
|
154
|
+
| `/loop` | on the `turn/end` session event, `followup()` the next iteration; or force-continue |
|
|
155
|
+
| Dynamic workflow | `ctx.workflowEngine` + the PTC workflow engine + the `workflow` tool; structured in-process children enforce output with scoped prompt/tool registrations, a monotonic tool guard, final `tools/result` commit (including enclosing `run_code`), and the structured-output execution's monotonic `concludeTurn()` marker |
|
|
156
|
+
| Queued + steering messages | core `Agent.followup()` / `Agent.steer()` |
|
|
157
|
+
| Context compaction (auto + manual) | the `ctx.compaction` seam + `dsh-compaction-basic`; automatic pressure runs on serial `agent/pre-step`, canonical overflow recovery runs on `agent/request-error`, and manual callers use the same compact service ([compaction reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/README.md)) |
|
|
158
|
+
| System prompt configurability | `ctx.systemPrompt.section()` with ordering and scope-local shadowing |
|
|
159
|
+
| AGENTS.md (root) | a section provider reading the file |
|
|
160
|
+
| AGENTS.md (subdir, on-touch) + file-change notices | `agent.inject()` from a watcher / tool-result listener |
|
|
161
|
+
| Built-in tools | `ctx.tools.register()`; schemas flow into the assembly automatically — the `dsh-tool-*` families (bash, fs, web, subagent, todo) are the shipped examples |
|
|
162
|
+
| ToolSearch / progressive disclosure | replace a scoped `ctx.tools.restrict()` registration as the visible set changes; the registry keeps presentation, lookup, and execution aligned |
|
|
163
|
+
| Tool deadline / retry / metrics | wrap core dispatch with `tools/execute`; a wrapper may replace `exec.signal`, delegate, and inspect the normalized result in one lexical lifetime |
|
|
164
|
+
| Final tool-result metrics / audit / capture | observe immutable authoritative outcomes with `tools/result`; use `tools/post-execute` instead only when the plugin must transform the result or attach context |
|
|
165
|
+
| Monotonic terminal turn policy | call `ToolExecution.concludeTurn()` from the successful terminal tool; later tool calls in the same response remain guardable, and the loop stops after the step |
|
|
166
|
+
| Subprocess sandbox (landlock / sandbox-exec) | use a `ctx.sandbox` backend through `dsh-bash-sandbox`; use `tools/pre-execute` for capability-level denial |
|
|
167
|
+
| Permission system / AskUserQuestion | return `ask` from `tools/pre-execute` and answer through `ctx.approval`; register a separate model-facing ask tool for ordinary user questions |
|
|
168
|
+
| Plan mode | [`@deepseek-ai/dsh-plan-mode`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/plan/plan-mode/README.md) — logged `plan/mode` state, the `plan:policy` guidance section, `/plan [message]` entry, `/plan off` direct exit, and the user-reviewed `exit_plan_mode` exit; enforcement stays on the independent sandbox/approval axes |
|
|
169
|
+
| Sub-agent delegation | the `ctx.subagents` provider registry (`dsh-subagent-spawn-in-process`/`dsh-subagent-fork-in-process`/`dsh-subagent-acp`/`dsh-subagent-codex`/`dsh-subagent-claude-code`/`dsh-subagent-dsh-sdk`) + `dsh-tool-subagent` exposing one configured provider to the model |
|
|
170
|
+
| MCP | one plugin per server: discover tools → `ctx.tools.register()` |
|
|
171
|
+
| Skills | section + tool registration; `inject()` skill content on invocation |
|
|
172
|
+
| Memory | section provider + tool |
|
|
173
|
+
| Scheduled tasks (cron) | a plugin registers model-callable scheduling tools; a due timer delivers through `followup(…, {source: {kind: 'schedule'}})` |
|
|
174
|
+
| UI (GUI; CLI emits JSONL) | listen to `agent/assistant-stream` for live chunks and `session/event` for durable settlements, boundaries, and tool activity; input → `followup()` |
|
|
175
|
+
| Web Client Chat business node | register a `ConversationNodeDefinition` and `conversation.chat.node` keyed renderer |
|
|
176
|
+
| SessionTelemetryBackend / replayable trace | `session/event` → JSONL; replay = `sessions.create(id, { seed })` |
|
|
177
|
+
| Model adapters | `LlmAdapter` subclass via `registerAdapter` (`dsh-llm-deepseek`, `dsh-llm-pi-ai`) |
|
|
178
|
+
| Plugin hot-reload | every registration is a `ctx.effect` → vendored HMR just works |
|