paseo-plugin-zcode-provider 0.0.0-stage → 0.2.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 (141) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +29 -0
  3. package/README.md +112 -2
  4. package/client/account.tsx +827 -0
  5. package/client/diagnostics.tsx +379 -0
  6. package/client/runtime.tsx +296 -0
  7. package/client/settings.tsx +84 -0
  8. package/client/value.tsx +20 -0
  9. package/icon.svg +1 -0
  10. package/index.client.tsx +22 -0
  11. package/index.server.ts +39 -0
  12. package/package.json +77 -4
  13. package/paseo-plugin.json +6 -0
  14. package/server/account.ts +781 -0
  15. package/server/attachments.ts +150 -0
  16. package/server/build-info.ts +2 -0
  17. package/server/conversation.ts +319 -0
  18. package/server/diagnostics.ts +252 -0
  19. package/server/discovery/discover.ts +225 -0
  20. package/server/discovery/manifest.ts +36 -0
  21. package/server/discovery/types.ts +30 -0
  22. package/server/errors.ts +36 -0
  23. package/server/host/bridge.ts +490 -0
  24. package/server/host/schemas.ts +119 -0
  25. package/server/logger.ts +19 -0
  26. package/server/mapping.ts +270 -0
  27. package/server/models.ts +68 -0
  28. package/server/persistence.ts +146 -0
  29. package/server/presentation.ts +470 -0
  30. package/server/provider-status.ts +81 -0
  31. package/server/provider.ts +838 -0
  32. package/server/runtime/managed.ts +501 -0
  33. package/server/runtime/pins.ts +72 -0
  34. package/server/runtime-setup.ts +77 -0
  35. package/server/session-types.ts +49 -0
  36. package/server/session.ts +866 -0
  37. package/server/status.ts +89 -0
  38. package/server/timeline.ts +18 -0
  39. package/server/usage.ts +362 -0
  40. package/server/vendor/zcode/LICENSE +202 -0
  41. package/server/vendor/zcode/NOTICE.md +70 -0
  42. package/server/vendor/zcode/THIRD-PARTY-NOTICES.md +37 -0
  43. package/server/vendor/zcode/packages/model-option-map/src/compiler.ts +92 -0
  44. package/server/vendor/zcode/packages/model-option-map/src/evaluator.ts +214 -0
  45. package/server/vendor/zcode/packages/model-option-map/src/index.ts +5 -0
  46. package/server/vendor/zcode/packages/model-option-map/src/merge-patch.ts +97 -0
  47. package/server/vendor/zcode/packages/model-option-map/src/option-maps.ts +42 -0
  48. package/server/vendor/zcode/packages/model-option-map/src/parser.ts +240 -0
  49. package/server/vendor/zcode/packages/model-option-map/src/tokenizer.ts +141 -0
  50. package/server/vendor/zcode/packages/model-option-map/src/types.ts +36 -0
  51. package/server/vendor/zcode/packages/rpc/src/buffer.ts +88 -0
  52. package/server/vendor/zcode/packages/rpc/src/channelClient.ts +275 -0
  53. package/server/vendor/zcode/packages/rpc/src/channelServer.ts +283 -0
  54. package/server/vendor/zcode/packages/rpc/src/channels.shared.ts +66 -0
  55. package/server/vendor/zcode/packages/rpc/src/channels.ts +4 -0
  56. package/server/vendor/zcode/packages/rpc/src/delayedChannel.ts +17 -0
  57. package/server/vendor/zcode/packages/rpc/src/foundation.ts +260 -0
  58. package/server/vendor/zcode/packages/rpc/src/protocol.ts +397 -0
  59. package/server/vendor/zcode/packages/rpc/src/proxy-channel.ts +213 -0
  60. package/server/vendor/zcode/packages/rpc/src/serialization.ts +291 -0
  61. package/server/vendor/zcode/packages/shared/src/account-provider-state.ts +13 -0
  62. package/server/vendor/zcode/packages/shared/src/background-bash-output.ts +24 -0
  63. package/server/vendor/zcode/packages/shared/src/background-task-controls.ts +404 -0
  64. package/server/vendor/zcode/packages/shared/src/bash-output-display.ts +11 -0
  65. package/server/vendor/zcode/packages/shared/src/bots.ts +558 -0
  66. package/server/vendor/zcode/packages/shared/src/browser-use/backend.ts +80 -0
  67. package/server/vendor/zcode/packages/shared/src/browser-use/command-metadata.ts +170 -0
  68. package/server/vendor/zcode/packages/shared/src/browser-use/commands.ts +588 -0
  69. package/server/vendor/zcode/packages/shared/src/browser-use/result.ts +130 -0
  70. package/server/vendor/zcode/packages/shared/src/browser-use/snapshot.ts +77 -0
  71. package/server/vendor/zcode/packages/shared/src/command-types.ts +96 -0
  72. package/server/vendor/zcode/packages/shared/src/config-schema.ts +8 -0
  73. package/server/vendor/zcode/packages/shared/src/cuaAccessibilitySettings.ts +41 -0
  74. package/server/vendor/zcode/packages/shared/src/database-startup.ts +178 -0
  75. package/server/vendor/zcode/packages/shared/src/env.ts +63 -0
  76. package/server/vendor/zcode/packages/shared/src/execution-output-preview.ts +14 -0
  77. package/server/vendor/zcode/packages/shared/src/localTtft.ts +192 -0
  78. package/server/vendor/zcode/packages/shared/src/model-config.ts +123 -0
  79. package/server/vendor/zcode/packages/shared/src/model-execution.ts +23 -0
  80. package/server/vendor/zcode/packages/shared/src/model-provider-family.ts +171 -0
  81. package/server/vendor/zcode/packages/shared/src/model-provider-types.ts +81 -0
  82. package/server/vendor/zcode/packages/shared/src/model-selection.ts +60 -0
  83. package/server/vendor/zcode/packages/shared/src/oauth.ts +203 -0
  84. package/server/vendor/zcode/packages/shared/src/official-mcp-auth.ts +272 -0
  85. package/server/vendor/zcode/packages/shared/src/official-mcp-tool-error.ts +68 -0
  86. package/server/vendor/zcode/packages/shared/src/process-diagnostic.ts +42 -0
  87. package/server/vendor/zcode/packages/shared/src/protocol.ts +369 -0
  88. package/server/vendor/zcode/packages/shared/src/provider-family-connection-selection.ts +32 -0
  89. package/server/vendor/zcode/packages/shared/src/remoteAssetInstallMode.ts +11 -0
  90. package/server/vendor/zcode/packages/shared/src/remoteResourcePackages.ts +91 -0
  91. package/server/vendor/zcode/packages/shared/src/runtimeEnv.ts +315 -0
  92. package/server/vendor/zcode/packages/shared/src/settings-source.ts +10 -0
  93. package/server/vendor/zcode/packages/shared/src/usage-quota.ts +74 -0
  94. package/server/vendor/zcode/packages/shared/src/usage-stats.ts +462 -0
  95. package/server/vendor/zcode/packages/shared/src/validationAppSettings.ts +562 -0
  96. package/server/vendor/zcode/packages/shared/src/workspacePurpose.ts +2 -0
  97. package/server/vendor/zcode/packages/shared/src/wslUserValidation.ts +33 -0
  98. package/server/vendor/zcode/packages/shared/src/zcode-agent-policy.ts +25 -0
  99. package/server/vendor/zcode/packages/shared/src/zcode-media-policy.ts +10 -0
  100. package/server/vendor/zcode/packages/shared/src/zcode-protocol/index.ts +3720 -0
  101. package/server/vendor/zcode/packages/shared/src/zcode-protocol-legacy-types.ts +529 -0
  102. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/apply.ts +218 -0
  103. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/attachment-ref.ts +14 -0
  104. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/command.ts +482 -0
  105. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/core.ts +100 -0
  106. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/create-workflow-display.ts +156 -0
  107. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/cuaPermission.ts +41 -0
  108. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/delta.ts +147 -0
  109. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/input-intent.ts +69 -0
  110. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/rows.ts +432 -0
  111. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/session-config.ts +43 -0
  112. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index-workflow-activity.ts +195 -0
  113. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index.ts +85 -0
  114. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/shared-context-import.ts +38 -0
  115. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/shared-context-ref.ts +10 -0
  116. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/snapshot.ts +509 -0
  117. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/submission.ts +5 -0
  118. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/toolDisplay.ts +264 -0
  119. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/transport.ts +1152 -0
  120. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-assembler.ts +574 -0
  121. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-binary.ts +65 -0
  122. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-codec.ts +240 -0
  123. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-fault.ts +39 -0
  124. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire.ts +159 -0
  125. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-artifacts.ts +291 -0
  126. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-observation-display.ts +281 -0
  127. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-row-meta.ts +163 -0
  128. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-run-settings-command.ts +62 -0
  129. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs-delta.ts +517 -0
  130. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs.ts +512 -0
  131. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workspace-config.ts +81 -0
  132. package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workspace-hook-review.ts +210 -0
  133. package/server/vendor/zcode/packages/shared/src/zcode-task-mode-schema.ts +6 -0
  134. package/server/vendor/zcode/packages/shared/src/zcode-task-types-core.ts +1187 -0
  135. package/server/vendor/zcode/packages/shared/src/zcodeEndpoint.ts +296 -0
  136. package/server/vendor/zcode/provenance.json +405 -0
  137. package/shared/account.ts +201 -0
  138. package/shared/diagnostics.ts +52 -0
  139. package/shared/runtime-setup.ts +73 -0
  140. package/vendor/acp-registry/LICENSE +176 -0
  141. package/vendor/paseo/LICENSE +211 -0
