dsh-plugin-dev-kb 1.0.9 → 1.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.
Files changed (120) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.en.md +6 -6
  3. package/README.md +6 -6
  4. package/kb/INDEX.md +4 -2
  5. package/kb/README.md +4 -4
  6. package/kb/extra/AGENTS.md +1 -1
  7. package/kb/extra/cookbook/adding-a-remote-api.md +197 -0
  8. package/kb/extra/cookbook/adding-a-remote-api.zh.md +197 -0
  9. package/kb/extra/deepseek-llm-api-wire-extensions.md +18 -14
  10. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +18 -14
  11. package/kb/extra/event-producer-consumer.md +44 -43
  12. package/kb/extra/event-producer-consumer.zh.md +47 -46
  13. package/kb/extra/i18n/style-samples.md +2 -2
  14. package/kb/extra/module-graph.md +444 -991
  15. package/kb/extra/module-graph.zh.md +446 -993
  16. package/kb/extra/subsystems/agent-team.md +4 -3
  17. package/kb/extra/subsystems/agent-team.zh.md +4 -3
  18. package/kb/extra/subsystems/attachment.md +157 -4
  19. package/kb/extra/subsystems/attachment.zh.md +157 -4
  20. package/kb/extra/subsystems/feedback.md +2 -2
  21. package/kb/extra/subsystems/feedback.zh.md +2 -2
  22. package/kb/extra/testing.md +6 -2
  23. package/kb/extra/testing.zh.md +6 -2
  24. package/kb/extra/web-styling.md +4 -0
  25. package/kb/extra/web-styling.zh.md +4 -0
  26. package/kb/meta/search-index.json +135 -111
  27. package/kb/meta/site-pages.txt +184 -182
  28. package/kb/meta/source.json +5 -5
  29. package/kb/meta/topics.md +4 -4
  30. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +3 -2
  31. package/kb/site/develop/practice/llm-adapter.md +4 -3
  32. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +3 -2
  33. package/kb/site/en/develop/practice/llm-adapter.md +4 -3
  34. package/kb/site/en/guide/network-proxy.md +87 -0
  35. package/kb/site/en/guide/providers.md +70 -17
  36. package/kb/site/en/guide/schedule.md +2 -0
  37. package/kb/site/en/reference/agent-lifecycle.md +5 -3
  38. package/kb/site/en/reference/api-gateway.md +2 -2
  39. package/kb/site/en/reference/capability-seams.md +14 -7
  40. package/kb/site/en/reference/config-catalog.md +157 -230
  41. package/kb/site/en/reference/cookbook/adding-a-package.md +1 -2
  42. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +10 -8
  43. package/kb/site/en/reference/cookbook/extension-cookbook.md +15 -12
  44. package/kb/site/en/reference/index.md +11 -4
  45. package/kb/site/en/reference/persistence-catalog.md +91 -70
  46. package/kb/site/en/reference/subsystems/code-runtime.md +7 -3
  47. package/kb/site/en/reference/subsystems/commands.md +25 -16
  48. package/kb/site/en/reference/subsystems/compaction.md +9 -9
  49. package/kb/site/en/reference/subsystems/conversation.md +11 -4
  50. package/kb/site/en/reference/subsystems/core.md +96 -15
  51. package/kb/site/en/reference/subsystems/credentials.md +5 -4
  52. package/kb/site/en/reference/subsystems/goal.md +1 -1
  53. package/kb/site/en/reference/subsystems/index.md +1 -1
  54. package/kb/site/en/reference/subsystems/llm-streaming.md +24 -3
  55. package/kb/site/en/reference/subsystems/permission-presets.md +5 -5
  56. package/kb/site/en/reference/subsystems/persistence.md +185 -194
  57. package/kb/site/en/reference/subsystems/plan.md +3 -3
  58. package/kb/site/en/reference/subsystems/sandbox.md +2 -0
  59. package/kb/site/en/reference/subsystems/schedule.md +9 -3
  60. package/kb/site/en/reference/subsystems/session-projection.md +50 -24
  61. package/kb/site/en/reference/subsystems/session-query.md +19 -13
  62. package/kb/site/en/reference/subsystems/session-reference.md +25 -1
  63. package/kb/site/en/reference/subsystems/session-telemetry.md +6 -5
  64. package/kb/site/en/reference/subsystems/session-title.md +6 -6
  65. package/kb/site/en/reference/subsystems/session.md +156 -73
  66. package/kb/site/en/reference/subsystems/settings.md +30 -12
  67. package/kb/site/en/reference/subsystems/skills.md +1 -1
  68. package/kb/site/en/reference/subsystems/slots.md +1 -0
  69. package/kb/site/en/reference/subsystems/storage.md +28 -5
  70. package/kb/site/en/reference/subsystems/subagent.md +43 -97
  71. package/kb/site/en/reference/subsystems/system-prompt.md +16 -3
  72. package/kb/site/en/reference/subsystems/token-meter.md +2 -2
  73. package/kb/site/en/reference/subsystems/typert.md +18 -18
  74. package/kb/site/en/reference/subsystems/web-client.md +1 -1
  75. package/kb/site/en/reference/subsystems/workspace.md +8 -8
  76. package/kb/site/en/reference/tool-catalog.md +10 -64
  77. package/kb/site/guide/network-proxy.md +87 -0
  78. package/kb/site/guide/providers.md +70 -17
  79. package/kb/site/guide/schedule.md +2 -0
  80. package/kb/site/reference/agent-lifecycle.md +5 -3
  81. package/kb/site/reference/api-gateway.md +2 -2
  82. package/kb/site/reference/capability-seams.md +14 -7
  83. package/kb/site/reference/config-catalog.md +156 -229
  84. package/kb/site/reference/cookbook/adding-a-package.md +1 -2
  85. package/kb/site/reference/cookbook/adding-a-settings-card.md +10 -8
  86. package/kb/site/reference/cookbook/extension-cookbook.md +15 -12
  87. package/kb/site/reference/index.md +11 -4
  88. package/kb/site/reference/persistence-catalog.md +91 -70
  89. package/kb/site/reference/subsystems/code-runtime.md +7 -3
  90. package/kb/site/reference/subsystems/commands.md +25 -16
  91. package/kb/site/reference/subsystems/compaction.md +9 -9
  92. package/kb/site/reference/subsystems/conversation.md +11 -4
  93. package/kb/site/reference/subsystems/core.md +96 -15
  94. package/kb/site/reference/subsystems/credentials.md +5 -4
  95. package/kb/site/reference/subsystems/goal.md +1 -1
  96. package/kb/site/reference/subsystems/index.md +1 -1
  97. package/kb/site/reference/subsystems/llm-streaming.md +24 -3
  98. package/kb/site/reference/subsystems/permission-presets.md +5 -5
  99. package/kb/site/reference/subsystems/persistence.md +184 -193
  100. package/kb/site/reference/subsystems/plan.md +3 -3
  101. package/kb/site/reference/subsystems/schedule.md +9 -3
  102. package/kb/site/reference/subsystems/session-projection.md +50 -24
  103. package/kb/site/reference/subsystems/session-query.md +19 -13
  104. package/kb/site/reference/subsystems/session-reference.md +25 -1
  105. package/kb/site/reference/subsystems/session-telemetry.md +6 -5
  106. package/kb/site/reference/subsystems/session-title.md +6 -6
  107. package/kb/site/reference/subsystems/session.md +156 -73
  108. package/kb/site/reference/subsystems/settings.md +30 -12
  109. package/kb/site/reference/subsystems/skills.md +1 -1
  110. package/kb/site/reference/subsystems/slots.md +1 -0
  111. package/kb/site/reference/subsystems/storage.md +28 -5
  112. package/kb/site/reference/subsystems/subagent.md +43 -97
  113. package/kb/site/reference/subsystems/system-prompt.md +16 -3
  114. package/kb/site/reference/subsystems/token-meter.md +2 -2
  115. package/kb/site/reference/subsystems/typert.md +18 -18
  116. package/kb/site/reference/subsystems/web-client.md +1 -1
  117. package/kb/site/reference/subsystems/workspace.md +8 -8
  118. package/kb/site/reference/tool-catalog.md +9 -63
  119. package/package.json +2 -2
  120. package/skills/dsh-plugin-dev-kb.md +4 -4
