@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,38 @@
1
+ import type { RenderFormat, RenderStatus } from './render-enums';
2
+ import type { RenderSource } from './render-source';
3
+
4
+ /**
5
+ * The persistent record returned by `GET /renders/:id` (and embedded in
6
+ * `POST /renders` responses). Once `status === READY`, `downloadUrl` is a
7
+ * pre-signed URL the FE can navigate to directly.
8
+ */
9
+ export interface RenderRecordDto {
10
+ readonly id: string;
11
+ readonly format: RenderFormat;
12
+ readonly status: RenderStatus;
13
+ readonly source: RenderSource;
14
+ readonly downloadUrl: string | null;
15
+ readonly failureReason: string | null;
16
+ /** ISO-8601 timestamp. */
17
+ readonly createdAt: string;
18
+ /** ISO-8601 timestamp; null until terminal. */
19
+ readonly completedAt: string | null;
20
+ /** Convenience: byte size of the rendered file when READY. */
21
+ readonly byteSize: number | null;
22
+ }
23
+
24
+ /**
25
+ * SSE event payload streamed from `GET /renders/:id/stream`. The FE
26
+ * subscribes once after `POST /renders` and tears down on terminal
27
+ * status. Progress percent is best-effort and may be null for fast
28
+ * renders that flip QUEUED → RUNNING → READY without a measurable
29
+ * mid-state.
30
+ */
31
+ export interface RenderProgressEventDto {
32
+ readonly renderId: string;
33
+ readonly status: RenderStatus;
34
+ readonly progressPercent: number | null;
35
+ readonly message: string | null;
36
+ readonly downloadUrl: string | null;
37
+ readonly failureReason: string | null;
38
+ }
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+
3
+ import { RenderFormat } from './render-enums';
4
+ import { RenderSourceSchema } from './render-source';
5
+
6
+ /**
7
+ * Request body for `POST /renders`. `idempotencyKey` deduplicates retries
8
+ * from the same caller — when present, repeat POSTs return the existing
9
+ * record instead of enqueueing duplicate work.
10
+ */
11
+ export const RenderRequestSchema = z.object({
12
+ source: RenderSourceSchema,
13
+ format: z.enum(RenderFormat),
14
+ idempotencyKey: z.string().min(1).max(200).optional(),
15
+ });
16
+ export type RenderRequestDto = z.infer<typeof RenderRequestSchema>;
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+
3
+ import { RenderSourceKind } from './render-enums';
4
+
5
+ export const PageRenderSourceSchema = z.object({
6
+ kind: z.literal(RenderSourceKind.PAGE),
7
+ pageId: z.string().min(1),
8
+ /** Omit for the latest published version. */
9
+ version: z.number().int().min(1).optional(),
10
+ });
11
+ export type PageRenderSource = z.infer<typeof PageRenderSourceSchema>;
12
+
13
+ export const DesignSystemBuilderExportRenderSourceSchema = z.object({
14
+ kind: z.literal(RenderSourceKind.DESIGN_SYSTEM_BUILDER_EXPORT),
15
+ designSystemBuildId: z.string().min(1),
16
+ });
17
+ export type DesignSystemBuilderExportRenderSource = z.infer<
18
+ typeof DesignSystemBuilderExportRenderSourceSchema
19
+ >;
20
+
21
+ export const WorkflowDeliverableRenderSourceSchema = z.object({
22
+ kind: z.literal(RenderSourceKind.WORKFLOW_DELIVERABLE),
23
+ artifactId: z.string().min(1),
24
+ versionId: z.string().min(1),
25
+ });
26
+ export type WorkflowDeliverableRenderSource = z.infer<
27
+ typeof WorkflowDeliverableRenderSourceSchema
28
+ >;
29
+
30
+ export const InlineHtmlRenderSourceSchema = z.object({
31
+ kind: z.literal(RenderSourceKind.INLINE_HTML),
32
+ /** Full HTML document. Must include the A4 template CSS to paginate. */
33
+ html: z.string().min(1).max(2_000_000),
34
+ title: z.string().max(200).optional(),
35
+ });
36
+ export type InlineHtmlRenderSource = z.infer<typeof InlineHtmlRenderSourceSchema>;
37
+
38
+ export const RenderSourceSchema = z.discriminatedUnion('kind', [
39
+ PageRenderSourceSchema,
40
+ DesignSystemBuilderExportRenderSourceSchema,
41
+ WorkflowDeliverableRenderSourceSchema,
42
+ InlineHtmlRenderSourceSchema,
43
+ ]);
44
+ export type RenderSource = z.infer<typeof RenderSourceSchema>;
@@ -0,0 +1,100 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // Inline "Ask Buddy" prompt blocks — the `xema-prompt` fenced-code contract.
3
+ //
4
+ // A user can drop an instruction for the Document Buddy agent *inside* a
5
+ // MARKDOWN_DOCUMENT, at the exact spot the work belongs, as a fenced code
6
+ // block whose info string is `xema-prompt`:
7
+ //
8
+ // ```xema-prompt
9
+ // Rewrite the section above to be tighter; keep the table.
10
+ // ```
11
+ //
12
+ // The block is an instruction to the agent, never document content — it
13
+ // must never reach the Paged.js preview, the exported PDF, or the DOCX.
14
+ // This module is the single source of truth for that contract, shared by:
15
+ // - the render pipeline (PDF/DOCX/measure) — strips blocks before render;
16
+ // - the Monaco "Ask Buddy" editor — inserts blocks and locates them for
17
+ // the inline Run affordance (the file is frontend-bridged).
18
+ //
19
+ // Pure string utilities. Zero runtime deps so the file bridges cleanly.
20
+ // ═══════════════════════════════════════════════════════════════════════════
21
+
22
+ /** Fenced-code-block info string that marks an inline "Ask Buddy" prompt. */
23
+ export const XEMA_PROMPT_FENCE = 'xema-prompt';
24
+
25
+ /**
26
+ * Matches a whole `xema-prompt` fenced block: an opening fence (3+
27
+ * backticks or tildes, up to 3 spaces of indent) whose info string is
28
+ * `xema-prompt`, the body, and the matching closing fence. Global +
29
+ * multiline so every block in the document is removed; the trailing
30
+ * newline is consumed so no blank gap is left behind.
31
+ */
32
+ export const XEMA_PROMPT_BLOCK_RE = new RegExp(
33
+ '^ {0,3}(`{3,}|~{3,})[ \\t]*' +
34
+ XEMA_PROMPT_FENCE +
35
+ '[^\\n]*\\n[\\s\\S]*?^ {0,3}\\1[ \\t]*$\\n?',
36
+ 'gm',
37
+ );
38
+
39
+ /** Remove every inline "Ask Buddy" prompt block from markdown source. */
40
+ export function stripXemaPromptBlocks(markdown: string): string {
41
+ return markdown.replace(XEMA_PROMPT_BLOCK_RE, '');
42
+ }
43
+
44
+ /**
45
+ * Build a canonical `xema-prompt` block (3 backticks) carrying an
46
+ * optional instruction. Used by the Monaco editor's `/ask` completion so
47
+ * the inserted block always matches what the strip + locate logic
48
+ * expects. Ends with a newline so the block sits on its own lines.
49
+ */
50
+ export function buildXemaPromptBlock(instruction = ''): string {
51
+ return '```' + XEMA_PROMPT_FENCE + '\n' + instruction + '\n```\n';
52
+ }
53
+
54
+ /** A located `xema-prompt` block, with 1-based inclusive line bounds. */
55
+ export interface XemaPromptBlockRange {
56
+ /** 1-based line of the opening fence. */
57
+ readonly startLine: number;
58
+ /** 1-based line of the closing fence. */
59
+ readonly endLine: number;
60
+ /** Instruction text between the fences (may be empty / whitespace). */
61
+ readonly instruction: string;
62
+ }
63
+
64
+ /**
65
+ * Locate every `xema-prompt` block in `text`, returning 1-based line
66
+ * ranges. Drives the Monaco "Ask Buddy" CodeLens — the editor renders a
67
+ * Run affordance over each range. Unterminated blocks (no closing fence)
68
+ * are skipped: they are still being typed and carry no actionable lens.
69
+ */
70
+ export function findXemaPromptBlockRanges(text: string): XemaPromptBlockRange[] {
71
+ const lines = text.split('\n');
72
+ const openRe = new RegExp(
73
+ '^ {0,3}(`{3,}|~{3,})[ \\t]*' + XEMA_PROMPT_FENCE + '[^\\n]*$',
74
+ );
75
+ const ranges: XemaPromptBlockRange[] = [];
76
+ let i = 0;
77
+ while (i < lines.length) {
78
+ const open = openRe.exec(lines[i] ?? '');
79
+ if (!open) {
80
+ i += 1;
81
+ continue;
82
+ }
83
+ const fence = open[1] ?? '```';
84
+ const closeRe = new RegExp('^ {0,3}' + fence + '[ \\t]*$');
85
+ let j = i + 1;
86
+ while (j < lines.length && !closeRe.test(lines[j] ?? '')) {
87
+ j += 1;
88
+ }
89
+ if (j >= lines.length) {
90
+ break; // unterminated block — no actionable lens
91
+ }
92
+ ranges.push({
93
+ startLine: i + 1,
94
+ endLine: j + 1,
95
+ instruction: lines.slice(i + 1, j).join('\n'),
96
+ });
97
+ i = j + 1;
98
+ }
99
+ return ranges;
100
+ }
@@ -0,0 +1,23 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // @xemahq/inquiry-contracts — Kernel layer
3
+ //
4
+ // Abstract types for the Inquiry primitive: "ask one or more recipients
5
+ // (humans, agents, endpoints) a typed prompt, validate replies against a
6
+ // kind-specific schema, aggregate per a policy, return a verdict."
7
+ //
8
+ // Runtime-agnostic. Pure types + Zod schemas. Zero framework / persistence /
9
+ // workflow-runtime imports. The plan-of-record lives at
10
+ // .claude/plans/i-think-what-we-ve-transient-zebra.md.
11
+ //
12
+ // Per-kind prompt + reply Zod schemas live in their own contract packages
13
+ // (`@xemahq/decision-gate-contracts`, `@xemahq/agent-tool-inquiry-
14
+ // contracts`) and are registered with this package's `KindSchemaRegistry`
15
+ // at the engine boundary.
16
+ // ═══════════════════════════════════════════════════════════════════════════
17
+
18
+ export * from './lib/enums';
19
+ export * from './lib/recipient';
20
+ export * from './lib/policy';
21
+ export * from './lib/inquiry';
22
+ export * from './lib/kind-registry';
23
+ export * from './lib/workflow-verdict-evaluator';
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Discriminator on the inquiry row. Determines which Zod schemas apply to
3
+ * the `prompt` and `reply` payloads. Future kinds (e.g. TOOL_PROMPT,
4
+ * CONFIRMATION) extend this enum without breaking existing rows.
5
+ *
6
+ * `REVIEW` is the comment-only review surface — pins one or more
7
+ * artifact versions and asks recipients to leave free-form commentary.
8
+ * No approve/reject verdict, no policy aggregation, no terminal
9
+ * "approved/rejected" outcome. Compose with DECISION_GATE when both
10
+ * review-and-gate semantics are needed.
11
+ */
12
+ export enum InquiryKind {
13
+ DECISION_GATE = 'decision_gate',
14
+ AGENT_TOOL_INQUIRY = 'agent_tool_inquiry',
15
+ REVIEW = 'review',
16
+ }
17
+
18
+ /**
19
+ * Lifecycle states. Once an inquiry is non-PENDING, no further replies are
20
+ * accepted; reply ingest returns 409.
21
+ */
22
+ export enum InquiryStatus {
23
+ PENDING = 'pending',
24
+ RESOLVED = 'resolved',
25
+ EXPIRED = 'expired',
26
+ CANCELLED = 'cancelled',
27
+ }
28
+
29
+ /**
30
+ * Source of a recipient's reply. Discriminates the `target` payload shape
31
+ * on `Recipient` and the `submittedBy` attribution on `InquiryReply`.
32
+ *
33
+ * `IDENTITY_GROUP` is an *authoring* kind: it is never persisted as a
34
+ * recipient row. The engine resolves it at inquiry-create time against
35
+ * the identity-system group registry (recursive members) and replaces it
36
+ * with N concrete `HUMAN` recipients. From the moment the inquiry exists
37
+ * the wire payload is identical to today's recipient list. Resolution is
38
+ * snapshot-at-create — later membership changes do not affect the
39
+ * inquiry.
40
+ *
41
+ * `WORKFLOW` is a non-human responder: the engine dispatches a child
42
+ * workflow (slug + inputs) and maps its outputs to a verdict. Same
43
+ * uniform reply contract as `HUMAN`/`AGENT`/`ENDPOINT`. Useful for
44
+ * "approval-as-workflow" — e.g. compliance-review.workflow.yaml as a
45
+ * recipient that produces approve/reject after running its own gates.
46
+ */
47
+ export enum RecipientKind {
48
+ HUMAN = 'human',
49
+ AGENT = 'agent',
50
+ ENDPOINT = 'endpoint',
51
+ IDENTITY_GROUP = 'identity_group',
52
+ WORKFLOW = 'workflow',
53
+ }
54
+
55
+ /**
56
+ * Per-recipient lifecycle. The engine flips PENDING → REPLIED atomically
57
+ * under `SELECT … FOR UPDATE` so concurrent reply attempts can't both win.
58
+ * SKIPPED is set when the policy short-circuits (e.g. quorum reached);
59
+ * ERRORED when a non-human decider activity exhausted its retries.
60
+ */
61
+ export enum InquiryRecipientStatus {
62
+ PENDING = 'pending',
63
+ REPLIED = 'replied',
64
+ SKIPPED = 'skipped',
65
+ ERRORED = 'errored',
66
+ }
67
+
68
+ /**
69
+ * Aggregation rules applied across recipients' replies. Discriminated union
70
+ * shapes live in `./policy.ts`. The decider workflow short-circuits as soon
71
+ * as the policy is provably decided (e.g. M_OF_N approves once `m`
72
+ * approvals are in; rejects once remaining recipients can no longer reach
73
+ * `m`).
74
+ */
75
+ export enum ReplyPolicyKind {
76
+ SINGLE = 'single',
77
+ M_OF_N = 'm_of_n',
78
+ ALL_OF = 'all_of',
79
+ ANY_OF = 'any_of',
80
+ }
81
+
82
+ /**
83
+ * Action when the inquiry's deadline passes with no terminal verdict.
84
+ *
85
+ * - `REJECT` / `APPROVE` — auto-decide on timeout. For DECISION_GATE this
86
+ * becomes `EXPIRED_REJECTED` / `EXPIRED_APPROVED`. For
87
+ * AGENT_TOOL_INQUIRY only `REJECT` is meaningful (the activity returns
88
+ * `null`, which aborts the tool); `APPROVE` is rejected by the
89
+ * schema for that kind.
90
+ * - `ESCALATE` — instead of auto-deciding, advance to the next level in
91
+ * the inquiry's `escalationChain`. Pending recipients are marked
92
+ * skipped(`escalation_timeout`); the next level's recipients are
93
+ * inserted as fresh PENDING rows; `expiresAt` resets to
94
+ * `now + nextLevel.timeoutSeconds`. When the chain is exhausted,
95
+ * `escalationChain[].onExhaustion` (or the inquiry's
96
+ * `onEscalationExhaustion` field) decides the final action — defaults
97
+ * to REJECT so a misconfigured chain never silently approves.
98
+ */
99
+ export enum InquiryTimeoutAction {
100
+ REJECT = 'reject',
101
+ APPROVE = 'approve',
102
+ ESCALATE = 'escalate',
103
+ }
@@ -0,0 +1,182 @@
1
+ import { z } from 'zod';
2
+
3
+ import {
4
+ InquiryKind,
5
+ InquiryRecipientStatus,
6
+ InquiryStatus,
7
+ InquiryTimeoutAction,
8
+ RecipientKind,
9
+ } from './enums';
10
+ import { ReplyPolicySchema } from './policy';
11
+ import { RecipientSchema } from './recipient';
12
+
13
+ /**
14
+ * One step in an inquiry's escalation chain. When the inquiry's
15
+ * `onTimeout === ESCALATE` and the deadline passes, the engine advances
16
+ * to the next step: marks all PENDING recipients as
17
+ * `skipped(reason='escalation_timeout')`, inserts the step's recipients
18
+ * as fresh PENDING rows, and resets the deadline to
19
+ * `now + timeoutSeconds`. The step's `policy` (when present) replaces
20
+ * the inquiry's policy for that level so escalations can demand a
21
+ * different aggregation rule than the original ask.
22
+ *
23
+ * `recipients` MUST be non-empty. The chain is linear; each step is
24
+ * tried in order. When the chain is exhausted, the inquiry's
25
+ * `onEscalationExhaustion` field decides the final action — defaults
26
+ * to `REJECT` when omitted so a misconfigured chain never silently
27
+ * approves.
28
+ */
29
+ export const EscalationStepSchema = z.object({
30
+ recipients: z.array(RecipientSchema).min(1),
31
+ policy: ReplyPolicySchema.optional(),
32
+ timeoutSeconds: z.number().int().positive(),
33
+ });
34
+ export type EscalationStep = z.infer<typeof EscalationStepSchema>;
35
+
36
+ /**
37
+ * Wire-shape of an Inquiry envelope. The `prompt` and `verdict` fields
38
+ * are kind-discriminated JSON — their shapes are owned by the per-kind
39
+ * contract packages (see `KindSchemaRegistry`).
40
+ *
41
+ * Engine + worker import this for cross-process consistency. The
42
+ * persisted model on the engine side mirrors these field names but stores
43
+ * `prompt`/`policy`/`verdict` as JSON columns; the engine validates the
44
+ * payload against the kind-registered Zod schemas at the controller
45
+ * boundary.
46
+ */
47
+ export const InquirySchema = z.object({
48
+ id: z.string().min(1),
49
+ orgId: z.string().min(1),
50
+ projectId: z.string().min(1),
51
+ workflowRunId: z.string().min(1),
52
+ jobRunId: z.string().min(1),
53
+ kind: z.nativeEnum(InquiryKind),
54
+ title: z.string(),
55
+ prompt: z.record(z.string(), z.unknown()),
56
+ policy: ReplyPolicySchema,
57
+ status: z.nativeEnum(InquiryStatus),
58
+ expiresAtIso: z.string(),
59
+ onTimeout: z.nativeEnum(InquiryTimeoutAction),
60
+ /**
61
+ * Escalation chain — linear list of recipient sets, each tried in
62
+ * order on deadline-passed (`onTimeout === ESCALATE`). Empty when
63
+ * `onTimeout !== ESCALATE`. Validated at create time.
64
+ */
65
+ escalationChain: z.array(EscalationStepSchema),
66
+ /**
67
+ * Action when the escalation chain is exhausted (i.e. the final
68
+ * step's deadline passes with no terminal verdict). Closed set:
69
+ * `REJECT` (default) or `APPROVE`. `ESCALATE` is rejected here at
70
+ * the schema level — would be a runtime infinite loop.
71
+ */
72
+ onEscalationExhaustion: z.enum(['reject', 'approve']),
73
+ /**
74
+ * Zero-based pointer into `escalationChain`. Bumped each time the
75
+ * engine advances. `0` means "still on the original recipients";
76
+ * `1` means "currently on chain[0]"; etc. (i.e. it counts how many
77
+ * escalations have fired, NOT which slot of the chain is active).
78
+ */
79
+ currentEscalationLevel: z.number().int().nonnegative(),
80
+ verdict: z.record(z.string(), z.unknown()).nullable(),
81
+ resolvedAtIso: z.string().nullable(),
82
+ cancelledAtIso: z.string().nullable(),
83
+ createdAtIso: z.string(),
84
+ updatedAtIso: z.string(),
85
+ recipients: z.array(
86
+ z.object({
87
+ id: z.string().min(1),
88
+ ord: z.number().int().nonnegative(),
89
+ kind: z.nativeEnum(RecipientKind),
90
+ target: z.record(z.string(), z.unknown()),
91
+ status: z.nativeEnum(InquiryRecipientStatus),
92
+ replyId: z.string().nullable(),
93
+ mandatory: z.boolean(),
94
+ }),
95
+ ),
96
+ replies: z
97
+ .array(
98
+ z.object({
99
+ id: z.string().min(1),
100
+ recipientId: z.string().min(1),
101
+ payload: z.record(z.string(), z.unknown()),
102
+ submittedBy: z.string().min(1),
103
+ submittedAtIso: z.string(),
104
+ }),
105
+ )
106
+ .optional(),
107
+ });
108
+ export type Inquiry = z.infer<typeof InquirySchema>;
109
+
110
+ /**
111
+ * Caller-supplied input for `POST /inquiries`. The engine generates the
112
+ * recipient IDs and timestamps. `id` is caller-supplied so the engine is
113
+ * idempotent on retry — a duplicate POST returns the existing row.
114
+ */
115
+ export const CreateInquiryInputSchema = z
116
+ .object({
117
+ id: z.string().min(1),
118
+ orgId: z.string().min(1),
119
+ projectId: z.string().min(1),
120
+ workflowRunId: z.string().min(1),
121
+ jobRunId: z.string().min(1),
122
+ kind: z.nativeEnum(InquiryKind),
123
+ title: z.string(),
124
+ prompt: z.record(z.string(), z.unknown()),
125
+ policy: ReplyPolicySchema,
126
+ recipients: z.array(RecipientSchema).min(1),
127
+ expiresAtIso: z.string(),
128
+ onTimeout: z.nativeEnum(InquiryTimeoutAction),
129
+ escalationChain: z.array(EscalationStepSchema).optional(),
130
+ onEscalationExhaustion: z.enum(['reject', 'approve']).optional(),
131
+ })
132
+ .superRefine((value, ctx) => {
133
+ // ESCALATE without a chain is meaningless — would have to fall back
134
+ // to REJECT/APPROVE on the first timeout, defeating the point.
135
+ if (
136
+ value.onTimeout === InquiryTimeoutAction.ESCALATE &&
137
+ (value.escalationChain === undefined || value.escalationChain.length === 0)
138
+ ) {
139
+ ctx.addIssue({
140
+ code: z.ZodIssueCode.custom,
141
+ path: ['escalationChain'],
142
+ message:
143
+ 'onTimeout=ESCALATE requires a non-empty escalationChain. Configure at least one escalation step or change onTimeout.',
144
+ });
145
+ }
146
+ // A chain on a non-escalating inquiry is dead weight; flag it so the
147
+ // workflow author notices the misconfiguration.
148
+ if (
149
+ value.onTimeout !== InquiryTimeoutAction.ESCALATE &&
150
+ value.escalationChain !== undefined &&
151
+ value.escalationChain.length > 0
152
+ ) {
153
+ ctx.addIssue({
154
+ code: z.ZodIssueCode.custom,
155
+ path: ['escalationChain'],
156
+ message: `escalationChain is set but onTimeout=${value.onTimeout} — change onTimeout to ESCALATE or remove the chain.`,
157
+ });
158
+ }
159
+ });
160
+ export type CreateInquiryInput = z.infer<typeof CreateInquiryInputSchema>;
161
+
162
+ /**
163
+ * Reply submitted by one recipient. Engine validates `payload` against the
164
+ * kind-specific reply schema before insert; per-recipient idempotency is
165
+ * enforced via `SELECT … FOR UPDATE` on the recipient row.
166
+ */
167
+ export const InquiryReplySchema = z.object({
168
+ id: z.string().min(1),
169
+ inquiryId: z.string().min(1),
170
+ recipientId: z.string().min(1),
171
+ payload: z.record(z.string(), z.unknown()),
172
+ submittedBy: z.string().min(1),
173
+ submittedAtIso: z.string(),
174
+ });
175
+ export type InquiryReply = z.infer<typeof InquiryReplySchema>;
176
+
177
+ export const SubmitReplyInputSchema = z.object({
178
+ recipientId: z.string().min(1),
179
+ payload: z.record(z.string(), z.unknown()),
180
+ submittedBy: z.string().min(1),
181
+ });
182
+ export type SubmitReplyInput = z.infer<typeof SubmitReplyInputSchema>;
@@ -0,0 +1,57 @@
1
+ import type { z } from 'zod';
2
+
3
+ import type { InquiryKind } from './enums';
4
+
5
+ /**
6
+ * Per-kind schema pair. Engine + bridge use these to validate `prompt` on
7
+ * inquiry creation and `payload` on reply submission. Each consumer of an
8
+ * `InquiryKind` registers its schemas at module init.
9
+ *
10
+ * The registry is intentionally NOT auto-populated here — populating it
11
+ * would create a hard dependency from this package to every kind's
12
+ * contract package, defeating the point of keeping per-kind contracts in
13
+ * their own packages. Instead, the engine imports each contract package
14
+ * and calls `registerInquiryKind` at boot.
15
+ */
16
+ export interface InquiryKindSchemas {
17
+ readonly promptSchema: z.ZodType<unknown>;
18
+ readonly replySchema: z.ZodType<unknown>;
19
+ /**
20
+ * Optional verdict shape — only relevant for kinds that aggregate
21
+ * across recipients (e.g. DECISION_GATE). For per-reply kinds (e.g.
22
+ * AGENT_TOOL_INQUIRY with policy=SINGLE), this can be omitted; the
23
+ * verdict is just the first reply's payload.
24
+ */
25
+ readonly verdictSchema?: z.ZodType<unknown>;
26
+ }
27
+
28
+ /**
29
+ * In-process registry. The engine has one instance bound at module init;
30
+ * the worker has another. Tests construct their own registries.
31
+ */
32
+ export class InquiryKindSchemaRegistry {
33
+ private readonly entries = new Map<InquiryKind, InquiryKindSchemas>();
34
+
35
+ register(kind: InquiryKind, schemas: InquiryKindSchemas): void {
36
+ if (this.entries.has(kind)) {
37
+ throw new Error(
38
+ `InquiryKindSchemaRegistry: kind '${kind}' is already registered`,
39
+ );
40
+ }
41
+ this.entries.set(kind, schemas);
42
+ }
43
+
44
+ get(kind: InquiryKind): InquiryKindSchemas {
45
+ const schemas = this.entries.get(kind);
46
+ if (!schemas) {
47
+ throw new Error(
48
+ `InquiryKindSchemaRegistry: no schemas registered for kind '${kind}'`,
49
+ );
50
+ }
51
+ return schemas;
52
+ }
53
+
54
+ has(kind: InquiryKind): boolean {
55
+ return this.entries.has(kind);
56
+ }
57
+ }
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+
3
+ import { ReplyPolicyKind } from './enums';
4
+
5
+ /**
6
+ * What to do when an agent or endpoint recipient submits an ABSTAIN
7
+ * verdict. `skip` (default) ignores the recipient's vote and waits for the
8
+ * remaining recipients; `reject_implicit` treats abstention as a rejection
9
+ * for purposes of M_OF_N / ALL_OF arithmetic. Without this knob, a flaky
10
+ * LLM can silently sink an inquiry by abstaining.
11
+ */
12
+ export enum AbstainTreatment {
13
+ SKIP = 'skip',
14
+ REJECT_IMPLICIT = 'reject_implicit',
15
+ }
16
+
17
+ export const ReplyPolicySchema = z.discriminatedUnion('kind', [
18
+ z.object({ kind: z.literal(ReplyPolicyKind.SINGLE) }),
19
+ z.object({
20
+ kind: z.literal(ReplyPolicyKind.M_OF_N),
21
+ m: z.number().int().positive(),
22
+ abstainTreatment: z.nativeEnum(AbstainTreatment).optional(),
23
+ }),
24
+ z.object({ kind: z.literal(ReplyPolicyKind.ALL_OF) }),
25
+ z.object({ kind: z.literal(ReplyPolicyKind.ANY_OF) }),
26
+ ]);
27
+ export type ReplyPolicy = z.infer<typeof ReplyPolicySchema>;