@xemahq/kernel-contracts 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/LICENSE +201 -0
  2. package/dist/agent-tool-inquiry/index.d.ts +2 -0
  3. package/dist/agent-tool-inquiry/index.d.ts.map +1 -0
  4. package/dist/agent-tool-inquiry/index.js +18 -0
  5. package/dist/agent-tool-inquiry/index.js.map +1 -0
  6. package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.d.ts +43 -0
  7. package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.d.ts.map +1 -0
  8. package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.js +32 -0
  9. package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.js.map +1 -0
  10. package/dist/agent-workspace/awp-spec.json +1 -1
  11. package/dist/app-runtime/index.d.ts +9 -0
  12. package/dist/app-runtime/index.d.ts.map +1 -0
  13. package/dist/app-runtime/index.js +25 -0
  14. package/dist/app-runtime/index.js.map +1 -0
  15. package/dist/app-runtime/lib/app-client.d.ts +11 -0
  16. package/dist/app-runtime/lib/app-client.d.ts.map +1 -0
  17. package/dist/app-runtime/lib/app-client.js +23 -0
  18. package/dist/app-runtime/lib/app-client.js.map +1 -0
  19. package/dist/app-runtime/lib/app-lockfile.d.ts +12 -0
  20. package/dist/app-runtime/lib/app-lockfile.d.ts.map +1 -0
  21. package/dist/app-runtime/lib/app-lockfile.js +17 -0
  22. package/dist/app-runtime/lib/app-lockfile.js.map +1 -0
  23. package/dist/app-runtime/lib/app.d.ts +26 -0
  24. package/dist/app-runtime/lib/app.d.ts.map +1 -0
  25. package/dist/app-runtime/lib/app.js +31 -0
  26. package/dist/app-runtime/lib/app.js.map +1 -0
  27. package/dist/app-runtime/lib/audience-policy.d.ts +31 -0
  28. package/dist/app-runtime/lib/audience-policy.d.ts.map +1 -0
  29. package/dist/app-runtime/lib/audience-policy.js +38 -0
  30. package/dist/app-runtime/lib/audience-policy.js.map +1 -0
  31. package/dist/app-runtime/lib/biome-install.d.ts +9 -0
  32. package/dist/app-runtime/lib/biome-install.d.ts.map +1 -0
  33. package/dist/app-runtime/lib/biome-install.js +13 -0
  34. package/dist/app-runtime/lib/biome-install.js.map +1 -0
  35. package/dist/app-runtime/lib/branding-config.d.ts +9 -0
  36. package/dist/app-runtime/lib/branding-config.d.ts.map +1 -0
  37. package/dist/app-runtime/lib/branding-config.js +24 -0
  38. package/dist/app-runtime/lib/branding-config.js.map +1 -0
  39. package/dist/app-runtime/lib/delegated-session.d.ts +15 -0
  40. package/dist/app-runtime/lib/delegated-session.d.ts.map +1 -0
  41. package/dist/app-runtime/lib/delegated-session.js +29 -0
  42. package/dist/app-runtime/lib/delegated-session.js.map +1 -0
  43. package/dist/app-runtime/lib/external-subject.d.ts +9 -0
  44. package/dist/app-runtime/lib/external-subject.d.ts.map +1 -0
  45. package/dist/app-runtime/lib/external-subject.js +19 -0
  46. package/dist/app-runtime/lib/external-subject.js.map +1 -0
  47. package/dist/connector/index.d.ts +9 -0
  48. package/dist/connector/index.d.ts.map +1 -0
  49. package/dist/connector/index.js +25 -0
  50. package/dist/connector/index.js.map +1 -0
  51. package/dist/connector/lib/adapter-kind.d.ts +8 -0
  52. package/dist/connector/lib/adapter-kind.d.ts.map +1 -0
  53. package/dist/connector/lib/adapter-kind.js +14 -0
  54. package/dist/connector/lib/adapter-kind.js.map +1 -0
  55. package/dist/connector/lib/capability-refs.d.ts +14 -0
  56. package/dist/connector/lib/capability-refs.d.ts.map +1 -0
  57. package/dist/connector/lib/capability-refs.js +15 -0
  58. package/dist/connector/lib/capability-refs.js.map +1 -0
  59. package/dist/connector/lib/capability.d.ts +18 -0
  60. package/dist/connector/lib/capability.d.ts.map +1 -0
  61. package/dist/connector/lib/capability.js +24 -0
  62. package/dist/connector/lib/capability.js.map +1 -0
  63. package/dist/connector/lib/credential-kind.d.ts +42 -0
  64. package/dist/connector/lib/credential-kind.d.ts.map +1 -0
  65. package/dist/connector/lib/credential-kind.js +26 -0
  66. package/dist/connector/lib/credential-kind.js.map +1 -0
  67. package/dist/connector/lib/envelope-schema.d.ts +6 -0
  68. package/dist/connector/lib/envelope-schema.d.ts.map +1 -0
  69. package/dist/connector/lib/envelope-schema.js +150 -0
  70. package/dist/connector/lib/envelope-schema.js.map +1 -0
  71. package/dist/connector/lib/filter-expr-schema.d.ts +4 -0
  72. package/dist/connector/lib/filter-expr-schema.d.ts.map +1 -0
  73. package/dist/connector/lib/filter-expr-schema.js +65 -0
  74. package/dist/connector/lib/filter-expr-schema.js.map +1 -0
  75. package/dist/connector/lib/filter-expr-validate.d.ts +10 -0
  76. package/dist/connector/lib/filter-expr-validate.d.ts.map +1 -0
  77. package/dist/connector/lib/filter-expr-validate.js +58 -0
  78. package/dist/connector/lib/filter-expr-validate.js.map +1 -0
  79. package/dist/connector/lib/filter-expr.d.ts +49 -0
  80. package/dist/connector/lib/filter-expr.d.ts.map +1 -0
  81. package/dist/connector/lib/filter-expr.js +135 -0
  82. package/dist/connector/lib/filter-expr.js.map +1 -0
  83. package/dist/connector/lib/onboarding-manifest.d.ts +45 -0
  84. package/dist/connector/lib/onboarding-manifest.d.ts.map +1 -0
  85. package/dist/connector/lib/onboarding-manifest.js +30 -0
  86. package/dist/connector/lib/onboarding-manifest.js.map +1 -0
  87. package/dist/document-render/index.d.ts +7 -0
  88. package/dist/document-render/index.d.ts.map +1 -0
  89. package/dist/document-render/index.js +23 -0
  90. package/dist/document-render/index.js.map +1 -0
  91. package/dist/document-render/lib/measure-layout.d.ts +44 -0
  92. package/dist/document-render/lib/measure-layout.d.ts.map +1 -0
  93. package/dist/document-render/lib/measure-layout.js +16 -0
  94. package/dist/document-render/lib/measure-layout.js.map +1 -0
  95. package/dist/document-render/lib/render-enums.d.ts +18 -0
  96. package/dist/document-render/lib/render-enums.d.ts.map +1 -0
  97. package/dist/document-render/lib/render-enums.js +24 -0
  98. package/dist/document-render/lib/render-enums.js.map +1 -0
  99. package/dist/document-render/lib/render-record.d.ts +22 -0
  100. package/dist/document-render/lib/render-record.d.ts.map +1 -0
  101. package/dist/document-render/lib/render-record.js +3 -0
  102. package/dist/document-render/lib/render-record.js.map +1 -0
  103. package/dist/document-render/lib/render-request.d.ts +24 -0
  104. package/dist/document-render/lib/render-request.d.ts.map +1 -0
  105. package/dist/document-render/lib/render-request.js +12 -0
  106. package/dist/document-render/lib/render-request.js.map +1 -0
  107. package/dist/document-render/lib/render-source.d.ts +43 -0
  108. package/dist/document-render/lib/render-source.d.ts.map +1 -0
  109. package/dist/document-render/lib/render-source.js +31 -0
  110. package/dist/document-render/lib/render-source.js.map +1 -0
  111. package/dist/document-render/lib/xema-prompt.d.ts +11 -0
  112. package/dist/document-render/lib/xema-prompt.d.ts.map +1 -0
  113. package/dist/document-render/lib/xema-prompt.js +46 -0
  114. package/dist/document-render/lib/xema-prompt.js.map +1 -0
  115. package/dist/inquiry/index.d.ts +7 -0
  116. package/dist/inquiry/index.d.ts.map +1 -0
  117. package/dist/inquiry/index.js +23 -0
  118. package/dist/inquiry/index.js.map +1 -0
  119. package/dist/inquiry/lib/enums.d.ts +36 -0
  120. package/dist/inquiry/lib/enums.d.ts.map +1 -0
  121. package/dist/inquiry/lib/enums.js +45 -0
  122. package/dist/inquiry/lib/enums.js.map +1 -0
  123. package/dist/inquiry/lib/inquiry.d.ts +332 -0
  124. package/dist/inquiry/lib/inquiry.d.ts.map +1 -0
  125. package/dist/inquiry/lib/inquiry.js +102 -0
  126. package/dist/inquiry/lib/inquiry.js.map +1 -0
  127. package/dist/inquiry/lib/kind-registry.d.ts +14 -0
  128. package/dist/inquiry/lib/kind-registry.d.ts.map +1 -0
  129. package/dist/inquiry/lib/kind-registry.js +24 -0
  130. package/dist/inquiry/lib/kind-registry.js.map +1 -0
  131. package/dist/inquiry/lib/policy.d.ts +19 -0
  132. package/dist/inquiry/lib/policy.d.ts.map +1 -0
  133. package/dist/inquiry/lib/policy.js +21 -0
  134. package/dist/inquiry/lib/policy.js.map +1 -0
  135. package/dist/inquiry/lib/recipient.d.ts +111 -0
  136. package/dist/inquiry/lib/recipient.d.ts.map +1 -0
  137. package/dist/inquiry/lib/recipient.js +64 -0
  138. package/dist/inquiry/lib/recipient.js.map +1 -0
  139. package/dist/inquiry/lib/workflow-verdict-evaluator.d.ts +15 -0
  140. package/dist/inquiry/lib/workflow-verdict-evaluator.d.ts.map +1 -0
  141. package/dist/inquiry/lib/workflow-verdict-evaluator.js +145 -0
  142. package/dist/inquiry/lib/workflow-verdict-evaluator.js.map +1 -0
  143. package/dist/org-database/index.d.ts +5 -0
  144. package/dist/org-database/index.d.ts.map +1 -0
  145. package/dist/org-database/index.js +21 -0
  146. package/dist/org-database/index.js.map +1 -0
  147. package/dist/org-database/lib/db-result-event.d.ts +24 -0
  148. package/dist/org-database/lib/db-result-event.d.ts.map +1 -0
  149. package/dist/org-database/lib/db-result-event.js +3 -0
  150. package/dist/org-database/lib/db-result-event.js.map +1 -0
  151. package/dist/org-database/lib/driver.d.ts +43 -0
  152. package/dist/org-database/lib/driver.d.ts.map +1 -0
  153. package/dist/org-database/lib/driver.js +3 -0
  154. package/dist/org-database/lib/driver.js.map +1 -0
  155. package/dist/org-database/lib/enums.d.ts +41 -0
  156. package/dist/org-database/lib/enums.d.ts.map +1 -0
  157. package/dist/org-database/lib/enums.js +51 -0
  158. package/dist/org-database/lib/enums.js.map +1 -0
  159. package/dist/org-database/lib/migration-runner.d.ts +15 -0
  160. package/dist/org-database/lib/migration-runner.d.ts.map +1 -0
  161. package/dist/org-database/lib/migration-runner.js +3 -0
  162. package/dist/org-database/lib/migration-runner.js.map +1 -0
  163. package/dist/project-kit/index.d.ts +2 -0
  164. package/dist/project-kit/index.d.ts.map +1 -0
  165. package/dist/project-kit/index.js +18 -0
  166. package/dist/project-kit/index.js.map +1 -0
  167. package/dist/project-kit/lib/project-kit.d.ts +63 -0
  168. package/dist/project-kit/lib/project-kit.d.ts.map +1 -0
  169. package/dist/project-kit/lib/project-kit.js +32 -0
  170. package/dist/project-kit/lib/project-kit.js.map +1 -0
  171. package/dist/provisioning/index.d.ts +2 -0
  172. package/dist/provisioning/index.d.ts.map +1 -0
  173. package/dist/provisioning/index.js +18 -0
  174. package/dist/provisioning/index.js.map +1 -0
  175. package/dist/provisioning/lib/provisioning.d.ts +256 -0
  176. package/dist/provisioning/lib/provisioning.d.ts.map +1 -0
  177. package/dist/provisioning/lib/provisioning.js +221 -0
  178. package/dist/provisioning/lib/provisioning.js.map +1 -0
  179. package/dist/worker-runtime/index.d.ts +6 -0
  180. package/dist/worker-runtime/index.d.ts.map +1 -0
  181. package/dist/worker-runtime/index.js +22 -0
  182. package/dist/worker-runtime/index.js.map +1 -0
  183. package/dist/worker-runtime/lib/capabilities.d.ts +22 -0
  184. package/dist/worker-runtime/lib/capabilities.d.ts.map +1 -0
  185. package/dist/worker-runtime/lib/capabilities.js +3 -0
  186. package/dist/worker-runtime/lib/capabilities.js.map +1 -0
  187. package/dist/worker-runtime/lib/enums.d.ts +10 -0
  188. package/dist/worker-runtime/lib/enums.d.ts.map +1 -0
  189. package/dist/worker-runtime/lib/enums.js +15 -0
  190. package/dist/worker-runtime/lib/enums.js.map +1 -0
  191. package/dist/worker-runtime/lib/messages.d.ts +33 -0
  192. package/dist/worker-runtime/lib/messages.d.ts.map +1 -0
  193. package/dist/worker-runtime/lib/messages.js +3 -0
  194. package/dist/worker-runtime/lib/messages.js.map +1 -0
  195. package/dist/worker-runtime/lib/runtime.d.ts +35 -0
  196. package/dist/worker-runtime/lib/runtime.d.ts.map +1 -0
  197. package/dist/worker-runtime/lib/runtime.js +3 -0
  198. package/dist/worker-runtime/lib/runtime.js.map +1 -0
  199. package/dist/worker-runtime/lib/schemas.d.ts +87 -0
  200. package/dist/worker-runtime/lib/schemas.d.ts.map +1 -0
  201. package/dist/worker-runtime/lib/schemas.js +57 -0
  202. package/dist/worker-runtime/lib/schemas.js.map +1 -0
  203. package/dist/workspace-storage/index.d.ts +4 -0
  204. package/dist/workspace-storage/index.d.ts.map +1 -0
  205. package/dist/workspace-storage/index.js +20 -0
  206. package/dist/workspace-storage/index.js.map +1 -0
  207. package/dist/workspace-storage/lib/enums.d.ts +34 -0
  208. package/dist/workspace-storage/lib/enums.d.ts.map +1 -0
  209. package/dist/workspace-storage/lib/enums.js +42 -0
  210. package/dist/workspace-storage/lib/enums.js.map +1 -0
  211. package/dist/workspace-storage/lib/schemas.d.ts +56 -0
  212. package/dist/workspace-storage/lib/schemas.d.ts.map +1 -0
  213. package/dist/workspace-storage/lib/schemas.js +59 -0
  214. package/dist/workspace-storage/lib/schemas.js.map +1 -0
  215. package/dist/workspace-storage/lib/types.d.ts +71 -0
  216. package/dist/workspace-storage/lib/types.d.ts.map +1 -0
  217. package/dist/workspace-storage/lib/types.js +3 -0
  218. package/dist/workspace-storage/lib/types.js.map +1 -0
  219. package/package.json +22 -153
  220. package/src/agent-composition/lib/composition-workspace.ts +1 -1
  221. package/src/agent-tool-inquiry/index.ts +16 -0
  222. package/src/agent-tool-inquiry/lib/agent-tool-inquiry.ts +82 -0
  223. package/src/agent-workspace/lib/workspace-spec.ts +1 -1
  224. package/src/app-runtime/index.ts +8 -0
  225. package/src/app-runtime/lib/app-client.ts +44 -0
  226. package/src/app-runtime/lib/app-lockfile.ts +54 -0
  227. package/src/app-runtime/lib/app.ts +84 -0
  228. package/src/app-runtime/lib/audience-policy.ts +87 -0
  229. package/src/app-runtime/lib/biome-install.ts +29 -0
  230. package/src/app-runtime/lib/branding-config.ts +54 -0
  231. package/src/app-runtime/lib/delegated-session.ts +69 -0
  232. package/src/app-runtime/lib/external-subject.ts +34 -0
  233. package/src/connector/index.ts +8 -0
  234. package/src/connector/lib/adapter-kind.ts +37 -0
  235. package/src/connector/lib/capability-refs.ts +29 -0
  236. package/src/connector/lib/capability.ts +38 -0
  237. package/src/connector/lib/credential-kind.ts +120 -0
  238. package/src/connector/lib/envelope-schema.ts +256 -0
  239. package/src/connector/lib/filter-expr-schema.ts +75 -0
  240. package/src/connector/lib/filter-expr-validate.ts +91 -0
  241. package/src/connector/lib/filter-expr.ts +208 -0
  242. package/src/connector/lib/onboarding-manifest.ts +167 -0
  243. package/src/document-render/index.ts +25 -0
  244. package/src/document-render/lib/measure-layout.ts +61 -0
  245. package/src/document-render/lib/render-enums.ts +49 -0
  246. package/src/document-render/lib/render-record.ts +38 -0
  247. package/src/document-render/lib/render-request.ts +16 -0
  248. package/src/document-render/lib/render-source.ts +44 -0
  249. package/src/document-render/lib/xema-prompt.ts +100 -0
  250. package/src/inquiry/index.ts +23 -0
  251. package/src/inquiry/lib/enums.ts +103 -0
  252. package/src/inquiry/lib/inquiry.ts +182 -0
  253. package/src/inquiry/lib/kind-registry.ts +57 -0
  254. package/src/inquiry/lib/policy.ts +27 -0
  255. package/src/inquiry/lib/recipient.ts +188 -0
  256. package/src/inquiry/lib/workflow-verdict-evaluator.ts +220 -0
  257. package/src/org-database/index.ts +4 -0
  258. package/src/org-database/lib/db-result-event.ts +59 -0
  259. package/src/org-database/lib/driver.ts +47 -0
  260. package/src/org-database/lib/enums.ts +51 -0
  261. package/src/org-database/lib/migration-runner.ts +17 -0
  262. package/src/project-kit/index.ts +17 -0
  263. package/src/project-kit/lib/project-kit.ts +227 -0
  264. package/src/provisioning/index.ts +17 -0
  265. package/src/provisioning/lib/provisioning.ts +499 -0
  266. package/src/worker-runtime/index.ts +14 -0
  267. package/src/worker-runtime/lib/capabilities.ts +58 -0
  268. package/src/worker-runtime/lib/enums.ts +33 -0
  269. package/src/worker-runtime/lib/messages.ts +49 -0
  270. package/src/worker-runtime/lib/runtime.ts +109 -0
  271. package/src/worker-runtime/lib/schemas.ts +72 -0
  272. package/src/workflow/lib/activity-outputs.ts +1 -1
  273. package/src/workflow/lib/compiled-run.ts +1 -1
  274. package/src/workflow/lib/compiled-workspace-manifest.ts +1 -1
  275. package/src/workflow/lib/model-ref.ts +1 -1
  276. package/src/workflow/lib/workspace-manifest-enums.ts +1 -1
  277. package/src/workspace-storage/index.ts +12 -0
  278. package/src/workspace-storage/lib/enums.ts +78 -0
  279. package/src/workspace-storage/lib/schemas.ts +75 -0
  280. package/src/workspace-storage/lib/types.ts +145 -0
