dsh-plugin-dev-kb 1.0.0 → 1.0.2

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 (55) hide show
  1. package/README.md +60 -9
  2. package/kb/INDEX.md +1 -1
  3. package/kb/README.md +22 -11
  4. package/kb/extra/development.md +2 -0
  5. package/kb/extra/development.zh.md +2 -0
  6. package/kb/extra/event-producer-consumer.md +9 -9
  7. package/kb/extra/event-producer-consumer.zh.md +9 -9
  8. package/kb/extra/i18n/README.md +1 -1
  9. package/kb/extra/i18n/README.zh.md +1 -1
  10. package/kb/extra/module-graph.md +251 -210
  11. package/kb/extra/module-graph.zh.md +251 -210
  12. package/kb/extra/subsystems/agent-team.md +183 -0
  13. package/kb/extra/subsystems/agent-team.zh.md +183 -0
  14. package/kb/extra/subsystems/attachment.md +16 -2
  15. package/kb/extra/subsystems/attachment.zh.md +16 -2
  16. package/kb/meta/search-index.json +54 -42
  17. package/kb/meta/source.json +3 -3
  18. package/kb/meta/topics.md +1 -1
  19. package/kb/site/en/guide/providers.md +40 -1
  20. package/kb/site/en/reference/capability-seams.md +12 -0
  21. package/kb/site/en/reference/config-catalog.md +238 -72
  22. package/kb/site/en/reference/index.md +2 -0
  23. package/kb/site/en/reference/persistence-catalog.md +76 -13
  24. package/kb/site/en/reference/subsystems/client-modules.md +11 -3
  25. package/kb/site/en/reference/subsystems/commands.md +28 -5
  26. package/kb/site/en/reference/subsystems/index.md +1 -0
  27. package/kb/site/en/reference/subsystems/llm-streaming.md +11 -2
  28. package/kb/site/en/reference/subsystems/persistence.md +3 -3
  29. package/kb/site/en/reference/subsystems/plan.md +1 -1
  30. package/kb/site/en/reference/subsystems/session-reference.md +71 -5
  31. package/kb/site/en/reference/subsystems/session.md +6 -2
  32. package/kb/site/en/reference/subsystems/subagent.md +22 -3
  33. package/kb/site/en/reference/subsystems/web.md +5 -4
  34. package/kb/site/en/reference/tool-catalog.md +353 -5
  35. package/kb/site/guide/providers.md +40 -1
  36. package/kb/site/reference/capability-seams.md +12 -0
  37. package/kb/site/reference/config-catalog.md +252 -86
  38. package/kb/site/reference/index.md +2 -0
  39. package/kb/site/reference/persistence-catalog.md +76 -13
  40. package/kb/site/reference/subsystems/client-modules.md +11 -3
  41. package/kb/site/reference/subsystems/commands.md +28 -5
  42. package/kb/site/reference/subsystems/index.md +1 -0
  43. package/kb/site/reference/subsystems/llm-streaming.md +11 -2
  44. package/kb/site/reference/subsystems/persistence.md +3 -3
  45. package/kb/site/reference/subsystems/plan.md +1 -1
  46. package/kb/site/reference/subsystems/session-reference.md +71 -5
  47. package/kb/site/reference/subsystems/session.md +6 -2
  48. package/kb/site/reference/subsystems/subagent.md +22 -3
  49. package/kb/site/reference/subsystems/web.md +5 -4
  50. package/kb/site/reference/tool-catalog.md +352 -5
  51. package/lib/index.js +113 -0
  52. package/package.json +14 -2
  53. package/scripts/rebuild-index.mjs +2 -1
  54. package/scripts/selfcheck.mjs +30 -0
  55. package/skills/dsh-plugin-dev-kb.md +2 -2
