@qodeca/xezar 0.13.1 → 0.14.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 (250) hide show
  1. package/README.md +45 -15
  2. package/dist/agent-config/account-identity.d.ts +2 -8
  3. package/dist/agent-config/account-identity.js +54 -10
  4. package/dist/agent-config/account-identity.js.map +1 -1
  5. package/dist/agent-config/catalog.d.ts +49 -7
  6. package/dist/agent-config/catalog.js +107 -0
  7. package/dist/agent-config/catalog.js.map +1 -1
  8. package/dist/agent-config/model-settings/pi.d.ts +12 -6
  9. package/dist/agent-config/model-settings/pi.js +12 -6
  10. package/dist/agent-config/model-settings/pi.js.map +1 -1
  11. package/dist/agent-config/seed.js +10 -0
  12. package/dist/agent-config/seed.js.map +1 -1
  13. package/dist/contract/github.d.ts +15 -0
  14. package/dist/contract/index.d.ts +9 -0
  15. package/dist/contract/index.js +1527 -895
  16. package/dist/contract/mcp-api-reference.d.ts +174 -0
  17. package/dist/contract/mcp-audit.d.ts +103 -0
  18. package/dist/contract/mcp-discovery.d.ts +257 -0
  19. package/dist/contract/mcp-event-catalog.d.ts +121 -0
  20. package/dist/contract/mcp-event-catalog.test.d.ts +1 -0
  21. package/dist/contract/mcp-idempotency.d.ts +200 -0
  22. package/dist/contract/mcp-journal.d.ts +268 -0
  23. package/dist/contract/mcp-leader.d.ts +88 -0
  24. package/dist/contract/mcp-ownership.d.ts +78 -0
  25. package/dist/contract/mcp-versioning.d.ts +139 -0
  26. package/dist/contract/runs.d.ts +81 -0
  27. package/dist/core/agent-profiles.d.ts +15 -4
  28. package/dist/core/agent-profiles.js +22 -8
  29. package/dist/core/agent-profiles.js.map +1 -1
  30. package/dist/core/opencode-server-runner.js +71 -11
  31. package/dist/core/opencode-server-runner.js.map +1 -1
  32. package/dist/core/secret-redaction.d.ts +7 -1
  33. package/dist/core/secret-redaction.js +44 -10
  34. package/dist/core/secret-redaction.js.map +1 -1
  35. package/dist/index.js +138 -27
  36. package/dist/index.js.map +1 -1
  37. package/dist/machine-identity.d.ts +66 -0
  38. package/dist/machine-identity.js +96 -0
  39. package/dist/machine-identity.js.map +1 -0
  40. package/dist/mcp/adapters/claude-code.d.ts +41 -0
  41. package/dist/mcp/adapters/claude-code.js +40 -0
  42. package/dist/mcp/adapters/claude-code.js.map +1 -0
  43. package/dist/mcp/adapters/codex.d.ts +140 -0
  44. package/dist/mcp/adapters/codex.js +323 -0
  45. package/dist/mcp/adapters/codex.js.map +1 -0
  46. package/dist/mcp/adapters/opencode.d.ts +148 -0
  47. package/dist/mcp/adapters/opencode.js +528 -0
  48. package/dist/mcp/adapters/opencode.js.map +1 -0
  49. package/dist/mcp/adapters/pi-link.d.ts +102 -0
  50. package/dist/mcp/adapters/pi-link.js +235 -0
  51. package/dist/mcp/adapters/pi-link.js.map +1 -0
  52. package/dist/mcp/adapters/pi.d.ts +188 -0
  53. package/dist/mcp/adapters/pi.js +418 -0
  54. package/dist/mcp/adapters/pi.js.map +1 -0
  55. package/dist/mcp/api-reference.d.ts +26 -0
  56. package/dist/mcp/api-reference.js +133 -0
  57. package/dist/mcp/api-reference.js.map +1 -0
  58. package/dist/mcp/audit-trail.d.ts +162 -0
  59. package/dist/mcp/audit-trail.js +306 -0
  60. package/dist/mcp/audit-trail.js.map +1 -0
  61. package/dist/mcp/bridge.d.ts +81 -0
  62. package/dist/mcp/bridge.js +407 -0
  63. package/dist/mcp/bridge.js.map +1 -0
  64. package/dist/mcp/connection-file.d.ts +49 -0
  65. package/dist/mcp/connection-file.js +63 -0
  66. package/dist/mcp/connection-file.js.map +1 -0
  67. package/dist/mcp/echo-guard.d.ts +94 -0
  68. package/dist/mcp/echo-guard.js +160 -0
  69. package/dist/mcp/echo-guard.js.map +1 -0
  70. package/dist/mcp/event-catalog.d.ts +120 -0
  71. package/dist/mcp/event-catalog.js +306 -0
  72. package/dist/mcp/event-catalog.js.map +1 -0
  73. package/dist/mcp/event-controller.d.ts +230 -0
  74. package/dist/mcp/event-controller.js +596 -0
  75. package/dist/mcp/event-controller.js.map +1 -0
  76. package/dist/mcp/event-journal.d.ts +57 -0
  77. package/dist/mcp/event-journal.js +423 -0
  78. package/dist/mcp/event-journal.js.map +1 -0
  79. package/dist/mcp/index.d.ts +63 -0
  80. package/dist/mcp/index.js +386 -0
  81. package/dist/mcp/index.js.map +1 -0
  82. package/dist/mcp/ipc.d.ts +202 -0
  83. package/dist/mcp/ipc.js +206 -0
  84. package/dist/mcp/ipc.js.map +1 -0
  85. package/dist/mcp/leader-delivery.d.ts +119 -0
  86. package/dist/mcp/leader-delivery.js +450 -0
  87. package/dist/mcp/leader-delivery.js.map +1 -0
  88. package/dist/mcp/operation-receipts.d.ts +210 -0
  89. package/dist/mcp/operation-receipts.js +723 -0
  90. package/dist/mcp/operation-receipts.js.map +1 -0
  91. package/dist/mcp/project-catalogs.d.ts +23 -0
  92. package/dist/mcp/project-catalogs.js +25 -0
  93. package/dist/mcp/project-catalogs.js.map +1 -0
  94. package/dist/mcp/project-leaders.d.ts +26 -0
  95. package/dist/mcp/project-leaders.js +17 -0
  96. package/dist/mcp/project-leaders.js.map +1 -0
  97. package/dist/mcp/protocol.d.ts +50 -0
  98. package/dist/mcp/protocol.js +47 -0
  99. package/dist/mcp/protocol.js.map +1 -0
  100. package/dist/mcp/reconnect.d.ts +297 -0
  101. package/dist/mcp/reconnect.js +465 -0
  102. package/dist/mcp/reconnect.js.map +1 -0
  103. package/dist/mcp/resource-ownership.d.ts +228 -0
  104. package/dist/mcp/resource-ownership.js +390 -0
  105. package/dist/mcp/resource-ownership.js.map +1 -0
  106. package/dist/mcp/service-adapter.d.ts +16488 -0
  107. package/dist/mcp/service-adapter.js +148 -0
  108. package/dist/mcp/service-adapter.js.map +1 -0
  109. package/dist/mcp/service.d.ts +83 -0
  110. package/dist/mcp/service.js +233 -0
  111. package/dist/mcp/service.js.map +1 -0
  112. package/dist/mcp/session-binding.d.ts +105 -0
  113. package/dist/mcp/session-binding.js +163 -0
  114. package/dist/mcp/session-binding.js.map +1 -0
  115. package/dist/mcp/stale-write.d.ts +145 -0
  116. package/dist/mcp/stale-write.js +219 -0
  117. package/dist/mcp/stale-write.js.map +1 -0
  118. package/dist/mcp/tool.d.ts +48 -0
  119. package/dist/mcp/tool.js +24 -0
  120. package/dist/mcp/tool.js.map +1 -0
  121. package/dist/mcp/tools/discovery.d.ts +40 -0
  122. package/dist/mcp/tools/discovery.js +232 -0
  123. package/dist/mcp/tools/discovery.js.map +1 -0
  124. package/dist/mcp/tools/execution-control.d.ts +171 -0
  125. package/dist/mcp/tools/execution-control.js +513 -0
  126. package/dist/mcp/tools/execution-control.js.map +1 -0
  127. package/dist/mcp/tools/handoff-git.d.ts +26 -0
  128. package/dist/mcp/tools/handoff-git.js +544 -0
  129. package/dist/mcp/tools/handoff-git.js.map +1 -0
  130. package/dist/mcp/tools/index.d.ts +2 -0
  131. package/dist/mcp/tools/index.js +23 -0
  132. package/dist/mcp/tools/index.js.map +1 -0
  133. package/dist/mcp/tools/leader-events.d.ts +46 -0
  134. package/dist/mcp/tools/leader-events.js +126 -0
  135. package/dist/mcp/tools/leader-events.js.map +1 -0
  136. package/dist/mcp/tools/local-handoff.d.ts +102 -0
  137. package/dist/mcp/tools/local-handoff.js +306 -0
  138. package/dist/mcp/tools/local-handoff.js.map +1 -0
  139. package/dist/mcp/tools/project-config.d.ts +340 -0
  140. package/dist/mcp/tools/project-config.js +1075 -0
  141. package/dist/mcp/tools/project-config.js.map +1 -0
  142. package/dist/mcp/tools/results-evidence.d.ts +112 -0
  143. package/dist/mcp/tools/results-evidence.js +1045 -0
  144. package/dist/mcp/tools/results-evidence.js.map +1 -0
  145. package/dist/mcp/tools/task-create.d.ts +70 -0
  146. package/dist/mcp/tools/task-create.js +473 -0
  147. package/dist/mcp/tools/task-create.js.map +1 -0
  148. package/dist/mcp/tools/task-reads.d.ts +102 -0
  149. package/dist/mcp/tools/task-reads.js +689 -0
  150. package/dist/mcp/tools/task-reads.js.map +1 -0
  151. package/dist/mcp/tools/work-organisation.d.ts +2 -0
  152. package/dist/mcp/tools/work-organisation.js +502 -0
  153. package/dist/mcp/tools/work-organisation.js.map +1 -0
  154. package/dist/paths.d.ts +17 -7
  155. package/dist/paths.js +18 -8
  156. package/dist/paths.js.map +1 -1
  157. package/dist/runs/project-writer.js +76 -11
  158. package/dist/runs/project-writer.js.map +1 -1
  159. package/dist/runs/retention.d.ts +24 -1
  160. package/dist/runs/retention.js +62 -1
  161. package/dist/runs/retention.js.map +1 -1
  162. package/dist/server/forge/github.js +44 -0
  163. package/dist/server/forge/github.js.map +1 -1
  164. package/dist/server/forge/types.d.ts +16 -0
  165. package/dist/server/project-context.d.ts +81 -8
  166. package/dist/server/project-context.js +143 -35
  167. package/dist/server/project-context.js.map +1 -1
  168. package/dist/server/server.d.ts +1050 -53
  169. package/dist/server/server.js +326 -120
  170. package/dist/server/server.js.map +1 -1
  171. package/dist/server/validators.d.ts +26 -6
  172. package/dist/server/validators.js +17 -0
  173. package/dist/server/validators.js.map +1 -1
  174. package/dist/skills-remote.js +64 -6
  175. package/dist/skills-remote.js.map +1 -1
  176. package/dist/workflows/run.d.ts +277 -12
  177. package/dist/workflows/run.js +554 -59
  178. package/dist/workflows/run.js.map +1 -1
  179. package/dist/workspace/agent-profiles.d.ts +30 -3
  180. package/dist/workspace/agent-profiles.js +39 -4
  181. package/dist/workspace/agent-profiles.js.map +1 -1
  182. package/dist/workspace/config.js +25 -4
  183. package/dist/workspace/config.js.map +1 -1
  184. package/dist/workspace/project-owner.d.ts +210 -0
  185. package/dist/workspace/project-owner.js +518 -0
  186. package/dist/workspace/project-owner.js.map +1 -0
  187. package/package.json +5 -3
  188. package/scripts/pi-leader-extension.ts +420 -0
  189. package/scripts/sync-readme.mjs +83 -2
  190. package/web/dist/assets/{alert-dialog-BVsVcbFy.js → alert-dialog-D6rP6d39.js} +1 -1
  191. package/web/dist/assets/arrow-down-DMOfFIzW.js +1 -0
  192. package/web/dist/assets/arrow-left-C4Ec2BUg.js +1 -0
  193. package/web/dist/assets/{centered-state-Djgly6Ni.js → centered-state-B0ZqrPaa.js} +12 -12
  194. package/web/dist/assets/chevron-right-mHJ-crvn.js +1 -0
  195. package/web/dist/assets/{collapsible-DZ4D-DHG.js → collapsible-DchEHgUM.js} +1 -1
  196. package/web/dist/assets/{commit-list-B-z1JL9G.js → commit-list-BpMim1Rv.js} +1 -1
  197. package/web/dist/assets/{compare-variants-D62m4j3B.js → compare-variants-D5ItQbAq.js} +1 -1
  198. package/web/dist/assets/{diff-BKew9rQX.js → diff-HqqZ_WDR.js} +2 -2
  199. package/web/dist/assets/{diff-stat-D0mc5V6Z.js → diff-stat-NsU-3ecr.js} +1 -1
  200. package/web/dist/assets/{diff-view-xpIcuLIC.js → diff-view-B7c11Xux.js} +1 -1
  201. package/web/dist/assets/{dropdown-menu-CEQziH7X.js → dropdown-menu-CtTpnyod.js} +1 -1
  202. package/web/dist/assets/{editable-title-BCX3T2BY.js → editable-title-BXtuGQry.js} +1 -1
  203. package/web/dist/assets/{ellipsis-vertical-ByVdDc4z.js → ellipsis-vertical-MHtGZSH6.js} +1 -1
  204. package/web/dist/assets/{file-xBSB5hXO.js → file-DKLw5SOb.js} +1 -1
  205. package/web/dist/assets/{folder-CldgbZ5A.js → folder-Drw6-ufH.js} +1 -1
  206. package/web/dist/assets/{git-toolbar-DJANqg7Y.js → git-toolbar-BQH8bORV.js} +1 -1
  207. package/web/dist/assets/github-ynnpKFCJ.js +1 -0
  208. package/web/dist/assets/{image-preview-Cv5mZr0n.js → image-preview-DLhMN_R9.js} +1 -1
  209. package/web/dist/assets/index-BEsrNdXt.js +29 -0
  210. package/web/dist/assets/index-Da8DOBau.css +2 -0
  211. package/web/dist/assets/{markdown-CgEEE2ND.js → markdown-q365eN6Y.js} +1 -1
  212. package/web/dist/assets/{new-task-form-1r2bgsdD.js → new-task-form-CW-hNIWQ.js} +1 -1
  213. package/web/dist/assets/{pill-q-x22_ej.js → pill-B_TFulXa.js} +1 -1
  214. package/web/dist/assets/{project-router-VDN4jQM8.js → project-router-CLPc-ImZ.js} +1 -1
  215. package/web/dist/assets/{prompt-templates-BmZtCe-L.js → prompt-templates-CLc4RxyO.js} +1 -1
  216. package/web/dist/assets/{repo-git-btG0sdbO.js → repo-git-Is7R6-Tj.js} +1 -1
  217. package/web/dist/assets/{run-diff-vguEMJzh.js → run-diff-DHMvDlVo.js} +2 -2
  218. package/web/dist/assets/run-header-DvZJbQ8I.js +1 -0
  219. package/web/dist/assets/{search-x-QmhaAbg5.js → search-x-Ce2MMetu.js} +1 -1
  220. package/web/dist/assets/{skill-empty-hint-BrzUwByZ.js → skill-empty-hint-C_xCSvzB.js} +1 -1
  221. package/web/dist/assets/skills-CivqD4si.js +1 -0
  222. package/web/dist/assets/{sparkles-CP8QDOgX.js → sparkles-BCqPoj5g.js} +1 -1
  223. package/web/dist/assets/{square-terminal-CGypshSD.js → square-terminal-ikj5g-oK.js} +1 -1
  224. package/web/dist/assets/{tab-link-D4lFzzI1.js → tab-link-VsEjFV1Y.js} +1 -1
  225. package/web/dist/assets/{task-changes-BtZId14z.js → task-changes-CH-E81-_.js} +1 -1
  226. package/web/dist/assets/{task-commits-BoeyJXrv.js → task-commits-DqfkMFxp.js} +1 -1
  227. package/web/dist/assets/{task-files-DIy2oUnj.js → task-files-D_nkHZ_a.js} +2 -2
  228. package/web/dist/assets/task-thread-bxQompxJ.js +9 -0
  229. package/web/dist/assets/{textarea-CyBCyKIk.js → textarea-xajuW1L_.js} +1 -1
  230. package/web/dist/assets/{thread-loading-Cuq2jchC.js → thread-loading-C3JQZbIE.js} +1 -1
  231. package/web/dist/assets/{trash-2-B6Dp3ZNs.js → trash-2-hJrBhpUD.js} +1 -1
  232. package/web/dist/assets/{triangle-alert-xBya8FUp.js → triangle-alert-D1u82y1a.js} +1 -1
  233. package/web/dist/assets/{upload-D6MXEB9p.js → upload-Bn6FBZ59.js} +1 -1
  234. package/web/dist/assets/{use-desktop-CPBwzQ7M.js → use-desktop-DOIMfHfY.js} +1 -1
  235. package/web/dist/assets/{use-submit-shortcut-JTpNzU-u.js → use-submit-shortcut-Dj4DHTdE.js} +1 -1
  236. package/web/dist/assets/utils-YwBpOoRN.js +64 -0
  237. package/web/dist/assets/{workflows-DG115scU.js → workflows-CTaAKz2m.js} +3 -3
  238. package/web/dist/assets/{zoomable-image-GTYwLtkS.js → zoomable-image-C1-6P3tg.js} +1 -1
  239. package/web/dist/index.html +23 -23
  240. package/web/dist/assets/arrow-down-CYgAlZtW.js +0 -1
  241. package/web/dist/assets/arrow-left-BOqE0a3k.js +0 -1
  242. package/web/dist/assets/chevron-right-Cc9BWnbN.js +0 -1
  243. package/web/dist/assets/github-D6vK0jFn.js +0 -1
  244. package/web/dist/assets/index-CkmR6h7s.css +0 -2
  245. package/web/dist/assets/index-DVDqF4bM.js +0 -9
  246. package/web/dist/assets/refresh-cw-DcNCj2nu.js +0 -1
  247. package/web/dist/assets/run-header-DM7MiKj9.js +0 -1
  248. package/web/dist/assets/skills-DMfxQtrD.js +0 -1
  249. package/web/dist/assets/task-thread-CbMPmrWq.js +0 -9
  250. package/web/dist/assets/utils--z9hRtl3.js +0 -64
@@ -118,64 +118,90 @@ var healthResponseSchema = z2.object({
118
118
  bootProject: z2.string()
119
119
  });
120
120
 
121
+ // ../contract/src/mcp-ownership.ts
122
+ import { z as z3 } from "zod";
123
+ var MCP_PROJECT_OCCUPIED_CODE = -32080;
124
+ var MCP_SESSION_EXPIRED_CODE = -32081;
125
+ var MCP_PROJECT_OCCUPIED_REASON = "com.qodeca.xezar/project-occupied";
126
+ var MCP_SESSION_EXPIRED_REASON = "com.qodeca.xezar/session-expired";
127
+ var mcpProjectOccupiedErrorSchema = z3.object({
128
+ code: z3.literal(MCP_PROJECT_OCCUPIED_CODE),
129
+ message: z3.string().min(1),
130
+ data: z3.object({
131
+ reason: z3.literal(MCP_PROJECT_OCCUPIED_REASON),
132
+ projectId: z3.string().min(1),
133
+ retryable: z3.literal(true)
134
+ }).strict()
135
+ }).strict();
136
+ var mcpSessionExpiredErrorSchema = z3.object({
137
+ code: z3.literal(MCP_SESSION_EXPIRED_CODE),
138
+ message: z3.string().min(1),
139
+ data: z3.object({
140
+ reason: z3.literal(MCP_SESSION_EXPIRED_REASON),
141
+ projectId: z3.string().min(1),
142
+ retryable: z3.literal(true)
143
+ }).strict()
144
+ }).strict();
145
+ var projectOwnerStateSchema = z3.enum(["unowned", "owned", "expired"]);
146
+
121
147
  // ../contract/src/runs.ts
122
- import { z as z5 } from "zod";
148
+ import { z as z7 } from "zod";
123
149
 
124
150
  // ../contract/src/github.ts