@@ -24,7 +24,7 @@ packages/<group>/<pkg>/
24
24
 
25
25
  Choose an existing group when one matches the package's role (`core`, `llm`, `shell`, `compaction`, `subagent`, `todo`, `session`, `client`/`host`, `util`, or `test-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.
26
26
 
27
- 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`.
27
+ 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/types/**/*.d.ts`, and package-specific runtime artifacts recognized by the gate; a package that publishes `./invariant` also includes `lib/invariant.js`. 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`.
28
28
 
29
29
  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.
30
30
 
@@ -34,7 +34,6 @@ In-package relative imports use explicit `.ts` specifiers in source (for example
34
34
  |---|---|
35
35
  | `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 |
36
36
  | `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](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/development.md#typescript-project-layout)) |
37
- | `knip.json` | only if the package has entrypoints that repository discovery does not already cover |
38
37
 
39
38
  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](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/AGENTS.md) for the client-side contract.
40
39
 
@@ -10,17 +10,17 @@ The two halves live in one package — the Host half under `src/`, the browser h
10
10
 
11
11
  ## 1. Register the namespace (Host half)
12
12
 
13
- The namespace is the join key, so pick it once and spell it in both halves. A consumer that already has a `cordis.yml` entry should register through `installSettingsSection`, which layers the entry under the user document and keeps working when no settings provider is mounted:
13
+ The namespace is the join key, so pick it once and spell it in both halves. A consumer that already has a `cordis.yml` entry should register through `ctx.settings.installSection()`, which layers the entry under the user document and keeps working when no settings provider is mounted:
14
14
 
15
15
  ```ts