@@ -0,0 +1,499 @@
1
+ import { z } from 'zod';
2
+
3
+ // ─── Closed enums ────────────────────────────────────────────────────────────
4
+
5
+ /**
6
+ * Kind of provisioning step.
7
+ *
8
+ * - `SCAFFOLD` — seed an empty target with a project skeleton (e.g.
9
+ * `create-next-app`). Only runs at workspace boot, guard-gated on the
10
+ * target being scaffold-safe-empty.
11
+ * - `EQUIP` — install a reusable unit (a Project Kit) into an already
12
+ * scaffolded repo. Idempotent: guard-gated on a marker being absent.
13
+ */
14
+ export enum ProvisioningStepKind {
15
+ SCAFFOLD = 'scaffold',
16
+ EQUIP = 'equip',
17
+ }
18
+
19
+ /**
20
+ * Pre-condition the executor evaluates against the LIVE filesystem before
21
+ * running a step. A failing guard ⇒ the step is recorded `skipped` — this
22
+ * is what makes the `provision` phase self-idempotent with no mutable
23
+ * ledger.
24
+ *
25
+ * - `REPO_EMPTY` — `repos/<repoRef>/` holds only `SCAFFOLD_SAFE_NOISE`.
26
+ * - `PATH_ABSENT` — `targetDir` is absent, or holds only safe noise.
27
+ * - `MARKER_ABSENT` — `guardArgs.markerJsonPointer` resolves to nothing
28
+ * (e.g. the kit package is not yet in `package.json`).
29
+ * - `ALWAYS` — no pre-condition; the step always runs.
30
+ */
31
+ export enum ProvisioningGuard {
32
+ REPO_EMPTY = 'repo_empty',
33
+ PATH_ABSENT = 'path_absent',
34
+ MARKER_ABSENT = 'marker_absent',
35
+ ALWAYS = 'always',
36
+ }
37
+
38
+ /**
39
+ * When a scaffold declaration is allowed to run.
40
+ *
41
+ * - `WORKSPACE_BOOT` — during the `provision` phase of session launch.
42
+ * - `RUNTIME_REQUEST` — on an explicit later request (EQUIP only).
43
+ *
44
+ * A `SCAFFOLD` step may only declare `WORKSPACE_BOOT` — scaffolding a
45
+ * non-empty repo mid-session is never safe.
46
+ */
47
+ export enum ProvisioningTrigger {
48
+ WORKSPACE_BOOT = 'workspace-boot',
49
+ RUNTIME_REQUEST = 'runtime-request',
50
+ }
51
+
52
+ /** Mutation a `fileOp` applies to a path under the workspace. */
53
+ export enum ProvisioningFileOpKind {
54
+ WRITE = 'write',
55
+ MERGE_JSON = 'merge-json',
56
+ MERGE_YAML = 'merge-yaml',
57
+ }
58
+
59
+ /** Terminal per-step outcome the executor reports back. */
60
+ export enum ProvisioningStepStatus {
61
+ /** The guard failed — the step was a no-op (already provisioned). */
62
+ SKIPPED = 'skipped',
63
+ /** The guard passed and the content-addressed cache served the result. */
64
+ CACHE_HIT = 'cache_hit',
65
+ /** The guard passed and the commands ran (then wrote through to cache). */
66
+ BUILT = 'built',
67
+ }
68
+
69
+ /**
70
+ * Filesystem entries that do NOT disqualify a directory from being
71
+ * "scaffold-safe-empty". A repo with a committed `README.md` is still
72
+ * safe to scaffold into. Closed allowlist — both `REPO_EMPTY` and
73
+ * `PATH_ABSENT` guards evaluate against exactly this set.
74
+ */
75
+ export const SCAFFOLD_SAFE_NOISE: readonly string[] = [
76
+ '.git',
77
+ '.gitignore',
78
+ 'README.md',
79
+ 'LICENSE',
80
+ '.xema',
81
+ ];
82
+
83
+ // ─── Enum schemas ────────────────────────────────────────────────────────────
84
+
85
+ export const ProvisioningStepKindSchema = z.enum(ProvisioningStepKind);
86
+ export const ProvisioningGuardSchema = z.enum(ProvisioningGuard);
87
+ export const ProvisioningTriggerSchema = z.enum(ProvisioningTrigger);
88
+ export const ProvisioningFileOpKindSchema = z.enum(ProvisioningFileOpKind);
89
+ export const ProvisioningStepStatusSchema = z.enum(ProvisioningStepStatus);
90
+
91
+ // ─── Wire shapes (resolver → executor) ───────────────────────────────────────
92
+
93
+ /**
94
+ * One command the executor runs via `spawn(argv)`. **`argv` arrays only,
95
+ * never a shell string** — no shell interpolation, no injection surface.
96
+ * `cwd` is workspace-relative and the executor enforces it resolves under
97
+ * `/workspace/repos/` or `/workspace/.xema/`.
98
+ */
99
+ export const ProvisioningCommandSpecSchema = z
100
+ .object({
101
+ argv: z.array(z.string().min(1)).min(1),
102
+ cwd: z.string().min(1),
103
+ env: z.record(z.string(), z.string()).optional(),
104
+ timeoutMs: z.number().int().positive(),
105
+ })
106
+ .strict();
107
+ export type ProvisioningCommandSpec = z.infer<
108
+ typeof ProvisioningCommandSpecSchema
109
+ >;
110
+
111
+ /**
112
+ * A declarative file mutation applied after a step's commands run.
113
+ * `contentBase64` decodes to the file body (`write`) or the fragment to
114
+ * merge (`merge-json` / `merge-yaml`). `path` is workspace-relative and
115
+ * boundary-checked by the executor.
116
+ */
117
+ export const ProvisioningFileOpSchema = z
118
+ .object({
119
+ kind: ProvisioningFileOpKindSchema,
120
+ path: z.string().min(1),
121
+ contentBase64: z.string().min(1),
122
+ })
123
+ .strict();
124
+ export type ProvisioningFileOp = z.infer<typeof ProvisioningFileOpSchema>;
125
+
126
+ /**
127
+ * An optional residue of judgement that no deterministic command can
128
+ * cover. The executor NEVER runs an agent — it returns the instruction to
129
+ * agent-session-api, which decides whether/how to surface it. Most steps
130
+ * carry none.
131
+ */
132
+ export const ProvisioningAgentInstructionSchema = z
133
+ .object({
134
+ agentSlug: z.string().min(1),
135
+ promptBase64: z.string().min(1),
136
+ })
137
+ .strict();
138
+ export type ProvisioningAgentInstruction = z.infer<
139
+ typeof ProvisioningAgentInstructionSchema
140
+ >;
141
+
142
+ /**
143
+ * Presigned-URL pair for the content-addressed scaffold cache (Epic A §A4).
144
+ * agent-session-api mints these from a step's `cacheKey`; workspace-proxy
145
+ * GETs `getUrl` to probe for a hit, and on a miss PUTs the built tar to
146
+ * `putUrl` (write-through). `getHeaders` / `putHeaders` are the headers the
147
+ * presigned URL requires sent verbatim (e.g. the signed `Content-Type`).
148
+ *
149
+ * Absent on a step that is not cacheable (`cacheKey === null` — e.g. an
150
+ * `EQUIP` of a private Project Kit) or when the cache backend could not be
151
+ * reached at resolve time. The executor then builds locally — the plan's
152
+ * declared, logged optimization-bypass, never a silent degradation.
153
+ */
154
+ export const ProvisioningCacheRefSchema = z
155
+ .object({
156
+ getUrl: z.string().min(1),
157
+ getHeaders: z.record(z.string(), z.string()),
158
+ putUrl: z.string().min(1),
159
+ putHeaders: z.record(z.string(), z.string()),
160
+ })
161
+ .strict();
162
+ export type ProvisioningCacheRef = z.infer<typeof ProvisioningCacheRefSchema>;
163
+
164
+ /** Per-guard arguments. Only `MARKER_ABSENT` needs one today. */
165
+ export const ProvisioningGuardArgsSchema = z
166
+ .object({
167
+ /**
168
+ * JSON Pointer (RFC 6901) into a file under `targetDir` — the
169
+ * `MARKER_ABSENT` guard passes when it resolves to nothing. For an
170
+ * `EQUIP` kit the marker is the kit package key in `package.json`.
171
+ */
172
+ markerJsonPointer: z.string().min(1).optional(),
173
+ /** File the `markerJsonPointer` is resolved against, relative to `targetDir`. */
174
+ markerFile: z.string().min(1).optional(),
175
+ })
176
+ .strict();
177
+ export type ProvisioningGuardArgs = z.infer<typeof ProvisioningGuardArgsSchema>;
178
+
179
+ /**
180
+ * One fully-resolved provisioning step. Every biome-specific fact is
181
+ * baked in here — the executor is generic and never special-cases a
182
+ * biome. `cacheKey` is the content-addressed scaffold-cache key, or
183
+ * `null` for a step that must not be cached (e.g. an `EQUIP` of a private
184
+ * Project Kit fetched from an authenticated source).
185
+ */
186
+ export const ResolvedProvisioningStepSchema = z
187
+ .object({
188
+ id: z.string().min(1),
189
+ version: z.string().min(1),
190
+ kind: ProvisioningStepKindSchema,
191
+ guard: ProvisioningGuardSchema,
192
+ guardArgs: ProvisioningGuardArgsSchema.optional(),
193
+ /** Workspace-relative directory the step provisions. */
194
+ targetDir: z.string().min(1),
195
+ cacheKey: z.string().min(1).nullable(),
196
+ /**
197
+ * Presigned scaffold-cache URLs derived from `cacheKey` (Epic A §A4).
198
+ * Present only on a cacheable step whose URLs were minted at resolve
199
+ * time; absent ⇒ the executor builds locally with no cache.
200
+ */
201
+ cache: ProvisioningCacheRefSchema.optional(),
202
+ commands: z.array(ProvisioningCommandSpecSchema),
203
+ fileOps: z.array(ProvisioningFileOpSchema),
204
+ agentInstruction: ProvisioningAgentInstructionSchema.optional(),
205
+ })
206
+ .strict();
207
+ export type ResolvedProvisioningStep = z.infer<
208
+ typeof ResolvedProvisioningStepSchema
209
+ >;
210
+
211
+ /**
212
+ * The full plan agent-session-api emits and workspace-proxy executes.
213
+ * Steps are ordered: every `SCAFFOLD` precedes every `EQUIP` (you cannot
214
+ * equip a repo that has not been scaffolded). `version` is a literal `1`
215
+ * so a future wire change fails fast instead of silently mis-parsing.
216
+ */
217
+ export const ResolvedProvisioningPlanSchema = z
218
+ .object({
219
+ version: z.literal(1),
220
+ sessionId: z.string().min(1),
221
+ steps: z.array(ResolvedProvisioningStepSchema),
222
+ })
223
+ .strict();
224
+ export type ResolvedProvisioningPlan = z.infer<
225
+ typeof ResolvedProvisioningPlanSchema
226
+ >;
227
+
228
+ // ─── Wire shapes (executor → resolver) ───────────────────────────────────────
229
+
230
+ /**
231
+ * A `built` step that had a `cache` ref and is eligible for an out-of-band
232
+ * cache write. The executor no longer writes the cache inline; instead it
233
+ * surfaces the pending write here, and the caller (agent-session-api)
234
+ * dispatches `writeScaffoldCacheWorkflow` per entry (Phase J §J3).
235
+ *
236
+ * `cacheRef` is the SAME ref the plan carried in — re-passed to keep the
237
+ * activity stateless (workspace-proxy doesn't have to retain a presigned
238
+ * URL between the build and the workflow's callback).
239
+ */
240
+ export const ProvisioningPendingCacheWriteSchema = z
241
+ .object({
242
+ sourceDir: z.string().min(1),
243
+ cacheRef: ProvisioningCacheRefSchema,
244
+ })
245
+ .strict();
246
+ export type ProvisioningPendingCacheWrite = z.infer<
247
+ typeof ProvisioningPendingCacheWriteSchema
248
+ >;
249
+
250
+ /** Outcome of one executed step. */
251
+ export const ProvisioningStepResultSchema = z
252
+ .object({
253
+ id: z.string().min(1),
254
+ status: ProvisioningStepStatusSchema,
255
+ /** Non-empty only on `built`/`cache_hit` steps that carried one. */
256
+ pendingAgentInstruction: ProvisioningAgentInstructionSchema.optional(),
257
+ /**
258
+ * Non-empty only on a `built` step whose plan carried a `cache` ref.
259
+ * The caller dispatches `writeScaffoldCacheWorkflow` per entry — the
260
+ * executor never writes the cache itself (Phase J §J3).
261
+ */
262
+ pendingCacheWrite: ProvisioningPendingCacheWriteSchema.optional(),
263
+ })
264
+ .strict();
265
+ export type ProvisioningStepResult = z.infer<
266
+ typeof ProvisioningStepResultSchema
267
+ >;
268
+
269
+ /**
270
+ * The executor's reply. `pendingAgentInstructions` collects every step's
271
+ * `agentInstruction` (the proxy ran none) so agent-session-api can decide
272
+ * how to surface them.
273
+ */
274
+ export const ProvisioningPlanResultSchema = z
275
+ .object({
276
+ version: z.literal(1),
277
+ sessionId: z.string().min(1),
278
+ steps: z.array(ProvisioningStepResultSchema),
279
+ pendingAgentInstructions: z.array(ProvisioningAgentInstructionSchema),
280
+ })
281
+ .strict();
282
+ export type ProvisioningPlanResult = z.infer<
283
+ typeof ProvisioningPlanResultSchema
284
+ >;
285
+
286
+ // ─── Parse helpers ───────────────────────────────────────────────────────────
287
+
288
+ /** Thrown when a provisioning wire payload fails schema validation. */
289
+ export class ProvisioningContractParseError extends Error {
290
+ readonly issues: readonly z.core.$ZodIssue[];
291
+ constructor(what: string, issues: readonly z.core.$ZodIssue[]) {
292
+ super(
293
+ `Invalid ${what}: ${issues
294
+ .map((i) => `[${i.path.join('.')}] ${i.message}`)
295
+ .join('; ')}`,
296
+ );
297
+ this.name = 'ProvisioningContractParseError';
298
+ this.issues = issues;
299
+ }
300
+ }
301
+
302
+ /** Fail-fast parse of a `ResolvedProvisioningPlan` (executor entry point). */
303
+ export function parseResolvedProvisioningPlan(
304
+ raw: unknown,
305
+ ): ResolvedProvisioningPlan {
306
+ const result = ResolvedProvisioningPlanSchema.safeParse(raw);
307
+ if (!result.success) {
308
+ throw new ProvisioningContractParseError(
309
+ 'ResolvedProvisioningPlan',
310
+ result.error.issues,
311
+ );
312
+ }
313
+ return result.data;
314
+ }
315
+
316
+ /** Fail-fast parse of a `ProvisioningPlanResult` (resolver-side reply parse). */
317
+ export function parseProvisioningPlanResult(
318
+ raw: unknown,
319
+ ): ProvisioningPlanResult {
320
+ const result = ProvisioningPlanResultSchema.safeParse(raw);
321
+ if (!result.success) {
322
+ throw new ProvisioningContractParseError(
323
+ 'ProvisioningPlanResult',
324
+ result.error.issues,
325
+ );
326
+ }
327
+ return result.data;
328
+ }
329
+
330
+ // ─── Authoring schema — biome `provisioning/<id>.yaml` ──────────────────────
331
+ //
332
+ // The wire shapes above are what agent-session-api emits and workspace-proxy
333
+ // executes. The shapes below are what a PLUGIN AUTHOR writes on disk. The
334
+ // `provisioning-plan-resolver` (agent-session-api) reads an authored
335
+ // `ProvisioningScaffoldDefinition` (served, with its template files
336
+ // base64-inlined, by biome-host-api), expands it per the manifest selector
337
+ // — one rendered step per matched element — interpolates `{{placeholder}}`
338
+ // tokens against the match context, and emits the wire
339
+ // `ResolvedProvisioningStep`s above.
340
+ //
341
+ // Only `SCAFFOLD` recipes are authored here. `EQUIP` steps are NOT: the
342
+ // resolver synthesizes them from the session's resolved Project Kit set,
343
+ // because a kit's install command is a function of its runtime-resolved
344
+ // source (git URL / npm package + version + auth), not authorable static
345
+ // content.
346
+
347
+ /**
348
+ * Variant key used when a scaffold declares no `variantField`. The single
349
+ * `variants` entry MUST then be authored under exactly this key — the
350
+ * `ProvisioningScaffoldDefinition` `superRefine` enforces it.
351
+ */
352
+ export const DEFAULT_PROVISIONING_VARIANT = 'default';
353
+
354
+ /**
355
+ * One command in an authored recipe. Identical in shape to the wire
356
+ * `ProvisioningCommandSpec`, except every `argv` / `cwd` / `env` value MAY
357
+ * carry `{{placeholder}}` tokens the resolver substitutes from the match
358
+ * context (matched-element fields + session context such as `repoRef`)
359
+ * before emitting the resolved step.
360
+ */
361
+ export const ProvisioningCommandTemplateSchema = z
362
+ .object({
363
+ argv: z.array(z.string().min(1)).min(1),
364
+ cwd: z.string().min(1),
365
+ env: z.record(z.string(), z.string()).optional(),
366
+ timeoutMs: z.number().int().positive(),
367
+ })
368
+ .strict();
369
+ export type ProvisioningCommandTemplate = z.infer<
370
+ typeof ProvisioningCommandTemplateSchema
371
+ >;
372
+
373
+ /**
374
+ * One file mutation in an authored recipe. `templateRef` is a path —
375
+ * relative to the scaffold's sibling template directory
376
+ * `provisioning/<scaffoldId>/` — to the file whose bytes are this op's
377
+ * content. biome-host-api reads + base64-encodes every referenced
378
+ * template when it serves the definition, so the resolver never touches
379
+ * the biome filesystem. `{{placeholder}}` tokens are interpolated in
380
+ * `path` only — never in the file body.
381
+ */
382
+ export const ProvisioningFileOpTemplateSchema = z
383
+ .object({
384
+ kind: ProvisioningFileOpKindSchema,
385
+ path: z.string().min(1),
386
+ templateRef: z.string().min(1),
387
+ })
388
+ .strict();
389
+ export type ProvisioningFileOpTemplate = z.infer<
390
+ typeof ProvisioningFileOpTemplateSchema
391
+ >;
392
+
393
+ /**
394
+ * The residue-of-judgement instruction an authored recipe may carry. The
395
+ * executor never runs an agent — `promptTemplateRef` points at a template
396
+ * file the resolver base64-encodes into the wire
397
+ * `ProvisioningAgentInstruction`.
398
+ */
399
+ export const ProvisioningAgentInstructionTemplateSchema = z
400
+ .object({
401
+ agentSlug: z.string().min(1),
402
+ promptTemplateRef: z.string().min(1),
403
+ })
404
+ .strict();
405
+ export type ProvisioningAgentInstructionTemplate = z.infer<
406
+ typeof ProvisioningAgentInstructionTemplateSchema
407
+ >;
408
+
409
+ /**
410
+ * The recipe applied to one matched element — the commands + file ops +
411
+ * optional agent instruction. A scaffold that sets `variantField` declares
412
+ * one recipe per discriminator value; a single-variant scaffold declares
413
+ * exactly one recipe under the `DEFAULT_PROVISIONING_VARIANT` key.
414
+ */
415
+ export const ProvisioningRecipeSchema = z
416
+ .object({
417
+ commands: z.array(ProvisioningCommandTemplateSchema),
418
+ // Optional in authored YAML — many scaffolds (e.g. Next.js, Vite) ship
419
+ // no template `fileOps` because all file shaping happens at runtime in
420
+ // workspace-proxy. Defaults to `[]` so downstream code always sees an
421
+ // array without each biome author having to write `fileOps: []`.
422
+ fileOps: z.array(ProvisioningFileOpTemplateSchema).default([]),
423
+ agentInstruction: ProvisioningAgentInstructionTemplateSchema.optional(),
424
+ })
425
+ .strict();
426
+ export type ProvisioningRecipe = z.infer<typeof ProvisioningRecipeSchema>;
427
+
428
+ /**
429
+ * The parsed `provisioning/<id>.yaml` authoring document — a biome's
430
+ * deterministic `SCAFFOLD` recipe.
431
+ */
432
+ export const ProvisioningScaffoldDefinitionSchema = z
433
+ .object({
434
+ /** MUST equal the file basename AND the manifest `provisioning[].id`. */
435
+ id: z
436
+ .string()
437
+ .min(1)
438
+ .regex(
439
+ /^[a-z][a-z0-9-]*$/,
440
+ 'scaffold id must be lowercase kebab-case and match the provisioning/<id>.yaml basename',
441
+ ),
442
+ /**
443
+ * Author-bumped recipe version. Folds into every emitted step's
444
+ * content-addressed `cacheKey` — bump it to invalidate the cache.
445
+ */
446
+ scaffoldVersion: z.string().min(1),
447
+ /**
448
+ * Workspace-relative directory the scaffold provisions — e.g.
449
+ * `repos/{{repoRef}}/{{workingDir}}`. Carries `{{placeholder}}` tokens.
450
+ */
451
+ targetDir: z.string().min(1),
452
+ /**
453
+ * Field on each matched element whose value selects the variant. Omit
454
+ * for a single-variant scaffold (then `variants` MUST hold exactly the
455
+ * `DEFAULT_PROVISIONING_VARIANT` key).
456
+ */
457
+ variantField: z.string().min(1).optional(),
458
+ variants: z.record(z.string().min(1), ProvisioningRecipeSchema),
459
+ })
460
+ .strict()
461
+ .superRefine((value, ctx) => {
462
+ const variantKeys = Object.keys(value.variants);
463
+ if (variantKeys.length === 0) {
464
+ ctx.addIssue({
465
+ code: 'custom',
466
+ path: ['variants'],
467
+ message: 'a scaffold must declare at least one variant',
468
+ });
469
+ return;
470
+ }
471
+ if (
472
+ !value.variantField &&
473
+ (variantKeys.length !== 1 ||
474
+ variantKeys[0] !== DEFAULT_PROVISIONING_VARIANT)
475
+ ) {
476
+ ctx.addIssue({
477
+ code: 'custom',
478
+ path: ['variants'],
479
+ message: `a scaffold with no \`variantField\` must declare exactly one variant under the "${DEFAULT_PROVISIONING_VARIANT}" key`,
480
+ });
481
+ }
482
+ });
483
+ export type ProvisioningScaffoldDefinition = z.infer<
484
+ typeof ProvisioningScaffoldDefinitionSchema
485
+ >;
486
+
487
+ /** Fail-fast parse of an authored `provisioning/<id>.yaml` document. */
488
+ export function parseProvisioningScaffoldDefinition(
489
+ raw: unknown,
490
+ ): ProvisioningScaffoldDefinition {
491
+ const result = ProvisioningScaffoldDefinitionSchema.safeParse(raw);
492
+ if (!result.success) {
493
+ throw new ProvisioningContractParseError(
494
+ 'ProvisioningScaffoldDefinition',
495
+ result.error.issues,
496
+ );
497
+ }
498
+ return result.data;
499
+ }
@@ -0,0 +1,14 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // ── Worker Runtime Contracts — Barrel Export ──
3
+ //
4
+ // Kernel (Layer 1) contracts for the WorkerRuntime abstraction — the
5
+ // pluggable seam that lets Xema host multiple agent-runtime implementations
6
+ // (Opencode in v1; ClaudeCode, CopilotCLI, OpenHands as forward-compat
7
+ // targets). Pure types + closed enums + zod schemas. Zero NestJS.
8
+ // ═══════════════════════════════════════════════════════════════════════════
9
+
10
+ export * from './lib/enums';
11
+ export * from './lib/capabilities';
12
+ export * from './lib/messages';
13
+ export * from './lib/runtime';
14
+ export * from './lib/schemas';
@@ -0,0 +1,58 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // ── Worker runtime — capability bits & scheduler contract ──
3
+ //
4
+ // Capability bits describe which optional runtime features a concrete
5
+ // `WorkerRuntime` implementation supports. The composer reads these to
6
+ // decide which platform features are available for a given runtime; a
7
+ // runtime that does NOT support `hotModelSwap` for instance forces the
8
+ // composer to fall back to re-launching the worker on a model change.
9
+ // ═══════════════════════════════════════════════════════════════════════════
10
+
11
+ import type { HookKind } from './enums';
12
+
13
+ /**
14
+ * Capability bits a worker-runtime implementation exposes. All fields are
15
+ * required so a runtime cannot accidentally silently mis-declare a feature
16
+ * by omission.
17
+ */
18
+ export interface WorkerRuntimeCapabilityBits {
19
+ /** Can dynamically add/remove MCP services without a restart. */
20
+ readonly hotMcp: boolean;
21
+ /** Can swap the active model mid-session without a restart. */
22
+ readonly hotModelSwap: boolean;
23
+ /** Can fork an existing session into a sibling. */
24
+ readonly sessionFork: boolean;
25
+ /** Supports CRUD on sub-agent bindings during a live session. */
26
+ readonly subAgentCrud: boolean;
27
+ /** Lifecycle hooks supported. Empty = no hooks. */
28
+ readonly hooks: readonly HookKind[];
29
+ /** Has an in-runtime preview supervisor (long-running dev servers). */
30
+ readonly previewSupervisor: boolean;
31
+ /** Tags outbound LLM calls with attribution headers. */
32
+ readonly gatewayAttributedCalls: boolean;
33
+ /** Honors a runtime-supplied LLM endpoint override. */
34
+ readonly llmEndpointOverride: boolean;
35
+ }
36
+
37
+ /**
38
+ * Scheduler-side capability bits. The runtime declares which scheduler
39
+ * features it depends on; the scheduler advertises which it provides. The
40
+ * composer matches the two — a required capability missing on the
41
+ * scheduler is a fail-fast error (per plan §D18: no silent degradation).
42
+ */
43
+ export interface SchedulerCapabilityBits {
44
+ readonly autoRestart: boolean;
45
+ readonly healthCheck: boolean;
46
+ readonly hpa: boolean;
47
+ readonly networkPolicy: boolean;
48
+ }
49
+
50
+ /**
51
+ * A single scheduler capability the runtime asks for. `optional: true`
52
+ * means the runtime can function without it (degraded path is the
53
+ * runtime's responsibility, not the scheduler's silent fallback).
54
+ */
55
+ export interface SchedulerCapabilityRequest {
56
+ readonly kind: keyof SchedulerCapabilityBits;
57
+ readonly optional: boolean;
58
+ }
@@ -0,0 +1,33 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // ── Worker runtime — closed-domain enums ──
3
+ //
4
+ // Identifiers for worker-runtime implementations and the closed sets of
5
+ // capabilities they may expose. Future runtimes (Claude Code, Copilot CLI,
6
+ // OpenHands, …) will join `WorkerRuntimeKind` here; v1 ships Opencode only.
7
+ // ═══════════════════════════════════════════════════════════════════════════
8
+
9
+ /**
10
+ * Identifier of a concrete worker-runtime implementation. v1 ships
11
+ * Opencode only — additional kinds are reserved for forward compatibility:
12
+ *
13
+ * ClaudeCode = 'claude-code'
14
+ * CopilotCli = 'copilot-cli'
15
+ * OpenHands = 'open-hands'
16
+ *
17
+ * They are intentionally NOT exported yet. The enum is the single source
18
+ * of truth and consumers must `switch` exhaustively on it.
19
+ */
20
+ export enum WorkerRuntimeKind {
21
+ Opencode = 'opencode',
22
+ }
23
+
24
+ /**
25
+ * Lifecycle hook surfaces that a runtime may support. The set is closed —
26
+ * adding a new hook is a kernel change.
27
+ */
28
+ export enum HookKind {
29
+ ToolExecuteBefore = 'tool.execute.before',
30
+ ToolExecuteAfter = 'tool.execute.after',
31
+ SessionIdle = 'session.idle',
32
+ SessionStart = 'session.start',
33
+ }
@@ -0,0 +1,49 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // ── Worker runtime — user message & event shapes ──
3
+ //
4
+ // Wire-side shapes the composer hands to a runtime's `sendUserMessage`
5
+ // and what the runtime yields back. Discriminated unions are closed —
6
+ // adding a new event kind is a kernel change.
7
+ // ═══════════════════════════════════════════════════════════════════════════
8
+
9
+ /**
10
+ * Who is sending a message — a logged-in org member or an external guest
11
+ * (e.g. anonymous brainstorm participant). Subject ref disambiguates.
12
+ */
13
+ export interface ActorRef {
14
+ readonly subjectKind: 'org_user' | 'external_guest';
15
+ readonly subjectRef: string;
16
+ readonly displayName: string;
17
+ }
18
+
19
+ /**
20
+ * An attachment carried alongside a user message. `value` is the
21
+ * kind-specific payload: a file/asset URI, an inline image URL/dataurl,
22
+ * or a plain URL. The runtime decides how to materialize it.
23
+ */
24
+ export interface Attachment {
25
+ readonly kind: 'file' | 'image' | 'url';
26
+ readonly value: string;
27
+ }
28
+
29
+ /**
30
+ * A single message handed to the runtime via `sendUserMessage`. The
31
+ * runtime streams `RuntimeEvent`s back as the model processes the turn.
32
+ */
33
+ export interface UserMessage {
34
+ readonly actor: ActorRef;
35
+ readonly content: string;
36
+ readonly attachments?: readonly Attachment[];
37
+ }
38
+
39
+ /**
40
+ * Closed, discriminated union of events a runtime emits during a turn.
41
+ * `error.retryable` is REQUIRED so consumers cannot silently retry on a
42
+ * permanent failure or give up on a transient one.
43
+ */
44
+ export type RuntimeEvent =
45
+ | { readonly kind: 'text-delta'; readonly text: string }
46
+ | { readonly kind: 'tool-use'; readonly tool: string; readonly input: unknown }
47
+ | { readonly kind: 'tool-result'; readonly tool: string; readonly output: unknown }
48
+ | { readonly kind: 'turn-end' }
49
+ | { readonly kind: 'error'; readonly message: string; readonly retryable: boolean };