@@ -0,0 +1,291 @@
1
+ // ============================================================
2
+ // 用户面产物(artifact)的协议词汇表
3
+ // ============================================================
4
+ // ⚠ 术语:
5
+ // 本模块的 artifact 是**脚本经 `artifact.*` 发布给用户看的产出**——一个文件、一段 markdown、
6
+ // 或一张由 `report` 流喂养的预置看板。它与同目录 `workflow-artifact.ts`(单数)里的
7
+ // `serializeWorkflowArtifact` **不是一回事**:那个 artifact 是引擎内部对「脚本顶层返回值」
8
+ // 的叫法(`RunSettlement.artifact`),是给**模型**看的。两个文件名只差一个 s,读代码时按
9
+ // 这条注释区分,不要靠文件名。
10
+ //
11
+ // 本模块只放 schema + 三条 v4 查询的参数/结果形状。状态键上的**摘要**元素
12
+ // (`workflowRuns[].artifacts`)也住这里而不是 workflow-runs.ts:它与三条查询共享
13
+ // `kind` 的枚举与「不带 spec、不带字节、不带 items」这条裁剪规则,拆开两处早晚漂移。
14
+ //
15
+ // 分层:字节永不进任何一个 schema(除 `workflowRunArtifactRead` 一次一块的 base64)。
16
+ // 权威在 journal——`workflowRuns.artifacts` 只是「有没有变」的信号。
17
+
18
+ import { z } from "zod";
19
+
20
+ import { PROTOCOL_V4_LIMITS } from "./core.js";
21
+
22
+ /**
23
+ * 用户面产物的成员种类,= facade `artifact.*` 的六个成员。
24
+ *
25
+ * 两族:内容成员(`file` / `markdown`)有字节与版本历史;预置看板
26
+ * (`chart` / `table` / `metrics` / `board`)没有字节,它的每一个点都是一条打了标签的
27
+ * `report` journal 行(看板是 journal 的投影)。
28
+ *
29
+ * 闭集枚举。加值是**破坏性**的偏斜(旧读端整帧拒收),与 `workflowRuns[].status` 同一档。
30
+ */
31
+ export const workflowRunArtifactKindSchema = z.enum([
32
+ "file",
33
+ "markdown",
34
+ "chart",
35
+ "table",
36
+ "metrics",
37
+ "board",
38
+ ]);
39
+ export type WorkflowRunArtifactKind = z.infer<typeof workflowRunArtifactKindSchema>;
40
+
41
+ /** 产物字段的展示上界。数字即契约——engine 侧的同名上限在 `ARTIFACT_CAPS`。 */
42
+ export const WORKFLOW_ARTIFACT_LIMITS = {
43
+ maxIdLength: 64,
44
+ maxTitleLength: 120,
45
+ maxDescriptionLength: 500,
46
+ /** 每 id ≤ 16 版(`ARTIFACT_CAPS.maxVersionsPerArtifact`)。 */
47
+ maxVersions: 16,
48
+ /** `workflowRunArtifactData` 一页的条目上界;`limit` 的钳制在网关侧。 */
49
+ maxItemsPerPage: 500,
50
+ /** 一页的缺省条数(调用方不传 limit 时网关用它)。 */
51
+ defaultItemsPerPage: 200,
52
+ } as const;
53
+
54
+ /**
55
+ * 一个产物版本的**元数据**(journal `dwf_node.result_json` 上 `ArtifactVersionRecord` 的
56
+ * zod 镜像)。字节不在这里——`uri` 指向 tool-artifact store,取字节走
57
+ * `workflowRunArtifactRead`。
58
+ *
59
+ * `publishedAt` **必填**:driver 在每条记录上恒写 `Date.now()`(引擎
60
+ * 自己没有时钟,所以纯包侧的 TS 类型仍是 optional)。这里必填是让「版本没有时刻」在协议
61
+ * 边界上就红掉,而不是让 UI 的版本步进器拿到一个 undefined 去排序。
62
+ */
63
+ export const workflowRunArtifactVersionSchema = z
64
+ .object({
65
+ version: z.number().int().positive().max(WORKFLOW_ARTIFACT_LIMITS.maxVersions),
66
+ title: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxTitleLength).optional(),
67
+ description: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxDescriptionLength).optional(),
68
+ contentType: z.string().min(1).max(128).optional(),
69
+ /** 该版本在 store 里的字节数(内容成员才有)。 */
70
+ bytes: z.number().int().nonnegative().optional(),
71
+ /** store 的 `zcode-artifact://…`;**只给 CLI 侧用**,模型与 renderer 都读不了它。 */
72
+ uri: z.string().min(1).max(512).optional(),
73
+ /** 工作区相对的原路径(`file` 才有)——卡片的「在工作区显示」按它定位。 */
74
+ sourcePath: z.string().min(1).max(1024).optional(),
75
+ /** 预置看板的 spec(canonical)。形状由 UI 的四个渲染器各自解释,协议不复述。 */
76
+ spec: z.unknown().optional(),
77
+ /** 发布时刻(epoch 毫秒)。 */
78
+ publishedAt: z.number().int().nonnegative(),
79
+ /** 这一版属于 run 的交付物;引擎盖章,按 id 粘着。 */
80
+ primary: z.literal(true).optional(),
81
+ })
82
+ .strict();
83
+ export type WorkflowRunArtifactVersion = z.infer<typeof workflowRunArtifactVersionSchema>;
84
+
85
+ /**
86
+ * 一个产物的**全部**版本 + 喂给它的标签 report 计数。`workflowRunArtifacts` 查询的元素,
87
+ * 也是冷恢复与中枢详情的 durable 读法。
88
+ *
89
+ * 顶层的 `title` / `description` / `contentType` / `sourcePath` / `spec` 取**最新版**的值:
90
+ * 只关心「现在是什么」的读者不必自己翻 `versions`。与 contracts 的
91
+ * `DynamicWorkflowRunArtifact` 同形(那边是 TS 镜像,这边是线上校验)。
92
+ */
93
+ export const workflowRunArtifactSchema = z
94
+ .object({
95
+ id: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxIdLength),
96
+ kind: workflowRunArtifactKindSchema,
97
+ title: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxTitleLength).optional(),
98
+ description: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxDescriptionLength).optional(),
99
+ contentType: z.string().min(1).max(128).optional(),
100
+ sourcePath: z.string().min(1).max(1024).optional(),
101
+ spec: z.unknown().optional(),
102
+ /** 最新版号(= `versions` 末项的 version)。 */
103
+ version: z.number().int().positive().max(WORKFLOW_ARTIFACT_LIMITS.maxVersions),
104
+ /** 版本升序。失败的发布**不在**这里:失败行不认领 id / 种类 / 版本。 */
105
+ versions: z.array(workflowRunArtifactVersionSchema).max(WORKFLOW_ARTIFACT_LIMITS.maxVersions),
106
+ /** 打了这个 id 标签的 `report` 条目数(预置看板的数据量;内容产物恒 0)。 */
107
+ itemCount: z.number().int().nonnegative(),
108
+ /** run 的交付物(至多一件);清单以它带头。 */
109
+ primary: z.literal(true).optional(),
110
+ })
111
+ .strict();
112
+ export type WorkflowRunArtifact = z.infer<typeof workflowRunArtifactSchema>;
113
+
114
+ /**
115
+ * `workflowRuns[].artifacts` 的元素:**只带最新版的元数据**。
116
+ *
117
+ * 刻意不带 `versions` / `spec` / `sourcePath` / `uri`,更不带字节或条目:这是一个高频状态键,
118
+ * 而它的读者只需要知道「有哪些产物、现在是第几版、变了没有」。真要看内容,两条 query
119
+ * (`workflowRunArtifacts` 取全量元数据、`workflowRunArtifactData` 取看板条目、
120
+ * `workflowRunArtifactRead` 取字节)按需拉——权威始终在 journal。
121
+ *
122
+ * `itemCount` 在这里的职责是**刷新信号**:看板 hook 见它变化就带 `afterSequence` 增量取数。
123
+ * 把标签 report 的原值放进快照会让 256 条 × 32KB 的最坏情形把状态帧撑到 2MB。
124
+ */
125
+ export const workflowRunArtifactSummarySchema = z
126
+ .object({
127
+ id: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxIdLength),
128
+ kind: workflowRunArtifactKindSchema,
129
+ title: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxTitleLength).optional(),
130
+ version: z.number().int().positive().max(WORKFLOW_ARTIFACT_LIMITS.maxVersions),
131
+ contentType: z.string().min(1).max(128).optional(),
132
+ bytes: z.number().int().nonnegative().optional(),
133
+ itemCount: z.number().int().nonnegative().optional(),
134
+ /** run 的交付物(至多一件)。UI 据它排先后与选形态;缺席即不是。 */
135
+ primary: z.literal(true).optional(),
136
+ })
137
+ .strict();
138
+ export type WorkflowRunArtifactSummary = z.infer<typeof workflowRunArtifactSummarySchema>;
139
+
140
+ // ── v4 query ①:workflowRunArtifacts(产物清单)──
141
+ // 与 workflowRunEvents 同族:只读、无状态、超时重发安全,刻意不是 v4 command。
142
+ // 同样**不带** atSeq / atLogEpoch:读的是 journal,与 conversation log 无关,没有陈旧可防
143
+ // (完整论证见 transport.ts 里 workflowRunEvents 结果 schema 之后那段注释)。
144
+ // 新方法天然偏斜安全——旧桌面根本不会调用它。
145
+ export const v4ConversationWorkflowRunArtifactsParamsSchema = z
146
+ .object({
147
+ sessionId: z.string().min(1),
148
+ runId: z.string().min(1),
149
+ })
150
+ .strict();
151
+ export type V4ConversationWorkflowRunArtifactsParams = z.infer<
152
+ typeof v4ConversationWorkflowRunArtifactsParamsSchema
153
+ >;
154
+
155
+ export const v4ConversationWorkflowRunArtifactsResultSchema = z
156
+ .object({
157
+ /** 按首次出现顺序(= journal 里该 id 第一条 artifact 行的 ordinal)。 */
158
+ artifacts: z.array(workflowRunArtifactSchema),
159
+ })
160
+ .strict();
161
+ export type V4ConversationWorkflowRunArtifactsResult = z.infer<
162
+ typeof v4ConversationWorkflowRunArtifactsResultSchema
163
+ >;
164
+
165
+ // ── v4 query ②:workflowRunArtifactData(预置看板的取数面)──
166
+ // 刻意**不复用** workflowRunEvents:那要翻整条 journal 才筛得出一个 id 的条目。
167
+ // cursor = journal sequence(与事件日志同一个游标语义,`afterSequence` 严格大于)。
168
+ export const v4ConversationWorkflowRunArtifactDataParamsSchema = z
169
+ .object({
170
+ sessionId: z.string().min(1),
171
+ runId: z.string().min(1),
172
+ artifactId: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxIdLength),
173
+ /** 只取 sequence 严格大于该值的条目;缺省从头取。 */
174
+ afterSequence: z.number().int().nonnegative().optional(),
175
+ /** 缺省 200、钳 [1, 500]——两者都在网关侧执行(存储层不得自造页大小,也不得再钳)。 */
176
+ limit: z.number().int().positive().max(WORKFLOW_ARTIFACT_LIMITS.maxItemsPerPage).optional(),
177
+ })
178
+ .strict();
179
+ export type V4ConversationWorkflowRunArtifactDataParams = z.infer<
180
+ typeof v4ConversationWorkflowRunArtifactDataParamsSchema
181
+ >;
182
+
183
+ export const v4ConversationWorkflowRunArtifactDataResultSchema = z
184
+ .object({
185
+ items: z.array(
186
+ z
187
+ .object({
188
+ /** journal sequence——回传成 `afterSequence` 就是下一页的游标。 */
189
+ sequence: z.number().int().nonnegative(),
190
+ /** 产出该条目的 report 站点(如 `report#1`)。 */
191
+ siteId: z.string().min(1).max(64),
192
+ ordinal: z.number().int().nonnegative(),
193
+ /**
194
+ * 条目原值,**不做预览序列化**:看板的纯函数要按字段路径取数
195
+ * (`ChartSpec.x.field` 形如 "timing.after"),拿到一段 pretty JSON 文本就没法取了。
196
+ * 单条在线上已由 `REPORT_CAPS.maxItemSerializedBytes`(32KB)与事件载荷有界化
197
+ * 双重保证,这里不再叠一层界。
198
+ */
199
+ item: z.unknown(),
200
+ })
201
+ .strict(),
202
+ ),
203
+ /** 本页取满 limit 且后面仍有条目(网关多取一条判定)。 */
204
+ hasMore: z.boolean(),
205
+ })
206
+ .strict();
207
+ export type V4ConversationWorkflowRunArtifactDataResult = z.infer<
208
+ typeof v4ConversationWorkflowRunArtifactDataResultSchema
209
+ >;
210
+
211
+ // ── v4 query ③:workflowRunArtifactRead(内容产物的字节)──
212
+ // **逐字照 `v4AttachmentRead*`**:≤ 512 KiB 一块(PROTOCOL_V4_LIMITS.attachmentChunkMaxBytes,
213
+ // 同一个常量,不另铸),host→CLI 每请求 ≤ 1 MiB 的既有证明因此原样沿用。
214
+ //
215
+ // 刻意不复用 attachmentRead 本身:它按 conversation 的 user row 授权,而产物不挂在任何消息
216
+ // 行上。授权链在 CLI 侧:sessionId 必须是该 run 的 parentSessionId ∧
217
+ // (artifactId, version) 在 journal 有 completed 行 ⇒ 才拿行上的 uri 去 store 读。
218
+ // renderer 传来的任何 id **绝不**直接成为路径——与 attachmentRead 同一条纪律。
219
+ export const v4ConversationWorkflowRunArtifactReadParamsSchema = z
220
+ .object({
221
+ sessionId: z.string().min(1),
222
+ runId: z.string().min(1),
223
+ artifactId: z.string().min(1).max(WORKFLOW_ARTIFACT_LIMITS.maxIdLength),
224
+ version: z.number().int().positive().max(WORKFLOW_ARTIFACT_LIMITS.maxVersions),
225
+ offset: z.number().int().nonnegative(),
226
+ limit: z.number().int().positive().max(PROTOCOL_V4_LIMITS.attachmentChunkMaxBytes),
227
+ })
228
+ .strict();
229
+ export type V4ConversationWorkflowRunArtifactReadParams = z.infer<
230
+ typeof v4ConversationWorkflowRunArtifactReadParamsSchema
231
+ >;
232
+
233
+ export const v4ConversationWorkflowRunArtifactReadResultSchema = z
234
+ .object({
235
+ /** base64(不带 data: 前缀);解码后 ≤ attachmentChunkMaxBytes。 */
236
+ dataBase64: z.string(),
237
+ /**
238
+ * 该版本的 contentType,取 journal 记录上的值(driver 按扩展名表算出、`opts.contentType`
239
+ * 可覆盖)——那是 UI 分派渲染器的**精确匹配**契约。刻意不像 attachmentRead 那样把
240
+ * mediaType 限死在 image/video/pdf:产物的合法类型就是 driver 那张 17 项扩展名表加
241
+ * `application/octet-stream`,限死会让 markdown 与 office 文件整条读不出来。
242
+ */
243
+ mediaType: z.string().min(1).max(128),
244
+ /** 该版本的总字节数(≤ ARTIFACT_CAPS.maxFileBytes = attachmentMaxBytes)。 */
245
+ totalBytes: z.number().int().nonnegative().max(PROTOCOL_V4_LIMITS.attachmentMaxBytes),
246
+ /** 下一块的 offset;本块读到尾时为 null。 */
247
+ nextOffset: z.number().int().positive().nullable(),
248
+ })
249
+ .strict()
250
+ .superRefine((value, context) => {
251
+ const decodedBytes = decodedBase64ByteLength(value.dataBase64);
252
+ if (decodedBytes === null) {
253
+ context.addIssue({ code: "custom", message: "invalid base64", path: ["dataBase64"] });
254
+ return;
255
+ }
256
+ if (decodedBytes > PROTOCOL_V4_LIMITS.attachmentChunkMaxBytes) {
257
+ context.addIssue({
258
+ code: "too_big",
259
+ maximum: PROTOCOL_V4_LIMITS.attachmentChunkMaxBytes,
260
+ origin: "string",
261
+ inclusive: true,
262
+ message: "workflow artifact read chunk exceeds decoded byte limit",
263
+ path: ["dataBase64"],
264
+ });
265
+ }
266
+ if (value.nextOffset !== null && value.nextOffset > value.totalBytes) {
267
+ context.addIssue({
268
+ code: "custom",
269
+ message: "nextOffset exceeds totalBytes",
270
+ path: ["nextOffset"],
271
+ });
272
+ }
273
+ });
274
+ export type V4ConversationWorkflowRunArtifactReadResult = z.infer<
275
+ typeof v4ConversationWorkflowRunArtifactReadResultSchema
276
+ >;
277
+
278
+ /**
279
+ * base64 字符串的解码字节数,非法输入回 null。
280
+ *
281
+ * 与 transport.ts 里同名的私有 helper 逐字相同,而不是把那个导出过来:那个文件不导出它,
282
+ * 而 import 它会成环——transport.ts → snapshot.ts → workflow-runs.ts → 本模块。十行纯算术
283
+ * 复制一份,比为它开一个新的公共模块便宜——两处若漂移,双方的 superRefine 测试都会红。
284
+ */
285
+ function decodedBase64ByteLength(value: string): number | null {
286
+ if (value.length === 0) return 0;
287
+ if (value.length % 4 !== 0) return null;
288
+ if (!/^[A-Za-z0-9+/]+={0,2}$/.test(value)) return null;
289
+ const padding = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
290
+ return (value.length / 4) * 3 - padding;
291
+ }
@@ -0,0 +1,281 @@
1
+ // ============================================================
2
+ // 观察类工作流工具(GetWorkflowRun / ListWorkflowRuns / EvalWorkflowSnippet /
3
+ // ListSavedWorkflows / ListModels)的工具卡 display 载荷
4
+ // ============================================================
5
+ // 照 create-workflow-display.ts 的先例单独成模块(特性级 schema 不堆进 toolDisplay.ts)。
6
+ //
7
+ // ⚠ 与 apps/zcode-cli/packages/contracts/src/tools/workflow-observation-display.ts 的
8
+ // toolResultDisplayPayloadSchema 成员必须同步——两侧都是 strict,少一侧整条 row/display
9
+ // 校验失败、工具卡退化成文本(create_workflow display 注释记录过同款坑)。
10
+ // 限长常量与 CLI 构造侧一一对应;display 不经过 result budget。
11
+
12
+ import { z } from "zod";
13
+
14
+ /** `stopped` 的原因。 */
15
+ export const WORKFLOW_RUN_STOP_REASONS = [
16
+ "user",
17
+ "model",
18
+ "provider",
19
+ "interrupted",
20
+ "superseded",
21
+ ] as const;
22
+
23
+ export const WORKFLOW_RUN_OBSERVATION_STATUSES = [
24
+ "pending",
25
+ "running",
26
+ "completed",
27
+ "errored",
28
+ "stopped",
29
+ ] as const;
30
+
31
+ const usageSchema = z
32
+ .object({
33
+ spentTokens: z.number(),
34
+ nodesObserved: z.number(),
35
+ nodesRunning: z.number(),
36
+ nodesCompleted: z.number(),
37
+ nodesFailed: z.number(),
38
+ })
39
+ .strict();
40
+
41
+ const actorSchema = z
42
+ .object({
43
+ siteId: z.string(),
44
+ ordinal: z.number(),
45
+ name: z.string().optional(),
46
+ })
47
+ .strict();
48
+
49
+ // 情势截面(阶段 / 子代理 / 健康)的卡面载荷。与 CLI 侧
50
+ // getWorkflowRunToolResultDisplayPayloadSchema 的对应成员**逐字段同步**,枚举集闭合且同词表——
51
+ // 两侧都是 strict,少一个字段或多一个枚举值,整条 row/display 校验失败、工具卡退化成文本。
52
+ // 数字界与 CLI 侧常量一一对应(32 阶段 / 64 子代理 / 240 指令头 / 400 摘要)。
53
+ const workflowRunPhaseViewSchema = z
54
+ .object({
55
+ name: z.string().min(1).max(128),
56
+ state: z.enum(["done", "current", "ahead", "unfinished"]),
57
+ rounds: z.number().int().nonnegative(),
58
+ nodesSettled: z.number().int().nonnegative(),
59
+ nodesRunning: z.number().int().nonnegative(),
60
+ enteredAt: z.number().optional(),
61
+ exitedAt: z.number().optional(),
62
+ })
63
+ .strict();
64
+
65
+ const workflowRunLastToolSchema = z
66
+ .object({
67
+ name: z.string().min(1).max(64),
68
+ target: z.string().max(120).optional(),
69
+ at: z.number().optional(),
70
+ })
71
+ .strict();
72
+
73
+ const workflowRunSubagentViewSchema = z
74
+ .object({
75
+ siteId: z.string().min(1),
76
+ ordinal: z.number().int().nonnegative(),
77
+ name: z.string().max(128).optional(),
78
+ state: z.enum(["idle", "executing", "waiting", "parked", "done", "failed", "unfinished"]),
79
+ phaseName: z.string().max(128).optional(),
80
+ instructionsHead: z.string().max(240).optional(),
81
+ startedAt: z.number().optional(),
82
+ turn: z.number().int().nonnegative().optional(),
83
+ toolCalls: z.number().int().nonnegative().optional(),
84
+ lastTool: workflowRunLastToolSchema.optional(),
85
+ waitCause: z.enum(["slot", "backoff"]).optional(),
86
+ retryAfterMs: z.number().nonnegative().optional(),
87
+ waitSince: z.number().optional(),
88
+ parkedOn: z.string().optional(),
89
+ stepsSettled: z.number().int().nonnegative(),
90
+ stepsFailed: z.number().int().nonnegative(),
91
+ tokens: z.number().int().nonnegative(),
92
+ lastProgressAt: z.number().optional(),
93
+ })
94
+ .strict();
95
+
96
+ const workflowRunHealthSchema = z
97
+ .object({
98
+ lastProgressAt: z.number().optional(),
99
+ stalledSince: z.number().optional(),
100
+ concurrency: z
101
+ .object({
102
+ effective: z.number().int().nonnegative(),
103
+ cap: z.number().int().positive(),
104
+ reason: z.string().max(240).optional(),
105
+ since: z.number().optional(),
106
+ })
107
+ .strict()
108
+ .optional(),
109
+ consecutiveFailures: z.number().int().nonnegative(),
110
+ cachedSteps: z.number().int().nonnegative(),
111
+ leftoverRunning: z.number().int().positive().optional(),
112
+ pendingQuestionsKnown: z.boolean(),
113
+ })
114
+ .strict();
115
+
116
+ const diagnosticSchema = z
117
+ .object({
118
+ line: z.number().int().nonnegative(),
119
+ column: z.number().int().nonnegative(),
120
+ code: z.number().int().nonnegative(),
121
+ message: z.string().min(1).max(2_048),
122
+ })
123
+ .strict();
124
+
125
+ const workflowRunSummaryRowSchema = z
126
+ .object({
127
+ runId: z.string().min(1),
128
+ label: z.string(),
129
+ labelSource: z.enum(["name", "script"]),
130
+ status: z.enum(WORKFLOW_RUN_OBSERVATION_STATUSES),
131
+ stopReason: z.enum(WORKFLOW_RUN_STOP_REASONS).optional(),
132
+ ownedByThisSession: z.boolean(),
133
+ possiblyInterrupted: z.boolean().optional(),
134
+ createdAt: z.number(),
135
+ updatedAt: z.number(),
136
+ spentTokens: z.number(),
137
+ })
138
+ .strict();
139
+
140
+ export const toolCallGetWorkflowRunDisplaySchema = z
141
+ .object({
142
+ kind: z.literal("get_workflow_run"),
143
+ runId: z.string().min(1),
144
+ label: z.string(),
145
+ status: z.enum(WORKFLOW_RUN_OBSERVATION_STATUSES),
146
+ stopReason: z.enum(WORKFLOW_RUN_STOP_REASONS).optional(),
147
+ possiblyInterrupted: z.boolean().optional(),
148
+ // 情势截面五件全部可选:情势上线前持久化的 transcript 载荷没有这些键,而本 schema 是
149
+ // strict 的——设成必填会让升级后打开的每一条历史会话里这张卡整块被剥、退化成纯文本。
150
+ // 构造侧每次仍然全填(CLI 侧同款注释)。
151
+ summary: z.string().max(400).optional(),
152
+ generatedAt: z.number().optional(),
153
+ usage: usageSchema,
154
+ phases: z.array(workflowRunPhaseViewSchema).max(32).optional(),
155
+ subagents: z.array(workflowRunSubagentViewSchema).max(64).optional(),
156
+ health: workflowRunHealthSchema.optional(),
157
+ actors: z.array(actorSchema).max(32),
158
+ logTail: z
159
+ .array(
160
+ z
161
+ .object({
162
+ sequence: z.number(),
163
+ message: z.string().max(1_024),
164
+ // 事件落 journal 的时刻(epoch ms);卡上的「多久以前」对 generatedAt 算。
165
+ // 可选:这一列在情势截面之前的载荷上不存在,读旧行时缺席而不是拒收。
166
+ at: z.number().optional(),
167
+ })
168
+ .strict(),
169
+ )
170
+ .max(40),
171
+ result: z.string().max(4_000).optional(),
172
+ error: z
173
+ .object({
174
+ code: z.string(),
175
+ message: z.string(),
176
+ })
177
+ .strict()
178
+ .optional(),
179
+ truncated: z.boolean().optional(),
180
+ })
181
+ .strict();
182
+ export type ToolCallGetWorkflowRunDisplay = z.infer<typeof toolCallGetWorkflowRunDisplaySchema>;
183
+
184
+ export const toolCallListWorkflowRunsDisplaySchema = z
185
+ .object({
186
+ kind: z.literal("list_workflow_runs"),
187
+ runs: z.array(workflowRunSummaryRowSchema).max(50),
188
+ truncated: z.boolean().optional(),
189
+ })
190
+ .strict();
191
+ export type ToolCallListWorkflowRunsDisplay = z.infer<typeof toolCallListWorkflowRunsDisplaySchema>;
192
+
193
+ export const toolCallEvalWorkflowSnippetDisplaySchema = z
194
+ .object({
195
+ kind: z.literal("eval_workflow_snippet"),
196
+ ok: z.boolean(),
197
+ diagnostics: z.array(diagnosticSchema).max(100),
198
+ logs: z.array(z.string().max(1_024)).max(40),
199
+ response: z.string().max(4_000),
200
+ durationMs: z.number().int().nonnegative(),
201
+ truncated: z.boolean().optional(),
202
+ })
203
+ .strict();
204
+ export type ToolCallEvalWorkflowSnippetDisplay = z.infer<
205
+ typeof toolCallEvalWorkflowSnippetDisplaySchema
206
+ >;
207
+
208
+ export const toolCallSavedWorkflowListDisplaySchema = z
209
+ .object({
210
+ kind: z.literal("saved_workflow_list"),
211
+ workflows: z
212
+ .array(
213
+ z
214
+ .object({
215
+ name: z.string().min(1),
216
+ description: z.string().max(2_048).optional(),
217
+ whenToUse: z.string().max(2_048).optional(),
218
+ scope: z.string(),
219
+ path: z.string().min(1),
220
+ argNames: z.array(z.string()).max(32),
221
+ })
222
+ .strict(),
223
+ )
224
+ .max(50),
225
+ invalid: z
226
+ .array(
227
+ z
228
+ .object({
229
+ path: z.string().min(1),
230
+ reason: z.string().max(1_024).optional(),
231
+ })
232
+ .strict(),
233
+ )
234
+ .optional(),
235
+ truncated: z.boolean().optional(),
236
+ })
237
+ .strict();
238
+ export type ToolCallSavedWorkflowListDisplay = z.infer<
239
+ typeof toolCallSavedWorkflowListDisplaySchema
240
+ >;
241
+
242
+ // ListModels 的目录卡载荷。与
243
+ // contracts 侧 listModelsToolResultDisplayPayloadSchema 成员同步——两侧都 strict,缺成员整块
244
+ // 被剥、工具卡退化成 `<models>` 文本。限长数字与 CLI 侧常量一一对应(100 行 / 2048 字符)。
245
+ export const toolCallListModelsDisplaySchema = z
246
+ .object({
247
+ kind: z.literal("list_models"),
248
+ current: z.string().optional(),
249
+ models: z
250
+ .array(
251
+ z
252
+ .object({
253
+ id: z.string().min(1),
254
+ providerId: z.string().min(1),
255
+ modelId: z.string().min(1),
256
+ providerLabel: z.string().max(2_048).optional(),
257
+ reasoningLevels: z.array(z.string()),
258
+ defaultReasoningLevel: z.string().optional(),
259
+ contextWindow: z.number().optional(),
260
+ disabledReason: z.string().max(2_048).optional(),
261
+ })
262
+ .strict(),
263
+ )
264
+ .max(100),
265
+ truncated: z.boolean().optional(),
266
+ })
267
+ .strict();
268
+ export type ToolCallListModelsDisplay = z.infer<typeof toolCallListModelsDisplaySchema>;
269
+
270
+ // ResumeWorkflowRun 的结果卡载荷。与 contracts 侧
271
+ // resumeWorkflowRunToolResultDisplayPayloadSchema 成员同步——两侧都 strict,缺成员整块被剥、
272
+ // 工具卡退化成文本。载荷刻意最小 {runId}(理由见 contracts 侧注释)。
273
+ export const toolCallResumeWorkflowRunDisplaySchema = z
274
+ .object({
275
+ kind: z.literal("resume_workflow_run"),
276
+ runId: z.string().min(1),
277
+ })
278
+ .strict();
279
+ export type ToolCallResumeWorkflowRunDisplay = z.infer<
280
+ typeof toolCallResumeWorkflowRunDisplaySchema
281
+ >;