@@ -0,0 +1,183 @@
1
+ # Agent Teams
2
+
3
+ English | [中文](agent-team.zh.md)
4
+
5
+ Types shared by the experimental implicit-root Team domain, model tools, and host adapters. The [Agent Teams Agent Note](../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md) owns identity, mailbox, task, and shared-checkout decisions; this page records the literal durable forms from [`packages/experimental/agent-team/src/types.ts`](../../packages/experimental/agent-team/src/types.ts).
6
+
7
+ ## Identity and roster
8
+
9
+ `TeamId` is the root `SessionId` under a distinct [brand](core.md#branded-ids). `TeamTaskId` is Team-local and monotonically allocated as `task-<n>`; `TeamMessageId` is globally random. A teammate's Session id remains its persistent identity, while `name` is an immutable model/UI label.
10
+
11
+ ```ts type-equiv
12
+ /** Whole durable value written on every teammate lifecycle change. */
13
+ interface TeamMemberSnapshot {
14
+ readonly id: SessionId
15
+ readonly name: string
16
+ readonly description: string
17
+ readonly provider: string
18
+ readonly context: 'fresh' | 'fork'
19
+ readonly phase: TeamMemberPhase
20
+ readonly error?: string
21
+ }
22
+ ```
23
+
24
+ Every member starts in `provisioning` and reaches exactly one terminal roster phase, `active` or `failed`. Runtime `running`/`idle`/`inactive` status is derived separately and never rewrites this record.
25
+
26
+ ## Durable mailbox
27
+
28
+ The Lead Session first stores the complete queued message. A target receipt is acknowledged only after its pending inbox item or recorded user message is durable, leaving queued-minus-delivered as the recovery mailbox.
29
+
30
+ ```ts type-equiv
31
+ /** One peer message retained until its target Session records it. */
32
+ interface TeamMessageSnapshot {
33
+ readonly id: TeamMessageId
34
+ readonly senderId: SessionId
35
+ readonly senderName: string
36
+ readonly targetId: SessionId
37
+ readonly delivery: 'quiet' | 'wakeup'
38
+ readonly content: ContentBlock[]
39
+ }
40
+ ```
41
+
42
+ The target Session keeps message identity and sender attribution on both the pending inbox item and the eventual user message. Folding that source across inbox and history is the target-side de-duplication key; the model-visible framing repeats the id and sender.
43
+
44
+ ```ts type-equiv
45
+ /** Source retained by the target Session for durable mailbox de-duplication. */
46
+ interface TeamMessageSource {
47
+ readonly kind: 'team-message'
48
+ readonly teamId: TeamId
49
+ readonly messageId: TeamMessageId
50
+ readonly senderId: SessionId
51
+ readonly senderName: string
52
+ }
53
+ ```
54
+
55
+ ## Shared task DAG
56
+
57
+ Every task event stores a complete snapshot. `revision` is the compare-and-set value and increments by one per mutation. `blockedBy` edges must name non-deleted tasks and keep the graph acyclic. `writeScopes` are normalized advisory path prefixes rather than locks.
58
+
59
+ ```ts type-equiv
60
+ /** Whole durable task snapshot; every mutation increments {@link revision}. */
61
+ interface TeamTaskSnapshot {
62
+ readonly id: TeamTaskId
63
+ readonly revision: number
64
+ readonly subject: string
65
+ readonly description: string
66
+ readonly status: TeamTaskStatus
67
+ readonly ownerId?: SessionId
68
+ readonly blockedBy: TeamTaskId[]
69
+ readonly writeScopes: string[]
70
+ }
71
+ ```
72
+
73
+ `pending` is unstarted or released, `in_progress` carries an owner, `completed` satisfies blockers, and `deleted` is a retained tombstone. Views add owner name, readiness, and write-scope overlap warnings without changing the durable snapshot.
74
+
75
+ ## Replay
76
+
77
+ `foldTeam()` replays one root Session into the roster, task board, and queued-minus-delivered mailbox that every Team operation reads. It selects records by `TeamId`, so events inherited by an ordinary fork retain the ancestor id and never enter the new root's state. Session event `seq` and `time` remain the ordering and timing record; Team snapshots do not duplicate them. Roster and task reads reach callers as views that add owner name, readiness, and write-scope warnings, while pending mail stays internal to delivery and recovery. The package [README](../../packages/experimental/agent-team/README.md) owns operation, authorization, recovery, and limit behavior.
78
+
79
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
80
+
81
+ <a id="cordis-surface"></a>
82
+
83
+ ## Cordis API
84
+
85
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
86
+
87
+ <a id="ctxagentteams--teamservice"></a>
88
+
89
+ ### `ctx.agentTeams` — `TeamService`
90
+
91
+ Agent Teams service backed by the exact live Lead Session log.
92
+
93
+ ```ts cordis-catalog
94
+ /**
95
+ * Resolve one exact live Agent's Team role.
96
+ * @param agent - exact live Agent used as the authority credential.
97
+ * @returns its root, Team identity, role, and model-facing name.
98
+ */
99
+ membership(agent: Agent): TeamMembership
100
+
101
+ /**
102
+ * List the runtime-enriched roster visible to one Team member.
103
+ * @param agent - exact live Team member.
104
+ * @returns Lead and teammate rows in creation order.
105
+ */
106
+ listMembers(agent: Agent): TeamMemberView[]
107
+
108
+ /**
109
+ * Create one named, continuable direct child of the Team Lead.
110
+ * @param caller - exact live Lead Agent.
111
+ * @param request - immutable name, description, prompt, context mode, provider, and cancellation.
112
+ * @returns the active roster row.
113
+ */
114
+ async spawnTeammate(caller: Agent, request: SpawnTeammateRequest): Promise<SpawnTeammateResult>
115
+
116
+ /**
117
+ * Queue one durable peer message, then attempt immediate delivery.
118
+ * @param caller - exact live sending Team member.
119
+ * @param request - target name, content, scheduling mode, and pre-queue cancellation.
120
+ * @returns durable message identity and immediate-delivery observation.
121
+ */
122
+ async sendMessage(caller: Agent, request: SendTeamMessageRequest): Promise<SendTeamMessageResult>
123
+
124
+ /**
125
+ * Create one unowned pending task in the Team Lead log.
126
+ * @param caller - exact live Team member creating the task.
127
+ * @param request - task text, blockers, and advisory write scopes.
128
+ * @returns the revision-one task view.
129
+ */
130
+ async createTask(caller: Agent, request: CreateTeamTaskRequest): Promise<TeamTaskView>
131
+
132
+ /**
133
+ * Return one task, including a deleted tombstone.
134
+ * @param caller - exact live Team member reading the task.
135
+ * @param id - Team-local task identity.
136
+ * @returns the latest task value and derived readiness diagnostics.
137
+ */
138
+ getTask(caller: Agent, id: TeamTaskId): TeamTaskView
139
+
140
+ /**
141
+ * List current non-deleted tasks in numeric creation order.
142
+ * @param caller - exact live Team member reading the board.
143
+ * @returns detached current task views.
144
+ */
145
+ listTasks(caller: Agent): TeamTaskView[]
146
+
147
+ /**
148
+ * Compare-and-set one authorized task transition.
149
+ * @param caller - exact live Team member authorizing the mutation.
150
+ * @param request - task identity, expected revision, action, and action fields.
151
+ * @returns the committed next task revision.
152
+ */
153
+ async updateTask(caller: Agent, request: UpdateTeamTaskRequest): Promise<TeamTaskView>
154
+
155
+ /**
156
+ * Wait for the next Team-domain or member-status change.
157
+ * @param caller - exact live Team member waiting for activity.
158
+ * @param timeoutMs - bounded wait duration from ten seconds through one hour.
159
+ * @param signal - caller cancellation for the wait only.
160
+ * @returns one observed change or a timeout result.
161
+ */
162
+ async waitForChange(caller: Agent, timeoutMs: number, signal: AbortSignal): Promise<TeamWaitResult>
163
+
164
+ /**
165
+ * Interrupt one live teammate turn without clearing its pending inbox.
166
+ * @param caller - exact live Lead Agent.
167
+ * @param targetName - durable teammate name.
168
+ * @returns the target status sampled before cancellation.
169
+ */
170
+ interrupt(caller: Agent, targetName: string): { previousStatus: 'running' | 'idle' | 'inactive' }
171
+
172
+ /**
173
+ * Resolve a caller without throwing, used by scoped-tool installation and observers.
174
+ * @param agent - candidate exact live Agent.
175
+ * @returns Team membership, or undefined for non-Team subagents and stale identities.
176
+ */
177
+ tryMembership(agent: Agent): TeamMembership | undefined
178
+ ```
179
+
180
+ Types: [Agent](core.md)
181
+
182
+ Source: [`packages/experimental/agent-team/src/index.ts:56`](../../packages/experimental/agent-team/src/index.ts)
183
+ <!-- END GENERATED cordis-surface -->
@@ -0,0 +1,183 @@
1
+ # Agent Teams
2
+
3
+ [English](agent-team.md) | 中文
4
+
5
+ 实验性隐式 Root Team 领域、模型工具与宿主适配器共享的类型。[Agent Teams Agent Note](../../.agents/notes/implemented/feature/2026-08-05-agent-teams.md)负责身份、mailbox、task 与共享 checkout 决策;本页记录 [`packages/experimental/agent-team/src/types.ts`](../../packages/experimental/agent-team/src/types.ts) 中的字面持久形式。
6
+
7
+ ## 身份与 roster
8
+
9
+ `TeamId` 是具有独立[品牌](core.md#branded-ids)的 Root `SessionId`。`TeamTaskId` 在 Team 内按 `task-<n>` 单调分配;`TeamMessageId` 是全局随机值。teammate 的 Session id 始终是持久身份,而 `name` 是不可变的模型/UI 标签。
10
+
11
+ ```ts type-equiv
12
+ /** Whole durable value written on every teammate lifecycle change. */
13
+ interface TeamMemberSnapshot {
14
+ readonly id: SessionId
15
+ readonly name: string
16
+ readonly description: string
17
+ readonly provider: string
18
+ readonly context: 'fresh' | 'fork'
19
+ readonly phase: TeamMemberPhase
20
+ readonly error?: string
21
+ }
22
+ ```
23
+
24
+ 每个 member 都从 `provisioning` 开始,并且只到达一个终态 roster phase:`active` 或 `failed`。运行时 `running`/`idle`/`inactive` 状态单独派生,绝不会重写该记录。
25
+
26
+ ## 持久 mailbox
27
+
28
+ Lead Session 首先存储完整 queued message。只有 target 的 pending inbox 条目或已记录用户消息完成持久化,才会写入独立 acknowledgement event,queued-minus-delivered 因而构成恢复 mailbox。
29
+
30
+ ```ts type-equiv
31
+ /** One peer message retained until its target Session records it. */
32
+ interface TeamMessageSnapshot {
33
+ readonly id: TeamMessageId
34
+ readonly senderId: SessionId
35
+ readonly senderName: string
36
+ readonly targetId: SessionId
37
+ readonly delivery: 'quiet' | 'wakeup'
38
+ readonly content: ContentBlock[]
39
+ }
40
+ ```
41
+
42
+ target Session 会在 pending inbox 条目和最终用户消息上保留消息身份与发送者归因。跨 inbox 与历史折叠该 source 构成 target 侧去重键;模型可见的 framing 会重复 id 和发送者。
43
+
44
+ ```ts type-equiv
45
+ /** Source retained by the target Session for durable mailbox de-duplication. */
46
+ interface TeamMessageSource {
47
+ readonly kind: 'team-message'
48
+ readonly teamId: TeamId
49
+ readonly messageId: TeamMessageId
50
+ readonly senderId: SessionId
51
+ readonly senderName: string
52
+ }
53
+ ```
54
+
55
+ ## 共享任务 DAG
56
+
57
+ 每条 task event 都存储完整快照。`revision` 是 compare-and-set 值,每次变更递增 1。`blockedBy` edge 必须指向未删除任务,并维持无环图。`writeScopes` 是规范化的提示性路径前缀,不是锁。
58
+
59
+ ```ts type-equiv
60
+ /** Whole durable task snapshot; every mutation increments {@link revision}. */
61
+ interface TeamTaskSnapshot {
62
+ readonly id: TeamTaskId
63
+ readonly revision: number
64
+ readonly subject: string
65
+ readonly description: string
66
+ readonly status: TeamTaskStatus
67
+ readonly ownerId?: SessionId
68
+ readonly blockedBy: TeamTaskId[]
69
+ readonly writeScopes: string[]
70
+ }
71
+ ```
72
+
73
+ `pending` 表示尚未开始或已经释放,`in_progress` 携带 owner,`completed` 满足 blocker,`deleted` 是保留的 tombstone。view 会添加 owner name、readiness 和 write-scope 重叠警告,但不会改变持久快照。
74
+
75
+ ## 回放
76
+
77
+ `foldTeam()` 把一个 Root Session 回放成每个 Team 操作所读取的 roster、任务板与 queued-minus-delivered mailbox。它按 `TeamId` 选取记录,因此普通 fork 继承的 event 保留 ancestor id,绝不会进入新 Root 的状态。Session event 的 `seq` 与 `time` 继续负责顺序和时间记录,Team snapshot 不再重复保存它们。roster 与 task 读取以 view 形式到达调用方,附带 owner name、readiness 与 write-scope 警告,而 pending 邮件仅供投递与恢复内部使用。包 [README](../../packages/experimental/agent-team/README.md)负责 operation、authorization、recovery 和限制行为。
78
+
79
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
80
+
81
+ <a id="cordis-surface"></a>
82
+
83
+ ## Cordis API
84
+
85
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
86
+
87
+ <a id="ctxagentteams--teamservice"></a>
88
+
89
+ ### `ctx.agentTeams` — `TeamService`
90
+
91
+ Agent Teams service backed by the exact live Lead Session log.
92
+
93
+ ```ts cordis-catalog
94
+ /**
95
+ * Resolve one exact live Agent's Team role.
96
+ * @param agent - exact live Agent used as the authority credential.
97
+ * @returns its root, Team identity, role, and model-facing name.
98
+ */
99
+ membership(agent: Agent): TeamMembership
100
+
101
+ /**
102
+ * List the runtime-enriched roster visible to one Team member.
103
+ * @param agent - exact live Team member.
104
+ * @returns Lead and teammate rows in creation order.
105
+ */
106
+ listMembers(agent: Agent): TeamMemberView[]
107
+
108
+ /**
109
+ * Create one named, continuable direct child of the Team Lead.
110
+ * @param caller - exact live Lead Agent.
111
+ * @param request - immutable name, description, prompt, context mode, provider, and cancellation.
112
+ * @returns the active roster row.
113
+ */
114
+ async spawnTeammate(caller: Agent, request: SpawnTeammateRequest): Promise<SpawnTeammateResult>
115
+
116
+ /**
117
+ * Queue one durable peer message, then attempt immediate delivery.
118
+ * @param caller - exact live sending Team member.
119
+ * @param request - target name, content, scheduling mode, and pre-queue cancellation.
120
+ * @returns durable message identity and immediate-delivery observation.
121
+ */
122
+ async sendMessage(caller: Agent, request: SendTeamMessageRequest): Promise<SendTeamMessageResult>
123
+
124
+ /**
125
+ * Create one unowned pending task in the Team Lead log.
126
+ * @param caller - exact live Team member creating the task.
127
+ * @param request - task text, blockers, and advisory write scopes.
128
+ * @returns the revision-one task view.
129
+ */
130
+ async createTask(caller: Agent, request: CreateTeamTaskRequest): Promise<TeamTaskView>
131
+
132
+ /**
133
+ * Return one task, including a deleted tombstone.
134
+ * @param caller - exact live Team member reading the task.
135
+ * @param id - Team-local task identity.
136
+ * @returns the latest task value and derived readiness diagnostics.
137
+ */
138
+ getTask(caller: Agent, id: TeamTaskId): TeamTaskView
139
+
140
+ /**
141
+ * List current non-deleted tasks in numeric creation order.
142
+ * @param caller - exact live Team member reading the board.
143
+ * @returns detached current task views.
144
+ */
145
+ listTasks(caller: Agent): TeamTaskView[]
146
+
147
+ /**
148
+ * Compare-and-set one authorized task transition.
149
+ * @param caller - exact live Team member authorizing the mutation.
150
+ * @param request - task identity, expected revision, action, and action fields.
151
+ * @returns the committed next task revision.
152
+ */
153
+ async updateTask(caller: Agent, request: UpdateTeamTaskRequest): Promise<TeamTaskView>
154
+
155
+ /**
156
+ * Wait for the next Team-domain or member-status change.
157
+ * @param caller - exact live Team member waiting for activity.
158
+ * @param timeoutMs - bounded wait duration from ten seconds through one hour.
159
+ * @param signal - caller cancellation for the wait only.
160
+ * @returns one observed change or a timeout result.
161
+ */
162
+ async waitForChange(caller: Agent, timeoutMs: number, signal: AbortSignal): Promise<TeamWaitResult>
163
+
164
+ /**
165
+ * Interrupt one live teammate turn without clearing its pending inbox.
166
+ * @param caller - exact live Lead Agent.
167
+ * @param targetName - durable teammate name.
168
+ * @returns the target status sampled before cancellation.
169
+ */
170
+ interrupt(caller: Agent, targetName: string): { previousStatus: 'running' | 'idle' | 'inactive' }
171
+
172
+ /**
173
+ * Resolve a caller without throwing, used by scoped-tool installation and observers.
174
+ * @param agent - candidate exact live Agent.
175
+ * @returns Team membership, or undefined for non-Team subagents and stale identities.
176
+ */
177
+ tryMembership(agent: Agent): TeamMembership | undefined
178
+ ```
179
+
180
+ Types: [Agent](core.md)
181
+
182
+ Source: [`packages/experimental/agent-team/src/index.ts:56`](../../packages/experimental/agent-team/src/index.ts)
183
+ <!-- END GENERATED cordis-surface -->
@@ -42,6 +42,8 @@ interface ImageAttachmentLimits {
42
42
  maxImagesPerMessage: number
43
43
  maxMessageImageBytes: number
44
44
  maxImagePixels: number
45
+ /** Maximum intrinsic width and maximum intrinsic height in pixels for one image. */
46
+ maxImageDimension: number
45
47
  mediaTypes: readonly ImageMediaType[]
46
48
  }
47
49
  ```
@@ -50,6 +52,18 @@ The reference records intrinsic dimensions and encoded length so clients can lay
50
52
 
51
53
  ## Commit and verified-read payloads
52
54
 
55
+ ```ts type-equiv
56
+ /** Base64-encoded image upload accompanying one wire request. */
57
+ interface EncodedImageAttachment {
58
+ /** Declared media type, verified against the decoded bytes during admission. */
59
+ mediaType: ImageMediaType
60
+ /** Canonical base64 encoding of the image bytes. */
61
+ data: string
62
+ /** Optional display name; it is never interpreted as a path. */
63
+ name?: string
64
+ }
65
+ ```
66
+
53
67
  ```ts type-equiv
54
68
  /** Request to validate and durably commit one image. */
55
69
  interface SaveImageAttachment {
@@ -69,7 +83,7 @@ interface StoredImageAttachment {
69
83
  }
70
84
  ```
71
85
 
72
- `saveImage()` validates bytes and atomically commits one object before returning its reference. `validateImage()` runs the same admission checks without persisting anything; batch callers validate every member through it before saving any member, so validation rejection leaves no partial objects behind. `readImage()` accepts a reference from an authorized session path and returns bytes only after integrity verification. The service is deliberately retention-neutral: resumed and forked sessions may share objects, so reference-aware garbage collection is deferred rather than tied to any one session's deletion.
86
+ `saveImage()` validates bytes and atomically commits one object before returning its reference. `validateImage()` runs the same admission checks without persisting anything; batch callers validate every member through it before saving any member, so validation rejection leaves no partial objects behind. `admitEncodedImages()` is the wire entry for base64 uploads: it enforces canonical base64, then delegates batch admission to `saveImages()`, which owns the count and aggregate-byte limits and the validate-all-before-save order. `readImage()` accepts a reference from an authorized session path and returns bytes only after integrity verification. The service is deliberately retention-neutral: resumed and forked sessions may share objects, so reference-aware garbage collection is deferred rather than tied to any one session's deletion.
73
87
 
74
88
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
75
89
 
@@ -121,5 +135,5 @@ abstract saveImage(input: SaveImageAttachment): Promise<ImageAttachmentRef>
121
135
  abstract readImage(ref: ImageAttachmentRef, signal?: AbortSignal): Promise<StoredImageAttachment>
122
136
  ```
123
137
 
124
- Source: [`packages/attachment/attachment/src/index.ts:31`](../../packages/attachment/attachment/src/index.ts)
138
+ Source: [`packages/attachment/attachment/src/index.ts:33`](../../packages/attachment/attachment/src/index.ts)
125
139
  <!-- END GENERATED cordis-surface -->
@@ -42,6 +42,8 @@ interface ImageAttachmentLimits {
42
42
  maxImagesPerMessage: number
43
43
  maxMessageImageBytes: number
44
44
  maxImagePixels: number
45
+ /** Maximum intrinsic width and maximum intrinsic height in pixels for one image. */
46
+ maxImageDimension: number
45
47
  mediaTypes: readonly ImageMediaType[]
46
48
  }
47
49
  ```
@@ -50,6 +52,18 @@ interface ImageAttachmentLimits {
50
52
 
51
53
  ## 提交与经校验读取的数据
52
54
 
55
+ ```ts type-equiv
56
+ /** Base64-encoded image upload accompanying one wire request. */
57
+ interface EncodedImageAttachment {
58
+ /** Declared media type, verified against the decoded bytes during admission. */
59
+ mediaType: ImageMediaType
60
+ /** Canonical base64 encoding of the image bytes. */
61
+ data: string
62
+ /** Optional display name; it is never interpreted as a path. */
63
+ name?: string
64
+ }
65
+ ```
66
+
53
67
  ```ts type-equiv
54
68
  /** Request to validate and durably commit one image. */
55
69
  interface SaveImageAttachment {
@@ -69,7 +83,7 @@ interface StoredImageAttachment {
69
83
  }
70
84
  ```
71
85
 
72
- `saveImage()` 校验字节并以原子方式提交一个对象,之后才返回其引用。`validateImage()` 执行相同的准入检查,但不持久化任何内容;批量调用方会在保存任何成员前通过它校验所有成员,因此校验拒绝不会留下部分对象。`readImage()` 接受来自已授权会话路径的引用,只在完整性校验通过后返回字节。该服务刻意不规定保留策略:恢复和 fork 后的会话可能共享对象,因此基于引用的垃圾回收会延期实现,而不是与任何一个会话的删除绑定。
86
+ `saveImage()` 校验字节并以原子方式提交一个对象,之后才返回其引用。`validateImage()` 执行相同的准入检查,但不持久化任何内容;批量调用方会在保存任何成员前通过它校验所有成员,因此校验拒绝不会留下部分对象。`admitEncodedImages()` 是面向 base64 上传的 wire 入口:强制执行规范 base64,随后把批量准入委托给 `saveImages()`,由后者负责张数与聚合字节上限以及先全量校验再保存的顺序。`readImage()` 接受来自已授权会话路径的引用,只在完整性校验通过后返回字节。该服务刻意不规定保留策略:恢复和 fork 后的会话可能共享对象,因此基于引用的垃圾回收会延期实现,而不是与任何一个会话的删除绑定。
73
87
 
74
88
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
75
89
 
@@ -121,5 +135,5 @@ abstract saveImage(input: SaveImageAttachment): Promise<ImageAttachmentRef>
121
135
  abstract readImage(ref: ImageAttachmentRef, signal?: AbortSignal): Promise<StoredImageAttachment>
122
136
  ```
123
137
 
124
- Source: [`packages/attachment/attachment/src/index.ts:31`](../../packages/attachment/attachment/src/index.ts)
138
+ Source: [`packages/attachment/attachment/src/index.ts:33`](../../packages/attachment/attachment/src/index.ts)
125
139
  <!-- END GENERATED cordis-surface -->