16
16
  import type { Context } from '@deepseek-ai/cordis'
17
- import { installSettingsSection, settingsNamespace } from '@deepseek-ai/dsh-settings'
17
+ import type {} from '@deepseek-ai/dsh-settings'
18
18
  import z from '@deepseek-ai/schemastery'
19
19
 
20
20
  declare function assertReachable(endpoint: string | undefined): void
21
21
  declare function rebuildFromSettings(config: Config): void
22
22
 
23
- export const MY_PLUGIN_NS = settingsNamespace('my-plugin')
23
+ export const MY_PLUGIN_NS = 'my-plugin'
24
24
 
25
25
  export interface Config {
26
26
  endpoint?: string
@@ -34,11 +34,13 @@ export const Config: z<Config> = z.object({
34
34
 
35
35
  export function apply(ctx: Context, config: Config) {
36
36
  let source = () => config
37
- installSettingsSection(ctx, MY_PLUGIN_NS, Config, config, {
38
- // Constraints the schema cannot express refuse the write, not the next use.
39
- validate: value => void assertReachable(value.endpoint),
40
- setSource: (current) => { source = current },
41
- onChange: () => { rebuildFromSettings(source()) },
37
+ ctx.inject(['settings'], (settingsCtx) => {
38
+ settingsCtx.settings.installSection(ctx, MY_PLUGIN_NS, Config, config, {
39
+ // Constraints the schema cannot express refuse the write, not the next use.
40
+ validate: value => void assertReachable(value.endpoint),
41
+ setSource: (current) => { source = current },
42
+ onChange: () => { rebuildFromSettings(source()) },
43
+ })
42
44
  })
43
45
  }
44
46
  ```
@@ -36,12 +36,13 @@ This waterfall is the reorderable policy layer. Use `ctx.tools.guard()` when an
36
36
 
37
37
  ## A UI plugin
38
38
 
39
- A UI plugin renders from the `session/event` feed (the assistant token stream as `assistant/chunk`, plus turn/step boundaries and tool activity), 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).
39
+ 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).
40
40
 
41
41
  ```ts
42
42
  import type { Context } from '@deepseek-ai/cordis'
43
+ import { brandString } from '@deepseek-ai/dsh-brand'
43
44
  import { createUserMessage } from '@deepseek-ai/dsh-llm'
44
- import { SessionId } from '@deepseek-ai/dsh-session'
45
+ import type { SessionId } from '@deepseek-ai/dsh-session'
45
46
 
46
47
  declare function render(text: string): void
47
48
  declare function onUserInput(handler: (text: string) => void): void
@@ -50,12 +51,12 @@ export const name = 'my-ui'
50
51
  export const inject = ['agents']
51
52
 
52
53
  export function apply(ctx: Context) {
53
- ctx.on('session/event', (_session, event) => {
54
- if (event.type === 'assistant/chunk' && event.data.chunk.type === 'text-delta') {
55
- render(event.data.chunk.text)
54
+ ctx.on('agent/assistant-stream', ({ frame }) => {
55
+ if (frame.type === 'chunk' && frame.chunk.type === 'text-delta') {
56
+ render(frame.chunk.text)
56
57
  }
57
58
  })
58
- onUserInput(text => ctx.agents.get(SessionId('client-session'))?.followup(createUserMessage({
59
+ onUserInput(text => ctx.agents.get(brandString<SessionId>('client-session'))?.followup(createUserMessage({
59
60
  content: [{ type: 'text', text }],
60
61
  source: { kind: 'user' },
61
62
  })))
@@ -70,17 +71,19 @@ A *protocol driver* adapts a wire peer to `ctx.agents`; it may serve a UI or an
70
71
 
71
72
  ```ts
72
73
  import type { Context } from '@deepseek-ai/cordis'
74
+ import { expandAssistantStream } from '@deepseek-ai/dsh-llm'
73
75
 
74
76
  export const name = 'my-protocol-bridge'
75
77
  export const inject = ['agents', 'sessions', 'sessionPersistence']
76
78
 
77
79
  export function apply(ctx: Context) {
78
- // Stream every logged assistant text/reasoning delta out to the client.
80
+ // Publish every committed Assistant text delta to the client.
79
81
  ctx.on('session/event', (_session, event) => {
80
- if (event.type === 'assistant/chunk') {
81
- const chunk = event.data.chunk
82
- if (chunk.type === 'text-delta') {
83
- // sendToClient({ kind: 'message_chunk', text: chunk.text })
82
+ if (event.type === 'assistant/message' || event.type === 'assistant/attempt') {
83
+ for (const { chunk } of expandAssistantStream(event.data.stream)) {
84
+ if (chunk.type === 'text-delta') {
85
+ // sendToClient({ kind: 'message_chunk', text: chunk.text })
86
+ }
84
87
  }
85
88
  }
86
89
  })
@@ -124,7 +127,7 @@ Every product feature maps to a listener on a documented extension point — the
124
127
  | Skills | section + tool registration; `inject()` skill content on invocation |
125
128
  | Memory | section provider + tool |
126
129
  | Scheduled tasks (cron) | a plugin registers model-callable scheduling tools; timer fires → `followup(…, {source: {kind: 'plugin', plugin: 'schedule'}})` when idle / `inject()` notification when busy |
127
- | UI (GUI; CLI emits JSONL) | listen `session/event` (assistant chunks, boundaries, tool activity); input → `followup()` |
130
+ | 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()` |
128
131
  | Web Client Chat business node | register a `ConversationNodeDefinition` and `conversation.chat.node` keyed renderer |
129
132
  | SessionTelemetryBackend / replayable trace | `session/event` → JSONL; replay = `sessions.create(id, { seed })` |
130
133
  | Model adapters | `LlmAdapter` subclass via `registerAdapter` (`dsh-llm-deepseek`, `dsh-llm-pi-ai`) |
@@ -86,7 +86,9 @@ turn/start
86
86
  step/start
87
87
  append entered messages as user/message
88
88
  derive model history from the log
89
- agent/request -> llm/stream -> assistant/chunk* -> assistant/message
89
+ agent/request -> llm/stream -> agent/assistant-stream start
90
+ agent/assistant-stream chunk*
91
+ assistant/message | assistant/attempt -> agent/assistant-stream end
90
92
  tool/call* -> tools/pre-execute -> tools/execute -> tools/post-execute -> tool/result*
91
93
  step/end
92
94
  tools owe another request, or next-step input arrived -> claim -> next step
@@ -94,7 +96,7 @@ turn/start
94
96
  turn/end
95
97
  ```
96
98
 
97
- `turn/*`, `step/*`, `user/message`, `assistant/*`, and `tool/*` are durable session events; the rest are live extension points across three domains. `agent/pre-step`, `agent/request`, `llm/stream`, and the three `tools/*` events are waterfalls, whose listeners must call `next()` to delegate; `agent/turn-stopping` is serial and has no `next()`.
99
+ `turn/*`, `step/*`, `user/message`, `assistant/message`, `assistant/attempt`, and `tool/*` are durable session events; the rest are live extension points across three domains. `agent/assistant-stream` publishes process-local start, transient chunk, and end frames. The loop commits the complete compact stream as one message or log-only attempt before a committed end frame, and the Web Session-follow adapter is the live event's only remote consumer. `agent/pre-step`, `agent/request`, `llm/stream`, and the three `tools/*` events are waterfalls, whose listeners must call `next()` to delegate; `agent/turn-stopping` is serial and has no `next()`.
98
100
 
99
101
  Input reaches the driver through one inbox. Some messages wake it immediately; injected context waits in the inbox until another message does.
100
102
 
@@ -104,10 +106,14 @@ Details: the [sequence diagram](./agent-lifecycle.md), the [tool pipeline](./too
104
106
 
105
107
  ## Session log
106
108
 
107
- The session log is the source of the context the model sees. `deriveMessages()` projects model history from it, and raw `assistant/chunk` events preserve replay and UI fidelity. Fork, resume, transcripts, telemetry, and persistence all derive from this stream.
109
+ The session log is the source of the context the model sees. `deriveMessages()` projects model history from it. Each `assistant/message` embeds the exact compact timed stream that produced its assembled content; `assistant/attempt` retains settled failed, retried, cancelled, and stream-error attempts without adding model history. Fork, resume, transcripts, telemetry, and persistence all derive from these durable settlements, while live UI incrementality comes from `agent/assistant-stream`; a hard process loss before settlement leaves no durable attempt stream ([decision](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-09-01-v2-embedded-assistant-streams.md)).
110
+
111
+ Session consumers know only the current logical format. Header-only `stat` and `list` rescan each Session directory, select its numerically highest canonical generation, and translate a supported historical header without loading events or publishing a successor. A stored-session `open` selects that same generation, refuses a future version, or composes the static adjacent migration chain in memory, validates the final result, and exclusively publishes only that version-named successor beside the unchanged source before returning a handle; semantic interrupted-turn repair remains a handle consumer responsibility. JSONL v0 uses `session.jsonl[.zstd]`, v1 and later use lowercase `session.vN.jsonl[.zstd]`, and committed generation paths are never renamed, replaced, or deleted. The JSONL provider owns physical framing, compression, generation selection, and exclusive publication, while each adjacent migration package owns exactly one `vN -> vN+1` step ([decision](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-31-released-session-format-migrations.md)).
108
112
 
109
113
  **Model-visible means logged.** Anything that reaches a model request must be reconstructable from the log, and a runtime invariant asserts it. This is why a new model-visible input requires a new session event: extend `SessionEventMap` and render from the log.
110
114
 
115
+ **Projection seam.** `dsh-session-projection` owns `ctx.sessionProjections`: registered units fold committed events incrementally, host consumers read one typed state with `stateOf()`, and carriers batch cropped client views with `snapshot()`. A host reader either requires this service during activation or fails explicitly when the registry or required key is absent. Contributors may retain `ctx.inject(['sessionProjections'], ...)` registration without silently defaulting a missing host value. The agent loop registers shared `turnBoundary` state for its readers ([decision](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-19-session-projection-mandatory-seam.md)).
116
+
111
117
  ## Capability seams
112
118
 
113
119
  A **seam** is a swappable capability with three roles: a **Service Definition** declaring the interface, a **Service Provider** implementing it, and a **Consumer** using it, commonly a model-facing tool. A package may combine roles, but one role alone is not a seam; adding a capability means designing all three ([capability graph](./capability-seams.md)).
@@ -139,7 +145,8 @@ New behavior attaches to a documented extension point. Changing the loop itself
139
145
  | Add durable session state | extend `SessionEventMap`; render and replay from the log |
140
146
  | Generate session titles | register the sole `ctx.sessionTitle` provider |
141
147
  | Manage a same-session objective | use `ctx.goals`; continue through `agent/*` |
142
- | Fork a live session | `ctx.sessions.fork(source, boundary?, childSessionId?)` |
148
+ | Fork a session at a turn boundary | `ctx.agents.create({ sessionId, seed, meta: { parentSession, seedLength } })` — only agent-loop-published sessions persist |
149
+ | Store sessions in a new backend | implement `SessionPersistence` (`create`/`open`/`stat`/`list`/`export`) over the shared handle scaffolding |
143
150
  | Scope a registration to one agent | use that agent's `agent.ctx` |
144
151
 
145
152
  The [extension cookbook](./cookbook/extension-cookbook.md) maps features to capabilities and indexes the step-by-step guides for [packages](./cookbook/adding-a-package.md), [tools](./cookbook/adding-a-tool.md), [LLM adapters](./cookbook/adding-an-llm-adapter.md), and [settings cards](./cookbook/adding-a-settings-card.md). The [Conversation subsystem](./subsystems/conversation.md) owns Chat-node assembly.