125
- import { z as z3 } from "zod";
126
- var checksGlyphSchema = z3.enum(["passing", "failing", "pending"]).nullable();
127
- var githubItemSchema = z3.object({
128
- kind: z3.enum(["issue", "pr"]),
129
- number: z3.number(),
130
- title: z3.string(),
131
- author: z3.string(),
132
- createdAt: z3.string(),
133
- labels: z3.array(z3.string()),
134
- body: z3.string(),
135
- url: z3.string(),
136
- comments: z3.number(),
151
+ import { z as z4 } from "zod";
152
+ var checksGlyphSchema = z4.enum(["passing", "failing", "pending"]).nullable();
153
+ var githubItemSchema = z4.object({
154
+ kind: z4.enum(["issue", "pr"]),
155
+ number: z4.number(),
156
+ title: z4.string(),
157
+ author: z4.string(),
158
+ createdAt: z4.string(),
159
+ labels: z4.array(z4.string()),
160
+ body: z4.string(),
161
+ url: z4.string(),
162
+ comments: z4.number(),
137
163
  /** PRs only. */
138
- isDraft: z3.boolean().optional(),
139
- additions: z3.number().optional(),
140
- deletions: z3.number().optional(),
164
+ isDraft: z4.boolean().optional(),
165
+ additions: z4.number().optional(),
166
+ deletions: z4.number().optional(),
141
167
  checks: checksGlyphSchema.optional()
142
168
  });
143
- var githubDataSchema = z3.object({
144
- available: z3.boolean(),
169
+ var githubDataSchema = z4.object({
170
+ available: z4.boolean(),
145
171
  /** Why it is unavailable (`gh` missing, no remote, offline…). Never an error — a hint. */
146
- reason: z3.string().optional(),
172
+ reason: z4.string().optional(),
147
173
  /** owner/name, when known. */
148
- repo: z3.string().optional(),
149
- syncedAt: z3.string().optional(),
150
- issues: z3.array(githubItemSchema),
151
- prs: z3.array(githubItemSchema),
174
+ repo: z4.string().optional(),
175
+ syncedAt: z4.string().optional(),
176
+ issues: z4.array(githubItemSchema),
177
+ prs: z4.array(githubItemSchema),
152
178
  /** Repo-wide label name → 6-hex color (no `#`); lets chips tint like GitHub. Additive. */
153
- labelColors: z3.record(z3.string(), z3.string()).optional()
179
+ labelColors: z4.record(z4.string(), z4.string()).optional()
154
180
  });
155
- var githubChecksDataSchema = z3.discriminatedUnion("available", [
156
- z3.object({
157
- available: z3.literal(true),
158
- checks: z3.record(z3.number(), checksGlyphSchema)
181
+ var githubChecksDataSchema = z4.discriminatedUnion("available", [
182
+ z4.object({
183
+ available: z4.literal(true),
184
+ checks: z4.record(z4.number(), checksGlyphSchema)
159
185
  }),
160
- z3.object({
161
- available: z3.literal(false),
162
- reason: z3.string()
186
+ z4.object({
187
+ available: z4.literal(false),
188
+ reason: z4.string()
163
189
  })
164
190
  ]);
165
- var githubSearchDataSchema = z3.object({
166
- available: z3.boolean(),
191
+ var githubSearchDataSchema = z4.object({
192
+ available: z4.boolean(),
167
193
  /** Why it could not search (`gh` missing, no remote, rate-limited…). A hint, never an error. */
168
- reason: z3.string().optional(),
194
+ reason: z4.string().optional(),
169
195
  /** The same rows the list ships. `checks` is always `null` here — hydrated lazily through
170
196
  * `/github/checks`, exactly as list rows have been since #664. */
171
- items: z3.array(githubItemSchema),
197
+ items: z4.array(githubItemSchema),
172
198
  /** The hit list filled the server's cap; there may be more matches on the forge. */
173
- truncated: z3.boolean().optional(),
199
+ truncated: z4.boolean().optional(),
174
200
  /** Label name → 6-hex color for the labels these hits carry. A closed item often wears labels
175
201
  * no open one does, which the repo-wide map from the list call would not cover. Additive. */
176
- labelColors: z3.record(z3.string(), z3.string()).optional()
202
+ labelColors: z4.record(z4.string(), z4.string()).optional()
177
203
  });
178
- var referenceStatusSchema = z3.enum([
204
+ var referenceStatusSchema = z4.enum([
179
205
  "draft",
180
206
  "review-required",
181
207
  "changes-requested",
@@ -188,13 +214,13 @@ var referenceStatusSchema = z3.enum([
188
214
  "completed",
189
215
  "not-planned"
190
216
  ]);
191
- var recheckAfterMsSchema = z3.number().nullable();
217
+ var recheckAfterMsSchema = z4.number().nullable();
192
218
  var REFERENCE_STATUS_MAX = 100;
193
- var githubRefStatusDataSchema = z3.discriminatedUnion("available", [
194
- z3.object({
195
- available: z3.literal(true),
196
- prs: z3.record(z3.number(), referenceStatusSchema),
197
- issues: z3.record(z3.number(), referenceStatusSchema),
219
+ var githubRefStatusDataSchema = z4.discriminatedUnion("available", [
220
+ z4.object({
221
+ available: z4.literal(true),
222
+ prs: z4.record(z4.number(), referenceStatusSchema),
223
+ issues: z4.record(z4.number(), referenceStatusSchema),
198
224
  /**
199
225
  * The pull request numbers that do NOT merge cleanly into their base right now.
200
226
  *
@@ -214,28 +240,28 @@ var githubRefStatusDataSchema = z3.discriminatedUnion("available", [
214
240
  * ever named — GitHub reports `UNKNOWN` for merged and closed ones, and `UNKNOWN` (which is
215
241
  * also what it answers while it is still computing) is never listed.
216
242
  */
217
- conflicts: z3.array(z3.number()).optional(),
243
+ conflicts: z4.array(z4.number()).optional(),
218
244
  recheckAfterMs: recheckAfterMsSchema
219
245
  }),
220
- z3.object({
221
- available: z3.literal(false),
222
- reason: z3.string(),
246
+ z4.object({
247
+ available: z4.literal(false),
248
+ reason: z4.string(),
223
249
  recheckAfterMs: recheckAfterMsSchema
224
250
  })
225
251
  ]);
226
- var githubCommentSchema = z3.object({
227
- id: z3.number(),
252
+ var githubCommentSchema = z4.object({
253
+ id: z4.number(),
228
254
  /** Author login, `'?'` fallback when gh omits the user. */
229
- author: z3.string(),
230
- avatarUrl: z3.string().optional(),
231
- createdAt: z3.string(),
232
- body: z3.string(),
233
- kind: z3.enum(["comment", "review"]),
255
+ author: z4.string(),
256
+ avatarUrl: z4.string().optional(),
257
+ createdAt: z4.string(),
258
+ body: z4.string(),
259
+ kind: z4.enum(["comment", "review"]),
234
260
  /** Reviews only — drives the state chip. */
235
- reviewState: z3.enum(["approved", "changes_requested", "commented", "dismissed"]).optional(),
236
- url: z3.string()
261
+ reviewState: z4.enum(["approved", "changes_requested", "commented", "dismissed"]).optional(),
262
+ url: z4.string()
237
263
  });
238
- var githubTimelineEventKindSchema = z3.enum([
264
+ var githubTimelineEventKindSchema = z4.enum([
239
265
  "committed",
240
266
  "labeled",
241
267
  "unlabeled",
@@ -248,178 +274,223 @@ var githubTimelineEventKindSchema = z3.enum([
248
274
  "cross-referenced",
249
275
  "renamed"
250
276
  ]);
251
- var githubTimelineEventSchema = z3.object({
252
- id: z3.string(),
277
+ var githubTimelineEventSchema = z4.object({
278
+ id: z4.string(),
253
279
  kind: githubTimelineEventKindSchema,
254
280
  /** Login — or the git author name for `committed`, which carries no GitHub actor. */
255
- actor: z3.string(),
281
+ actor: z4.string(),
256
282
  /** Absent for `committed`. */
257
- avatarUrl: z3.string().optional(),
258
- createdAt: z3.string(),
259
- url: z3.string().optional(),
283
+ avatarUrl: z4.string().optional(),
284
+ createdAt: z4.string(),
285
+ url: z4.string().optional(),
260
286
  /** `committed` — full 40-char SHA. */
261
- sha: z3.string().optional(),
287
+ sha: z4.string().optional(),
262
288
  /** `committed` — first line, capped at 120 chars. */
263
- message: z3.string().optional(),
289
+ message: z4.string().optional(),
264
290
  /** `committed` — **absent** (lookup failed/skipped) and **`null`** (no CI configured) both
265
291
  * render no glyph, but stay distinct values. */
266
292
  checks: checksGlyphSchema.optional(),
267
- label: z3.object({ name: z3.string(), color: z3.string().optional() }).optional(),
293
+ label: z4.object({ name: z4.string(), color: z4.string().optional() }).optional(),
268
294
  /** `assigned`/`unassigned` login, or the new title for `renamed`. */
269
- subject: z3.string().optional(),
270
- refNumber: z3.number().optional(),
271
- refTitle: z3.string().optional(),
272
- refIsPr: z3.boolean().optional()
273
- });
274
- var githubCommentsDataSchema = z3.object({
275
- available: z3.boolean(),
276
- reason: z3.string().optional(),
295
+ subject: z4.string().optional(),
296
+ refNumber: z4.number().optional(),
297
+ refTitle: z4.string().optional(),
298
+ refIsPr: z4.boolean().optional()
299
+ });
300
+ var githubCommentsDataSchema = z4.object({
301
+ available: z4.boolean(),
302
+ reason: z4.string().optional(),
277
303
  /** Chronological, oldest first. */
278
- comments: z3.array(githubCommentSchema),
304
+ comments: z4.array(githubCommentSchema),
279
305
  /** True when either stream hit its cap, or the timeline fetch stopped short. */
280
- truncated: z3.boolean().optional(),
306
+ truncated: z4.boolean().optional(),
281
307
  /** Timeline events (#525) — additive; absent when the server degraded to the legacy
282
308
  * comments-only fetch. Capped independently of `comments`. */
283
- events: z3.array(githubTimelineEventSchema).optional()
284
- });
285
- var githubMergeMethodSchema = z3.enum(["merge", "squash", "rebase"]);
286
- var githubPrCheckSchema = z3.object({
287
- name: z3.string(),
288
- state: z3.enum(["passing", "failing", "pending", "unknown"]),
289
- required: z3.boolean().nullable(),
290
- url: z3.string().optional()
291
- });
292
- var githubPrMergeStateSchema = z3.object({
293
- number: z3.number(),
294
- title: z3.string(),
295
- url: z3.string(),
296
- state: z3.enum(["open", "closed", "merged"]),
297
- isDraft: z3.boolean(),
298
- headRef: z3.string(),
299
- baseRef: z3.string(),
300
- headSha: z3.string(),
301
- mergeable: z3.enum(["mergeable", "conflicting", "unknown"]),
302
- reviewDecision: z3.enum(["approved", "changes-requested", "review-required", "unknown"]),
303
- checks: z3.array(githubPrCheckSchema),
304
- methods: z3.array(githubMergeMethodSchema),
309
+ events: z4.array(githubTimelineEventSchema).optional()
310
+ });
311
+ var githubMergeMethodSchema = z4.enum(["merge", "squash", "rebase"]);
312
+ var githubPrCheckSchema = z4.object({
313
+ name: z4.string(),
314
+ state: z4.enum(["passing", "failing", "pending", "unknown"]),
315
+ required: z4.boolean().nullable(),
316
+ url: z4.string().optional()
317
+ });
318
+ var githubPrMergeStateSchema = z4.object({
319
+ number: z4.number(),
320
+ title: z4.string(),
321
+ url: z4.string(),
322
+ state: z4.enum(["open", "closed", "merged"]),
323
+ isDraft: z4.boolean(),
324
+ headRef: z4.string(),
325
+ baseRef: z4.string(),
326
+ headSha: z4.string(),
327
+ mergeable: z4.enum(["mergeable", "conflicting", "unknown"]),
328
+ reviewDecision: z4.enum(["approved", "changes-requested", "review-required", "unknown"]),
329
+ checks: z4.array(githubPrCheckSchema),
330
+ methods: z4.array(githubMergeMethodSchema),
305
331
  defaultMethod: githubMergeMethodSchema.nullable(),
306
- eligibility: z3.enum(["ready", "blocked", "pending", "unauthorized", "terminal", "unknown"]),
307
- blockers: z3.array(z3.object({ code: z3.string(), message: z3.string() })),
308
- canMerge: z3.boolean(),
309
- canOverride: z3.boolean()
310
- });
311
- var githubPrMergeStateResponseSchema = z3.discriminatedUnion("available", [
312
- z3.object({ available: z3.literal(true), mergeState: githubPrMergeStateSchema }),
313
- z3.object({ available: z3.literal(false), reason: z3.string() })
332
+ eligibility: z4.enum(["ready", "blocked", "pending", "unauthorized", "terminal", "unknown"]),
333
+ blockers: z4.array(z4.object({ code: z4.string(), message: z4.string() })),
334
+ canMerge: z4.boolean(),
335
+ canOverride: z4.boolean()
336
+ });
337
+ var githubPrMergeStateResponseSchema = z4.discriminatedUnion("available", [
338
+ z4.object({ available: z4.literal(true), mergeState: githubPrMergeStateSchema }),
339
+ z4.object({ available: z4.literal(false), reason: z4.string() })
314
340
  ]);
315
- var githubMergeResponseSchema = z3.object({
316
- merged: z3.literal(true),
317
- number: z3.number(),
318
- url: z3.string(),
341
+ var githubMergeResponseSchema = z4.object({
342
+ merged: z4.literal(true),
343
+ number: z4.number(),
344
+ url: z4.string(),
319
345
  method: githubMergeMethodSchema,
320
- mergeCommitSha: z3.string().optional()
321
- });
322
- var githubPrChangeSchema = z3.object({
323
- path: z3.string(),
324
- previousPath: z3.string().optional(),
325
- status: z3.enum(["added", "modified", "removed", "renamed", "copied", "changed"]),
326
- additions: z3.number(),
327
- deletions: z3.number(),
328
- patch: z3.string().optional(),
329
- patchUnavailableReason: z3.enum(["binary", "too-large", "not-provided"]).optional(),
330
- truncated: z3.boolean().optional()
331
- });
332
- var githubPrChangesDataSchema = z3.discriminatedUnion("available", [
333
- z3.object({
334
- available: z3.literal(true),
335
- number: z3.number(),
336
- headSha: z3.string(),
337
- files: z3.array(githubPrChangeSchema),
338
- additions: z3.number(),
339
- deletions: z3.number(),
340
- truncated: z3.boolean(),
346
+ mergeCommitSha: z4.string().optional()
347
+ });
348
+ var githubPrReadyInputSchema = z4.object({ expectedHeadSha: z4.string().regex(/^[0-9a-f]{40}$/) }).strict();
349
+ var githubPrReadyResponseSchema = z4.object({
350
+ ready: z4.literal(true),
351
+ number: z4.number(),
352
+ url: z4.string()
353
+ });
354
+ var githubPrChangeSchema = z4.object({
355
+ path: z4.string(),
356
+ previousPath: z4.string().optional(),
357
+ status: z4.enum(["added", "modified", "removed", "renamed", "copied", "changed"]),
358
+ additions: z4.number(),
359
+ deletions: z4.number(),
360
+ patch: z4.string().optional(),
361
+ patchUnavailableReason: z4.enum(["binary", "too-large", "not-provided"]).optional(),
362
+ truncated: z4.boolean().optional()
363
+ });
364
+ var githubPrChangesDataSchema = z4.discriminatedUnion("available", [
365
+ z4.object({
366
+ available: z4.literal(true),
367
+ number: z4.number(),
368
+ headSha: z4.string(),
369
+ files: z4.array(githubPrChangeSchema),
370
+ additions: z4.number(),
371
+ deletions: z4.number(),
372
+ truncated: z4.boolean(),
341
373
  /** Present when the payload is complete but partial in some other way (a capped patch). */
342
- reason: z3.string().optional()
374
+ reason: z4.string().optional()
343
375
  }),
344
- z3.object({ available: z3.literal(false), reason: z3.string() })
376
+ z4.object({ available: z4.literal(false), reason: z4.string() })
377
+ ]);
378
+
379
+ // ../contract/src/mcp-versioning.ts
380
+ import { z as z5 } from "zod";
381
+ var MCP_VERSION_TOKEN_TAG = "rev1";
382
+ var mcpVersionTokenSchema = z5.string().min(1).max(512);
383
+ var mcpExpectedVersionSchema = mcpVersionTokenSchema;
384
+ var mcpVersionedResourceKindSchema = z5.string().min(1).max(32).regex(/^[a-z][a-z0-9-]*$/);
385
+ var mcpVersionedResourceRefSchema = z5.object({
386
+ kind: mcpVersionedResourceKindSchema,
387
+ id: z5.string().min(1)
388
+ });
389
+ var MCP_STALE_VERSION_GUIDANCE = "Not applied: this changed after you read it. Read the current state and decide again; a new decision is a new operation.";
390
+ var MCP_EXECUTION_FAILED_GUIDANCE = "Attempted and failed: the change ran and did not complete, so part of it may have applied. Read the current state before deciding again; do not repeat it blindly.";
391
+ var staleVersionRejectionSchema = z5.object({
392
+ status: z5.literal("conflict"),
393
+ applied: z5.literal(false),
394
+ error: z5.literal("stale_version"),
395
+ resource: mcpVersionedResourceRefSchema,
396
+ currentVersion: mcpVersionTokenSchema.optional(),
397
+ changedSince: z5.literal(true),
398
+ guidance: z5.literal(MCP_STALE_VERSION_GUIDANCE)
399
+ });
400
+ var executionFailedSchema = z5.object({
401
+ status: z5.literal("failed"),
402
+ executed: z5.literal(true),
403
+ error: z5.literal("execution_failed"),
404
+ resource: mcpVersionedResourceRefSchema,
405
+ guidance: z5.literal(MCP_EXECUTION_FAILED_GUIDANCE)
406
+ });
407
+ var versionedMutationDoneSchema = z5.object({
408
+ status: z5.literal("done"),
409
+ resource: mcpVersionedResourceRefSchema,
410
+ version: mcpVersionTokenSchema.optional()
411
+ });
412
+ var versionedMutationOutcomeSchema = z5.discriminatedUnion("status", [
413
+ versionedMutationDoneSchema,
414
+ staleVersionRejectionSchema,
415
+ executionFailedSchema
345
416
  ]);
346
417
 
347
418
  // ../contract/src/workflows.ts
348
- import { z as z4 } from "zod";
349
- var workflowStepDefSchema = z4.object({
350
- id: z4.string().min(1),
351
- name: z4.string().optional(),
419
+ import { z as z6 } from "zod";
420
+ var workflowStepDefSchema = z6.object({
421
+ id: z6.string().min(1),
422
+ name: z6.string().optional(),
352
423
  // agent step
353
- prompt: z4.string().optional(),
354
- skill: z4.string().optional(),
355
- model: z4.string().optional(),
424
+ prompt: z6.string().optional(),
425
+ skill: z6.string().optional(),
426
+ model: z6.string().optional(),
356
427
  /** Per-step agent backend override (falls back to the task / config default). */
357
428
  runner: runnerSchema.optional(),
358
- allowedTools: z4.array(z4.string()).optional(),
359
- bashAllowlist: z4.array(z4.string()).optional(),
429
+ allowedTools: z6.array(z6.string()).optional(),
430
+ bashAllowlist: z6.array(z6.string()).optional(),
360
431
  /** This step's own wall-clock cap (#22): `45s` / `90m` / `2h`, or `none` for no cap.
361
432
  * Typed as a plain string here, exactly as `model` is: the DURATION FORMAT is validated
362
433
  * by `src/workflows/types.ts`'s `stepTimeoutSchema`, which is the single source of truth
363
434
  * for what a user may author (workflow YAML and the inline chain on `POST /runs` both go
364
435
  * through it). Restating the grammar here would be a second copy free to drift. */
365
- timeout: z4.string().optional(),
436
+ timeout: z6.string().optional(),
366
437
  // check step
367
- command: z4.string().optional(),
368
- onFail: z4.object({
369
- retry: z4.string().min(1),
370
- max: z4.number().int().positive().default(2)
438
+ command: z6.string().optional(),
439
+ onFail: z6.object({
440
+ retry: z6.string().min(1),
441
+ max: z6.number().int().positive().default(2)
371
442
  }).optional()
372
443
  }).refine((s) => Boolean(s.command) !== Boolean(s.prompt ?? s.skill), {
373
444
  message: "a step is either an agent step (prompt/skill) or a check step (command), not both"
374
445
  });
375
- var workflowDefSchema = z4.object({
376
- name: z4.string(),
377
- description: z4.string().optional(),
378
- steps: z4.array(workflowStepDefSchema),
379
- source: z4.enum(["built-in", "file"]),
446
+ var workflowDefSchema = z6.object({
447
+ name: z6.string(),
448
+ description: z6.string().optional(),
449
+ steps: z6.array(workflowStepDefSchema),
450
+ source: z6.enum(["built-in", "file"]),
380
451
  /** Absent on built-ins — which is exactly what makes them undeletable. */
381
- path: z4.string().optional()
452
+ path: z6.string().optional()
382
453
  });
383
- var workflowLoadIssueSchema = z4.object({
384
- path: z4.string(),
385
- message: z4.string()
386
- });
387
- var workflowsResponseSchema = z4.object({
388
- workflows: z4.array(workflowDefSchema),
389
- issues: z4.array(workflowLoadIssueSchema)
390
- });
391
- var saveWorkflowInputSchema = z4.object({
392
- name: z4.string().trim().min(1).max(80),
393
- description: z4.string().max(2e3, "must be at most 2000 characters").optional(),
394
- steps: z4.array(workflowStepDefSchema).min(1).max(8).optional(),
395
- skills: z4.array(z4.string().trim().min(1)).min(1).max(8).optional(),
396
- overwrite: z4.boolean().optional()
454
+ var workflowLoadIssueSchema = z6.object({
455
+ path: z6.string(),
456
+ message: z6.string()
457
+ });
458
+ var workflowsResponseSchema = z6.object({
459
+ workflows: z6.array(workflowDefSchema),
460
+ issues: z6.array(workflowLoadIssueSchema)
461
+ });
462
+ var saveWorkflowInputSchema = z6.object({
463
+ name: z6.string().trim().min(1).max(80),
464
+ description: z6.string().max(2e3, "must be at most 2000 characters").optional(),
465
+ steps: z6.array(workflowStepDefSchema).min(1).max(8).optional(),
466
+ skills: z6.array(z6.string().trim().min(1)).min(1).max(8).optional(),
467
+ overwrite: z6.boolean().optional()
397
468
  }).refine((b) => Boolean(b.steps) !== Boolean(b.skills), {
398
469
  message: 'provide either "steps" or "skills", not both'
399
470
  });
400
- var saveWorkflowResponseSchema = z4.object({
401
- path: z4.string(),
402
- name: z4.string()
471
+ var saveWorkflowResponseSchema = z6.object({
472
+ path: z6.string(),
473
+ name: z6.string()
403
474
  });
404
- var parsedWorkflowSchema = z4.object({
405
- name: z4.string(),
406
- description: z4.string().optional(),
407
- steps: z4.array(workflowStepDefSchema)
475
+ var parsedWorkflowSchema = z6.object({
476
+ name: z6.string(),
477
+ description: z6.string().optional(),
478
+ steps: z6.array(workflowStepDefSchema)
408
479
  });
409
- var deleteWorkflowResponseSchema = z4.object({
410
- ok: z4.literal(true),
411
- path: z4.string()
480
+ var deleteWorkflowResponseSchema = z6.object({
481
+ ok: z6.literal(true),
482
+ path: z6.string()
412
483
  });
413
- var planResponseSchema = z4.object({
484
+ var planResponseSchema = z6.object({
414
485
  /** The kebab-case workflow title the planner proposed. Absent on the degraded fallback. */
415
- name: z4.string().optional(),
416
- steps: z4.array(workflowStepDefSchema),
417
- rationale: z4.string(),
418
- fallback: z4.boolean()
486
+ name: z6.string().optional(),
487
+ steps: z6.array(workflowStepDefSchema),
488
+ rationale: z6.string(),
489
+ fallback: z6.boolean()
419
490
  });
420
491
 
421
492
  // ../contract/src/runs.ts
422
- var runStatusSchema = z5.enum([
493
+ var runStatusSchema = z7.enum([
423
494
  "queued",
424
495
  "running",
425
496
  "waiting",
@@ -428,8 +499,8 @@ var runStatusSchema = z5.enum([
428
499
  "failed",
429
500
  "cancelled"
430
501
  ]);
431
- var runActivitySchema = z5.enum(["monitoring"]);
432
- var stepStatusSchema = z5.enum([
502
+ var runActivitySchema = z7.enum(["monitoring"]);
503
+ var stepStatusSchema = z7.enum([
433
504
  "pending",
434
505
  "running",
435
506
  "waiting",
@@ -439,14 +510,14 @@ var stepStatusSchema = z5.enum([
439
510
  "cancelled",
440
511
  "skipped"
441
512
  ]);
442
- var usageCounterSchema = z5.number().finite().nonnegative();
443
- var stepStateSchema = z5.object({
444
- id: z5.string(),
445
- name: z5.string(),
446
- kind: z5.enum(["agent", "check"]),
513
+ var usageCounterSchema = z7.number().finite().nonnegative();
514
+ var stepStateSchema = z7.object({
515
+ id: z7.string(),
516
+ name: z7.string(),
517
+ kind: z7.enum(["agent", "check"]),
447
518
  status: stepStatusSchema,
448
- iterations: z5.number(),
449
- tokensUsed: z5.number(),
519
+ iterations: z7.number(),
520
+ tokensUsed: z7.number(),
450
521
  inputTokens: usageCounterSchema.optional(),
451
522
  outputTokens: usageCounterSchema.optional(),
452
523
  usageInvocationsStarted: usageCounterSchema.optional(),
@@ -454,76 +525,76 @@ var stepStateSchema = z5.object({
454
525
  usageTurnsStarted: usageCounterSchema.optional(),
455
526
  usageTurnsRecorded: usageCounterSchema.optional(),
456
527
  usageInvocationEpoch: usageCounterSchema.optional(),
457
- startedAt: z5.string().optional(),
458
- finishedAt: z5.string().optional(),
459
- error: z5.string().optional(),
528
+ startedAt: z7.string().optional(),
529
+ finishedAt: z7.string().optional(),
530
+ error: z7.string().optional(),
460
531
  /** Latest agent session id — `claude --resume <id>` and friends. */
461
- sessionId: z5.string().optional(),
532
+ sessionId: z7.string().optional(),
462
533
  /** Backend that owns `sessionId`; absent on records written before backend affinity. */
463
534
  backend: runnerSchema.optional(),
464
535
  /** Agent account (spec 2026-07-29-agent-profiles) that owns `sessionId` — `default`, or a
465
536
  * stored profile id. The two are a PAIR: a session id only resolves inside the config dir
466
537
  * that created it, so resume and Continue read this rather than the project's current
467
538
  * selection. Absent on records written before accounts existed. */
468
- profileId: z5.string().optional(),
469
- costUsd: z5.number().optional()
539
+ profileId: z7.string().optional(),
540
+ costUsd: z7.number().optional()
470
541
  });
471
- var diffStatSchema = z5.object({
472
- adds: z5.number(),
473
- dels: z5.number(),
474
- files: z5.number(),
542
+ var diffStatSchema = z7.object({
543
+ adds: z7.number(),
544
+ dels: z7.number(),
545
+ files: z7.number(),
475
546
  /** Additive since #751, and present ONLY when true: the numbers were measured against a
476
547
  * branch the agent checked out into the task's worktree, as the run found it, because the
477
548
  * worktree's HEAD had been repointed off the task's own branch (every review/QA run does
478
549
  * this) and the merge-base anchor would otherwise have reported that branch's entire diff
479
550
  * as this task's. Absent on every normal run and on every record written before #751 — a
480
551
  * consumer that ignores it sees exactly the old shape. */
481
- repointed: z5.boolean().optional()
552
+ repointed: z7.boolean().optional()
482
553
  });
483
- var queuedMessageSchema = z5.object({
484
- id: z5.string(),
485
- text: z5.string(),
554
+ var queuedMessageSchema = z7.object({
555
+ id: z7.string(),
556
+ text: z7.string(),
486
557
  /** `/api/v1/runs/:id/images/…` URLs — attachments are persisted, never inlined. Images and
487
558
  * files share this one list; read `isImageAttachmentName` on the file name to tell them apart. */
488
- images: z5.array(z5.string()).optional(),
489
- createdAt: z5.string()
559
+ images: z7.array(z7.string()).optional(),
560
+ createdAt: z7.string()
490
561
  });
491
- var processUsageSchema = z5.object({
562
+ var processUsageSchema = z7.object({
492
563
  /** Sum of `%cpu` across the tree — can exceed 100 on multi-core work. */
493
- cpuPct: z5.number(),
494
- rssBytes: z5.number(),
495
- procCount: z5.number()
564
+ cpuPct: z7.number(),
565
+ rssBytes: z7.number(),
566
+ procCount: z7.number()
496
567
  });
497
- var runRecordSchema = z5.object({
498
- id: z5.string(),
499
- title: z5.string(),
568
+ var runRecordSchema = z7.object({
569
+ id: z7.string(),
570
+ title: z7.string(),
500
571
  /** Display title (#389): auto-derived from the first agent turn, or the user's inline edit
501
572
  * (`PATCH /runs/:id` sets it together with `title`). Show `titleSummary ?? title`. */
502
- titleSummary: z5.string().optional(),
573
+ titleSummary: z7.string().optional(),
503
574
  /** Refreshed on every turn-end; absent until the first turn ends (and on worktree-less runs). */
504
575
  diffStat: diffStatSchema.optional(),
505
- workflow: z5.string(),
506
- task: z5.string(),
576
+ workflow: z7.string(),
577
+ task: z7.string(),
507
578
  /** Prompt messages stacked onto the run while it waited for a free agent slot (#472). Folded
508
579
  * into the prompt at dequeue — never delivered as their own turns. Absent on pre-#472 runs. */
509
- queuedMessages: z5.array(queuedMessageSchema).optional(),
580
+ queuedMessages: z7.array(queuedMessageSchema).optional(),
510
581
  /** URLs of the attachments on the initial task prompt (#image-display) — images and, since
511
582
  * #950, files. One list, one numbering space; branch on `isImageAttachmentName`. */
512
- taskImages: z5.array(z5.string()).optional(),
513
- model: z5.string().optional(),
583
+ taskImages: z7.array(z7.string()).optional(),
584
+ model: z7.string().optional(),
514
585
  /** Normalized provider/model identity used for attribution and reproducible replay. */
515
- modelIdentity: z5.string().optional(),
586
+ modelIdentity: z7.string().optional(),
516
587
  runner: runnerSchema.optional(),
517
588
  /** The composer's per-task agent account (spec 2026-07-29-agent-profiles), applying to steps
518
589
  * on `runner`. Absent = the run follows the project's own selection. */
519
- agentProfile: z5.string().optional(),
590
+ agentProfile: z7.string().optional(),
520
591
  /** Echo of the extra system prompt the run used (POST override or config default). */
521
- systemPrompt: z5.string().optional(),
592
+ systemPrompt: z7.string().optional(),
522
593
  /** false when the run deliberately disabled follow-up todo generation. Absent means enabled. */
523
- generateFollowups: z5.boolean().optional(),
594
+ generateFollowups: z7.boolean().optional(),
524
595
  /** Autonomous mode (#autonomous): the run never parks at `waiting` or the terminal `review`
525
596
  * gate. Absent = falsy = not autonomous. */
526
- autonomous: z5.boolean().optional(),
597
+ autonomous: z7.boolean().optional(),
527
598
  /**
528
599
  * Provenance for a task a project GitHub automation launched (#694). Absent on every ordinary
529
600
  * run, which is what makes it additive — the cockpit shows the "from automation" link only when
@@ -533,94 +604,94 @@ var runRecordSchema = z5.object({
533
604
  * launching definition matched, recorded on the run for the audit trail, and `src/runs/store.ts`
534
605
  * persists it as free text so an older xezar can still read a record written by a newer one.
535
606
  */
536
- automation: z5.object({
537
- automationId: z5.string(),
538
- automationRevision: z5.number(),
539
- receiptId: z5.string(),
540
- event: z5.string(),
541
- githubUrl: z5.string()
607
+ automation: z7.object({
608
+ automationId: z7.string(),
609
+ automationRevision: z7.number(),
610
+ receiptId: z7.string(),
611
+ event: z7.string(),
612
+ githubUrl: z7.string()
542
613
  }).optional(),
543
614
  status: runStatusSchema,
544
615
  /** `monitoring` while `status === 'running'` and the agent is working on downstream work.
545
616
  * Absent on old runs; cleared on resume/end. */
546
617
  activity: runActivitySchema.optional(),
547
618
  /** Exact ISO-8601 deadline for the next automatic monitoring check. */
548
- monitoringWakeAt: z5.string().optional(),
619
+ monitoringWakeAt: z7.string().optional(),
549
620
  /** The current live monitoring epoch exhausted its 40 automatic checks. */
550
- monitoringWakeCapReached: z5.boolean().optional(),
621
+ monitoringWakeCapReached: z7.boolean().optional(),
551
622
  /** Exact ISO-8601 instant this run resumes itself after a provider usage limit stopped it
552
623
  * (spec 2026-08-03-auto-resume-after-usage-limit). Present only on a `failed` run with a
553
624
  * pending automatic resume — its absence is what "no resume is scheduled" looks like. */
554
- autoResumeAt: z5.string().optional(),
625
+ autoResumeAt: z7.string().optional(),
555
626
  /** Consecutive automatic resumes since the last human turn, against the safety cap. */
556
- autoResumeAttempts: z5.number().optional(),
557
- createdAt: z5.string(),
558
- startedAt: z5.string().optional(),
559
- finishedAt: z5.string().optional(),
560
- tokensUsed: z5.number(),
627
+ autoResumeAttempts: z7.number().optional(),
628
+ createdAt: z7.string(),
629
+ startedAt: z7.string().optional(),
630
+ finishedAt: z7.string().optional(),
631
+ tokensUsed: z7.number(),
561
632
  inputTokens: usageCounterSchema.optional(),
562
633
  outputTokens: usageCounterSchema.optional(),
563
- costUsd: z5.number().optional(),
564
- pullRequestUrl: z5.string().optional(),
634
+ costUsd: z7.number().optional(),
635
+ pullRequestUrl: z7.string().optional(),
565
636
  /** The PR this task is ABOUT (#407) — auto-discovered from conversation references. Display
566
637
  * tier only: `pullRequestUrl` (the PR this task CREATED) wins, and the action gates ignore it. */
567
- referencedPullRequestUrl: z5.string().optional(),
638
+ referencedPullRequestUrl: z7.string().optional(),
568
639
  /** The PR/issue number this task is ABOUT (task auto-naming spec) — display tier only. */
569
- prNumber: z5.number().optional(),
570
- issueNumber: z5.number().optional(),
640
+ prNumber: z7.number().optional(),
641
+ issueNumber: z7.number().optional(),
571
642
  /** Server-side provenance: referenced-issue discovery currently owns `issueNumber`. */
572
- referencedIssueNumberSeeded: z5.boolean().optional(),
643
+ referencedIssueNumberSeeded: z7.boolean().optional(),
573
644
  /** 'user' = renamed via PATCH, never auto-overwritten; 'marker' = agent-declared via
574
645
  * XEZ:TITLE (spec 2026-07-18-task-ref-markers); 'auto' = namer-owned. */
575
- titleOrigin: z5.enum(["user", "auto", "marker"]).optional(),
646
+ titleOrigin: z7.enum(["user", "auto", "marker"]).optional(),
576
647
  /** References the agent declared via XEZ:PR/XEZ:ISSUE markers — authoritative over the namer
577
648
  * for the matching kind. */
578
- markerRefs: z5.object({ pr: z5.number().optional(), issue: z5.number().optional() }).optional(),
649
+ markerRefs: z7.object({ pr: z7.number().optional(), issue: z7.number().optional() }).optional(),
579
650
  /** The referenced tier's working set (distinct PR URLs spotted, capped server-side). */
580
- referencedPrCandidates: z5.array(z5.string()).optional(),
651
+ referencedPrCandidates: z7.array(z7.string()).optional(),
581
652
  /** The issue this task is ABOUT (spec 2026-07-21-report-ref-discovery). Display-only. */
582
- referencedIssueUrl: z5.string().optional(),
653
+ referencedIssueUrl: z7.string().optional(),
583
654
  /** The referenced-issue working set, persisted like `referencedPrCandidates`. Capped. */
584
- referencedIssueCandidates: z5.array(z5.string()).optional(),
655
+ referencedIssueCandidates: z7.array(z7.string()).optional(),
585
656
  /** Explicit execution policy. `false` means the run intentionally uses the repo root;
586
657
  * absent on older runs and for the default isolated-worktree mode. */
587
- worktree: z5.literal(false).optional(),
658
+ worktree: z7.literal(false).optional(),
588
659
  /** Absent for in-place runs and after an isolated worktree is removed. */
589
- worktreePath: z5.string().optional(),
590
- branch: z5.string().optional(),
660
+ worktreePath: z7.string().optional(),
661
+ branch: z7.string().optional(),
591
662
  /** Stable baseline for session git views: a worktree's fork ref, or an in-place run's starting commit. */
592
- baseBranch: z5.string().optional(),
663
+ baseBranch: z7.string().optional(),
593
664
  /** Set when count-based retention (#483) reclaimed the worktree DIRECTORY (the branch is
594
665
  * kept): the dir is gone but recoverable. */
595
- worktreeReclaimedAt: z5.string().optional(),
666
+ worktreeReclaimedAt: z7.string().optional(),
596
667
  /** Parallel variants (spec 010): runs sharing a groupId are one group. */
597
- groupId: z5.string().optional(),
668
+ groupId: z7.string().optional(),
598
669
  /** Variant letter within the group — 'A' | 'B' | 'C'. */
599
- variant: z5.string().optional(),
600
- peakRssBytes: z5.number().optional(),
601
- peakProcCount: z5.number().optional(),
602
- archived: z5.boolean(),
603
- archivedAt: z5.string().optional(),
670
+ variant: z7.string().optional(),
671
+ peakRssBytes: z7.number().optional(),
672
+ peakProcCount: z7.number().optional(),
673
+ archived: z7.boolean(),
674
+ archivedAt: z7.string().optional(),
604
675
  /** Pinned to the top of this project's task list (#935) — the `Pinned` group above
605
676
  * `Needs you`. Optional, unlike `archived`: absent IS "not pinned", which is what every
606
677
  * record written before this carries, and the store never writes `false`. Archiving
607
678
  * clears it, because archiving is how a user resigns from a task. */
608
- pinned: z5.boolean().optional(),
679
+ pinned: z7.boolean().optional(),
609
680
  /** When the pin was set. Deliberately WRITE-ONLY today, like the `archivedAt` above it:
610
681
  * ordering inside `Pinned` uses the ordinary status/recency rules, so nothing reads this
611
682
  * yet. It is here because a field on a protected surface is far cheaper to add now than to
612
683
  * add later — "pinned oldest first" and "unpin what you pinned a month ago" both need it,
613
684
  * and neither can be reconstructed after the fact. */
614
- pinnedAt: z5.string().optional(),
685
+ pinnedAt: z7.string().optional(),
615
686
  /** Read receipt (#unread-done-items): ISO time the cockpit last opened this run's
616
687
  * thread. A finished (`done`/`failed`) run reads as *unread* until seen since it
617
688
  * finished — see `isUnread()` in the cockpit's `lib/read-state.ts`. Absent on old
618
689
  * runs, on any run not yet opened, and on one deliberately put back to unread via
619
690
  * `POST /runs/:id/unread` (#775) — all three count as unread. */
620
- seenAt: z5.string().optional(),
621
- currentStepId: z5.string().optional(),
622
- error: z5.string().optional(),
623
- steps: z5.array(stepStateSchema),
691
+ seenAt: z7.string().optional(),
692
+ currentStepId: z7.string().optional(),
693
+ error: z7.string().optional(),
694
+ steps: z7.array(stepStateSchema),
624
695
  /**
625
696
  * The persisted workflow definition, so a `queued` run survives a restart — including the ad-hoc
626
697
  * "(planned)" chains that exist nowhere else.
@@ -638,34 +709,34 @@ var runRecordSchema = z5.object({
638
709
  var apiRunSchema = runRecordSchema.extend({
639
710
  usage: processUsageSchema.optional()
640
711
  });
641
- var runIndexEntrySchema = z5.object({
712
+ var runIndexEntrySchema = z7.object({
642
713
  /** The registered project this run belongs to. Joins against `GET /projects`. */
643
- projectId: z5.string(),
644
- id: z5.string(),
645
- title: z5.string(),
646
- titleSummary: z5.string().optional(),
647
- titleOrigin: z5.enum(["user", "auto", "marker"]).optional(),
714
+ projectId: z7.string(),
715
+ id: z7.string(),
716
+ title: z7.string(),
717
+ titleSummary: z7.string().optional(),
718
+ titleOrigin: z7.enum(["user", "auto", "marker"]).optional(),
648
719
  status: runStatusSchema,
649
720
  activity: runActivitySchema.optional(),
650
- createdAt: z5.string(),
651
- finishedAt: z5.string().optional(),
721
+ createdAt: z7.string(),
722
+ finishedAt: z7.string().optional(),
652
723
  /** With `status`/`finishedAt`/`archived`, the four inputs `isUnread` reads — what lets the
653
724
  * palette lead with "finished while you weren't looking" across every project, not just the
654
725
  * one you happen to be standing in. */
655
- seenAt: z5.string().optional(),
726
+ seenAt: z7.string().optional(),
656
727
  /** Always present, like `RunRecord.archived`: absent would read as "not archived", and the
657
728
  * unread rule treats archiving as a stronger "done with this" than reading. */
658
- archived: z5.boolean(),
729
+ archived: z7.boolean(),
659
730
  /** A run parked by a provider usage limit is `failed` on the record with a resume booked
660
731
  * (spec 2026-08-03-auto-resume-after-usage-limit). Both `deriveAttention` and `isUnread` read
661
732
  * it, so without it here a cross-project row would show a red "failed" dot and land in
662
733
  * Recently finished for work that is simply waiting for its appointment. */
663
- autoResumeAt: z5.string().optional(),
734
+ autoResumeAt: z7.string().optional(),
664
735
  /** The workflow the run executes — the global Tasks page shows it in a column and groups by
665
736
  * it. Always present on the record (`RunRecord.workflow`), so required here; the display
666
737
  * refinement `workflowLabel` applies needs `steps[]`, which this row deliberately omits, so
667
738
  * a `(planned)` chain reads as itself here rather than as its first agent's name. */
668
- workflow: z5.string(),
739
+ workflow: z7.string(),
669
740
  /**
670
741
  * The backend this run ran as — RESOLVED server-side, in order of how good the evidence is.
671
742
  *
@@ -688,12 +759,12 @@ var runIndexEntrySchema = z5.object({
688
759
  * the value is what the task WOULD run as — which is why the cockpit renders it muted. Absent
689
760
  * means the row is reporting what actually ran.
690
761
  */
691
- runnerInherited: z5.boolean().optional(),
762
+ runnerInherited: z7.boolean().optional(),
692
763
  /** The model string the run recorded, VERBATIM (`RunRecord.model`). Absent means none was
693
764
  * recorded and the backend picked, which the cockpit prints as a muted `auto` — the same word
694
765
  * the task detail header uses. Never prettified through a catalog: a locally-hosted backend's
695
766
  * own id is the only honest answer. */
696
- model: z5.string().optional(),
767
+ model: z7.string().optional(),
697
768
  /**
698
769
  * How many DISTINCT backends this run's recorded steps used — a workflow may name one per step.
699
770
  *
@@ -702,13 +773,13 @@ var runIndexEntrySchema = z5.object({
702
773
  * server-side and reduced to the one number the cell renders (`Claude Code +1`). Absent means
703
774
  * one backend or none — which is every ordinary run.
704
775
  */
705
- stepBackends: z5.number().int().min(2).optional(),
776
+ stepBackends: z7.number().int().min(2).optional(),
706
777
  /** The task's branch, when it has one — a column on the global page, and the one field that
707
778
  * makes a cross-project row identifiable at a glance without opening it. */
708
- branch: z5.string().optional(),
779
+ branch: z7.string().optional(),
709
780
  /** When the agent actually started, as opposed to when the task was created. The global page's
710
781
  * age column prefers it and falls back to `createdAt`, exactly as the per-project table does. */
711
- startedAt: z5.string().optional(),
782
+ startedAt: z7.string().optional(),
712
783
  /**
713
784
  * The six fields `taskReference()` (`web/src/lib/tasks-table.ts`) reads to decide a task's PR
714
785
  * or issue chip. Carried verbatim rather than pre-resolved into a `{kind, number, url}` on the
@@ -720,20 +791,20 @@ var runIndexEntrySchema = z5.object({
720
791
  * Six scalars is still the slim row this schema exists to keep: `steps[]` and `workflowDef`,
721
792
  * the expensive half, stay off it.
722
793
  */
723
- pullRequestUrl: z5.string().optional(),
724
- referencedPullRequestUrl: z5.string().optional(),
725
- prNumber: z5.number().optional(),
726
- issueNumber: z5.number().optional(),
727
- referencedIssueUrl: z5.string().optional(),
728
- markerRefs: z5.object({ pr: z5.number().optional(), issue: z5.number().optional() }).optional(),
794
+ pullRequestUrl: z7.string().optional(),
795
+ referencedPullRequestUrl: z7.string().optional(),
796
+ prNumber: z7.number().optional(),
797
+ issueNumber: z7.number().optional(),
798
+ referencedIssueUrl: z7.string().optional(),
799
+ markerRefs: z7.object({ pr: z7.number().optional(), issue: z7.number().optional() }).optional(),
729
800
  /** What the run has cost so far. Absent means nothing was recorded, which is NOT `$0` — the
730
801
  * cockpit prints an em dash rather than claiming a measurement that never happened. */
731
- costUsd: z5.number().optional(),
802
+ costUsd: z7.number().optional(),
732
803
  /** The persisted high-water marks a FINISHED run leaves behind. `usage` below stops existing
733
804
  * the moment the process tree does, so without these a finished row could say nothing at all
734
805
  * about what it took to run. */
735
- peakRssBytes: z5.number().optional(),
736
- peakProcCount: z5.number().optional(),
806
+ peakRssBytes: z7.number().optional(),
807
+ peakProcCount: z7.number().optional(),
737
808
  /**
738
809
  * The live CPU/RSS sample of this run's process tree, attached on the way out exactly as
739
810
  * `GET /runs` attaches it (`withUsage`) — never persisted.
@@ -745,90 +816,90 @@ var runIndexEntrySchema = z5.object({
745
816
  */
746
817
  usage: processUsageSchema.optional()
747
818
  });
748
- var referenceStatusesByProjectSchema = z5.record(
749
- z5.string(),
750
- z5.object({
751
- prs: z5.record(z5.number(), referenceStatusSchema),
752
- issues: z5.record(z5.number(), referenceStatusSchema)
819
+ var referenceStatusesByProjectSchema = z7.record(
820
+ z7.string(),
821
+ z7.object({
822
+ prs: z7.record(z7.number(), referenceStatusSchema),
823
+ issues: z7.record(z7.number(), referenceStatusSchema)
753
824
  })
754
825
  );
755
- var runsIndexResponseSchema = z5.object({
826
+ var runsIndexResponseSchema = z7.object({
756
827
  /** Newest first, across every registered project. Archived runs are included — `GET /runs`
757
828
  * carries them for the project you are standing in, and a finder that dropped them elsewhere
758
829
  * would make a task vanish the moment you left its project. */
759
- runs: z5.array(runIndexEntrySchema),
830
+ runs: z7.array(runIndexEntrySchema),
760
831
  /** Additive: absent statuses mean "nothing warm", never "nothing to show". */
761
832
  referenceStatuses: referenceStatusesByProjectSchema,
762
833
  /** The per-project cap that produced this list. */
763
- perProjectLimit: z5.number(),
834
+ perProjectLimit: z7.number(),
764
835
  /** Ids of the projects that had more runs than the cap allowed. */
765
- truncated: z5.array(z5.string())
836
+ truncated: z7.array(z7.string())
766
837
  });
767
- var createRunResponseSchema = z5.union([
838
+ var createRunResponseSchema = z7.union([
768
839
  runRecordSchema,
769
- z5.object({ runs: z5.array(runRecordSchema) })
840
+ z7.object({ runs: z7.array(runRecordSchema) })
770
841
  ]);
771
- var cancelResponseSchema = z5.object({ cancelled: z5.boolean() });
772
- var cancelAutoResumeResponseSchema = z5.object({ cancelled: z5.literal(true) });
773
- var archiveFinishedResponseSchema = z5.object({ archived: z5.number() });
774
- var markAllReadResponseSchema = z5.object({ read: z5.number() });
775
- var deleteRunResponseSchema = z5.object({ deleted: z5.literal(true) });
776
- var finishResponseSchema = z5.object({ finished: z5.literal(true) });
777
- var continueResponseSchema = z5.object({ continued: z5.literal(true) });
778
- var createPrResponseSchema = z5.object({
779
- url: z5.string(),
780
- dryRun: z5.boolean()
781
- });
782
- var messageResponseSchema = z5.union([
783
- z5.object({ delivered: z5.literal(true) }),
784
- z5.object({ queued: z5.literal(true), message: queuedMessageSchema }),
785
- z5.object({ deferred: z5.literal(true) })
842
+ var cancelResponseSchema = z7.object({ cancelled: z7.boolean() });
843
+ var cancelAutoResumeResponseSchema = z7.object({ cancelled: z7.literal(true) });
844
+ var archiveFinishedResponseSchema = z7.object({ archived: z7.number() });
845
+ var markAllReadResponseSchema = z7.object({ read: z7.number() });
846
+ var deleteRunResponseSchema = z7.object({ deleted: z7.literal(true) });
847
+ var finishResponseSchema = z7.object({ finished: z7.literal(true) });
848
+ var continueResponseSchema = z7.object({ continued: z7.literal(true) });
849
+ var createPrResponseSchema = z7.object({
850
+ url: z7.string(),
851
+ dryRun: z7.boolean()
852
+ });
853
+ var messageResponseSchema = z7.union([
854
+ z7.object({ delivered: z7.literal(true) }),
855
+ z7.object({ queued: z7.literal(true), message: queuedMessageSchema }),
856
+ z7.object({ deferred: z7.literal(true) })
786
857
  ]);
787
- var editQueuedMessageResponseSchema = z5.object({ message: queuedMessageSchema });
788
- var removeQueuedMessageResponseSchema = z5.object({ removed: z5.literal(true) });
789
- var openInCliResponseSchema = z5.object({
790
- opened: z5.literal(true),
791
- command: z5.string()
792
- });
793
- var removeWorktreeResponseSchema = z5.object({ removed: z5.literal(true) });
794
- var gitCommitResponseSchema = z5.object({
795
- committed: z5.literal(true),
796
- sha: z5.string()
797
- });
798
- var gitPushResponseSchema = z5.object({
799
- pushed: z5.literal(true),
800
- branch: z5.string(),
801
- remote: z5.string(),
802
- upstreamSet: z5.boolean()
803
- });
804
- var runCommitSchema = z5.object({
805
- sha: z5.string(),
806
- subject: z5.string(),
807
- author: z5.string(),
858
+ var editQueuedMessageResponseSchema = z7.object({ message: queuedMessageSchema });
859
+ var removeQueuedMessageResponseSchema = z7.object({ removed: z7.literal(true) });
860
+ var openInCliResponseSchema = z7.object({
861
+ opened: z7.literal(true),
862
+ command: z7.string()
863
+ });
864
+ var removeWorktreeResponseSchema = z7.object({ removed: z7.literal(true) });
865
+ var gitCommitResponseSchema = z7.object({
866
+ committed: z7.literal(true),
867
+ sha: z7.string()
868
+ });
869
+ var gitPushResponseSchema = z7.object({
870
+ pushed: z7.literal(true),
871
+ branch: z7.string(),
872
+ remote: z7.string(),
873
+ upstreamSet: z7.boolean()
874
+ });
875
+ var runCommitSchema = z7.object({
876
+ sha: z7.string(),
877
+ subject: z7.string(),
878
+ author: z7.string(),
808
879
  /** Relative time ("3 hours ago") — git's `%cr`. */
809
- when: z5.string()
880
+ when: z7.string()
810
881
  });
811
- var runCommitsResponseSchema = z5.object({ commits: z5.array(runCommitSchema) });
812
- var groupVariantSchema = z5.object({
813
- id: z5.string(),
882
+ var runCommitsResponseSchema = z7.object({ commits: z7.array(runCommitSchema) });
883
+ var groupVariantSchema = z7.object({
884
+ id: z7.string(),
814
885
  /** 'A' | 'B' | 'C' in practice; `'?'` for a record that lost its letter. */
815
- variant: z5.string(),
816
- title: z5.string(),
886
+ variant: z7.string(),
887
+ title: z7.string(),
817
888
  status: runStatusSchema,
818
- archived: z5.boolean(),
819
- tokensUsed: z5.number(),
889
+ archived: z7.boolean(),
890
+ tokensUsed: z7.number(),
820
891
  inputTokens: usageCounterSchema.optional(),
821
892
  outputTokens: usageCounterSchema.optional(),
822
- costUsd: z5.number().optional(),
823
- diffStat: z5.string(),
893
+ costUsd: z7.number().optional(),
894
+ diffStat: z7.string(),
824
895
  /** First lines of the handoff journal's "## Progress log" section, as markdown. */
825
- handoffExcerpt: z5.string()
896
+ handoffExcerpt: z7.string()
826
897
  });
827
- var groupResponseSchema = z5.object({
828
- groupId: z5.string(),
829
- runs: z5.array(groupVariantSchema)
898
+ var groupResponseSchema = z7.object({
899
+ groupId: z7.string(),
900
+ runs: z7.array(groupVariantSchema)
830
901
  });
831
- var pickVariantResponseSchema = z5.object({
902
+ var pickVariantResponseSchema = z7.object({
832
903
  winner: runRecordSchema.optional()
833
904
  });
834
905
  var FILE_ATTACHMENT_MEDIA_TYPES = [
@@ -851,148 +922,179 @@ function isImageAttachmentName(name) {
851
922
  const ext = name.split(".").pop()?.toLowerCase();
852
923
  return ext !== void 0 && IMAGE_ATTACHMENT_EXTENSIONS.has(ext);
853
924
  }
854
- var attachmentInputSchema = z5.object({
855
- mediaType: z5.string().refine(isAttachmentMediaType, {
925
+ var attachmentInputSchema = z7.object({
926
+ mediaType: z7.string().refine(isAttachmentMediaType, {
856
927
  message: "unsupported attachment type \u2014 images, plain text, markdown and PDF only"
857
928
  }),
858
- data: z5.string().min(1).max(7e6)
929
+ data: z7.string().min(1).max(7e6)
859
930
  });
860
931
  var imageInputSchema = attachmentInputSchema;
861
- var createRunInputBaseSchema = z5.object({
862
- workflow: z5.string().min(1).optional(),
932
+ var createRunInputBaseSchema = z7.object({
933
+ workflow: z7.string().min(1).optional(),
863
934
  /** An inline chain (spec 008 — an approved plan runs as an ad-hoc workflow, never written to
864
935
  * a file). The catalog's own step shape, not a copy of it. */
865
- steps: z5.array(workflowStepDefSchema).min(1).max(8).optional(),
866
- task: z5.string().min(1).max(1e5, "must be at most 100000 characters"),
867
- model: z5.string().optional(),
936
+ steps: z7.array(workflowStepDefSchema).min(1).max(8).optional(),
937
+ task: z7.string().min(1).max(1e5, "must be at most 100000 characters"),
938
+ model: z7.string().optional(),
868
939
  runner: runnerSchema.optional(),
869
940
  /** Agent account for this task (spec 2026-07-29-agent-profiles). Omit to follow the
870
941
  * project's own selection; an id that no longer exists is a 400, not a silent default. */
871
- agentProfile: z5.string().max(64).optional(),
942
+ agentProfile: z7.string().max(64).optional(),
872
943
  /** 1–3. Above 1 the response is `{ runs }` rather than a single record. */
873
- variants: z5.number().int().min(1).max(3).optional(),
944
+ variants: z7.number().int().min(1).max(3).optional(),
874
945
  /** false → run in the repo working tree instead of an isolated worktree (read-only skills).
875
946
  * Omit for the default. Ignored server-side when variants > 1. */
876
- worktree: z5.boolean().optional(),
947
+ worktree: z7.boolean().optional(),
877
948
  /** true → autonomous run: never parks at "waiting"; auto-continues until done. */
878
- autonomous: z5.boolean().optional(),
949
+ autonomous: z7.boolean().optional(),
879
950
  /** false → keep the handoff journal but do not expose or request a follow-up todos file.
880
951
  * Omit for the default (enabled); a server with the capability off pins it to false. */
881
- generateFollowups: z5.boolean().optional(),
952
+ generateFollowups: z7.boolean().optional(),
882
953
  /** Per-run system-prompt override (R2 2.3) — programmatic callers only. Wins over the
883
954
  * config.json default; whitespace-only degrades to absent. */
884
- systemPrompt: z5.string().trim().max(2e4, "must be at most 20000 characters").optional().transform((s) => s ? s : void 0),
955
+ systemPrompt: z7.string().trim().max(2e4, "must be at most 20000 characters").optional().transform((s) => s ? s : void 0),
885
956
  /** Attachments pasted into the new-task form — screenshots, and since #950 PDF/TXT/MD files
886
957
  * too; delivered with the first agent step. The key keeps its name: the wire contract widened
887
958
  * in place rather than growing a second list. */
888
- images: z5.array(attachmentInputSchema).max(4).optional(),
959
+ images: z7.array(attachmentInputSchema).max(4).optional(),
889
960
  /** The inbox entry this task came from (#374). Best-effort bookkeeping: an unknown or
890
961
  * already-started id never fails the run. For ×2/×3 the FIRST variant is recorded. */
891
- todoId: z5.string().min(1).max(200, "must be at most 200 characters").optional()
962
+ todoId: z7.string().min(1).max(200, "must be at most 200 characters").optional()
892
963
  });
893
964
  var createRunInputSchema = createRunInputBaseSchema.refine(
894
965
  (b) => Boolean(b.workflow) !== Boolean(b.steps),
895
966
  { message: 'provide either "workflow" or "steps", not both' }
896
967
  );
897
- var messageInputSchema = z5.object({
898
- text: z5.string().max(1e5).default(""),
899
- images: z5.array(attachmentInputSchema).max(4).default([])
968
+ var messageInputSchema = z7.object({
969
+ text: z7.string().max(1e5).default(""),
970
+ images: z7.array(attachmentInputSchema).max(4).default([]),
971
+ expectedVersion: mcpVersionTokenSchema.optional()
900
972
  }).refine((m) => m.text.trim().length > 0 || m.images.length > 0, {
901
973
  message: "message needs text or at least one attachment"
902
974
  });
903
- var patchRunInputSchema = z5.object({
904
- title: z5.string().trim().min(1).max(300).optional(),
905
- task: z5.string().trim().min(1).max(1e5).optional()
975
+ var patchRunInputSchema = z7.object({
976
+ title: z7.string().trim().min(1).max(300).optional(),
977
+ task: z7.string().trim().min(1).max(1e5).optional(),
978
+ expectedVersion: mcpVersionTokenSchema.optional()
979
+ });
980
+ var runVersionGuardInputSchema = z7.object({
981
+ expectedVersion: mcpVersionTokenSchema.optional()
906
982
  });
983
+ var pickVariantInputSchema = runVersionGuardInputSchema.extend({
984
+ runId: z7.string().min(1)
985
+ });
986
+ var archiveRunInputSchema = runVersionGuardInputSchema.extend({
987
+ archived: z7.boolean().optional()
988
+ });
989
+ var pinRunInputSchema = runVersionGuardInputSchema.extend({
990
+ pinned: z7.boolean().optional()
991
+ });
992
+ var queuedMessagePatchInputSchema = runVersionGuardInputSchema.extend({
993
+ text: z7.string().max(1e5).optional(),
994
+ images: z7.array(attachmentInputSchema).max(4).optional()
995
+ }).refine((m) => m.text !== void 0 || m.images !== void 0, {
996
+ message: "message edit needs text or attachments"
997
+ });
998
+ var continueRunInputSchema = runVersionGuardInputSchema.extend({
999
+ text: z7.string().max(1e5, "must be at most 100000 characters").optional(),
1000
+ images: z7.array(attachmentInputSchema).max(4).optional(),
1001
+ runner: runnerSchema.optional(),
1002
+ model: z7.string().max(200).optional(),
1003
+ agentProfile: z7.string().max(64).optional()
1004
+ });
1005
+ var gitCommitInputSchema = runVersionGuardInputSchema.extend({
1006
+ message: z7.string().trim().min(1, "must not be empty").max(5e3)
1007
+ });
1008
+ var runVersionResponseSchema = z7.object({ version: mcpVersionTokenSchema });
907
1009
 
908
1010
  // ../contract/src/repo.ts
909
- import { z as z6 } from "zod";
910
- var statusEntrySchema = z6.object({
911
- status: z6.string(),
912
- path: z6.string()
1011
+ import { z as z8 } from "zod";
1012
+ var statusEntrySchema = z8.object({
1013
+ status: z8.string(),
1014
+ path: z8.string()
913
1015
  });
914
- var logEntrySchema = z6.object({
915
- hash: z6.string(),
916
- subject: z6.string(),
917
- author: z6.string(),
918
- when: z6.string()
919
- });
920
- var repoResponseSchema = z6.union([
921
- z6.object({
922
- info: z6.null(),
923
- status: z6.array(z6.never()),
924
- log: z6.array(z6.never()),
925
- branches: z6.array(z6.never()),
926
- baseBranch: z6.null()
1016
+ var logEntrySchema = z8.object({
1017
+ hash: z8.string(),
1018
+ subject: z8.string(),
1019
+ author: z8.string(),
1020
+ when: z8.string()
1021
+ });
1022
+ var repoResponseSchema = z8.union([
1023
+ z8.object({
1024
+ info: z8.null(),
1025
+ status: z8.array(z8.never()),
1026
+ log: z8.array(z8.never()),
1027
+ branches: z8.array(z8.never()),
1028
+ baseBranch: z8.null()
927
1029
  }),
928
- z6.object({
1030
+ z8.object({
929
1031
  info: repoInfoSchema,
930
- status: z6.array(statusEntrySchema),
931
- log: z6.array(logEntrySchema),
932
- branches: z6.array(z6.string()),
933
- baseBranch: z6.string().nullable()
1032
+ status: z8.array(statusEntrySchema),
1033
+ log: z8.array(logEntrySchema),
1034
+ branches: z8.array(z8.string()),
1035
+ baseBranch: z8.string().nullable()
934
1036
  })
935
1037
  ]);
936
- var repoBranchResponseSchema = z6.object({
937
- branch: z6.string(),
938
- created: z6.boolean()
1038
+ var repoBranchResponseSchema = z8.object({
1039
+ branch: z8.string(),
1040
+ created: z8.boolean()
939
1041
  });
940
- var diffStatSchema2 = z6.object({
941
- adds: z6.number(),
942
- dels: z6.number(),
943
- files: z6.number()
1042
+ var diffStatSchema2 = z8.object({
1043
+ adds: z8.number(),
1044
+ dels: z8.number(),
1045
+ files: z8.number()
944
1046
  });
945
- var changedFileSchema = z6.object({
946
- path: z6.string(),
1047
+ var changedFileSchema = z8.object({
1048
+ path: z8.string(),
947
1049
  /** Rename/copy source — present only when `status` is renamed/copied. */
948
- oldPath: z6.string().optional(),
949
- status: z6.enum(["added", "modified", "deleted", "renamed", "copied"]),
950
- adds: z6.number(),
951
- dels: z6.number(),
1050
+ oldPath: z8.string().optional(),
1051
+ status: z8.enum(["added", "modified", "deleted", "renamed", "copied"]),
1052
+ adds: z8.number(),
1053
+ dels: z8.number(),
952
1054
  /** Binary per numstat — there is no text patch to render. */
953
- binary: z6.boolean(),
1055
+ binary: z8.boolean(),
954
1056
  /** True when the path is one the raw-bytes route serves as an `<img>` (#365) — present only
955
1057
  * when true, so old clients that never read it stay correct. */
956
- image: z6.boolean().optional(),
1058
+ image: z8.boolean().optional(),
957
1059
  /** This file's unified-diff section; possibly `… (patch truncated)`, possibly empty. */
958
- patch: z6.string()
1060
+ patch: z8.string()
959
1061
  });
960
- var changesPayloadSchema = z6.object({
961
- files: z6.array(changedFileSchema),
1062
+ var changesPayloadSchema = z8.object({
1063
+ files: z8.array(changedFileSchema),
962
1064
  stat: diffStatSchema2,
963
1065
  /** Additive context for review tasks whose worktree HEAD no longer matches their own branch. */
964
- repointedHead: z6.object({ headBranch: z6.string(), taskBranch: z6.string() }).optional()
1066
+ repointedHead: z8.object({ headBranch: z8.string(), taskBranch: z8.string() }).optional()
965
1067
  });
966
- var repoCommitPayloadSchema = z6.object({
967
- sha: z6.string(),
968
- subject: z6.string(),
969
- author: z6.string(),
1068
+ var repoCommitPayloadSchema = z8.object({
1069
+ sha: z8.string(),
1070
+ subject: z8.string(),
1071
+ author: z8.string(),
970
1072
  /** Relative time ("3 hours ago") — same `%cr` format as the /api/v1/repo log. */
971
- when: z6.string(),
972
- files: z6.array(changedFileSchema),
1073
+ when: z8.string(),
1074
+ files: z8.array(changedFileSchema),
973
1075
  stat: diffStatSchema2
974
1076
  });
975
- var worktreeDirEntrySchema = z6.object({
976
- name: z6.string(),
977
- type: z6.enum(["dir", "file"]),
978
- size: z6.number().optional()
979
- });
980
- var worktreeEntrySchema = z6.discriminatedUnion("type", [
981
- z6.object({
982
- type: z6.literal("dir"),
983
- path: z6.string(),
984
- entries: z6.array(worktreeDirEntrySchema)
1077
+ var worktreeDirEntrySchema = z8.object({
1078
+ name: z8.string(),
1079
+ type: z8.enum(["dir", "file"]),
1080
+ size: z8.number().optional()
1081
+ });
1082
+ var worktreeEntrySchema = z8.discriminatedUnion("type", [
1083
+ z8.object({
1084
+ type: z8.literal("dir"),
1085
+ path: z8.string(),
1086
+ entries: z8.array(worktreeDirEntrySchema)
985
1087
  }),
986
- z6.object({
987
- type: z6.literal("file"),
988
- path: z6.string(),
989
- size: z6.number(),
990
- binary: z6.boolean(),
991
- tooLarge: z6.boolean(),
992
- content: z6.string().optional()
1088
+ z8.object({
1089
+ type: z8.literal("file"),
1090
+ path: z8.string(),
1091
+ size: z8.number(),
1092
+ binary: z8.boolean(),
1093
+ tooLarge: z8.boolean(),
1094
+ content: z8.string().optional()
993
1095
  })
994
1096
  ]);
995
- var worktreeRunStatusSchema = z6.enum([
1097
+ var worktreeRunStatusSchema = z8.enum([
996
1098
  "queued",
997
1099
  "running",
998
1100
  "waiting",
@@ -1001,41 +1103,41 @@ var worktreeRunStatusSchema = z6.enum([
1001
1103
  "failed",
1002
1104
  "cancelled"
1003
1105
  ]);
1004
- var worktreeInfoSchema = z6.object({
1005
- runId: z6.string(),
1006
- title: z6.string(),
1106
+ var worktreeInfoSchema = z8.object({
1107
+ runId: z8.string(),
1108
+ title: z8.string(),
1007
1109
  status: worktreeRunStatusSchema,
1008
- branch: z6.string().nullable(),
1009
- sizeBytes: z6.number().nullable(),
1010
- finishedAt: z6.string().nullable(),
1011
- reclaimable: z6.boolean()
1110
+ branch: z8.string().nullable(),
1111
+ sizeBytes: z8.number().nullable(),
1112
+ finishedAt: z8.string().nullable(),
1113
+ reclaimable: z8.boolean()
1012
1114
  });
1013
- var worktreesResponseSchema = z6.object({
1014
- worktrees: z6.array(worktreeInfoSchema),
1015
- totalBytes: z6.number().nullable(),
1016
- keep: z6.number()
1115
+ var worktreesResponseSchema = z8.object({
1116
+ worktrees: z8.array(worktreeInfoSchema),
1117
+ totalBytes: z8.number().nullable(),
1118
+ keep: z8.number()
1017
1119
  });
1018
- var reclaimWorktreesResponseSchema = z6.object({
1019
- reclaimed: z6.array(z6.string())
1120
+ var reclaimWorktreesResponseSchema = z8.object({
1121
+ reclaimed: z8.array(z8.string())
1020
1122
  });
1021
1123
 
1022
1124
  // ../contract/src/projects.ts
1023
- import { z as z7 } from "zod";
1024
- var projectListEntrySchema = z7.object({
1025
- id: z7.string(),
1026
- name: z7.string(),
1125
+ import { z as z9 } from "zod";
1126
+ var projectListEntrySchema = z9.object({
1127
+ id: z9.string(),
1128
+ name: z9.string(),
1027
1129
  /** Absolute, realpath-normalized repo root. */
1028
- root: z7.string(),
1029
- addedAt: z7.string(),
1030
- lastOpenedAt: z7.string(),
1031
- source: z7.enum(["local", "checkout"]),
1130
+ root: z9.string(),
1131
+ addedAt: z9.string(),
1132
+ lastOpenedAt: z9.string(),
1133
+ source: z9.enum(["local", "checkout"]),
1032
1134
  /** `not-git` is fully usable (degraded single-queue mode); only `missing` blocks. */
1033
- status: z7.enum(["ok", "missing", "not-git"]),
1135
+ status: z9.enum(["ok", "missing", "not-git"]),
1034
1136
  /** Current branch when cheaply available (omitted e.g. on an unborn HEAD). */
1035
- branch: z7.string().optional(),
1137
+ branch: z9.string().optional(),
1036
1138
  /** Which forge this project's remote belongs to (#698) — classified server-side from the
1037
1139
  * remote URL alone. Gates the project group's GitHub nav item; omitted = no forge remote. */
1038
- forge: z7.literal("github").optional(),
1140
+ forge: z9.literal("github").optional(),
1039
1141
  /**
1040
1142
  * The remote's web root, `https://github.com/owner/repo`. Rebuilt server-side from the parsed
1041
1143
  * remote rather than passed through, so a remote carrying credentials cannot leak into the
@@ -1045,10 +1147,10 @@ var projectListEntrySchema = z7.object({
1045
1147
  * the global Tasks page has one row per project, so it cannot use any single repo's base the
1046
1148
  * way a project-scoped view can. With this, every reference it shows is a link.
1047
1149
  */
1048
- repoUrl: z7.string().optional(),
1150
+ repoUrl: z9.string().optional(),
1049
1151
  /** Per-project cap on concurrently running tasks (spec 2026-07-22). Omitted = inherit the
1050
1152
  * workspace `resources.maxParallel`; a number pins this project. */
1051
- maxParallel: z7.number().optional(),
1153
+ maxParallel: z9.number().optional(),
1052
1154
  /**
1053
1155
  * Free-form labels grouping CONNECTED repositories — a `storefront` tag on the API, the web
1054
1156
  * app and the design system says those three are one piece of work spread over three repos.
@@ -1060,100 +1162,100 @@ var projectListEntrySchema = z7.object({
1060
1162
  * server-side (trimmed, deduped case-insensitively, sorted), so a consumer may compare them
1061
1163
  * directly.
1062
1164
  */
1063
- tags: z7.array(z7.string()).optional()
1165
+ tags: z9.array(z9.string()).optional()
1064
1166
  });
1065
- var projectsResponseSchema = z7.object({
1066
- projects: z7.array(projectListEntrySchema),
1067
- bootProject: z7.string(),
1068
- projectsDir: z7.string()
1167
+ var projectsResponseSchema = z9.object({
1168
+ projects: z9.array(projectListEntrySchema),
1169
+ bootProject: z9.string(),
1170
+ projectsDir: z9.string()
1069
1171
  });
1070
- var registerProjectResponseSchema = z7.object({
1172
+ var registerProjectResponseSchema = z9.object({
1071
1173
  project: projectListEntrySchema,
1072
- error: z7.string().optional()
1174
+ error: z9.string().optional()
1073
1175
  });
1074
- var removeProjectResponseSchema = z7.object({
1075
- removed: z7.literal(true),
1076
- id: z7.string()
1176
+ var removeProjectResponseSchema = z9.object({
1177
+ removed: z9.literal(true),
1178
+ id: z9.string()
1077
1179
  });
1078
- var updateProjectResponseSchema = z7.object({
1180
+ var updateProjectResponseSchema = z9.object({
1079
1181
  project: projectListEntrySchema
1080
1182
  });
1081
1183
  var PROJECT_TAG_MAX_LENGTH = 32;
1082
1184
  var PROJECT_TAGS_MAX = 20;
1083
- var updateProjectInputSchema = z7.object({
1084
- maxParallel: z7.number().int().min(1).max(16).nullable().optional(),
1085
- tags: z7.array(z7.string().trim().min(1).max(PROJECT_TAG_MAX_LENGTH)).max(PROJECT_TAGS_MAX).nullable().optional()
1185
+ var updateProjectInputSchema = z9.object({
1186
+ maxParallel: z9.number().int().min(1).max(16).nullable().optional(),
1187
+ tags: z9.array(z9.string().trim().min(1).max(PROJECT_TAG_MAX_LENGTH)).max(PROJECT_TAGS_MAX).nullable().optional()
1086
1188
  }).refine(
1087
1189
  (body) => body.maxParallel !== void 0 || body.tags !== void 0,
1088
1190
  "specify maxParallel or tags"
1089
1191
  );
1090
- var checkoutProjectInputSchema = z7.object({
1091
- url: z7.string().trim().min(1).max(512),
1092
- name: z7.string().trim().max(128).optional(),
1093
- checkoutId: z7.string().trim().max(128).optional()
1192
+ var checkoutProjectInputSchema = z9.object({
1193
+ url: z9.string().trim().min(1).max(512),
1194
+ name: z9.string().trim().max(128).optional(),
1195
+ checkoutId: z9.string().trim().max(128).optional()
1094
1196
  });
1095
- var fsBrowseDirSchema = z7.object({
1096
- name: z7.string(),
1097
- path: z7.string(),
1197
+ var fsBrowseDirSchema = z9.object({
1198
+ name: z9.string(),
1199
+ path: z9.string(),
1098
1200
  /** Has a `.git` entry — drives the "git" badge. A non-repo folder is still selectable. */
1099
- isRepo: z7.boolean()
1201
+ isRepo: z9.boolean()
1100
1202
  });
1101
- var fsBrowseResponseSchema = z7.object({
1203
+ var fsBrowseResponseSchema = z9.object({
1102
1204
  /** The realpath'd directory actually listed — never the spelling asked for, so the breadcrumb
1103
1205
  * shows where the picker really is. */
1104
- path: z7.string(),
1206
+ path: z9.string(),
1105
1207
  /** `null` AT the browse root: there is no "up" out of it, and the dialog must render no parent
1106
1208
  * row rather than one that 400s. */
1107
- parent: z7.string().nullable(),
1108
- dirs: z7.array(fsBrowseDirSchema),
1209
+ parent: z9.string().nullable(),
1210
+ dirs: z9.array(fsBrowseDirSchema),
1109
1211
  /** True when the listing was capped server-side — surfaced honestly instead of showing a
1110
1212
  * silently short list. */
1111
- truncated: z7.boolean()
1213
+ truncated: z9.boolean()
1112
1214
  });
1113
- var launchKeyResponseSchema = z7.object({
1114
- key: z7.string()
1215
+ var launchKeyResponseSchema = z9.object({
1216
+ key: z9.string()
1115
1217
  });
1116
1218
 
1117
1219
  // ../contract/src/workspace.ts
1118
- import { z as z8 } from "zod";
1119
- var workspaceConfigResponseSchema = z8.object({
1220
+ import { z as z10 } from "zod";
1221
+ var workspaceConfigResponseSchema = z10.object({
1120
1222
  /** Root exposed by the Add-project directory browser — stored as written (`~` kept). */
1121
- browseRoot: z8.string(),
1223
+ browseRoot: z10.string(),
1122
1224
  /** Checkout root for GUI-cloned projects — stored as written (`~` kept). */
1123
- projectsDir: z8.string(),
1225
+ projectsDir: z10.string(),
1124
1226
  /** Stored override; `null` means inherit `XEZ_SKILLS_AUTO_UPDATE`, then true. */
1125
- skillsAutoUpdate: z8.boolean().nullable(),
1126
- effectiveSkillsAutoUpdate: z8.boolean(),
1227
+ skillsAutoUpdate: z10.boolean().nullable(),
1228
+ effectiveSkillsAutoUpdate: z10.boolean(),
1127
1229
  /** Stored follow-up Inbox override (F); `null` = no stored key, `XEZ_FOLLOWUPS` decides. */
1128
- followups: z8.boolean().nullable(),
1230
+ followups: z10.boolean().nullable(),
1129
1231
  /** What `followups` + the env actually resolve to right now — what the cockpit shows. */
1130
- effectiveFollowups: z8.boolean(),
1232
+ effectiveFollowups: z10.boolean(),
1131
1233
  /** Stored extra agent env-passthrough names (F); `null` = no stored key,
1132
1234
  * `XEZ_ENV_PASSTHROUGH` decides. `[]` is a real stored "forward nothing". */
1133
- agentEnvPassthrough: z8.array(z8.string()).nullable(),
1235
+ agentEnvPassthrough: z10.array(z10.string()).nullable(),
1134
1236
  /** What `agentEnvPassthrough` + the env actually resolve to right now. */
1135
- effectiveAgentEnvPassthrough: z8.array(z8.string()),
1136
- composerDefaults: z8.object({
1137
- autonomous: z8.boolean().nullable(),
1138
- worktree: z8.boolean().nullable(),
1237
+ effectiveAgentEnvPassthrough: z10.array(z10.string()),
1238
+ composerDefaults: z10.object({
1239
+ autonomous: z10.boolean().nullable(),
1240
+ worktree: z10.boolean().nullable(),
1139
1241
  /** `'source-dependent'` when no `XEZ_AUTONOMOUS_DEFAULT` pins it either way. */
1140
- inheritedAutonomous: z8.union([z8.boolean(), z8.literal("source-dependent")]),
1141
- inheritedWorktree: z8.boolean()
1242
+ inheritedAutonomous: z10.union([z10.boolean(), z10.literal("source-dependent")]),
1243
+ inheritedWorktree: z10.boolean()
1142
1244
  }),
1143
- resources: z8.object({
1144
- maxParallel: z8.number(),
1145
- maxMonitoringSessions: z8.number(),
1146
- monitoringWakeIntervalMinutes: z8.number().nullable(),
1245
+ resources: z10.object({
1246
+ maxParallel: z10.number(),
1247
+ maxMonitoringSessions: z10.number(),
1248
+ monitoringWakeIntervalMinutes: z10.number().nullable(),
1147
1249
  /** Resume a run a provider usage limit stopped, once the limit resets. Default `true`. */
1148
- autoResumeOnUsageLimit: z8.boolean(),
1250
+ autoResumeOnUsageLimit: z10.boolean(),
1149
1251
  /** Wall clock for a session parked at `waiting`, in minutes; `null` = never close on
1150
1252
  * idle. Default 15. */
1151
- idleTimeoutMinutes: z8.number().nullable(),
1152
- memoryLimitMb: z8.number().nullable(),
1253
+ idleTimeoutMinutes: z10.number().nullable(),
1254
+ memoryLimitMb: z10.number().nullable(),
1153
1255
  /** The host-derived ceiling an ABSENT `memoryLimitMb` falls back to (B1) — reported so
1154
1256
  * the settings pane can name the machine's own default instead of guessing it. */
1155
- memoryLimitDefaultMb: z8.number(),
1156
- worktreeRetentionDefault: z8.number()
1257
+ memoryLimitDefaultMb: z10.number(),
1258
+ worktreeRetentionDefault: z10.number()
1157
1259
  }),
1158
1260
  /**
1159
1261
  * What a repo that has set none of its own runs (spec 2026-07-29-agent-profiles).
@@ -1163,125 +1265,125 @@ var workspaceConfigResponseSchema = z8.object({
1163
1265
  * from a value someone chose or the fallback collapses into "always claude". Consulted only where
1164
1266
  * the repo's own `.xezar/config.json` is silent — a repo that chose is never overruled.
1165
1267
  */
1166
- agentDefaults: z8.object({
1268
+ agentDefaults: z10.object({
1167
1269
  runner: runnerSchema.optional(),
1168
- models: z8.object({
1169
- claude: z8.string().optional(),
1170
- codex: z8.string().optional(),
1171
- opencode: z8.string().optional(),
1172
- pi: z8.string().optional()
1270
+ models: z10.object({
1271
+ claude: z10.string().optional(),
1272
+ codex: z10.string().optional(),
1273
+ opencode: z10.string().optional(),
1274
+ pi: z10.string().optional()
1173
1275
  }).optional()
1174
1276
  })
1175
1277
  });
1176
- var setWorkspaceConfigInputSchema = z8.object({
1177
- browseRoot: z8.string().trim().min(1).max(4096).optional(),
1178
- projectsDir: z8.string().trim().min(1).max(4096).optional(),
1179
- skillsAutoUpdate: z8.boolean().nullable().optional(),
1278
+ var setWorkspaceConfigInputSchema = z10.object({
1279
+ browseRoot: z10.string().trim().min(1).max(4096).optional(),
1280
+ projectsDir: z10.string().trim().min(1).max(4096).optional(),
1281
+ skillsAutoUpdate: z10.boolean().nullable().optional(),
1180
1282
  /** Stored Inbox override (F): `null` clears the key back to the `XEZ_FOLLOWUPS` default. */
1181
- followups: z8.boolean().nullable().optional(),
1283
+ followups: z10.boolean().nullable().optional(),
1182
1284
  /** Stored env-passthrough names (F): `null` clears the key back to the
1183
1285
  * `XEZ_ENV_PASSTHROUGH` default; `[]` stores a real "forward nothing". */
1184
- agentEnvPassthrough: z8.array(z8.string().trim().min(1).max(200)).max(64).nullable().optional(),
1185
- composerDefaults: z8.object({
1186
- autonomous: z8.boolean().nullable().optional(),
1187
- worktree: z8.boolean().nullable().optional()
1286
+ agentEnvPassthrough: z10.array(z10.string().trim().min(1).max(200)).max(64).nullable().optional(),
1287
+ composerDefaults: z10.object({
1288
+ autonomous: z10.boolean().nullable().optional(),
1289
+ worktree: z10.boolean().nullable().optional()
1188
1290
  }).optional(),
1189
1291
  /** Machine-wide agent defaults. `null` on a key CLEARS it back to "no opinion", which a bare
1190
1292
  * absent key cannot say in a partial patch. */
1191
- agentDefaults: z8.object({
1293
+ agentDefaults: z10.object({
1192
1294
  runner: runnerSchema.nullable().optional(),
1193
- models: z8.object({
1194
- claude: z8.string().trim().min(1).max(200).nullable().optional(),
1195
- codex: z8.string().trim().min(1).max(200).nullable().optional(),
1196
- opencode: z8.string().trim().min(1).max(200).nullable().optional(),
1197
- pi: z8.string().trim().min(1).max(200).nullable().optional()
1295
+ models: z10.object({
1296
+ claude: z10.string().trim().min(1).max(200).nullable().optional(),
1297
+ codex: z10.string().trim().min(1).max(200).nullable().optional(),
1298
+ opencode: z10.string().trim().min(1).max(200).nullable().optional(),
1299
+ pi: z10.string().trim().min(1).max(200).nullable().optional()
1198
1300
  }).optional()
1199
1301
  }).optional(),
1200
- resources: z8.object({
1201
- maxParallel: z8.number().int().min(1).max(16).optional(),
1202
- maxMonitoringSessions: z8.number().int().min(0).max(16).optional(),
1203
- monitoringWakeIntervalMinutes: z8.number().int().min(1).max(60).nullable().optional(),
1204
- autoResumeOnUsageLimit: z8.boolean().optional(),
1302
+ resources: z10.object({
1303
+ maxParallel: z10.number().int().min(1).max(16).optional(),
1304
+ maxMonitoringSessions: z10.number().int().min(0).max(16).optional(),
1305
+ monitoringWakeIntervalMinutes: z10.number().int().min(1).max(60).nullable().optional(),
1306
+ autoResumeOnUsageLimit: z10.boolean().optional(),
1205
1307
  /** `null` = never close an idle session; a number is minutes (1 to 1440). */
1206
- idleTimeoutMinutes: z8.number().int().min(1).max(1440).nullable().optional(),
1207
- memoryLimitMb: z8.number().int().min(0).max(1048576).nullable().optional(),
1208
- worktreeRetentionDefault: z8.number().int().min(0).max(1e3).optional()
1308
+ idleTimeoutMinutes: z10.number().int().min(1).max(1440).nullable().optional(),
1309
+ memoryLimitMb: z10.number().int().min(0).max(1048576).nullable().optional(),
1310
+ worktreeRetentionDefault: z10.number().int().min(0).max(1e3).optional()
1209
1311
  }).optional()
1210
1312
  });
1211
- var appearanceSchema = z8.object({
1212
- accent: z8.enum(["lime", "violet"]).optional(),
1213
- density: z8.enum(["comfortable", "compact", "ultra"]).optional(),
1214
- width: z8.enum(["narrow", "wide"]).optional()
1313
+ var appearanceSchema = z10.object({
1314
+ accent: z10.enum(["lime", "violet"]).optional(),
1315
+ density: z10.enum(["comfortable", "compact", "ultra"]).optional(),
1316
+ width: z10.enum(["narrow", "wide"]).optional()
1215
1317
  });
1216
- var taskTableUiStateSchema = z8.looseObject({
1318
+ var taskTableUiStateSchema = z10.looseObject({
1217
1319
  /** Explicit user choices only. Missing ids keep the registry-owned default. */
1218
- expandedColumns: z8.record(z8.string(), z8.boolean()).optional()
1320
+ expandedColumns: z10.record(z10.string(), z10.boolean()).optional()
1219
1321
  });
1220
- var uiStateSchema = z8.looseObject({
1322
+ var uiStateSchema = z10.looseObject({
1221
1323
  /** What the last started run used. `null` is a VALUE, not an absence: it records a run that
1222
1324
  * chose neither a skill nor a workflow (the plain built-in `quick-task`), which the composer
1223
1325
  * can now express since the source picker grew an empty state. Absent still means "no
1224
1326
  * run has been recorded here" — a cockpit reading either one selects nothing. */
1225
- lastTask: z8.object({ source: z8.enum(["workflow", "skill"]), ref: z8.string() }).nullable().optional(),
1327
+ lastTask: z10.object({ source: z10.enum(["workflow", "skill"]), ref: z10.string() }).nullable().optional(),
1226
1328
  /** Most-recently-run sources, newest first (deduped, capped). Feeds the composer picker's
1227
1329
  * recency sort. */
1228
- recentSources: z8.array(z8.object({ source: z8.enum(["workflow", "skill"]), ref: z8.string() })).optional(),
1330
+ recentSources: z10.array(z10.object({ source: z10.enum(["workflow", "skill"]), ref: z10.string() })).optional(),
1229
1331
  /** The last worktree choice for a single-skill run. Absent → the default (isolated worktree). */
1230
- lastWorktree: z8.boolean().optional(),
1332
+ lastWorktree: z10.boolean().optional(),
1231
1333
  /** The last autonomous choice — remembered like `lastWorktree`. Absent → off. */
1232
- lastAutonomous: z8.boolean().optional(),
1334
+ lastAutonomous: z10.boolean().optional(),
1233
1335
  /** Whether new runs should ask agents to append follow-up work. Absent → on. */
1234
- lastGenerateFollowups: z8.boolean().optional(),
1336
+ lastGenerateFollowups: z10.boolean().optional(),
1235
1337
  /** Skill selection frequency (#408): name → times chosen, across BOTH composers. */
1236
- skillUsage: z8.record(z8.string(), z8.number()).optional(),
1237
- runsView: z8.enum(["list", "table"]).optional(),
1338
+ skillUsage: z10.record(z10.string(), z10.number()).optional(),
1339
+ runsView: z10.enum(["list", "table"]).optional(),
1238
1340
  /** The GitHub tab's last-selected sub-tab (#417). Absent → issues. */
1239
- githubView: z8.enum(["issues", "prs"]).optional(),
1341
+ githubView: z10.enum(["issues", "prs"]).optional(),
1240
1342
  /** Settings → Appearance. The theme itself stays in localStorage (`xez-theme`) — it must
1241
1343
  * pre-paint, and it is per-browser by design. */
1242
1344
  appearance: appearanceSchema.optional(),
1243
1345
  /** Follow-up prompt templates (#413). Absent → the built-in defaults; present (even `[]`) is
1244
1346
  * the user's own edited list. `skills` are the skill names the template auto-applies for. */
1245
- promptTemplates: z8.array(
1246
- z8.object({
1247
- id: z8.string(),
1248
- label: z8.string(),
1249
- text: z8.string(),
1250
- skills: z8.array(z8.string()).optional()
1347
+ promptTemplates: z10.array(
1348
+ z10.object({
1349
+ id: z10.string(),
1350
+ label: z10.string(),
1351
+ text: z10.string(),
1352
+ skills: z10.array(z10.string()).optional()
1251
1353
  })
1252
1354
  ).optional(),
1253
1355
  /** The open-mercato/skills promo banner (#391), dismissed for good. Legacy — the banner is
1254
1356
  * gone, replaced by `WorkspaceUiState.importedSkills`; retained so old files round-trip. */
1255
- dismissedSkillsBanner: z8.boolean().optional()
1357
+ dismissedSkillsBanner: z10.boolean().optional()
1256
1358
  });
1257
- var workspaceLastLocationSchema = z8.strictObject({
1258
- projectId: z8.string().min(1).max(64),
1259
- pathname: z8.string().min(1).max(2048).startsWith("/p/"),
1260
- search: z8.string().max(4096).startsWith("?").optional(),
1261
- hash: z8.string().max(2048).startsWith("#").optional()
1359
+ var workspaceLastLocationSchema = z10.strictObject({
1360
+ projectId: z10.string().min(1).max(64),
1361
+ pathname: z10.string().min(1).max(2048).startsWith("/p/"),
1362
+ search: z10.string().max(4096).startsWith("?").optional(),
1363
+ hash: z10.string().max(2048).startsWith("#").optional()
1262
1364
  });
1263
- var workspaceUiStateSchema = z8.looseObject({
1365
+ var workspaceUiStateSchema = z10.looseObject({
1264
1366
  /** LEGACY — the sidebar's per-project collapse map (step 3.3). Still accepted and still
1265
1367
  * round-tripped so an older cockpit sharing this home keeps working, but the current cockpit
1266
1368
  * neither reads nor writes it: which groups are shut describes the WINDOW, not the workspace,
1267
1369
  * so it lives in that browser's localStorage (`packages/web/src/lib/sidebar-collapse.ts`).
1268
1370
  * One shared answer meant a phone collapsing a group collapsed it on the desktop too. */
1269
- sidebar: z8.looseObject({ collapsed: z8.record(z8.string(), z8.boolean()).optional() }).optional(),
1371
+ sidebar: z10.looseObject({ collapsed: z10.record(z10.string(), z10.boolean()).optional() }).optional(),
1270
1372
  /** Dismissed runtime-auth incident IDs, keyed by provider. An ID is only dismissed until the
1271
1373
  * provider reports a different incident, so this stays workspace-global with the browser
1272
1374
  * rather than one project checkout. */
1273
- dismissedProviderAuthFailures: z8.object({
1274
- claude: z8.string().optional(),
1275
- codex: z8.string().optional(),
1276
- opencode: z8.string().optional(),
1277
- pi: z8.string().optional()
1375
+ dismissedProviderAuthFailures: z10.object({
1376
+ claude: z10.string().optional(),
1377
+ codex: z10.string().optional(),
1378
+ opencode: z10.string().optional(),
1379
+ pi: z10.string().optional()
1278
1380
  }).optional(),
1279
1381
  /** Settings → Appearance, GLOBAL since step 3.5: accent + density describe the person at the
1280
1382
  * keyboard, not a repo. */
1281
1383
  appearance: appearanceSchema.optional(),
1282
1384
  /** Settings → Notifications, GLOBAL since step 3.5 — one answer for the whole workspace, since
1283
1385
  * the delivering browser is one browser whichever project you are looking at. */
1284
- notifications: z8.looseObject({ enabled: z8.boolean().optional() }).optional(),
1386
+ notifications: z10.looseObject({ enabled: z10.boolean().optional() }).optional(),
1285
1387
  /** Desktop Tasks-table density, shared across every project in this workspace. */
1286
1388
  taskTable: taskTableUiStateSchema.optional(),
1287
1389
  /** LEGACY, exactly like `sidebar` above — the last settled project-scoped page, restored when
@@ -1292,26 +1394,26 @@ var workspaceUiStateSchema = z8.looseObject({
1292
1394
  /** The user's curated selection of default (vendor) skills. Tri-state: ABSENT means "not
1293
1395
  * curated", so every default skill shows; a PRESENT array (even `[]`) means only those names
1294
1396
  * show from that repo. */
1295
- importedSkills: z8.array(z8.string()).optional()
1397
+ importedSkills: z10.array(z10.string()).optional()
1296
1398
  });
1297
1399
  var WORKSPACE_UI_STATE_MAX_KEYS = 200;
1298
1400
  var TASK_TABLE_MAX_COLUMNS = 50;
1299
- var setWorkspaceUiStateInputSchema = z8.looseObject({
1401
+ var setWorkspaceUiStateInputSchema = z10.looseObject({
1300
1402
  ...workspaceUiStateSchema.shape,
1301
- sidebar: z8.looseObject({
1302
- collapsed: z8.record(z8.string().min(1).max(64), z8.boolean()).refine((map) => Object.keys(map).length <= WORKSPACE_UI_STATE_MAX_KEYS, {
1403
+ sidebar: z10.looseObject({
1404
+ collapsed: z10.record(z10.string().min(1).max(64), z10.boolean()).refine((map) => Object.keys(map).length <= WORKSPACE_UI_STATE_MAX_KEYS, {
1303
1405
  message: `sidebar.collapsed must have at most ${WORKSPACE_UI_STATE_MAX_KEYS} entries`
1304
1406
  }).optional()
1305
1407
  }).optional(),
1306
- dismissedProviderAuthFailures: z8.strictObject({
1307
- claude: z8.string().min(1).max(128).optional(),
1308
- codex: z8.string().min(1).max(128).optional(),
1309
- opencode: z8.string().min(1).max(128).optional(),
1310
- pi: z8.string().min(1).max(128).optional()
1408
+ dismissedProviderAuthFailures: z10.strictObject({
1409
+ claude: z10.string().min(1).max(128).optional(),
1410
+ codex: z10.string().min(1).max(128).optional(),
1411
+ opencode: z10.string().min(1).max(128).optional(),
1412
+ pi: z10.string().min(1).max(128).optional()
1311
1413
  }).optional(),
1312
- importedSkills: z8.array(z8.string().min(1).max(200)).max(WORKSPACE_UI_STATE_MAX_KEYS).optional(),
1414
+ importedSkills: z10.array(z10.string().min(1).max(200)).max(WORKSPACE_UI_STATE_MAX_KEYS).optional(),
1313
1415
  taskTable: taskTableUiStateSchema.extend({
1314
- expandedColumns: z8.record(z8.string().min(1).max(64), z8.boolean()).refine((map) => Object.keys(map).length <= TASK_TABLE_MAX_COLUMNS, {
1416
+ expandedColumns: z10.record(z10.string().min(1).max(64), z10.boolean()).refine((map) => Object.keys(map).length <= TASK_TABLE_MAX_COLUMNS, {
1315
1417
  message: `taskTable.expandedColumns must have at most ${TASK_TABLE_MAX_COLUMNS} entries`
1316
1418
  }).optional()
1317
1419
  }).optional()
@@ -1323,73 +1425,73 @@ var setWorkspaceUiStateInputSchema = z8.looseObject({
1323
1425
  });
1324
1426
  }
1325
1427
  });
1326
- var runnerModelsSchema = z8.object({
1327
- claude: z8.string().optional(),
1328
- codex: z8.string().optional(),
1329
- opencode: z8.string().optional(),
1330
- pi: z8.string().optional()
1428
+ var runnerModelsSchema = z10.object({
1429
+ claude: z10.string().optional(),
1430
+ codex: z10.string().optional(),
1431
+ opencode: z10.string().optional(),
1432
+ pi: z10.string().optional()
1331
1433
  });
1332
- var configResponseSchema = z8.object({
1333
- baseBranch: z8.string().nullable(),
1434
+ var configResponseSchema = z10.object({
1435
+ baseBranch: z10.string().nullable(),
1334
1436
  defaultRunner: runnerSchema,
1335
- systemPrompt: z8.string().nullable(),
1437
+ systemPrompt: z10.string().nullable(),
1336
1438
  defaultModels: runnerModelsSchema,
1337
1439
  /** True when native coding-agent settings are authoritative and model picks are read-only. */
1338
- modelsLocked: z8.boolean(),
1440
+ modelsLocked: z10.boolean(),
1339
1441
  /** How many tasks run at once (1–16). */
1340
- maxParallel: z8.number(),
1442
+ maxParallel: z10.number(),
1341
1443
  /** Per-task memory ceiling in MiB (whole process tree); null = no limit. */
1342
- memoryLimitMb: z8.number().nullable(),
1444
+ memoryLimitMb: z10.number().nullable(),
1343
1445
  /** Keep the last N finished worktrees on disk (#483); 0 = unlimited. Older ones are reclaimed
1344
1446
  * (directory only — branch kept, so work is recoverable). */
1345
- worktreeRetention: z8.number(),
1447
+ worktreeRetention: z10.number(),
1346
1448
  /** Live title updates: null = no config key, the `XEZ_TITLE_UPDATES` env default (ON) decides. */
1347
- liveTitleUpdates: z8.boolean().nullable(),
1449
+ liveTitleUpdates: z10.boolean().nullable(),
1348
1450
  /** Optional review gate (#489): null = no config key, the `XEZ_REVIEW_GATE` env default (OFF)
1349
1451
  * decides. */
1350
- reviewGate: z8.boolean().nullable(),
1452
+ reviewGate: z10.boolean().nullable(),
1351
1453
  /** Model the chain planner runs on (Claude aliases only; other backends pick their own).
1352
1454
  * Always materialized — the file schema defaults it to `sonnet` (E). */
1353
- plannerModel: z8.string(),
1455
+ plannerModel: z10.string(),
1354
1456
  /** Model the task namer runs on, same rule as `plannerModel`. Defaults to `haiku` (E). */
1355
- namerModel: z8.string(),
1457
+ namerModel: z10.string(),
1356
1458
  /** Team skill sources (E). Always materialized: the file schema defaults it to the shared
1357
1459
  * catalog, and `[]` is a real "no team skills" choice. */
1358
- skillsRepos: z8.array(z8.object({ repo: z8.string(), ref: z8.string() }))
1460
+ skillsRepos: z10.array(z10.object({ repo: z10.string(), ref: z10.string() }))
1359
1461
  });
1360
1462
  var setConfigResponseSchema = configResponseSchema;
1361
- var setConfigInputSchema = z8.object({
1362
- baseBranch: z8.string().trim().min(1).max(200).nullable().optional(),
1463
+ var setConfigInputSchema = z10.object({
1464
+ baseBranch: z10.string().trim().min(1).max(200).nullable().optional(),
1363
1465
  defaultRunner: runnerSchema.optional(),
1364
- systemPrompt: z8.string().trim().max(2e4).nullable().optional(),
1365
- defaultModels: z8.object({
1366
- claude: z8.string().trim().max(200).nullable().optional(),
1367
- codex: z8.string().trim().max(200).nullable().optional(),
1368
- opencode: z8.string().trim().max(200).nullable().optional(),
1369
- pi: z8.string().trim().max(200).nullable().optional()
1466
+ systemPrompt: z10.string().trim().max(2e4).nullable().optional(),
1467
+ defaultModels: z10.object({
1468
+ claude: z10.string().trim().max(200).nullable().optional(),
1469
+ codex: z10.string().trim().max(200).nullable().optional(),
1470
+ opencode: z10.string().trim().max(200).nullable().optional(),
1471
+ pi: z10.string().trim().max(200).nullable().optional()
1370
1472
  }).optional(),
1371
- maxParallel: z8.number().int().min(1).max(16).optional(),
1473
+ maxParallel: z10.number().int().min(1).max(16).optional(),
1372
1474
  /** null or 0 clears the ceiling back to "no limit". */
1373
- memoryLimitMb: z8.number().int().min(0).max(1048576).nullable().optional(),
1475
+ memoryLimitMb: z10.number().int().min(0).max(1048576).nullable().optional(),
1374
1476
  /** Keep last N finished worktrees (#483); 0 = unlimited, null clears back to the default (10). */
1375
- worktreeRetention: z8.number().int().min(0).max(1e3).nullable().optional(),
1477
+ worktreeRetention: z10.number().int().min(0).max(1e3).nullable().optional(),
1376
1478
  /** null clears the key back to the env-default behavior. */
1377
- liveTitleUpdates: z8.boolean().nullable().optional(),
1479
+ liveTitleUpdates: z10.boolean().nullable().optional(),
1378
1480
  /** null clears the key back to the env-default behavior (OFF). */
1379
- reviewGate: z8.boolean().nullable().optional(),
1481
+ reviewGate: z10.boolean().nullable().optional(),
1380
1482
  /** `null` clears the key back to the schema default (`sonnet`). */
1381
- plannerModel: z8.string().trim().min(1).max(200).nullable().optional(),
1483
+ plannerModel: z10.string().trim().min(1).max(200).nullable().optional(),
1382
1484
  /** `null` clears the key back to the schema default (`haiku`). */
1383
- namerModel: z8.string().trim().min(1).max(200).nullable().optional(),
1485
+ namerModel: z10.string().trim().min(1).max(200).nullable().optional(),
1384
1486
  /** `null` clears the key back to the default catalog; `[]` disables team skills. */
1385
- skillsRepos: z8.array(
1386
- z8.object({
1387
- repo: z8.string().trim().min(1).max(500),
1388
- ref: z8.string().trim().min(1).max(200).optional()
1487
+ skillsRepos: z10.array(
1488
+ z10.object({
1489
+ repo: z10.string().trim().min(1).max(500),
1490
+ ref: z10.string().trim().min(1).max(200).optional()
1389
1491
  })
1390
1492
  ).max(32).nullable().optional()
1391
1493
  });
1392
- var skillsUpdateStatusSchema = z8.enum([
1494
+ var skillsUpdateStatusSchema = z10.enum([
1393
1495
  "idle",
1394
1496
  "checking",
1395
1497
  "available",
@@ -1398,224 +1500,224 @@ var skillsUpdateStatusSchema = z8.enum([
1398
1500
  "unavailable",
1399
1501
  "error"
1400
1502
  ]);
1401
- var skillsUpdateScopeStateSchema = z8.object({
1402
- scope: z8.enum(["project", "global"]),
1503
+ var skillsUpdateScopeStateSchema = z10.object({
1504
+ scope: z10.enum(["project", "global"]),
1403
1505
  status: skillsUpdateStatusSchema,
1404
- available: z8.boolean(),
1405
- skills: z8.array(z8.string()),
1406
- checkedAt: z8.string().nullable(),
1407
- updatedAt: z8.string().nullable(),
1408
- reason: z8.string().optional()
1506
+ available: z10.boolean(),
1507
+ skills: z10.array(z10.string()),
1508
+ checkedAt: z10.string().nullable(),
1509
+ updatedAt: z10.string().nullable(),
1510
+ reason: z10.string().optional()
1409
1511
  });
1410
- var skillsUpdateStateSchema = z8.object({
1512
+ var skillsUpdateStateSchema = z10.object({
1411
1513
  status: skillsUpdateStatusSchema,
1412
- available: z8.boolean(),
1413
- autoUpdateEnabled: z8.boolean(),
1414
- inherited: z8.boolean(),
1415
- checkedAt: z8.string().nullable(),
1416
- updatedAt: z8.string().nullable(),
1417
- scopes: z8.array(skillsUpdateScopeStateSchema),
1418
- needsUpgradeNotes: z8.boolean()
1514
+ available: z10.boolean(),
1515
+ autoUpdateEnabled: z10.boolean(),
1516
+ inherited: z10.boolean(),
1517
+ checkedAt: z10.string().nullable(),
1518
+ updatedAt: z10.string().nullable(),
1519
+ scopes: z10.array(skillsUpdateScopeStateSchema),
1520
+ needsUpgradeNotes: z10.boolean()
1419
1521
  });
1420
1522
  var providerIdSchema = runnerSchema;
1421
- var providerConnectionStateSchema = z8.enum([
1523
+ var providerConnectionStateSchema = z10.enum([
1422
1524
  "connected",
1423
1525
  "disconnected",
1424
1526
  "not-installed",
1425
1527
  "unknown"
1426
1528
  ]);
1427
- var providerStatusSchema = z8.object({
1529
+ var providerStatusSchema = z10.object({
1428
1530
  provider: providerIdSchema,
1429
1531
  status: providerConnectionStateSchema,
1430
- enabled: z8.boolean().optional(),
1431
- hint: z8.string().optional(),
1432
- authFailureId: z8.string().optional(),
1532
+ enabled: z10.boolean().optional(),
1533
+ hint: z10.string().optional(),
1534
+ authFailureId: z10.string().optional(),
1433
1535
  /** Which agent account this row describes (spec 2026-07-29-agent-profiles). ABSENT on
1434
1536
  * `GET /api/v1/providers/status`, which deliberately keeps answering exactly one row per
1435
1537
  * provider — the discovered default — so an older client sees no change at all. Per-account
1436
1538
  * rows are carried by `GET /api/v1/workspace/agent-profiles` instead. */
1437
- profileId: z8.string().optional()
1539
+ profileId: z10.string().optional()
1438
1540
  });
1439
- var providerStatusResponseSchema = z8.object({
1440
- providers: z8.array(providerStatusSchema)
1541
+ var providerStatusResponseSchema = z10.object({
1542
+ providers: z10.array(providerStatusSchema)
1441
1543
  });
1442
- var providerConnectResponseSchema = z8.discriminatedUnion("opened", [
1443
- z8.object({ opened: z8.literal(true), command: z8.string() }),
1444
- z8.object({ opened: z8.literal(false), connected: z8.literal(true), command: z8.string() })
1544
+ var providerConnectResponseSchema = z10.discriminatedUnion("opened", [
1545
+ z10.object({ opened: z10.literal(true), command: z10.string() }),
1546
+ z10.object({ opened: z10.literal(false), connected: z10.literal(true), command: z10.string() })
1445
1547
  ]);
1446
- var modelDiscoveryRunnerSchema = z8.enum(["claude", "codex", "opencode", "pi"]);
1548
+ var modelDiscoveryRunnerSchema = z10.enum(["claude", "codex", "opencode", "pi"]);
1447
1549
  var MODEL_DISCOVERY_RUNNERS = modelDiscoveryRunnerSchema.options;
1448
1550
  function runnerDiscoversModels(runner) {
1449
1551
  return MODEL_DISCOVERY_RUNNERS.includes(runner);
1450
1552
  }
1451
- var runnerModelOptionSchema = z8.object({
1452
- id: z8.string(),
1453
- label: z8.string(),
1454
- description: z8.string()
1553
+ var runnerModelOptionSchema = z10.object({
1554
+ id: z10.string(),
1555
+ label: z10.string(),
1556
+ description: z10.string()
1455
1557
  });
1456
- var runnerModelCatalogResponseSchema = z8.object({
1558
+ var runnerModelCatalogResponseSchema = z10.object({
1457
1559
  runner: runnerSchema,
1458
- models: z8.array(runnerModelOptionSchema),
1459
- source: z8.enum(["live", "cache", "unavailable"]),
1460
- stale: z8.boolean(),
1461
- reason: z8.string().optional()
1462
- });
1463
- var openTargetSchema = z8.object({
1464
- id: z8.string(),
1465
- label: z8.string(),
1560
+ models: z10.array(runnerModelOptionSchema),
1561
+ source: z10.enum(["live", "cache", "unavailable"]),
1562
+ stale: z10.boolean(),
1563
+ reason: z10.string().optional()
1564
+ });
1565
+ var openTargetSchema = z10.object({
1566
+ id: z10.string(),
1567
+ label: z10.string(),
1466
1568
  /** A stable icon key (#361) the UI maps to a concrete icon. Optional: an older server omitting
1467
1569
  * it just renders the generic fallback icon. */
1468
- icon: z8.string().optional()
1570
+ icon: z10.string().optional()
1469
1571
  });
1470
- var openTargetsResponseSchema = z8.object({
1471
- targets: z8.array(openTargetSchema)
1572
+ var openTargetsResponseSchema = z10.object({
1573
+ targets: z10.array(openTargetSchema)
1472
1574
  });
1473
- var openProjectInSchema = z8.object({
1575
+ var openProjectInSchema = z10.object({
1474
1576
  // A short bound (#429): matched against a downstream allowlist, so an app id is never long.
1475
- target: z8.string().trim().min(1, "target required").max(200)
1577
+ target: z10.string().trim().min(1, "target required").max(200)
1476
1578
  });
1477
- var openProjectInResponseSchema = z8.object({
1478
- opened: z8.literal(true),
1479
- path: z8.string()
1579
+ var openProjectInResponseSchema = z10.object({
1580
+ opened: z10.literal(true),
1581
+ path: z10.string()
1480
1582
  });
1481
1583
 
1482
1584
  // ../contract/src/skills.ts
1483
- import { z as z9 } from "zod";
1484
- var skillSchema = z9.object({
1485
- name: z9.string(),
1486
- description: z9.string().optional(),
1585
+ import { z as z11 } from "zod";
1586
+ var skillSchema = z11.object({
1587
+ name: z11.string(),
1588
+ description: z11.string().optional(),
1487
1589
  /** Advisory hint for untouched composer run-mode choices. */
1488
- interactive: z9.literal(true).optional(),
1489
- body: z9.string(),
1490
- path: z9.string(),
1491
- source: z9.enum(["ai", "xezar", "agents", "global", "team"]),
1590
+ interactive: z11.literal(true).optional(),
1591
+ body: z11.string(),
1592
+ path: z11.string(),
1593
+ source: z11.enum(["ai", "xezar", "agents", "global", "team"]),
1492
1594
  /** Team skills only: where the definition lives in its skills repo. */
1493
- team: z9.object({
1494
- repo: z9.string(),
1495
- ref: z9.string(),
1496
- path: z9.string(),
1595
+ team: z11.object({
1596
+ repo: z11.string(),
1597
+ ref: z11.string(),
1598
+ path: z11.string(),
1497
1599
  /** True for the `SKILL.md` convention — a whole directory (references/…). */
1498
- dir: z9.boolean(),
1600
+ dir: z11.boolean(),
1499
1601
  /**
1500
1602
  * The exact commit `ref` resolved to when the skill was read (#428).
1501
1603
  *
1502
1604
  * The hand-written DTO omitted this field entirely — it was NARROWER than the route,
1503
1605
  * which has served it since #428.
1504
1606
  */
1505
- commit: z9.string().optional()
1607
+ commit: z11.string().optional()
1506
1608
  }).optional()
1507
1609
  });
1508
- var importableSkillSchema = z9.object({
1509
- name: z9.string(),
1510
- description: z9.string().optional()
1610
+ var importableSkillSchema = z11.object({
1611
+ name: z11.string(),
1612
+ description: z11.string().optional()
1511
1613
  });
1512
- var todoItemSchema = z9.object({
1513
- id: z9.string(),
1514
- ts: z9.string().optional(),
1515
- taskId: z9.string().optional(),
1516
- summary: z9.string().min(1),
1517
- action: z9.string().optional(),
1518
- prUrl: z9.string().optional(),
1519
- suggestedSkill: z9.string().optional(),
1520
- suggestedArgs: z9.string().optional(),
1521
- suggestedPrompt: z9.string().optional(),
1614
+ var todoItemSchema = z11.object({
1615
+ id: z11.string(),
1616
+ ts: z11.string().optional(),
1617
+ taskId: z11.string().optional(),
1618
+ summary: z11.string().min(1),
1619
+ action: z11.string().optional(),
1620
+ prUrl: z11.string().optional(),
1621
+ suggestedSkill: z11.string().optional(),
1622
+ suggestedArgs: z11.string().optional(),
1623
+ suggestedPrompt: z11.string().optional(),
1522
1624
  /** Explicit intent; missing infers from suggestedSkill/suggestedPrompt for old files. */
1523
- runnable: z9.boolean().optional(),
1625
+ runnable: z11.boolean().optional(),
1524
1626
  /** Set once a task was started from this entry — it then leaves the inbox and stays as
1525
1627
  * the audit trail. A later launch never overwrites the first. */
1526
- startedTaskId: z9.string().optional()
1628
+ startedTaskId: z11.string().optional()
1527
1629
  });
1528
- var removeTodoResponseSchema = z9.object({
1529
- removed: z9.literal(true)
1630
+ var removeTodoResponseSchema = z11.object({
1631
+ removed: z11.literal(true)
1530
1632
  });
1531
- var startTodoResponseSchema = z9.object({
1633
+ var startTodoResponseSchema = z11.object({
1532
1634
  run: runRecordSchema
1533
1635
  });
1534
1636
 
1535
1637
  // ../contract/src/agent-config.ts
1536
- import { z as z10 } from "zod";
1537
- var agentConfigFormatSchema = z10.enum(["json", "jsonc", "toml", "markdown"]);
1538
- var agentConfigScopeSchema = z10.enum(["user", "project", "local"]);
1539
- var agentConfigKindSchema = z10.enum(["settings", "memory", "mcp"]);
1540
- var agentConfigTrackedSchema = z10.enum(["tracked", "gitignored", "outside-repo"]);
1541
- var agentConfigFileSchema = z10.object({
1638
+ import { z as z12 } from "zod";
1639
+ var agentConfigFormatSchema = z12.enum(["json", "jsonc", "toml", "markdown"]);
1640
+ var agentConfigScopeSchema = z12.enum(["user", "project", "local"]);
1641
+ var agentConfigKindSchema = z12.enum(["settings", "memory", "mcp"]);
1642
+ var agentConfigTrackedSchema = z12.enum(["tracked", "gitignored", "outside-repo"]);
1643
+ var agentConfigFileSchema = z12.object({
1542
1644
  /** Stable, opaque, URL-safe — the ONLY thing a client may name (traversal-proof). */
1543
- id: z10.string(),
1645
+ id: z12.string(),
1544
1646
  /** Every runner that reads this file: `<repo>/AGENTS.md` is one file, two readers. */
1545
- runners: z10.array(runnerSchema),
1647
+ runners: z12.array(runnerSchema),
1546
1648
  kind: agentConfigKindSchema,
1547
1649
  scope: agentConfigScopeSchema,
1548
- label: z10.string(),
1549
- path: z10.string(),
1650
+ label: z12.string(),
1651
+ path: z12.string(),
1550
1652
  format: agentConfigFormatSchema,
1551
1653
  tracked: agentConfigTrackedSchema,
1552
- seeded: z10.boolean(),
1553
- holdsMcp: z10.boolean(),
1654
+ seeded: z12.boolean(),
1655
+ holdsMcp: z12.boolean(),
1554
1656
  /** VERBATIM from the vendor docs. Never computed, never generic. */
1555
- precedence: z10.string(),
1657
+ precedence: z12.string(),
1556
1658
  /** Documented mid-run reload behaviour, or absent when the vendor is silent. */
1557
- hotReload: z10.string().optional(),
1558
- docsUrl: z10.string(),
1559
- exists: z10.boolean(),
1560
- size: z10.number(),
1659
+ hotReload: z12.string().optional(),
1660
+ docsUrl: z12.string(),
1661
+ exists: z12.boolean(),
1662
+ size: z12.number(),
1561
1663
  /** sha256 of the bytes, or null when absent. */
1562
- version: z10.string().nullable(),
1664
+ version: z12.string().nullable(),
1563
1665
  /** False in hosted mode (whole feature) — the client renders read-only up front. */
1564
- writable: z10.boolean(),
1565
- readOnlyReason: z10.string().optional()
1666
+ writable: z12.boolean(),
1667
+ readOnlyReason: z12.string().optional()
1566
1668
  });
1567
- var userMcpListingSchema = z10.object({
1568
- path: z10.string(),
1569
- servers: z10.array(z10.string()),
1570
- readable: z10.boolean()
1669
+ var userMcpListingSchema = z12.object({
1670
+ path: z12.string(),
1671
+ servers: z12.array(z12.string()),
1672
+ readable: z12.boolean()
1571
1673
  });
1572
- var agentConfigListingSchema = z10.object({
1573
- editable: z10.boolean(),
1574
- files: z10.array(agentConfigFileSchema),
1674
+ var agentConfigListingSchema = z12.object({
1675
+ editable: z12.boolean(),
1676
+ files: z12.array(agentConfigFileSchema),
1575
1677
  /** null in hosted mode (host-state disclosure guard). */
1576
1678
  userMcp: userMcpListingSchema.nullable()
1577
1679
  });
1578
- var agentConfigFileContentSchema = z10.object({
1579
- id: z10.string(),
1580
- path: z10.string(),
1581
- exists: z10.boolean(),
1582
- content: z10.string(),
1680
+ var agentConfigFileContentSchema = z12.object({
1681
+ id: z12.string(),
1682
+ path: z12.string(),
1683
+ exists: z12.boolean(),
1684
+ content: z12.string(),
1583
1685
  /** sha256 of the bytes, or null when the file does not exist yet. */
1584
- version: z10.string().nullable()
1686
+ version: z12.string().nullable()
1585
1687
  });
1586
- var setAgentConfigInputSchema = z10.object({
1587
- content: z10.string().max(2e6),
1588
- version: z10.string().nullable()
1688
+ var setAgentConfigInputSchema = z12.object({
1689
+ content: z12.string().max(2e6),
1690
+ version: z12.string().nullable()
1589
1691
  });
1590
1692
 
1591
1693
  // ../contract/src/agent-profiles.ts
1592
- import { z as z11 } from "zod";
1694
+ import { z as z13 } from "zod";
1593
1695
  var DEFAULT_AGENT_ACCOUNT_ID = "default";
1594
- var agentAccountFileSchema = z11.object({
1595
- id: z11.string(),
1696
+ var agentAccountFileSchema = z13.object({
1697
+ id: z13.string(),
1596
1698
  /** e.g. `settings.json` — the file's own name, since the folder is shown once on the account. */
1597
- label: z11.string(),
1699
+ label: z13.string(),
1598
1700
  /** Absolute, resolved inside this account's config folder. */
1599
- path: z11.string(),
1600
- exists: z11.boolean()
1701
+ path: z13.string(),
1702
+ exists: z13.boolean()
1601
1703
  });
1602
- var agentProfileSchema = z11.object({
1704
+ var agentProfileSchema = z13.object({
1603
1705
  /** `default` for the discovered profile, else the stored slug. */
1604
- id: z11.string(),
1706
+ id: z13.string(),
1605
1707
  provider: providerIdSchema,
1606
- label: z11.string(),
1708
+ label: z13.string(),
1607
1709
  /** As the user wrote it — a literal `~` is preserved, matching `browseRoot`/`projectsDir`. */
1608
- configDir: z11.string(),
1710
+ configDir: z13.string(),
1609
1711
  /** Expanded absolute path. Same-origin route, like `ProjectListEntry.root`. */
1610
- path: z11.string(),
1712
+ path: z13.string(),
1611
1713
  /** False for a dir the CLI has not created yet — legitimate, and NOT a reason to fall back
1612
1714
  * to another account at run time (that would silently bill the wrong subscription). */
1613
- exists: z11.boolean(),
1715
+ exists: z13.boolean(),
1614
1716
  /** Whether the dir carries this agent's own marker files. ADVISORY: an unrecognised dir is
1615
1717
  * still accepted, because "add profile → Connect → the CLI creates it" is the real flow. */
1616
- looksValid: z11.boolean(),
1718
+ looksValid: z13.boolean(),
1617
1719
  /** True for the profile xezar discovers from the environment. Never stored, never deletable. */
1618
- isDefault: z11.boolean(),
1720
+ isDefault: z13.boolean(),
1619
1721
  /** This account's own authentication state — two Claude logins answer independently.
1620
1722
  *
1621
1723
  * **Absent until the probe has warmed.** Every probe shells out to an agent CLI, and this
@@ -1626,35 +1728,35 @@ var agentProfileSchema = z11.object({
1626
1728
  status: providerStatusSchema.optional(),
1627
1729
  /** This agent's own user-scope config files, resolved inside THIS account's folder — so a
1628
1730
  * second login's `settings.json` is the one you open, not the default account's. */
1629
- files: z11.array(agentAccountFileSchema)
1731
+ files: z13.array(agentAccountFileSchema)
1630
1732
  });
1631
1733
  function agentAccountRouteId(profile) {
1632
1734
  return profile.isDefault ? `default:${profile.provider}` : profile.id;
1633
1735
  }
1634
- var agentAccountSelectionSchema = z11.object({
1635
- claude: z11.string().optional(),
1636
- codex: z11.string().optional(),
1637
- opencode: z11.string().optional(),
1638
- pi: z11.string().optional()
1639
- });
1640
- var agentProfilesResponseSchema = z11.object({
1641
- editable: z11.boolean(),
1642
- profiles: z11.array(agentProfileSchema),
1736
+ var agentAccountSelectionSchema = z13.object({
1737
+ claude: z13.string().optional(),
1738
+ codex: z13.string().optional(),
1739
+ opencode: z13.string().optional(),
1740
+ pi: z13.string().optional()
1741
+ });
1742
+ var agentProfilesResponseSchema = z13.object({
1743
+ editable: z13.boolean(),
1744
+ profiles: z13.array(agentProfileSchema),
1643
1745
  /** Providers that can carry more than one account at all — what "Add account" is offered for.
1644
1746
  * OpenCode is absent: its credentials live in a SQLite DB behind a separate `OPENCODE_DB`, so
1645
1747
  * a config-dir profile would swap settings while still billing the other account. */
1646
- profileCapableProviders: z11.array(providerIdSchema),
1748
+ profileCapableProviders: z13.array(providerIdSchema),
1647
1749
  /** Which account each project uses, keyed by the project's realpath'd ROOT.
1648
1750
  *
1649
1751
  * Served here rather than on `GET /api/v1/projects` because it is stored beside the accounts it
1650
1752
  * names (`~/.xezar/agent-accounts.json`) — one file, so deleting an account and scrubbing every
1651
1753
  * reference to it is one atomic write, and neither can be dropped by a xezar version that never
1652
1754
  * heard of accounts. Empty in hosted mode, where the whole family is withheld. */
1653
- selections: z11.record(z11.string(), agentAccountSelectionSchema),
1755
+ selections: z13.record(z13.string(), agentAccountSelectionSchema),
1654
1756
  /** The machine-wide fallback account per provider, used by any repo that has chosen none. */
1655
1757
  defaults: agentAccountSelectionSchema
1656
1758
  });
1657
- var selectAgentProfileInputSchema = z11.object({
1759
+ var selectAgentProfileInputSchema = z13.object({
1658
1760
  /**
1659
1761
  * Registry slug, or the reserved `default` boot alias. Resolved to a root server-side.
1660
1762
  *
@@ -1662,108 +1764,108 @@ var selectAgentProfileInputSchema = z11.object({
1662
1764
  * chosen nothing uses, so a second login is set up once rather than per checkout. A repo's own
1663
1765
  * choice always wins over it, which is what keeps this a default and not an override.
1664
1766
  */
1665
- projectId: z11.string().min(1).max(64).nullable(),
1767
+ projectId: z13.string().min(1).max(64).nullable(),
1666
1768
  provider: providerIdSchema,
1667
- profileId: z11.string().max(64).nullable()
1769
+ profileId: z13.string().max(64).nullable()
1668
1770
  });
1669
- var agentProfileSelectionsResponseSchema = z11.object({
1670
- selections: z11.record(z11.string(), agentAccountSelectionSchema),
1771
+ var agentProfileSelectionsResponseSchema = z13.object({
1772
+ selections: z13.record(z13.string(), agentAccountSelectionSchema),
1671
1773
  /** The machine-wide fallback, for repos with no selection of their own. */
1672
1774
  defaults: agentAccountSelectionSchema
1673
1775
  });
1674
- var agentAccountStatusResponseSchema = z11.object({ status: providerStatusSchema });
1675
- var agentAccountDetailsResponseSchema = z11.object({
1676
- available: z11.boolean(),
1677
- reason: z11.string().optional(),
1678
- fields: z11.array(z11.object({ label: z11.string(), value: z11.string() }))
1776
+ var agentAccountStatusResponseSchema = z13.object({ status: providerStatusSchema });
1777
+ var agentAccountDetailsResponseSchema = z13.object({
1778
+ available: z13.boolean(),
1779
+ reason: z13.string().optional(),
1780
+ fields: z13.array(z13.object({ label: z13.string(), value: z13.string() }))
1679
1781
  });
1680
- var openAgentAccountFileInputSchema = z11.object({
1681
- file: z11.string().min(1).max(200),
1682
- target: z11.string().min(1).max(64).optional()
1782
+ var openAgentAccountFileInputSchema = z13.object({
1783
+ file: z13.string().min(1).max(200),
1784
+ target: z13.string().min(1).max(64).optional()
1683
1785
  });
1684
- var openAgentAccountFileResponseSchema = z11.object({
1685
- opened: z11.literal(true),
1686
- path: z11.string()
1786
+ var openAgentAccountFileResponseSchema = z13.object({
1787
+ opened: z13.literal(true),
1788
+ path: z13.string()
1687
1789
  });
1688
- var createAgentProfileInputSchema = z11.object({
1790
+ var createAgentProfileInputSchema = z13.object({
1689
1791
  provider: providerIdSchema,
1690
- label: z11.string().trim().max(200).optional(),
1792
+ label: z13.string().trim().max(200).optional(),
1691
1793
  /** Stored as written; validated absolute after `~` expansion, server-side. */
1692
- configDir: z11.string().trim().min(1).max(4096)
1794
+ configDir: z13.string().trim().min(1).max(4096)
1693
1795
  });
1694
- var agentProfileResponseSchema = z11.object({ profile: agentProfileSchema });
1695
- var updateAgentProfileInputSchema = z11.object({
1696
- label: z11.string().trim().max(200).optional(),
1697
- configDir: z11.string().trim().min(1).max(4096).optional()
1796
+ var agentProfileResponseSchema = z13.object({ profile: agentProfileSchema });
1797
+ var updateAgentProfileInputSchema = z13.object({
1798
+ label: z13.string().trim().max(200).optional(),
1799
+ configDir: z13.string().trim().min(1).max(4096).optional()
1698
1800
  });
1699
- var removeAgentProfileResponseSchema = z11.object({
1700
- removed: z11.literal(true),
1701
- id: z11.string()
1801
+ var removeAgentProfileResponseSchema = z13.object({
1802
+ removed: z13.literal(true),
1803
+ id: z13.string()
1702
1804
  });
1703
1805
 
1704
1806
  // ../contract/src/automations.ts
1705
- import { z as z12 } from "zod";
1706
- var automationEventSchema = z12.enum([
1807
+ import { z as z14 } from "zod";
1808
+ var automationEventSchema = z14.enum([
1707
1809
  "pull_request.opened",
1708
1810
  "issue.opened",
1709
1811
  "issue.labeled",
1710
1812
  "issue.unlabeled"
1711
1813
  ]);
1712
- var automationFiltersSchema = z12.object({
1713
- authors: z12.array(z12.string()).optional(),
1714
- assignees: z12.array(z12.string()).optional(),
1715
- allLabels: z12.array(z12.string()).optional(),
1716
- anyLabels: z12.array(z12.string()).optional(),
1717
- excludeLabels: z12.array(z12.string()).optional(),
1814
+ var automationFiltersSchema = z14.object({
1815
+ authors: z14.array(z14.string()).optional(),
1816
+ assignees: z14.array(z14.string()).optional(),
1817
+ allLabels: z14.array(z14.string()).optional(),
1818
+ anyLabels: z14.array(z14.string()).optional(),
1819
+ excludeLabels: z14.array(z14.string()).optional(),
1718
1820
  /** Required for the two label events — the server rejects a definition without it. */
1719
- changedLabels: z12.array(z12.string()).optional(),
1720
- lookbackDays: z12.number(),
1721
- maxRecords: z12.number()
1821
+ changedLabels: z14.array(z14.string()).optional(),
1822
+ lookbackDays: z14.number(),
1823
+ maxRecords: z14.number()
1722
1824
  });
1723
1825
  var automationTaskSchema = createRunInputBaseSchema.omit({ task: true, images: true, todoId: true, systemPrompt: true }).extend({
1724
1826
  /** The prompt template. `{{github.number}}`, `{{github.title}}`, `{{github.url}}` and
1725
1827
  * `{{github.labels}}` are substituted per match; GitHub content is appended as untrusted
1726
1828
  * context, never interpolated into instructions. */
1727
- prompt: z12.string(),
1728
- variants: z12.union([z12.literal(1), z12.literal(2), z12.literal(3)]).optional(),
1729
- systemPrompt: z12.string().optional()
1829
+ prompt: z14.string(),
1830
+ variants: z14.union([z14.literal(1), z14.literal(2), z14.literal(3)]).optional(),
1831
+ systemPrompt: z14.string().optional()
1730
1832
  });
1731
- var automationDefinitionSchema = z12.object({
1732
- id: z12.string(),
1833
+ var automationDefinitionSchema = z14.object({
1834
+ id: z14.string(),
1733
1835
  /** Bumped on every edit; a PUT must echo the revision it read (optimistic concurrency). */
1734
- revision: z12.number(),
1735
- name: z12.string(),
1736
- description: z12.string().optional(),
1836
+ revision: z14.number(),
1837
+ name: z14.string(),
1838
+ description: z14.string().optional(),
1737
1839
  /** Always present: the storage schema defaults it to `false`, so a definition is created
1738
1840
  * PAUSED and enabling it is a separate, baseline-establishing act. */
1739
- enabled: z12.boolean(),
1740
- events: z12.array(automationEventSchema),
1741
- intervalSeconds: z12.number(),
1841
+ enabled: z14.boolean(),
1842
+ events: z14.array(automationEventSchema),
1843
+ intervalSeconds: z14.number(),
1742
1844
  filters: automationFiltersSchema,
1743
1845
  task: automationTaskSchema,
1744
- createdAt: z12.string(),
1745
- updatedAt: z12.string()
1846
+ createdAt: z14.string(),
1847
+ updatedAt: z14.string()
1746
1848
  });
1747
- var automationCursorSchema = z12.object({
1748
- timestamp: z12.string(),
1749
- tieBreaker: z12.string().optional()
1849
+ var automationCursorSchema = z14.object({
1850
+ timestamp: z14.string(),
1851
+ tieBreaker: z14.string().optional()
1750
1852
  });
1751
- var automationRuntimeStateSchema = z12.object({
1853
+ var automationRuntimeStateSchema = z14.object({
1752
1854
  /** The definition revision this state belongs to; a bumped revision re-baselines. */
1753
- revision: z12.number().optional(),
1855
+ revision: z14.number().optional(),
1754
1856
  /** Enabling establishes a CURRENT-TIME baseline: records older than this never launch. */
1755
- baselineAt: z12.string().optional(),
1857
+ baselineAt: z14.string().optional(),
1756
1858
  cursor: automationCursorSchema.optional(),
1757
- frozenHighWatermark: automationCursorSchema.extend({ tieBreaker: z12.string() }).optional(),
1758
- backlogAfter: automationCursorSchema.extend({ tieBreaker: z12.string() }).optional(),
1759
- nextCheckAt: z12.string().optional(),
1760
- lastSuccessAt: z12.string().optional(),
1859
+ frozenHighWatermark: automationCursorSchema.extend({ tieBreaker: z14.string() }).optional(),
1860
+ backlogAfter: automationCursorSchema.extend({ tieBreaker: z14.string() }).optional(),
1861
+ nextCheckAt: z14.string().optional(),
1862
+ lastSuccessAt: z14.string().optional(),
1761
1863
  /** Per-query GitHub ETags, so an unchanged page costs no rate-limit budget. */
1762
- etags: z12.record(z12.string(), z12.string()).optional(),
1763
- backoffUntil: z12.string().optional(),
1764
- consecutiveFailures: z12.number().optional()
1864
+ etags: z14.record(z14.string(), z14.string()).optional(),
1865
+ backoffUntil: z14.string().optional(),
1866
+ consecutiveFailures: z14.number().optional()
1765
1867
  });
1766
- var automationLogResultSchema = z12.enum([
1868
+ var automationLogResultSchema = z14.enum([
1767
1869
  "launched",
1768
1870
  "no-match",
1769
1871
  "duplicate",
@@ -1772,87 +1874,544 @@ var automationLogResultSchema = z12.enum([
1772
1874
  "baseline",
1773
1875
  "preview"
1774
1876
  ]);
1775
- var automationLogRecordSchema = z12.object({
1776
- seq: z12.number(),
1777
- ts: z12.string(),
1778
- automationId: z12.string(),
1779
- revision: z12.number(),
1877
+ var automationLogRecordSchema = z14.object({
1878
+ seq: z14.number(),
1879
+ ts: z14.string(),
1880
+ automationId: z14.string(),
1881
+ revision: z14.number(),
1780
1882
  event: automationEventSchema.optional(),
1781
1883
  result: automationLogResultSchema,
1782
- reason: z12.string().optional(),
1783
- durationMs: z12.number().optional(),
1784
- receiptId: z12.string().optional(),
1785
- runId: z12.string().optional(),
1786
- githubNumber: z12.number().optional(),
1787
- githubTitle: z12.string().optional(),
1788
- githubUrl: z12.string().optional(),
1789
- rateLimit: z12.object({
1790
- bucket: z12.enum(["core", "search"]),
1791
- remaining: z12.number().optional(),
1792
- resetAt: z12.string().optional()
1884
+ reason: z14.string().optional(),
1885
+ durationMs: z14.number().optional(),
1886
+ receiptId: z14.string().optional(),
1887
+ runId: z14.string().optional(),
1888
+ githubNumber: z14.number().optional(),
1889
+ githubTitle: z14.string().optional(),
1890
+ githubUrl: z14.string().optional(),
1891
+ rateLimit: z14.object({
1892
+ bucket: z14.enum(["core", "search"]),
1893
+ remaining: z14.number().optional(),
1894
+ resetAt: z14.string().optional()
1793
1895
  }).optional()
1794
1896
  });
1795
- var automationCountsSchema = z12.object({
1796
- matches: z12.number(),
1797
- launched: z12.number(),
1798
- duplicates: z12.number(),
1799
- errors: z12.number()
1897
+ var automationCountsSchema = z14.object({
1898
+ matches: z14.number(),
1899
+ launched: z14.number(),
1900
+ duplicates: z14.number(),
1901
+ errors: z14.number()
1800
1902
  });
1801
1903
  var automationListEntrySchema = automationDefinitionSchema.extend({
1802
1904
  state: automationRuntimeStateSchema.optional(),
1803
1905
  latestLog: automationLogRecordSchema.optional(),
1804
1906
  counts: automationCountsSchema
1805
1907
  });
1806
- var automationsResponseSchema = z12.object({
1807
- available: z12.boolean(),
1808
- reason: z12.string().optional(),
1809
- scheduler: z12.object({
1810
- state: z12.enum(["scheduled", "idle"]),
1811
- nextDue: z12.string().optional()
1908
+ var automationsResponseSchema = z14.object({
1909
+ available: z14.boolean(),
1910
+ reason: z14.string().optional(),
1911
+ scheduler: z14.object({
1912
+ state: z14.enum(["scheduled", "idle"]),
1913
+ nextDue: z14.string().optional()
1812
1914
  }),
1813
- automations: z12.array(automationListEntrySchema)
1915
+ automations: z14.array(automationListEntrySchema)
1814
1916
  });
1815
- var automationResponseSchema = z12.object({ automation: automationDefinitionSchema });
1816
- var automationDetailResponseSchema = z12.object({
1917
+ var automationResponseSchema = z14.object({ automation: automationDefinitionSchema });
1918
+ var automationDetailResponseSchema = z14.object({
1817
1919
  automation: automationDefinitionSchema,
1818
1920
  state: automationRuntimeStateSchema.optional(),
1819
1921
  latestLog: automationLogRecordSchema.optional()
1820
1922
  });
1821
- var automationCheckSchema = z12.object({
1822
- id: z12.string(),
1823
- automationId: z12.string(),
1824
- mode: z12.enum(["preview", "execute"]),
1825
- status: z12.enum(["queued", "running", "complete", "error"]),
1826
- createdAt: z12.string(),
1827
- completedAt: z12.string().optional(),
1828
- matches: z12.number().optional(),
1829
- truncated: z12.boolean().optional(),
1830
- error: z12.string().optional()
1831
- });
1832
- var automationCheckQueuedResponseSchema = z12.object({ checkId: z12.string() });
1833
- var automationLogResponseSchema = z12.object({
1834
- records: z12.array(automationLogRecordSchema)
1835
- });
1836
- var automationRetryResponseSchema = z12.object({
1837
- receiptId: z12.string(),
1838
- runId: z12.string()
1839
- });
1840
- var createAutomationInputSchema = automationDefinitionSchema.omit({ id: true, revision: true, createdAt: true, updatedAt: true, enabled: true }).extend({ enable: z12.boolean().optional() });
1923
+ var automationCheckSchema = z14.object({
1924
+ id: z14.string(),
1925
+ automationId: z14.string(),
1926
+ mode: z14.enum(["preview", "execute"]),
1927
+ status: z14.enum(["queued", "running", "complete", "error"]),
1928
+ createdAt: z14.string(),
1929
+ completedAt: z14.string().optional(),
1930
+ matches: z14.number().optional(),
1931
+ truncated: z14.boolean().optional(),
1932
+ error: z14.string().optional()
1933
+ });
1934
+ var automationCheckQueuedResponseSchema = z14.object({ checkId: z14.string() });
1935
+ var automationLogResponseSchema = z14.object({
1936
+ records: z14.array(automationLogRecordSchema)
1937
+ });
1938
+ var automationRetryResponseSchema = z14.object({
1939
+ receiptId: z14.string(),
1940
+ runId: z14.string()
1941
+ });
1942
+ var createAutomationInputSchema = automationDefinitionSchema.omit({ id: true, revision: true, createdAt: true, updatedAt: true, enabled: true }).extend({ enable: z14.boolean().optional() });
1841
1943
  var updateAutomationInputSchema = createAutomationInputSchema.omit({ enable: true }).extend({
1842
- enabled: z12.boolean().optional(),
1843
- expectedRevision: z12.number()
1944
+ enabled: z14.boolean().optional(),
1945
+ expectedRevision: z14.number()
1946
+ });
1947
+ var automationCheckInputSchema = z14.object({
1948
+ mode: z14.enum(["preview", "execute"])
1949
+ });
1950
+
1951
+ // ../contract/src/mcp-idempotency.ts
1952
+ import { z as z15 } from "zod";
1953
+ var operationIdSchema = z15.string().min(8).max(128).regex(/^[A-Za-z0-9_.:-]+$/);
1954
+ var operationOutcomeSchema = z15.enum(["ok", "rejected", "not-applied", "unverified"]);
1955
+ var operationResultRefSchema = z15.object({
1956
+ kind: z15.string().min(1).max(64),
1957
+ id: z15.string().min(1).max(256)
1958
+ });
1959
+ var operationReasonSchema = z15.string().min(1).max(64).regex(/^[a-z0-9_ -]+$/);
1960
+ var reconcilePredicateSchema = z15.discriminatedUnion("kind", [
1961
+ /** The run id predicted from the operation key before the effect (D-06 § 12.1). */
1962
+ z15.object({ kind: z15.literal("run-by-key"), predictedRunId: z15.uuid() }),
1963
+ /** A forge list/search read, e.g. `gh pr list --head <branch>`. */
1964
+ z15.object({
1965
+ kind: z15.literal("forge-search"),
1966
+ repository: z15.string().min(1),
1967
+ headBranch: z15.string().min(1)
1968
+ }),
1969
+ /** The expected ref and the sha it should point at after the effect. */
1970
+ z15.object({ kind: z15.literal("git-state"), ref: z15.string().min(1), sha: z15.string().min(1) }),
1971
+ /** The action has no external effect to look for. */
1972
+ z15.object({ kind: z15.literal("none") })
1973
+ ]);
1974
+ var UNVERIFIED_GUIDANCE = "read current state; a new operationId is a new action";
1975
+ var operationSettledResultSchema = z15.object({
1976
+ status: z15.enum(["ok", "rejected", "not-applied"]),
1977
+ operationId: operationIdSchema,
1978
+ action: z15.string().min(1),
1979
+ /** `true` when this answer came from a stored receipt and no effect ran for this call. */
1980
+ replayed: z15.boolean(),
1981
+ /** Present on `ok` only. */
1982
+ resultRef: operationResultRefSchema.optional(),
1983
+ /** Present on `rejected` and `not-applied` only. */
1984
+ errorCode: operationReasonSchema.optional()
1985
+ });
1986
+ var operationInProgressResultSchema = z15.object({
1987
+ status: z15.literal("in-progress"),
1988
+ operationId: operationIdSchema,
1989
+ action: z15.string().min(1),
1990
+ startedAt: z15.string()
1991
+ });
1992
+ var operationUnverifiedResultSchema = z15.object({
1993
+ status: z15.literal("unverified"),
1994
+ operationId: operationIdSchema,
1995
+ action: z15.string().min(1),
1996
+ startedAt: z15.string(),
1997
+ reconcile: z15.object({
1998
+ kind: z15.enum(["run-by-key", "forge-search", "git-state", "none"]),
1999
+ attemptedAt: z15.string().optional(),
2000
+ reason: operationReasonSchema
2001
+ }),
2002
+ guidance: z15.literal(UNVERIFIED_GUIDANCE)
2003
+ });
2004
+ var operationKeyConflictSchema = z15.object({
2005
+ error: z15.literal("operation_key_conflict"),
2006
+ operationId: operationIdSchema,
2007
+ storedAction: z15.string().min(1),
2008
+ storedAt: z15.string(),
2009
+ mismatch: z15.enum(["action", "payload"])
2010
+ });
2011
+ var operationReceiptUnavailableSchema = z15.object({
2012
+ error: z15.literal("operation_receipt_unavailable"),
2013
+ operationId: operationIdSchema,
2014
+ reason: z15.literal("journal_unwritable")
2015
+ });
2016
+ var operationAnswerSchema = z15.union([
2017
+ operationSettledResultSchema,
2018
+ operationInProgressResultSchema,
2019
+ operationUnverifiedResultSchema,
2020
+ operationKeyConflictSchema,
2021
+ operationReceiptUnavailableSchema
2022
+ ]);
2023
+
2024
+ // ../contract/src/mcp-journal.ts
2025
+ import { z as z16 } from "zod";
2026
+ var MCP_JOURNAL_RETAINED_ROWS = 1e4;
2027
+ var MCP_JOURNAL_MIN_RETENTION_DAYS = 14;
2028
+ var MCP_JOURNAL_PAGE_ROWS = RUN_HISTORY_PAGE_ITEMS;
2029
+ var MCP_JOURNAL_PAGE_BYTES = 4e4;
2030
+ var MCP_JOURNAL_CURSOR_MAX_BYTES = 2048;
2031
+ var MCP_JOURNAL_SUMMARY_MAX_CHARS = 500;
2032
+ var mcpJournalCategorySchema = z16.enum(["E-01", "E-02", "E-03", "E-04", "E-05", "E-06"]);
2033
+ var mcpJournalOriginSchema = z16.enum(["human", "leader", "system"]);
2034
+ var mcpJournalOperationIdSchema = z16.string().min(8).max(128).regex(/^[A-Za-z0-9_.:-]+$/);
2035
+ var mcpJournalProjectIdSchema = z16.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/);
2036
+ var mcpJournalSubjectSchema = z16.object({
2037
+ type: z16.string().regex(/^[a-z][a-z0-9-]{0,63}$/),
2038
+ id: z16.string().min(1).max(256),
2039
+ version: z16.string().min(1).max(512).nullable()
2040
+ });
2041
+ var mcpJournalSourceSchema = z16.object({
2042
+ runId: z16.string().min(1).max(128),
2043
+ runSeq: z16.number().int().nonnegative()
2044
+ });
2045
+ var mcpJournalKindSchema = z16.string().max(64).regex(/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/);
2046
+ var originFields = {
2047
+ category: mcpJournalCategorySchema,
2048
+ kind: mcpJournalKindSchema,
2049
+ subject: mcpJournalSubjectSchema,
2050
+ origin: mcpJournalOriginSchema,
2051
+ causedBy: mcpJournalOperationIdSchema.nullable(),
2052
+ summary: z16.string().min(1).max(MCP_JOURNAL_SUMMARY_MAX_CHARS),
2053
+ source: mcpJournalSourceSchema.optional()
2054
+ };
2055
+ function leaderNamesItsOperation(value) {
2056
+ return value.origin !== "leader" || value.causedBy !== null;
2057
+ }
2058
+ var LEADER_NEEDS_OPERATION = { message: "a leader row must name the operation that caused it", path: ["causedBy"] };
2059
+ var mcpJournalAppendInputSchema = z16.object(originFields).refine(leaderNamesItsOperation, LEADER_NEEDS_OPERATION);
2060
+ var mcpJournalRowSchema = z16.object({
2061
+ eventId: z16.string().min(1),
2062
+ journalSeq: z16.number().int().positive(),
2063
+ ts: z16.string(),
2064
+ projectId: mcpJournalProjectIdSchema,
2065
+ ...originFields
2066
+ }).refine(leaderNamesItsOperation, LEADER_NEEDS_OPERATION);
2067
+ var mcpJournalCursorSchema = z16.string().min(1).max(MCP_JOURNAL_CURSOR_MAX_BYTES);
2068
+ var mcpJournalReadInputSchema = z16.object({
2069
+ cursor: mcpJournalCursorSchema.optional(),
2070
+ limit: z16.number().int().min(1).max(MCP_JOURNAL_PAGE_ROWS).optional()
2071
+ });
2072
+ var mcpJournalPageSchema = z16.object({
2073
+ status: z16.literal("ok"),
2074
+ events: z16.array(mcpJournalRowSchema),
2075
+ /** Read after this next; equals the request's position when nothing was outstanding. */
2076
+ nextCursor: mcpJournalCursorSchema,
2077
+ /** More rows are already retained past `nextCursor` — read again, do not wait for an event. */
2078
+ hasMore: z16.boolean(),
2079
+ /** `null` while the journal is empty. */
2080
+ oldestSeq: z16.number().int().positive().nullable(),
2081
+ latestSeq: z16.number().int().nonnegative()
2082
+ });
2083
+ var mcpJournalCursorTooOldSchema = z16.object({
2084
+ status: z16.literal("cursor_too_old"),
2085
+ oldestSeq: z16.number().int().positive().nullable(),
2086
+ latestSeq: z16.number().int().nonnegative(),
2087
+ resumeCursor: mcpJournalCursorSchema,
2088
+ recovery: z16.object({
2089
+ required: z16.literal("current-state"),
2090
+ message: z16.string()
2091
+ })
1844
2092
  });
1845
- var automationCheckInputSchema = z12.object({
1846
- mode: z12.enum(["preview", "execute"])
2093
+ var mcpJournalReadResultSchema = z16.discriminatedUnion("status", [
2094
+ mcpJournalPageSchema,
2095
+ mcpJournalCursorTooOldSchema
2096
+ ]);
2097
+ var mcpJournalCursorRejectionSchema = z16.object({
2098
+ error: z16.enum(["invalid_cursor", "cursor_project_mismatch"]),
2099
+ message: z16.string()
1847
2100
  });
2101
+
2102
+ // ../contract/src/mcp-event-catalog.ts
2103
+ import { z as z17 } from "zod";
2104
+ var MCP_EVENT_CATALOG = {
2105
+ "E-01": "Task completion, failure, cancellation or blocking.",
2106
+ "E-02": "A question requiring attention and a human answer to a question.",
2107
+ "E-03": "Quality-gate result or a completed result ready for assessment.",
2108
+ "E-04": "Human change to goal, acceptance criteria, instruction, plan or task state.",
2109
+ "E-05": "Configuration/workflow change affecting execution.",
2110
+ "E-06": "Executor availability change affecting execution."
2111
+ };
2112
+ var MCP_EVENT_KIND_CATEGORY = {
2113
+ // E-01 — derived from a run STATUS transition (D-05 § 5.1: a terminal status is not an event type).
2114
+ "task.done": "E-01",
2115
+ "task.failed": "E-01",
2116
+ "task.cancelled": "E-01",
2117
+ /** The run parked at `waiting` with no structured question: it cannot go on without input. */
2118
+ "task.blocked": "E-01",
2119
+ // E-02
2120
+ /** The agent raised a structured question (`ask.requested`) and parked at `waiting`. */
2121
+ "question.asked": "E-02",
2122
+ /** A human replied to a run that was waiting on one. */
2123
+ "question.answered": "E-02",
2124
+ // E-03 — F-11: the optional `review` status is a result ready for assessment, and is kept a
2125
+ // DIFFERENT kind from a mandatory quality gate so neither can be mistaken for the other.
2126
+ "gate.passed": "E-03",
2127
+ "gate.failed": "E-03",
2128
+ "result.ready": "E-03",
2129
+ // E-04 — only ever with `origin: 'human'`.
2130
+ "goal.changed": "E-04",
2131
+ "instruction.added": "E-04",
2132
+ "instruction.queued": "E-04",
2133
+ "instruction.edited": "E-04",
2134
+ "instruction.removed": "E-04",
2135
+ // E-05
2136
+ "config.changed": "E-05",
2137
+ "workflow.saved": "E-05",
2138
+ "workflow.deleted": "E-05",
2139
+ "agent-config.changed": "E-05",
2140
+ // E-06
2141
+ "executor.available": "E-06",
2142
+ "executor.unavailable": "E-06"
2143
+ };
2144
+ var mcpEventKindSchema = z17.enum(
2145
+ Object.keys(MCP_EVENT_KIND_CATEGORY)
2146
+ );
2147
+ var MCP_EVENT_SUBJECT_TYPES = ["run", "config", "workflow", "agent-config", "executor"];
2148
+ var mcpEventSubjectTypeSchema = z17.enum(MCP_EVENT_SUBJECT_TYPES);
2149
+ var mcpCatalogEventSchema = mcpJournalRowSchema.superRefine((row, ctx) => {
2150
+ const kind = mcpEventKindSchema.safeParse(row.kind);
2151
+ if (!kind.success) {
2152
+ ctx.addIssue({ code: "custom", path: ["kind"], message: `not a catalog kind: ${row.kind}` });
2153
+ return;
2154
+ }
2155
+ if (MCP_EVENT_KIND_CATEGORY[kind.data] !== row.category) {
2156
+ ctx.addIssue({ code: "custom", path: ["category"], message: `${row.kind} belongs to ${MCP_EVENT_KIND_CATEGORY[kind.data]}` });
2157
+ }
2158
+ if (!mcpEventSubjectTypeSchema.safeParse(row.subject.type).success) {
2159
+ ctx.addIssue({ code: "custom", path: ["subject", "type"], message: `not a catalog subject: ${row.subject.type}` });
2160
+ }
2161
+ if (row.category === "E-04" && row.origin !== "human") {
2162
+ ctx.addIssue({ code: "custom", path: ["origin"], message: "an E-04 row is a human change" });
2163
+ }
2164
+ });
2165
+
2166
+ // ../contract/src/mcp-audit.ts
2167
+ import { z as z18 } from "zod";
2168
+ var auditOriginSchema = z18.enum(["ui", "mcp", "automation", "cli"]);
2169
+ var auditOutcomeSchema = z18.enum(["ok", "rejected", "not-applied", "unverified"]);
2170
+ var AUDIT_ACTION_RE = /^[a-z][A-Za-z0-9-]*(\.[a-z][A-Za-z0-9-]*)+$/;
2171
+ var AUDIT_RESOURCE_KIND_RE = /^[a-z][a-z0-9-]*$/;
2172
+ var AUDIT_ID_RE = /^[A-Za-z0-9_.:-]+$/;
2173
+ var AUDIT_ERROR_CODE_RE = /^[a-z][a-z0-9_]*$/;
2174
+ var AUDIT_VERSION_TOKEN_RE = /^rev1:[a-z][a-z0-9-]*:[A-Za-z0-9_.-]{1,128}:(?:\d+|-):[0-9a-f]{12}$/;
2175
+ var auditResourceSchema = z18.object({
2176
+ kind: z18.string().min(1).max(32).regex(AUDIT_RESOURCE_KIND_RE),
2177
+ id: z18.string().min(1).max(128).regex(AUDIT_ID_RE)
2178
+ });
2179
+ var auditEntrySchema = z18.object({
2180
+ /** Record format tag. A future incompatible shape is `v: 2`. */
2181
+ v: z18.literal(1),
2182
+ /** SHOULD — ISO 8601 time the operation settled. */
2183
+ ts: z18.iso.datetime(),
2184
+ /** MUST — the project the connection or cockpit scope is bound to. */
2185
+ projectId: z18.string().min(1).max(128).regex(AUDIT_ID_RE),
2186
+ /** SHOULD — the action id. */
2187
+ action: z18.string().min(3).max(64).regex(AUDIT_ACTION_RE),
2188
+ /** SHOULD — the resource acted on, when there is one. */
2189
+ resource: auditResourceSchema.optional(),
2190
+ /** SHOULD — the D-06 outcome. */
2191
+ outcome: auditOutcomeSchema,
2192
+ /** MUST be server-derived. Only `mcp` is written today — see `auditOriginSchema` above. */
2193
+ origin: auditOriginSchema,
2194
+ /**
2195
+ * SHOULD — the wall-clock ms prefix of the D-02.3 fencing token (`<ms>-<UUIDv4>`) the mutation
2196
+ * arrived under; absent for non-MCP origins. Never the whole token: that passes the fence.
2197
+ */
2198
+ ownerGeneration: z18.number().int().nonnegative().optional(),
2199
+ /** SHOULD — `<projectId>/<operationId>` (D-06 § 5.2); absent for non-MCP origins. */
2200
+ operationKey: z18.string().min(1).max(257).regex(/^[A-Za-z0-9_.:-]+\/[A-Za-z0-9_.:-]{8,128}$/).optional(),
2201
+ /** SHOULD — the `expectedVersion` the caller sent, kept only when it has the `rev1` shape. */
2202
+ versionToken: z18.string().max(200).regex(AUDIT_VERSION_TOKEN_RE).optional(),
2203
+ /** SHOULD — SHA-256 (lowercase hex) of the canonical parsed payload (D-06 § 5.4). */
2204
+ payloadDigest: z18.string().regex(/^[0-9a-f]{64}$/).optional(),
2205
+ /** SHOULD — present when the outcome is not `ok`. */
2206
+ errorCode: z18.string().min(1).max(64).regex(AUDIT_ERROR_CODE_RE).optional()
2207
+ });
2208
+
2209
+ // ../contract/src/mcp-discovery.ts
2210
+ import { z as z19 } from "zod";
2211
+ var mcpDiscoveryActionIdSchema = z19.enum([
2212
+ "create_task",
2213
+ "parallel_variants",
2214
+ "worktree_choice",
2215
+ "model_selection",
2216
+ "github",
2217
+ "automations",
2218
+ "inbox",
2219
+ "open_in_app",
2220
+ "agent_config_write",
2221
+ "workspace_limits"
2222
+ ]);
2223
+ var mcpDiscoveryActionSchema = z19.discriminatedUnion("status", [
2224
+ z19.strictObject({ id: mcpDiscoveryActionIdSchema, label: z19.string(), status: z19.literal("available") }),
2225
+ z19.strictObject({
2226
+ id: mcpDiscoveryActionIdSchema,
2227
+ label: z19.string(),
2228
+ status: z19.literal("unavailable"),
2229
+ reason: z19.string().min(1)
2230
+ }),
2231
+ z19.strictObject({
2232
+ id: mcpDiscoveryActionIdSchema,
2233
+ label: z19.string(),
2234
+ status: z19.literal("read-only"),
2235
+ reason: z19.string().min(1)
2236
+ })
2237
+ ]);
2238
+ var mcpDiscoveryAgentSchema = z19.strictObject({
2239
+ runner: runnerSchema,
2240
+ installed: z19.boolean(),
2241
+ version: z19.string().optional(),
2242
+ enabled: z19.boolean(),
2243
+ signIn: providerConnectionStateSchema,
2244
+ usable: z19.boolean(),
2245
+ reason: z19.string().optional()
2246
+ });
2247
+ var mcpDiscoveryToolCheckSchema = z19.strictObject({
2248
+ name: z19.enum(["gh", "git"]),
2249
+ available: z19.boolean(),
2250
+ reason: z19.string().optional()
2251
+ });
2252
+ var mcpDiscoveryLimitsSchema = z19.strictObject({
2253
+ maxParallel: z19.strictObject({ effective: z19.number(), project: z19.number().nullable(), workspace: z19.number() }),
2254
+ memoryLimitMb: z19.strictObject({
2255
+ effective: z19.number().nullable(),
2256
+ project: z19.number().nullable(),
2257
+ workspace: z19.number().nullable()
2258
+ }),
2259
+ maxMonitoringSessions: z19.number(),
2260
+ /** `null` means a parked session stays parked. */
2261
+ monitoringWakeIntervalMinutes: z19.number().nullable(),
2262
+ autoResumeOnUsageLimit: z19.boolean(),
2263
+ /** `null` means an idle session is never closed. */
2264
+ idleTimeoutMinutes: z19.number().nullable(),
2265
+ /** This project's count of finished worktrees kept on disk; 0 keeps all. */
2266
+ worktreeRetention: z19.number()
2267
+ });
2268
+ var mcpDiscoverySchema = z19.strictObject({
2269
+ project: z19.strictObject({
2270
+ id: z19.string(),
2271
+ name: z19.string(),
2272
+ /** The bound project's own root; trimmed to its basename in hosted mode, like `/health`. */
2273
+ root: z19.string()
2274
+ }),
2275
+ xezarVersion: z19.string(),
2276
+ repository: z19.strictObject({ git: z19.boolean(), branch: z19.string().optional() }),
2277
+ settings: z19.strictObject({
2278
+ defaultRunner: runnerSchema,
2279
+ baseBranch: z19.string().nullable(),
2280
+ modelsLocked: z19.boolean()
2281
+ }),
2282
+ capabilities: capabilitiesSchema.pick({ localHandoff: true, followups: true, automations: true }).strict(),
2283
+ agents: z19.array(mcpDiscoveryAgentSchema),
2284
+ tools: z19.array(mcpDiscoveryToolCheckSchema),
2285
+ limits: mcpDiscoveryLimitsSchema,
2286
+ actions: z19.array(mcpDiscoveryActionSchema)
2287
+ });
2288
+
2289
+ // ../contract/src/mcp-api-reference.ts
2290
+ import { z as z20 } from "zod";
2291
+ var mcpToolAnnotationsSchema = z20.strictObject({
2292
+ readOnlyHint: z20.boolean().optional(),
2293
+ destructiveHint: z20.boolean().optional(),
2294
+ idempotentHint: z20.boolean().optional(),
2295
+ openWorldHint: z20.boolean().optional()
2296
+ });
2297
+ var mcpToolListingSchema = z20.strictObject({
2298
+ name: z20.string(),
2299
+ title: z20.string().optional(),
2300
+ description: z20.string(),
2301
+ inputSchema: z20.record(z20.string(), z20.unknown()),
2302
+ annotations: mcpToolAnnotationsSchema.optional()
2303
+ });
2304
+ var mcpRefusedActionSchema = z20.object({
2305
+ tool: z20.string(),
2306
+ action: z20.string(),
2307
+ boundary: z20.string(),
2308
+ reason: z20.string()
2309
+ });
2310
+ var mcpRefusedArgumentSchema = z20.object({
2311
+ tool: z20.string(),
2312
+ argument: z20.string(),
2313
+ reason: z20.string()
2314
+ });
2315
+ var mcpGuardSchema = z20.object({
2316
+ tool: z20.string(),
2317
+ argument: z20.string(),
2318
+ everyCall: z20.boolean(),
2319
+ requiredBy: z20.array(z20.string())
2320
+ });
2321
+ var mcpNotExposedSchema = z20.object({
2322
+ what: z20.string(),
2323
+ detail: z20.string(),
2324
+ forbiddenBy: z20.array(z20.string())
2325
+ });
2326
+ var mcpApiReferenceAvailableSchema = z20.object({
2327
+ available: z20.literal(true),
2328
+ xezarVersion: z20.string(),
2329
+ /** Newest first — the revisions the bridge negotiates. */
2330
+ protocolVersions: z20.array(z20.string()),
2331
+ capabilities: z20.object({ tools: z20.object({ listChanged: z20.boolean() }) }),
2332
+ /** Exactly `tools/list`: `[HEALTH_TOOL, ...tools.map(toolListing)]`, in that order. */
2333
+ tools: z20.array(mcpToolListingSchema),
2334
+ refusedActions: z20.array(mcpRefusedActionSchema),
2335
+ refusedArguments: z20.array(mcpRefusedArgumentSchema),
2336
+ /** One entry per tool and guard the tool's schema lists. */
2337
+ guards: z20.array(mcpGuardSchema),
2338
+ notExposed: z20.array(mcpNotExposedSchema)
2339
+ });
2340
+ var mcpApiReferenceSchema = z20.discriminatedUnion("available", [
2341
+ mcpApiReferenceAvailableSchema,
2342
+ z20.object({ available: z20.literal(false), reason: z20.string() })
2343
+ ]);
2344
+
2345
+ // ../contract/src/mcp-leader.ts
2346
+ import { z as z21 } from "zod";
2347
+ var mcpLeaderAttachInputSchema = z21.discriminatedUnion("client", [
2348
+ z21.strictObject({
2349
+ action: z21.literal("attach"),
2350
+ client: z21.literal("opencode"),
2351
+ baseUrl: z21.url({ protocol: /^https?$/ }).max(500),
2352
+ sessionId: z21.string().trim().min(1).max(200)
2353
+ }),
2354
+ z21.strictObject({ action: z21.literal("attach"), client: z21.literal("pi") })
2355
+ ]);
2356
+ var mcpLeaderActionInputSchema = z21.union([
2357
+ mcpLeaderAttachInputSchema,
2358
+ z21.strictObject({ action: z21.literal("stop") })
2359
+ ]);
2360
+ var mcpLeaderSessionSchema = z21.object({
2361
+ client: z21.enum(["opencode", "pi"]),
2362
+ state: z21.literal("attached")
2363
+ });
2364
+ var mcpLeaderDeliverySchema = z21.object({
2365
+ state: z21.enum(["inert", "idle", "dispatching", "recovering", "disconnected", "ended"]),
2366
+ deliveredSeq: z21.number().int().nonnegative(),
2367
+ ackedSeq: z21.number().int().nonnegative(),
2368
+ reactedSeq: z21.number().int().nonnegative(),
2369
+ latestSeq: z21.number().int().nonnegative()
2370
+ });
2371
+ var mcpLeaderBlockerSchema = z21.object({
2372
+ code: z21.string(),
2373
+ message: z21.string(),
2374
+ fix: z21.string()
2375
+ });
2376
+ var mcpLeaderStatusSchema = z21.discriminatedUnion("available", [
2377
+ z21.object({ available: z21.literal(false), reason: z21.string() }),
2378
+ z21.object({
2379
+ available: z21.literal(true),
2380
+ leader: mcpLeaderSessionSchema.nullable(),
2381
+ delivery: mcpLeaderDeliverySchema.nullable(),
2382
+ blocker: mcpLeaderBlockerSchema.nullable()
2383
+ })
2384
+ ]);
1848
2385
  export {
2386
+ AUDIT_ACTION_RE,
2387
+ AUDIT_ERROR_CODE_RE,
2388
+ AUDIT_ID_RE,
2389
+ AUDIT_RESOURCE_KIND_RE,
2390
+ AUDIT_VERSION_TOKEN_RE,
1849
2391
  DEFAULT_AGENT_ACCOUNT_ID,
1850
2392
  FILE_ATTACHMENT_MEDIA_TYPES,
2393
+ MCP_EVENT_CATALOG,
2394
+ MCP_EVENT_KIND_CATEGORY,
2395
+ MCP_EVENT_SUBJECT_TYPES,
2396
+ MCP_EXECUTION_FAILED_GUIDANCE,
2397
+ MCP_JOURNAL_CURSOR_MAX_BYTES,
2398
+ MCP_JOURNAL_MIN_RETENTION_DAYS,
2399
+ MCP_JOURNAL_PAGE_BYTES,
2400
+ MCP_JOURNAL_PAGE_ROWS,
2401
+ MCP_JOURNAL_RETAINED_ROWS,
2402
+ MCP_JOURNAL_SUMMARY_MAX_CHARS,
2403
+ MCP_PROJECT_OCCUPIED_CODE,
2404
+ MCP_PROJECT_OCCUPIED_REASON,
2405
+ MCP_SESSION_EXPIRED_CODE,
2406
+ MCP_SESSION_EXPIRED_REASON,
2407
+ MCP_STALE_VERSION_GUIDANCE,
2408
+ MCP_VERSION_TOKEN_TAG,
1851
2409
  MODEL_DISCOVERY_RUNNERS,
1852
2410
  PROJECT_TAGS_MAX,
1853
2411
  PROJECT_TAG_MAX_LENGTH,
1854
2412
  REFERENCE_STATUS_MAX,
1855
2413
  RUN_HISTORY_PAGE_ITEMS,
2414
+ UNVERIFIED_GUIDANCE,
1856
2415
  agentAccountDetailsResponseSchema,
1857
2416
  agentAccountFileSchema,
1858
2417
  agentAccountRouteId,
@@ -1871,8 +2430,13 @@ export {
1871
2430
  agentProfilesResponseSchema,
1872
2431
  apiRunSchema,
1873
2432
  archiveFinishedResponseSchema,
2433
+ archiveRunInputSchema,
1874
2434
  attachmentExtension,
1875
2435
  attachmentInputSchema,
2436
+ auditEntrySchema,
2437
+ auditOriginSchema,
2438
+ auditOutcomeSchema,
2439
+ auditResourceSchema,
1876
2440
  automationCheckInputSchema,
1877
2441
  automationCheckQueuedResponseSchema,
1878
2442
  automationCheckSchema,
@@ -1901,6 +2465,7 @@ export {
1901
2465
  checkoutProjectInputSchema,
1902
2466
  configResponseSchema,
1903
2467
  continueResponseSchema,
2468
+ continueRunInputSchema,
1904
2469
  createAgentProfileInputSchema,
1905
2470
  createAutomationInputSchema,
1906
2471
  createPrResponseSchema,
@@ -1911,10 +2476,12 @@ export {
1911
2476
  deleteWorkflowResponseSchema,
1912
2477
  diffStatSchema,
1913
2478
  editQueuedMessageResponseSchema,
2479
+ executionFailedSchema,
1914
2480
  finishResponseSchema,
1915
2481
  forgeInfoSchema,
1916
2482
  fsBrowseDirSchema,
1917
2483
  fsBrowseResponseSchema,
2484
+ gitCommitInputSchema,
1918
2485
  gitCommitResponseSchema,
1919
2486
  gitPushResponseSchema,
1920
2487
  githubChecksDataSchema,
@@ -1929,6 +2496,8 @@ export {
1929
2496
  githubPrCheckSchema,
1930
2497
  githubPrMergeStateResponseSchema,
1931
2498
  githubPrMergeStateSchema,
2499
+ githubPrReadyInputSchema,
2500
+ githubPrReadyResponseSchema,
1932
2501
  githubRefStatusDataSchema,
1933
2502
  githubSearchDataSchema,
1934
2503
  githubTimelineEventKindSchema,
@@ -1944,6 +2513,49 @@ export {
1944
2513
  launchKeyResponseSchema,
1945
2514
  logEntrySchema,
1946
2515
  markAllReadResponseSchema,
2516
+ mcpApiReferenceAvailableSchema,
2517
+ mcpApiReferenceSchema,
2518
+ mcpCatalogEventSchema,
2519
+ mcpDiscoveryActionIdSchema,
2520
+ mcpDiscoveryActionSchema,
2521
+ mcpDiscoveryAgentSchema,
2522
+ mcpDiscoveryLimitsSchema,
2523
+ mcpDiscoverySchema,
2524
+ mcpDiscoveryToolCheckSchema,
2525
+ mcpEventKindSchema,
2526
+ mcpEventSubjectTypeSchema,
2527
+ mcpExpectedVersionSchema,
2528
+ mcpGuardSchema,
2529
+ mcpJournalAppendInputSchema,
2530
+ mcpJournalCategorySchema,
2531
+ mcpJournalCursorRejectionSchema,
2532
+ mcpJournalCursorSchema,
2533
+ mcpJournalCursorTooOldSchema,
2534
+ mcpJournalKindSchema,
2535
+ mcpJournalOperationIdSchema,
2536
+ mcpJournalOriginSchema,
2537
+ mcpJournalPageSchema,
2538
+ mcpJournalProjectIdSchema,
2539
+ mcpJournalReadInputSchema,
2540
+ mcpJournalReadResultSchema,
2541
+ mcpJournalRowSchema,
2542
+ mcpJournalSourceSchema,
2543
+ mcpJournalSubjectSchema,
2544
+ mcpLeaderActionInputSchema,
2545
+ mcpLeaderBlockerSchema,
2546
+ mcpLeaderDeliverySchema,
2547
+ mcpLeaderSessionSchema,
2548
+ mcpLeaderStatusSchema,
2549
+ mcpNotExposedSchema,
2550
+ mcpProjectOccupiedErrorSchema,
2551
+ mcpRefusedActionSchema,
2552
+ mcpRefusedArgumentSchema,
2553
+ mcpSessionExpiredErrorSchema,
2554
+ mcpToolAnnotationsSchema,
2555
+ mcpToolListingSchema,
2556
+ mcpVersionTokenSchema,
2557
+ mcpVersionedResourceKindSchema,
2558
+ mcpVersionedResourceRefSchema,
1947
2559
  messageInputSchema,
1948
2560
  messageResponseSchema,
1949
2561
  modelDiscoveryRunnerSchema,
@@ -1954,20 +2566,35 @@ export {
1954
2566
  openProjectInSchema,
1955
2567
  openTargetSchema,
1956
2568
  openTargetsResponseSchema,
2569
+ operationAnswerSchema,
2570
+ operationIdSchema,
2571
+ operationInProgressResultSchema,
2572
+ operationKeyConflictSchema,
2573
+ operationOutcomeSchema,
2574
+ operationReasonSchema,
2575
+ operationReceiptUnavailableSchema,
2576
+ operationResultRefSchema,
2577
+ operationSettledResultSchema,
2578
+ operationUnverifiedResultSchema,
1957
2579
  parsedWorkflowSchema,
1958
2580
  patchRunInputSchema,
2581
+ pickVariantInputSchema,
1959
2582
  pickVariantResponseSchema,
2583
+ pinRunInputSchema,
1960
2584
  planResponseSchema,
1961
2585
  processUsageSchema,
1962
2586
  projectListEntrySchema,
2587
+ projectOwnerStateSchema,
1963
2588
  projectsResponseSchema,
1964
2589
  providerConnectResponseSchema,
1965
2590
  providerConnectionStateSchema,
1966
2591
  providerIdSchema,
1967
2592
  providerStatusResponseSchema,
1968
2593
  providerStatusSchema,
2594
+ queuedMessagePatchInputSchema,
1969
2595
  queuedMessageSchema,
1970
2596
  reclaimWorktreesResponseSchema,
2597
+ reconcilePredicateSchema,
1971
2598
  referenceStatusSchema,
1972
2599
  referenceStatusesByProjectSchema,
1973
2600
  registerProjectResponseSchema,
@@ -1994,6 +2621,8 @@ export {
1994
2621
  runIndexEntrySchema,
1995
2622
  runRecordSchema,
1996
2623
  runStatusSchema,
2624
+ runVersionGuardInputSchema,
2625
+ runVersionResponseSchema,
1997
2626
  runnerDiscoversModels,
1998
2627
  runnerModelCatalogResponseSchema,
1999
2628
  runnerModelOptionSchema,
@@ -2012,6 +2641,7 @@ export {
2012
2641
  skillsUpdateScopeStateSchema,
2013
2642
  skillsUpdateStateSchema,
2014
2643
  skillsUpdateStatusSchema,
2644
+ staleVersionRejectionSchema,
2015
2645
  startTodoResponseSchema,
2016
2646
  statusEntrySchema,
2017
2647
  stepStateSchema,
@@ -2023,6 +2653,8 @@ export {
2023
2653
  updateProjectInputSchema,
2024
2654
  updateProjectResponseSchema,
2025
2655
  userMcpListingSchema,
2656
+ versionedMutationDoneSchema,
2657
+ versionedMutationOutcomeSchema,
2026
2658
  workflowDefSchema,
2027
2659
  workflowLoadIssueSchema,
2028
2660
  workflowStepDefSchema,