@xemahq/kernel-contracts 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/agent-tool-inquiry/index.d.ts +2 -0
- package/dist/agent-tool-inquiry/index.d.ts.map +1 -0
- package/dist/agent-tool-inquiry/index.js +18 -0
- package/dist/agent-tool-inquiry/index.js.map +1 -0
- package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.d.ts +43 -0
- package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.d.ts.map +1 -0
- package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.js +32 -0
- package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.js.map +1 -0
- package/dist/agent-workspace/awp-spec.json +1 -1
- package/dist/app-runtime/index.d.ts +9 -0
- package/dist/app-runtime/index.d.ts.map +1 -0
- package/dist/app-runtime/index.js +25 -0
- package/dist/app-runtime/index.js.map +1 -0
- package/dist/app-runtime/lib/app-client.d.ts +11 -0
- package/dist/app-runtime/lib/app-client.d.ts.map +1 -0
- package/dist/app-runtime/lib/app-client.js +23 -0
- package/dist/app-runtime/lib/app-client.js.map +1 -0
- package/dist/app-runtime/lib/app-lockfile.d.ts +12 -0
- package/dist/app-runtime/lib/app-lockfile.d.ts.map +1 -0
- package/dist/app-runtime/lib/app-lockfile.js +17 -0
- package/dist/app-runtime/lib/app-lockfile.js.map +1 -0
- package/dist/app-runtime/lib/app.d.ts +26 -0
- package/dist/app-runtime/lib/app.d.ts.map +1 -0
- package/dist/app-runtime/lib/app.js +31 -0
- package/dist/app-runtime/lib/app.js.map +1 -0
- package/dist/app-runtime/lib/audience-policy.d.ts +31 -0
- package/dist/app-runtime/lib/audience-policy.d.ts.map +1 -0
- package/dist/app-runtime/lib/audience-policy.js +38 -0
- package/dist/app-runtime/lib/audience-policy.js.map +1 -0
- package/dist/app-runtime/lib/biome-install.d.ts +9 -0
- package/dist/app-runtime/lib/biome-install.d.ts.map +1 -0
- package/dist/app-runtime/lib/biome-install.js +13 -0
- package/dist/app-runtime/lib/biome-install.js.map +1 -0
- package/dist/app-runtime/lib/branding-config.d.ts +9 -0
- package/dist/app-runtime/lib/branding-config.d.ts.map +1 -0
- package/dist/app-runtime/lib/branding-config.js +24 -0
- package/dist/app-runtime/lib/branding-config.js.map +1 -0
- package/dist/app-runtime/lib/delegated-session.d.ts +15 -0
- package/dist/app-runtime/lib/delegated-session.d.ts.map +1 -0
- package/dist/app-runtime/lib/delegated-session.js +29 -0
- package/dist/app-runtime/lib/delegated-session.js.map +1 -0
- package/dist/app-runtime/lib/external-subject.d.ts +9 -0
- package/dist/app-runtime/lib/external-subject.d.ts.map +1 -0
- package/dist/app-runtime/lib/external-subject.js +19 -0
- package/dist/app-runtime/lib/external-subject.js.map +1 -0
- package/dist/connector/index.d.ts +9 -0
- package/dist/connector/index.d.ts.map +1 -0
- package/dist/connector/index.js +25 -0
- package/dist/connector/index.js.map +1 -0
- package/dist/connector/lib/adapter-kind.d.ts +8 -0
- package/dist/connector/lib/adapter-kind.d.ts.map +1 -0
- package/dist/connector/lib/adapter-kind.js +14 -0
- package/dist/connector/lib/adapter-kind.js.map +1 -0
- package/dist/connector/lib/capability-refs.d.ts +14 -0
- package/dist/connector/lib/capability-refs.d.ts.map +1 -0
- package/dist/connector/lib/capability-refs.js +15 -0
- package/dist/connector/lib/capability-refs.js.map +1 -0
- package/dist/connector/lib/capability.d.ts +18 -0
- package/dist/connector/lib/capability.d.ts.map +1 -0
- package/dist/connector/lib/capability.js +24 -0
- package/dist/connector/lib/capability.js.map +1 -0
- package/dist/connector/lib/credential-kind.d.ts +42 -0
- package/dist/connector/lib/credential-kind.d.ts.map +1 -0
- package/dist/connector/lib/credential-kind.js +26 -0
- package/dist/connector/lib/credential-kind.js.map +1 -0
- package/dist/connector/lib/envelope-schema.d.ts +6 -0
- package/dist/connector/lib/envelope-schema.d.ts.map +1 -0
- package/dist/connector/lib/envelope-schema.js +150 -0
- package/dist/connector/lib/envelope-schema.js.map +1 -0
- package/dist/connector/lib/filter-expr-schema.d.ts +4 -0
- package/dist/connector/lib/filter-expr-schema.d.ts.map +1 -0
- package/dist/connector/lib/filter-expr-schema.js +65 -0
- package/dist/connector/lib/filter-expr-schema.js.map +1 -0
- package/dist/connector/lib/filter-expr-validate.d.ts +10 -0
- package/dist/connector/lib/filter-expr-validate.d.ts.map +1 -0
- package/dist/connector/lib/filter-expr-validate.js +58 -0
- package/dist/connector/lib/filter-expr-validate.js.map +1 -0
- package/dist/connector/lib/filter-expr.d.ts +49 -0
- package/dist/connector/lib/filter-expr.d.ts.map +1 -0
- package/dist/connector/lib/filter-expr.js +135 -0
- package/dist/connector/lib/filter-expr.js.map +1 -0
- package/dist/connector/lib/onboarding-manifest.d.ts +45 -0
- package/dist/connector/lib/onboarding-manifest.d.ts.map +1 -0
- package/dist/connector/lib/onboarding-manifest.js +30 -0
- package/dist/connector/lib/onboarding-manifest.js.map +1 -0
- package/dist/document-render/index.d.ts +7 -0
- package/dist/document-render/index.d.ts.map +1 -0
- package/dist/document-render/index.js +23 -0
- package/dist/document-render/index.js.map +1 -0
- package/dist/document-render/lib/measure-layout.d.ts +44 -0
- package/dist/document-render/lib/measure-layout.d.ts.map +1 -0
- package/dist/document-render/lib/measure-layout.js +16 -0
- package/dist/document-render/lib/measure-layout.js.map +1 -0
- package/dist/document-render/lib/render-enums.d.ts +18 -0
- package/dist/document-render/lib/render-enums.d.ts.map +1 -0
- package/dist/document-render/lib/render-enums.js +24 -0
- package/dist/document-render/lib/render-enums.js.map +1 -0
- package/dist/document-render/lib/render-record.d.ts +22 -0
- package/dist/document-render/lib/render-record.d.ts.map +1 -0
- package/dist/document-render/lib/render-record.js +3 -0
- package/dist/document-render/lib/render-record.js.map +1 -0
- package/dist/document-render/lib/render-request.d.ts +24 -0
- package/dist/document-render/lib/render-request.d.ts.map +1 -0
- package/dist/document-render/lib/render-request.js +12 -0
- package/dist/document-render/lib/render-request.js.map +1 -0
- package/dist/document-render/lib/render-source.d.ts +43 -0
- package/dist/document-render/lib/render-source.d.ts.map +1 -0
- package/dist/document-render/lib/render-source.js +31 -0
- package/dist/document-render/lib/render-source.js.map +1 -0
- package/dist/document-render/lib/xema-prompt.d.ts +11 -0
- package/dist/document-render/lib/xema-prompt.d.ts.map +1 -0
- package/dist/document-render/lib/xema-prompt.js +46 -0
- package/dist/document-render/lib/xema-prompt.js.map +1 -0
- package/dist/inquiry/index.d.ts +7 -0
- package/dist/inquiry/index.d.ts.map +1 -0
- package/dist/inquiry/index.js +23 -0
- package/dist/inquiry/index.js.map +1 -0
- package/dist/inquiry/lib/enums.d.ts +36 -0
- package/dist/inquiry/lib/enums.d.ts.map +1 -0
- package/dist/inquiry/lib/enums.js +45 -0
- package/dist/inquiry/lib/enums.js.map +1 -0
- package/dist/inquiry/lib/inquiry.d.ts +332 -0
- package/dist/inquiry/lib/inquiry.d.ts.map +1 -0
- package/dist/inquiry/lib/inquiry.js +102 -0
- package/dist/inquiry/lib/inquiry.js.map +1 -0
- package/dist/inquiry/lib/kind-registry.d.ts +14 -0
- package/dist/inquiry/lib/kind-registry.d.ts.map +1 -0
- package/dist/inquiry/lib/kind-registry.js +24 -0
- package/dist/inquiry/lib/kind-registry.js.map +1 -0
- package/dist/inquiry/lib/policy.d.ts +19 -0
- package/dist/inquiry/lib/policy.d.ts.map +1 -0
- package/dist/inquiry/lib/policy.js +21 -0
- package/dist/inquiry/lib/policy.js.map +1 -0
- package/dist/inquiry/lib/recipient.d.ts +111 -0
- package/dist/inquiry/lib/recipient.d.ts.map +1 -0
- package/dist/inquiry/lib/recipient.js +64 -0
- package/dist/inquiry/lib/recipient.js.map +1 -0
- package/dist/inquiry/lib/workflow-verdict-evaluator.d.ts +15 -0
- package/dist/inquiry/lib/workflow-verdict-evaluator.d.ts.map +1 -0
- package/dist/inquiry/lib/workflow-verdict-evaluator.js +145 -0
- package/dist/inquiry/lib/workflow-verdict-evaluator.js.map +1 -0
- package/dist/org-database/index.d.ts +5 -0
- package/dist/org-database/index.d.ts.map +1 -0
- package/dist/org-database/index.js +21 -0
- package/dist/org-database/index.js.map +1 -0
- package/dist/org-database/lib/db-result-event.d.ts +24 -0
- package/dist/org-database/lib/db-result-event.d.ts.map +1 -0
- package/dist/org-database/lib/db-result-event.js +3 -0
- package/dist/org-database/lib/db-result-event.js.map +1 -0
- package/dist/org-database/lib/driver.d.ts +43 -0
- package/dist/org-database/lib/driver.d.ts.map +1 -0
- package/dist/org-database/lib/driver.js +3 -0
- package/dist/org-database/lib/driver.js.map +1 -0
- package/dist/org-database/lib/enums.d.ts +41 -0
- package/dist/org-database/lib/enums.d.ts.map +1 -0
- package/dist/org-database/lib/enums.js +51 -0
- package/dist/org-database/lib/enums.js.map +1 -0
- package/dist/org-database/lib/migration-runner.d.ts +15 -0
- package/dist/org-database/lib/migration-runner.d.ts.map +1 -0
- package/dist/org-database/lib/migration-runner.js +3 -0
- package/dist/org-database/lib/migration-runner.js.map +1 -0
- package/dist/project-kit/index.d.ts +2 -0
- package/dist/project-kit/index.d.ts.map +1 -0
- package/dist/project-kit/index.js +18 -0
- package/dist/project-kit/index.js.map +1 -0
- package/dist/project-kit/lib/project-kit.d.ts +63 -0
- package/dist/project-kit/lib/project-kit.d.ts.map +1 -0
- package/dist/project-kit/lib/project-kit.js +32 -0
- package/dist/project-kit/lib/project-kit.js.map +1 -0
- package/dist/provisioning/index.d.ts +2 -0
- package/dist/provisioning/index.d.ts.map +1 -0
- package/dist/provisioning/index.js +18 -0
- package/dist/provisioning/index.js.map +1 -0
- package/dist/provisioning/lib/provisioning.d.ts +256 -0
- package/dist/provisioning/lib/provisioning.d.ts.map +1 -0
- package/dist/provisioning/lib/provisioning.js +221 -0
- package/dist/provisioning/lib/provisioning.js.map +1 -0
- package/dist/worker-runtime/index.d.ts +6 -0
- package/dist/worker-runtime/index.d.ts.map +1 -0
- package/dist/worker-runtime/index.js +22 -0
- package/dist/worker-runtime/index.js.map +1 -0
- package/dist/worker-runtime/lib/capabilities.d.ts +22 -0
- package/dist/worker-runtime/lib/capabilities.d.ts.map +1 -0
- package/dist/worker-runtime/lib/capabilities.js +3 -0
- package/dist/worker-runtime/lib/capabilities.js.map +1 -0
- package/dist/worker-runtime/lib/enums.d.ts +10 -0
- package/dist/worker-runtime/lib/enums.d.ts.map +1 -0
- package/dist/worker-runtime/lib/enums.js +15 -0
- package/dist/worker-runtime/lib/enums.js.map +1 -0
- package/dist/worker-runtime/lib/messages.d.ts +33 -0
- package/dist/worker-runtime/lib/messages.d.ts.map +1 -0
- package/dist/worker-runtime/lib/messages.js +3 -0
- package/dist/worker-runtime/lib/messages.js.map +1 -0
- package/dist/worker-runtime/lib/runtime.d.ts +35 -0
- package/dist/worker-runtime/lib/runtime.d.ts.map +1 -0
- package/dist/worker-runtime/lib/runtime.js +3 -0
- package/dist/worker-runtime/lib/runtime.js.map +1 -0
- package/dist/worker-runtime/lib/schemas.d.ts +87 -0
- package/dist/worker-runtime/lib/schemas.d.ts.map +1 -0
- package/dist/worker-runtime/lib/schemas.js +57 -0
- package/dist/worker-runtime/lib/schemas.js.map +1 -0
- package/dist/workspace-storage/index.d.ts +4 -0
- package/dist/workspace-storage/index.d.ts.map +1 -0
- package/dist/workspace-storage/index.js +20 -0
- package/dist/workspace-storage/index.js.map +1 -0
- package/dist/workspace-storage/lib/enums.d.ts +34 -0
- package/dist/workspace-storage/lib/enums.d.ts.map +1 -0
- package/dist/workspace-storage/lib/enums.js +42 -0
- package/dist/workspace-storage/lib/enums.js.map +1 -0
- package/dist/workspace-storage/lib/schemas.d.ts +56 -0
- package/dist/workspace-storage/lib/schemas.d.ts.map +1 -0
- package/dist/workspace-storage/lib/schemas.js +59 -0
- package/dist/workspace-storage/lib/schemas.js.map +1 -0
- package/dist/workspace-storage/lib/types.d.ts +71 -0
- package/dist/workspace-storage/lib/types.d.ts.map +1 -0
- package/dist/workspace-storage/lib/types.js +3 -0
- package/dist/workspace-storage/lib/types.js.map +1 -0
- package/package.json +22 -153
- package/src/agent-composition/lib/composition-workspace.ts +1 -1
- package/src/agent-tool-inquiry/index.ts +16 -0
- package/src/agent-tool-inquiry/lib/agent-tool-inquiry.ts +82 -0
- package/src/agent-workspace/lib/workspace-spec.ts +1 -1
- package/src/app-runtime/index.ts +8 -0
- package/src/app-runtime/lib/app-client.ts +44 -0
- package/src/app-runtime/lib/app-lockfile.ts +54 -0
- package/src/app-runtime/lib/app.ts +84 -0
- package/src/app-runtime/lib/audience-policy.ts +87 -0
- package/src/app-runtime/lib/biome-install.ts +29 -0
- package/src/app-runtime/lib/branding-config.ts +54 -0
- package/src/app-runtime/lib/delegated-session.ts +69 -0
- package/src/app-runtime/lib/external-subject.ts +34 -0
- package/src/connector/index.ts +8 -0
- package/src/connector/lib/adapter-kind.ts +37 -0
- package/src/connector/lib/capability-refs.ts +29 -0
- package/src/connector/lib/capability.ts +38 -0
- package/src/connector/lib/credential-kind.ts +120 -0
- package/src/connector/lib/envelope-schema.ts +256 -0
- package/src/connector/lib/filter-expr-schema.ts +75 -0
- package/src/connector/lib/filter-expr-validate.ts +91 -0
- package/src/connector/lib/filter-expr.ts +208 -0
- package/src/connector/lib/onboarding-manifest.ts +167 -0
- package/src/document-render/index.ts +25 -0
- package/src/document-render/lib/measure-layout.ts +61 -0
- package/src/document-render/lib/render-enums.ts +49 -0
- package/src/document-render/lib/render-record.ts +38 -0
- package/src/document-render/lib/render-request.ts +16 -0
- package/src/document-render/lib/render-source.ts +44 -0
- package/src/document-render/lib/xema-prompt.ts +100 -0
- package/src/inquiry/index.ts +23 -0
- package/src/inquiry/lib/enums.ts +103 -0
- package/src/inquiry/lib/inquiry.ts +182 -0
- package/src/inquiry/lib/kind-registry.ts +57 -0
- package/src/inquiry/lib/policy.ts +27 -0
- package/src/inquiry/lib/recipient.ts +188 -0
- package/src/inquiry/lib/workflow-verdict-evaluator.ts +220 -0
- package/src/org-database/index.ts +4 -0
- package/src/org-database/lib/db-result-event.ts +59 -0
- package/src/org-database/lib/driver.ts +47 -0
- package/src/org-database/lib/enums.ts +51 -0
- package/src/org-database/lib/migration-runner.ts +17 -0
- package/src/project-kit/index.ts +17 -0
- package/src/project-kit/lib/project-kit.ts +227 -0
- package/src/provisioning/index.ts +17 -0
- package/src/provisioning/lib/provisioning.ts +499 -0
- package/src/worker-runtime/index.ts +14 -0
- package/src/worker-runtime/lib/capabilities.ts +58 -0
- package/src/worker-runtime/lib/enums.ts +33 -0
- package/src/worker-runtime/lib/messages.ts +49 -0
- package/src/worker-runtime/lib/runtime.ts +109 -0
- package/src/worker-runtime/lib/schemas.ts +72 -0
- package/src/workflow/lib/activity-outputs.ts +1 -1
- package/src/workflow/lib/compiled-run.ts +1 -1
- package/src/workflow/lib/compiled-workspace-manifest.ts +1 -1
- package/src/workflow/lib/model-ref.ts +1 -1
- package/src/workflow/lib/workspace-manifest-enums.ts +1 -1
- package/src/workspace-storage/index.ts +12 -0
- package/src/workspace-storage/lib/enums.ts +78 -0
- package/src/workspace-storage/lib/schemas.ts +75 -0
- 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 };
|