@drisp/protocol 0.8.4 → 0.8.6

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/dist/v2.d.ts CHANGED
@@ -18,14 +18,78 @@ declare function classOfCap(declaredCap: number): SizeClass;
18
18
  /** What a Run declaring `declaredCap` is expected to use: its class's forecast. */
19
19
  declare function forecastOfCap(declaredCap: number): number;
20
20
  /**
21
- * What one attempt holds against the budget: a closed attempt (finished, failed, cancelled) its forecast, never more
22
- * than its own declared cap (so the rule stays looser than the cap sum it replaces); a running or queued one still its
23
- * declared cap. A closed attempt whose cap is no positive number counts its forecast.
21
+ * What an attempt declaring `declaredCap` is expected to use: its class's forecast, never more than its own cap (so
22
+ * the rule stays looser than the cap sum it replaces). A cap that is no positive number counts the `S` forecast.
24
23
  */
25
- declare function attemptCost(attempt: {
24
+ declare function attemptForecast(declaredCap: number): number;
25
+ /**
26
+ * One attempt of a child: its declared cap, whether it has closed, and the counted tokens it reported, if any. No
27
+ * caller passes `spent` yet: the CLI and the Hub count forecasts until reported usage feeds the rule (DRI-246).
28
+ */
29
+ type BudgetAttempt = {
26
30
  tokenCap: number;
27
31
  closed: boolean;
28
- }): number;
32
+ spent?: number;
33
+ };
34
+ /**
35
+ * What one attempt holds against the budget: a closed attempt (finished, failed, cancelled) what it reported, else its
36
+ * forecast; a running or queued one the larger of its forecast and what it reported, so a resumed attempt never counts
37
+ * the same tokens twice and an overrun counts once reported.
38
+ */
39
+ declare function attemptCost(attempt: BudgetAttempt): number;
40
+ /**
41
+ * The budget rule the CLI and the Hub share (root ADR-0011). `used` is the sum over every attempt of every child, a
42
+ * retry being a new attempt; the next start, forecast at `next`, fits when `used + next` is within the budget. Issues
43
+ * not yet started never enter it: the app warns of them on the plan sheet (Kit `shortfallNote`) and nothing parks.
44
+ */
45
+ declare function budgetCheck(input: {
46
+ tokenBudget: number;
47
+ attempts: readonly BudgetAttempt[];
48
+ next: number;
49
+ }): {
50
+ used: number;
51
+ fits: boolean;
52
+ };
53
+ /** A class needs this many finished Runs of a harness before its forecast is measured (DRI-244). */
54
+ declare const CALIBRATION_MIN_RUNS = 10;
55
+ /** Only Runs closed within this many days count. */
56
+ declare const CALIBRATION_WINDOW_DAYS = 90;
57
+ /** What one size class measured to: the figure the plan uses, and how many finished Runs it rests on. */
58
+ type ClassCalibration = Readonly<Partial<Record<SizeClass, {
59
+ forecast: number;
60
+ runs: number;
61
+ }>>>;
62
+ /** The measured classes per harness name; a harness or class with too few Runs is absent. */
63
+ type Calibration = Readonly<Partial<Record<string, ClassCalibration>>>;
64
+ /** One finished Run's final counted tokens (cache reads excluded), by its harness and the class its cap belongs to. */
65
+ type CalibrationSample = {
66
+ harness: string;
67
+ sizeClass: SizeClass;
68
+ counted: number | undefined;
69
+ };
70
+ /**
71
+ * The forecast of each class and harness with at least `CALIBRATION_MIN_RUNS` samples: max(constant, p90 of the
72
+ * samples), the p90 by nearest rank. The constants are the floor, so calibration only raises a forecast. A sample with
73
+ * no figure is ignored. Which Runs are samples (completed, first attempt, in the window) is the Hub's to say.
74
+ */
75
+ declare function calibrate(samples: readonly CalibrationSample[]): Calibration;
76
+ /** `GET /calibration`: the measured classes per harness name. */
77
+ declare const calibrationSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
78
+ S: z.ZodOptional<z.ZodObject<{
79
+ forecast: z.ZodNumber;
80
+ runs: z.ZodNumber;
81
+ }, z.core.$strict>>;
82
+ M: z.ZodOptional<z.ZodObject<{
83
+ forecast: z.ZodNumber;
84
+ runs: z.ZodNumber;
85
+ }, z.core.$strict>>;
86
+ L: z.ZodOptional<z.ZodObject<{
87
+ forecast: z.ZodNumber;
88
+ runs: z.ZodNumber;
89
+ }, z.core.$strict>>;
90
+ }, z.core.$strict>>;
91
+ /** A class's forecast: its measured figure when `calibration` has one, else the constant. */
92
+ declare function forecastOfClass(sizeClass: SizeClass, calibration: ClassCalibration | undefined): number;
29
93
 
30
94
  declare const protocolVersion: {
31
95
  readonly major: 2;
@@ -495,6 +559,10 @@ declare const commandSchema: z.ZodObject<{
495
559
  kind: z.ZodLiteral<"resume">;
496
560
  interruptionId: z.ZodString;
497
561
  guidance: z.ZodOptional<z.ZodString>;
562
+ }, z.core.$strict>, z.ZodObject<{
563
+ kind: z.ZodLiteral<"setBudget">;
564
+ tokenBudget: z.ZodNumber;
565
+ resume: z.ZodOptional<z.ZodBoolean>;
498
566
  }, z.core.$strict>], "kind">;
499
567
  }, z.core.$strict>;
500
568
  declare const grantSchema: z.ZodObject<{
@@ -935,6 +1003,10 @@ declare const runViewSchema: z.ZodObject<{
935
1003
  kind: z.ZodLiteral<"resume">;
936
1004
  interruptionId: z.ZodString;
937
1005
  guidance: z.ZodOptional<z.ZodString>;
1006
+ }, z.core.$strict>, z.ZodObject<{
1007
+ kind: z.ZodLiteral<"setBudget">;
1008
+ tokenBudget: z.ZodNumber;
1009
+ resume: z.ZodOptional<z.ZodBoolean>;
938
1010
  }, z.core.$strict>], "kind">>;
939
1011
  runnerStopped: z.ZodOptional<z.ZodBoolean>;
940
1012
  canAbandon: z.ZodOptional<z.ZodBoolean>;
@@ -1030,6 +1102,10 @@ declare const clientFrameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1030
1102
  kind: z.ZodLiteral<"resume">;
1031
1103
  interruptionId: z.ZodString;
1032
1104
  guidance: z.ZodOptional<z.ZodString>;
1105
+ }, z.core.$strict>, z.ZodObject<{
1106
+ kind: z.ZodLiteral<"setBudget">;
1107
+ tokenBudget: z.ZodNumber;
1108
+ resume: z.ZodOptional<z.ZodBoolean>;
1033
1109
  }, z.core.$strict>], "kind">;
1034
1110
  }, z.core.$strict>;
1035
1111
  }, z.core.$strict>, z.ZodObject<{
@@ -1476,4 +1552,4 @@ type ConnectPendingResponse = z.infer<typeof connectPendingResponseSchema>;
1476
1552
  type TeamDefault = z.infer<typeof teamDefaultSchema>;
1477
1553
  type RunsGoTo = z.infer<typeof runsGoToSchema>;
1478
1554
 
1479
- export { type Audience, type BuildCloseReason, type Checkpoint, type Command, type ConnectAlreadyConnected, type ConnectPendingResponse, type ConnectRedeemRequest, type ConnectRedeemResponse, type ConnectStartRequest, type ConnectStartResponse, type ControlRecord, type Delegation, type ExecutionFact, type Grant, type Harness, type HarnessReadiness, type HistoryRecord, type InstalledWorkflow, type RepositoryBinding, type RepositorySource, type RunCloseReason, type RunParent, type RunUsage, type RunView, type RunnerAdoptRequest, type RunnerDisconnectPreview, type RunnerDisconnectResponse, type RunnerFrame, type RunnerList, type RunnerListEntry, type RunnerReadiness, type RunsGoTo, SIZE_CLASS_CAPS, SIZE_CLASS_FORECASTS, type Scope, type SizeClass, type TeamDefault, type WorkflowIdentity, type WorkflowInstallReference, type WorkflowReference, abandonedConversationContinuationCapability, attemptCost, audienceSchema, buildCloseReasonSchema, canonicalJson, checkpointPathSchema, checkpointSchema, classOfCap, clientFrameSchema, commandSchema, connectAlreadyConnectedSchema, connectApproveRequestSchema, connectCodeAlphabet, connectCodeRequestSchema, connectCodeResponseSchema, connectCodeSchema, connectDenyRequestSchema, connectPendingResponseSchema, connectPollRequestSchema, connectRedeemRequestSchema, connectRedeemResponseSchema, connectStartRequestSchema, connectStartResponseSchema, controlRecordSchema, conversationContinuationCapability, delegationSchema, delegationTokenPrefix, forecastOfCap, grantSchema, harnessReadinessSchema, harnessSchema, historyRecordSchema, hubEpochRequestSchema, installReference, installedWorkflowsSchema, interruptionSchema, permissionAnswerSchema, protocolVersion, readableHistory, readinessFixCommand, repositoryAccessCapability, repositoryBindingSchema, repositoryRefSchema, repositorySourceSchema, repositoryWorkingDirectorySchema, runArtifactMaxBytes, runArtifactNameSchema, runCloseReasonSchema, runDelegationCapability, runKeySchema, runParentIntentSchema, runParentSchema, runSpecSchema, runUsageCapability, runUsageSchema, runViewSchema, runnerAdoptRequestSchema, runnerDisconnectPreviewSchema, runnerDisconnectRequestSchema, runnerDisconnectResponseSchema, runnerFrameSchema, runnerListEntrySchema, runnerListSchema, runnerReadinessSchema, runnerUpdateCommand, runnerUpdateRequestSchema, runsGoToSchema, sameWorkflow, scopeSchema, secretEnvironmentSchema, sequence, teamDefaultRequestSchema, teamDefaultSchema, workflowIdentitySchema, workflowInstallCapability, workflowName, workflowReferenceSchema, workflowSourceSchema };
1555
+ export { type Audience, type BudgetAttempt, type BuildCloseReason, CALIBRATION_MIN_RUNS, CALIBRATION_WINDOW_DAYS, type Calibration, type CalibrationSample, type Checkpoint, type ClassCalibration, type Command, type ConnectAlreadyConnected, type ConnectPendingResponse, type ConnectRedeemRequest, type ConnectRedeemResponse, type ConnectStartRequest, type ConnectStartResponse, type ControlRecord, type Delegation, type ExecutionFact, type Grant, type Harness, type HarnessReadiness, type HistoryRecord, type InstalledWorkflow, type RepositoryBinding, type RepositorySource, type RunCloseReason, type RunParent, type RunUsage, type RunView, type RunnerAdoptRequest, type RunnerDisconnectPreview, type RunnerDisconnectResponse, type RunnerFrame, type RunnerList, type RunnerListEntry, type RunnerReadiness, type RunsGoTo, SIZE_CLASS_CAPS, SIZE_CLASS_FORECASTS, type Scope, type SizeClass, type TeamDefault, type WorkflowIdentity, type WorkflowInstallReference, type WorkflowReference, abandonedConversationContinuationCapability, attemptCost, attemptForecast, audienceSchema, budgetCheck, buildCloseReasonSchema, calibrate, calibrationSchema, canonicalJson, checkpointPathSchema, checkpointSchema, classOfCap, clientFrameSchema, commandSchema, connectAlreadyConnectedSchema, connectApproveRequestSchema, connectCodeAlphabet, connectCodeRequestSchema, connectCodeResponseSchema, connectCodeSchema, connectDenyRequestSchema, connectPendingResponseSchema, connectPollRequestSchema, connectRedeemRequestSchema, connectRedeemResponseSchema, connectStartRequestSchema, connectStartResponseSchema, controlRecordSchema, conversationContinuationCapability, delegationSchema, delegationTokenPrefix, forecastOfCap, forecastOfClass, grantSchema, harnessReadinessSchema, harnessSchema, historyRecordSchema, hubEpochRequestSchema, installReference, installedWorkflowsSchema, interruptionSchema, permissionAnswerSchema, protocolVersion, readableHistory, readinessFixCommand, repositoryAccessCapability, repositoryBindingSchema, repositoryRefSchema, repositorySourceSchema, repositoryWorkingDirectorySchema, runArtifactMaxBytes, runArtifactNameSchema, runCloseReasonSchema, runDelegationCapability, runKeySchema, runParentIntentSchema, runParentSchema, runSpecSchema, runUsageCapability, runUsageSchema, runViewSchema, runnerAdoptRequestSchema, runnerDisconnectPreviewSchema, runnerDisconnectRequestSchema, runnerDisconnectResponseSchema, runnerFrameSchema, runnerListEntrySchema, runnerListSchema, runnerReadinessSchema, runnerUpdateCommand, runnerUpdateRequestSchema, runsGoToSchema, sameWorkflow, scopeSchema, secretEnvironmentSchema, sequence, teamDefaultRequestSchema, teamDefaultSchema, workflowIdentitySchema, workflowInstallCapability, workflowName, workflowReferenceSchema, workflowSourceSchema };
package/dist/v2.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-HMYWICNI.js";
4
4
 
5
5
  // src/v2.ts
6
- import { z } from "zod";
6
+ import { z as z2 } from "zod";
7
7
 
8
8
  // src/history.ts
9
9
  function readableHistory(records) {
@@ -48,6 +48,7 @@ function readableHistory(records) {
48
48
  }
49
49
 
50
50
  // src/budget.ts
51
+ import { z } from "zod";
51
52
  var SIZE_CLASS_CAPS = {
52
53
  S: 3e6,
53
54
  M: 6e6,
@@ -66,10 +67,47 @@ function classOfCap(declaredCap) {
66
67
  function forecastOfCap(declaredCap) {
67
68
  return SIZE_CLASS_FORECASTS[classOfCap(declaredCap)];
68
69
  }
70
+ function attemptForecast(declaredCap) {
71
+ const forecast = forecastOfCap(declaredCap);
72
+ return declaredCap > 0 ? Math.min(declaredCap, forecast) : forecast;
73
+ }
69
74
  function attemptCost(attempt) {
70
- if (!attempt.closed) return attempt.tokenCap;
71
- const forecast = forecastOfCap(attempt.tokenCap);
72
- return attempt.tokenCap > 0 ? Math.min(attempt.tokenCap, forecast) : forecast;
75
+ const forecast = attemptForecast(attempt.tokenCap);
76
+ if (attempt.closed) return attempt.spent ?? forecast;
77
+ return Math.max(forecast, attempt.spent ?? 0);
78
+ }
79
+ function budgetCheck(input) {
80
+ const used = input.attempts.reduce((sum, attempt) => sum + attemptCost(attempt), 0);
81
+ return { used, fits: used + input.next <= input.tokenBudget };
82
+ }
83
+ var CALIBRATION_MIN_RUNS = 10;
84
+ var CALIBRATION_WINDOW_DAYS = 90;
85
+ function calibrate(samples) {
86
+ const byKey = /* @__PURE__ */ new Map();
87
+ for (const { harness, sizeClass, counted } of samples) {
88
+ if (counted === void 0 || !Number.isFinite(counted) || counted < 0) continue;
89
+ const key = `${harness}\0${sizeClass}`;
90
+ const group = byKey.get(key) ?? { harness, sizeClass, counted: [] };
91
+ group.counted.push(counted);
92
+ byKey.set(key, group);
93
+ }
94
+ const result = {};
95
+ for (const { harness, sizeClass, counted } of byKey.values()) {
96
+ if (counted.length < CALIBRATION_MIN_RUNS) continue;
97
+ const sorted = [...counted].sort((a, b) => a - b);
98
+ const p90 = sorted[Math.ceil(sorted.length * 0.9) - 1];
99
+ (result[harness] ??= {})[sizeClass] = { forecast: Math.max(SIZE_CLASS_FORECASTS[sizeClass], p90), runs: sorted.length };
100
+ }
101
+ return result;
102
+ }
103
+ var classCalibrationSchema = z.strictObject({
104
+ S: z.strictObject({ forecast: z.number(), runs: z.number() }).optional(),
105
+ M: z.strictObject({ forecast: z.number(), runs: z.number() }).optional(),
106
+ L: z.strictObject({ forecast: z.number(), runs: z.number() }).optional()
107
+ });
108
+ var calibrationSchema = z.record(z.string(), classCalibrationSchema);
109
+ function forecastOfClass(sizeClass, calibration) {
110
+ return calibration?.[sizeClass]?.forecast ?? SIZE_CLASS_FORECASTS[sizeClass];
73
111
  }
74
112
 
75
113
  // src/v2.ts
@@ -81,29 +119,29 @@ var workflowInstallCapability = "workflow_install_v1";
81
119
  var runDelegationCapability = "run_delegation_v1";
82
120
  var runUsageCapability = "run_usage_v1";
83
121
  var delegationTokenPrefix = "drisp_dlg_";
84
- var runArtifactNameSchema = z.string().regex(/^[a-z][a-z0-9_]{0,63}$/);
122
+ var runArtifactNameSchema = z2.string().regex(/^[a-z][a-z0-9_]{0,63}$/);
85
123
  var runArtifactMaxBytes = 64 * 1024;
86
- var secretEnvironmentSchema = z.record(
87
- z.string().regex(/^(?:OPENAI_API_KEY|ANTHROPIC_API_KEY|CLAUDE_CODE_OAUTH_TOKEN|NPM_TOKEN|NODE_AUTH_TOKEN|PIP_INDEX_URL|PIP_EXTRA_INDEX_URL|UV_INDEX_URL|DRISP_TEST_[A-Z0-9_]+)$/),
88
- z.string().regex(/^projects\/[a-zA-Z0-9-]+\/secrets\/[a-zA-Z0-9_-]+\/versions\/(?:latest|[0-9]+)$/)
124
+ var secretEnvironmentSchema = z2.record(
125
+ z2.string().regex(/^(?:OPENAI_API_KEY|ANTHROPIC_API_KEY|CLAUDE_CODE_OAUTH_TOKEN|NPM_TOKEN|NODE_AUTH_TOKEN|PIP_INDEX_URL|PIP_EXTRA_INDEX_URL|UV_INDEX_URL|DRISP_TEST_[A-Z0-9_]+)$/),
126
+ z2.string().regex(/^projects\/[a-zA-Z0-9-]+\/secrets\/[a-zA-Z0-9_-]+\/versions\/(?:latest|[0-9]+)$/)
89
127
  );
90
- var permissionAnswerSchema = z.strictObject({
91
- kind: z.literal("permission"),
92
- decision: z.enum(["allow", "deny"]),
93
- reason: z.string().max(4096).optional()
128
+ var permissionAnswerSchema = z2.strictObject({
129
+ kind: z2.literal("permission"),
130
+ decision: z2.enum(["allow", "deny"]),
131
+ reason: z2.string().max(4096).optional()
94
132
  });
95
- var id = z.string().min(1).max(160);
96
- var sequence = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
133
+ var id = z2.string().min(1).max(160);
134
+ var sequence = z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
97
135
  var positive = sequence.refine((n) => n > 0);
98
- var timestamp = z.iso.datetime();
99
- var scopeSchema = z.discriminatedUnion("visibility", [
100
- z.strictObject({ visibility: z.literal("organization") }),
101
- z.strictObject({ visibility: z.literal("private"), ownerUserId: id })
136
+ var timestamp = z2.iso.datetime();
137
+ var scopeSchema = z2.discriminatedUnion("visibility", [
138
+ z2.strictObject({ visibility: z2.literal("organization") }),
139
+ z2.strictObject({ visibility: z2.literal("private"), ownerUserId: id })
102
140
  ]);
103
- var installedWorkflowsSchema = z.array(InstalledWorkflowSchema).max(256);
104
- var harnessSchema = z.enum(["claude-code", "codex"]);
105
- var harnessReadinessSchema = z.strictObject({ installed: z.boolean(), signedIn: z.boolean() });
106
- var runnerReadinessSchema = z.strictObject({
141
+ var installedWorkflowsSchema = z2.array(InstalledWorkflowSchema).max(256);
142
+ var harnessSchema = z2.enum(["claude-code", "codex"]);
143
+ var harnessReadinessSchema = z2.strictObject({ installed: z2.boolean(), signedIn: z2.boolean() });
144
+ var runnerReadinessSchema = z2.strictObject({
107
145
  "claude-code": harnessReadinessSchema.optional(),
108
146
  codex: harnessReadinessSchema.optional()
109
147
  });
@@ -118,25 +156,25 @@ function readinessFixCommand(harness, readiness) {
118
156
  return void 0;
119
157
  }
120
158
  var runnerUpdateCommand = "npm i -g @drisp/cli";
121
- var interruptionSchema = z.strictObject({
159
+ var interruptionSchema = z2.strictObject({
122
160
  interruptionId: id,
123
161
  revision: positive,
124
162
  /** `waiting` (root ADR-0008) is non-human: a Run parked until one of its children closes or parks. */
125
- kind: z.enum(["permission", "question", "guidance", "recovery", "waiting"]),
126
- message: z.string().max(16384),
163
+ kind: z2.enum(["permission", "question", "guidance", "recovery", "waiting"]),
164
+ message: z2.string().max(16384),
127
165
  requestId: id.optional()
128
166
  });
129
- var workflowIdentitySchema = z.strictObject({
130
- name: z.string().min(1).max(128),
131
- version: z.string().min(1).max(128).optional()
167
+ var workflowIdentitySchema = z2.strictObject({
168
+ name: z2.string().min(1).max(128),
169
+ version: z2.string().min(1).max(128).optional()
132
170
  });
133
- var buildCloseReasonSchema = z.enum([
171
+ var buildCloseReasonSchema = z2.enum([
134
172
  "workflow_template_mismatch",
135
173
  "child_project_dir_invalid",
136
174
  "build_not_approved",
137
175
  "approval_question_missing"
138
176
  ]);
139
- var runCloseReasonSchema = z.enum([
177
+ var runCloseReasonSchema = z2.enum([
140
178
  "execution_terminal",
141
179
  "cancelled_before_start",
142
180
  "admission_failed",
@@ -159,48 +197,48 @@ var factIdentity = {
159
197
  executionRevision: positive,
160
198
  emittedAt: timestamp
161
199
  };
162
- var runUsageSchema = z.strictObject({ counted: sequence, cacheRead: sequence });
200
+ var runUsageSchema = z2.strictObject({ counted: sequence, cacheRead: sequence });
163
201
  var reportedUsage = { usage: runUsageSchema.optional() };
164
- var controlRecordSchema = z.discriminatedUnion("kind", [
202
+ var controlRecordSchema = z2.discriminatedUnion("kind", [
165
203
  /** Instance-scoped, not tied to a Run: the full replacement inventory of installed Workflows. */
166
- z.strictObject({ kind: z.literal("workflows.changed"), workflows: installedWorkflowsSchema }),
204
+ z2.strictObject({ kind: z2.literal("workflows.changed"), workflows: installedWorkflowsSchema }),
167
205
  /** Instance-scoped, not tied to a Run: the Runner's full Readiness, sent when it changes after hello. */
168
- z.strictObject({ kind: z.literal("readiness.changed"), readiness: runnerReadinessSchema }),
169
- z.strictObject({ kind: z.literal("assignment.accepted"), runId: id, attemptId: id }),
170
- z.strictObject({
171
- kind: z.literal("assignment.rejected"),
206
+ z2.strictObject({ kind: z2.literal("readiness.changed"), readiness: runnerReadinessSchema }),
207
+ z2.strictObject({ kind: z2.literal("assignment.accepted"), runId: id, attemptId: id }),
208
+ z2.strictObject({
209
+ kind: z2.literal("assignment.rejected"),
172
210
  runId: id,
173
211
  attemptId: id,
174
- reason: z.string().max(1024)
212
+ reason: z2.string().max(1024)
175
213
  }),
176
- z.strictObject({
177
- kind: z.literal("run.started"),
214
+ z2.strictObject({
215
+ kind: z2.literal("run.started"),
178
216
  ...factIdentity,
179
217
  /** Absent from runners that predate Workflow reporting. */
180
218
  workflow: workflowIdentitySchema.optional()
181
219
  }),
182
- z.strictObject({ kind: z.literal("run.resumed"), ...factIdentity }),
183
- z.strictObject({
184
- kind: z.literal("run.attention"),
220
+ z2.strictObject({ kind: z2.literal("run.resumed"), ...factIdentity }),
221
+ z2.strictObject({
222
+ kind: z2.literal("run.attention"),
185
223
  ...factIdentity,
186
224
  interruption: interruptionSchema,
187
- occupancy: z.enum(["held", "released"]),
225
+ occupancy: z2.enum(["held", "released"]),
188
226
  historyThrough: sequence,
189
- continuation: z.discriminatedUnion("kind", [
190
- z.strictObject({ kind: z.literal("live_request") }),
191
- z.strictObject({ kind: z.literal("local_checkpoint"), checkpointId: id }),
192
- z.strictObject({ kind: z.literal("portable_checkpoint"), checkpointId: id }),
193
- z.strictObject({ kind: z.literal("repair_required"), detail: z.string().max(4096) })
227
+ continuation: z2.discriminatedUnion("kind", [
228
+ z2.strictObject({ kind: z2.literal("live_request") }),
229
+ z2.strictObject({ kind: z2.literal("local_checkpoint"), checkpointId: id }),
230
+ z2.strictObject({ kind: z2.literal("portable_checkpoint"), checkpointId: id }),
231
+ z2.strictObject({ kind: z2.literal("repair_required"), detail: z2.string().max(4096) })
194
232
  ]),
195
233
  ...reportedUsage
196
234
  }),
197
- z.strictObject({
198
- kind: z.literal("run.finished"),
235
+ z2.strictObject({
236
+ kind: z2.literal("run.finished"),
199
237
  ...factIdentity,
200
- status: z.enum(["completed", "failed", "cancelled"]),
238
+ status: z2.enum(["completed", "failed", "cancelled"]),
201
239
  historyThrough: sequence,
202
240
  /** No setup/harness executed and no workspace was produced; safe to retire without export. */
203
- workspaceUnavailable: z.literal(true).optional(),
241
+ workspaceUnavailable: z2.literal(true).optional(),
204
242
  /**
205
243
  * Why a Build Run failed, as its close reason (docs/specs/build-orchestrator.md). Sent only for a grant with
206
244
  * `parent` or `delegationToken`, which only a Hub that knows this field issues.
@@ -212,85 +250,85 @@ var controlRecordSchema = z.discriminatedUnion("kind", [
212
250
  * The usage of a Run while it executes, for a grant marked `reportUsage`. Not an execution fact: it carries no
213
251
  * execution revision, so it never advances, parks or closes the Run, and never wakes its parent.
214
252
  */
215
- z.strictObject({ kind: z.literal("run.usage"), runId: id, attemptId: id, ...runUsageSchema.shape }),
216
- z.strictObject({ kind: z.literal("command.applied"), runId: id, attemptId: id, commandId: id }),
217
- z.strictObject({
218
- kind: z.literal("command.rejected"),
253
+ z2.strictObject({ kind: z2.literal("run.usage"), runId: id, attemptId: id, ...runUsageSchema.shape }),
254
+ z2.strictObject({ kind: z2.literal("command.applied"), runId: id, attemptId: id, commandId: id }),
255
+ z2.strictObject({
256
+ kind: z2.literal("command.rejected"),
219
257
  runId: id,
220
258
  attemptId: id,
221
259
  commandId: id,
222
- reason: z.string().max(1024)
260
+ reason: z2.string().max(1024)
223
261
  }),
224
- z.strictObject({ kind: z.literal("revoked_not_started"), runId: id, attemptId: id })
262
+ z2.strictObject({ kind: z2.literal("revoked_not_started"), runId: id, attemptId: id })
225
263
  ]);
226
- var repositoryRefSchema = z.string().min(1).max(512).regex(
264
+ var repositoryRefSchema = z2.string().min(1).max(512).regex(
227
265
  /^(?![-/])(?!.*\.\.)(?!.*@\{)(?!.*(?:^|\/)\.)(?!.*\.lock(?:\/|$))(?!.*\/\/)[^\x00-\x20\x7f~^:?*\[\\]+(?<![/.])$/
228
266
  );
229
- var repositoryWorkingDirectorySchema = z.string().min(1).max(1024).regex(
267
+ var repositoryWorkingDirectorySchema = z2.string().min(1).max(1024).regex(
230
268
  /^(?:\.|(?!\/)(?!.*(?:^|\/)\.\.?(?:\/|$))(?!.*(?:^|\/)\.git(?:\/|$))[^\x00-\x1f\x7f\\:]+(?<!\/))$/
231
269
  );
232
270
  var repositoryIdentity = {
233
- repositoryId: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
234
- installationId: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
235
- owner: z.string().min(1).max(100).regex(/^[a-zA-Z0-9][a-zA-Z0-9-]*$/),
236
- name: z.string().min(1).max(100).regex(/^(?!\.{1,2}$)[a-zA-Z0-9_.-]+$/)
271
+ repositoryId: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
272
+ installationId: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
273
+ owner: z2.string().min(1).max(100).regex(/^[a-zA-Z0-9][a-zA-Z0-9-]*$/),
274
+ name: z2.string().min(1).max(100).regex(/^(?!\.{1,2}$)[a-zA-Z0-9_.-]+$/)
237
275
  };
238
- var repositoryBindingSchema = z.strictObject({
276
+ var repositoryBindingSchema = z2.strictObject({
239
277
  id,
240
- label: z.string().min(1).max(160),
278
+ label: z2.string().min(1).max(160),
241
279
  ...repositoryIdentity,
242
280
  defaultRef: repositoryRefSchema,
243
281
  workingDirectory: repositoryWorkingDirectorySchema,
244
- setupCommands: z.array(z.string().min(1).max(8192)).max(16),
282
+ setupCommands: z2.array(z2.string().min(1).max(8192)).max(16),
245
283
  revision: positive,
246
- enabled: z.boolean()
284
+ enabled: z2.boolean()
247
285
  });
248
- var repositorySourceSchema = z.strictObject({
286
+ var repositorySourceSchema = z2.strictObject({
249
287
  bindingId: id,
250
288
  ...repositoryIdentity,
251
289
  ref: repositoryRefSchema,
252
- commitSha: z.string().regex(/^[0-9a-f]{40}$/),
290
+ commitSha: z2.string().regex(/^[0-9a-f]{40}$/),
253
291
  branch: repositoryRefSchema,
254
292
  workingDirectory: repositoryWorkingDirectorySchema,
255
- setupCommands: z.array(z.string().min(1).max(8192)).max(16),
293
+ setupCommands: z2.array(z2.string().min(1).max(8192)).max(16),
256
294
  configRevision: positive
257
295
  });
258
- var workflowSourceSchema = z.string().max(201).regex(/^[A-Za-z0-9][A-Za-z0-9_.-]*\/[A-Za-z0-9][A-Za-z0-9_.-]*$/);
259
- var workflowReferenceSchema = z.union([
260
- z.string().max(512),
261
- z.strictObject({
262
- name: z.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*$/),
296
+ var workflowSourceSchema = z2.string().max(201).regex(/^[A-Za-z0-9][A-Za-z0-9_.-]*\/[A-Za-z0-9][A-Za-z0-9_.-]*$/);
297
+ var workflowReferenceSchema = z2.union([
298
+ z2.string().max(512),
299
+ z2.strictObject({
300
+ name: z2.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*$/),
263
301
  source: workflowSourceSchema.optional(),
264
- ref: z.string().min(1).max(512).optional(),
265
- version: z.string().min(1).max(128).regex(/^\d[A-Za-z0-9_.+-]*$/).optional()
302
+ ref: z2.string().min(1).max(512).optional(),
303
+ version: z2.string().min(1).max(128).regex(/^\d[A-Za-z0-9_.+-]*$/).optional()
266
304
  })
267
305
  ]);
268
306
  var workflowName = (workflow) => typeof workflow === "object" ? workflow.name : workflow;
269
307
  var installReference = (workflow) => typeof workflow === "object" && workflow.source !== void 0 ? workflow : void 0;
270
308
  var sameWorkflow = (a, b) => canonicalJson(a ?? null) === canonicalJson(b ?? null);
271
- var runSpecSchema = z.strictObject({
272
- prompt: z.string().min(1).max(131072),
273
- projectDir: z.string().min(1).max(4096),
309
+ var runSpecSchema = z2.strictObject({
310
+ prompt: z2.string().min(1).max(131072),
311
+ projectDir: z2.string().min(1).max(4096),
274
312
  harness: harnessSchema,
275
313
  workflow: workflowReferenceSchema.optional(),
276
314
  repository: repositorySourceSchema.optional()
277
315
  });
278
- var runKeySchema = z.string().min(1).max(160);
279
- var delegationSchema = z.strictObject({
280
- maxChildren: z.number().int().min(1).max(8),
281
- tokenBudget: z.number().int().positive().max(Number.MAX_SAFE_INTEGER)
316
+ var runKeySchema = z2.string().min(1).max(160);
317
+ var delegationSchema = z2.strictObject({
318
+ maxChildren: z2.number().int().min(1).max(8),
319
+ tokenBudget: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER)
282
320
  });
283
- var tokenCapSchema = z.number().int().positive().max(Number.MAX_SAFE_INTEGER);
284
- var runParentIntentSchema = z.strictObject({ runId: id, tokenCap: tokenCapSchema.optional() });
285
- var runParentSchema = z.strictObject({ runId: id, tokenCap: tokenCapSchema });
286
- var commandSchema = z.strictObject({
321
+ var tokenCapSchema = z2.number().int().positive().max(Number.MAX_SAFE_INTEGER);
322
+ var runParentIntentSchema = z2.strictObject({ runId: id, tokenCap: tokenCapSchema.optional() });
323
+ var runParentSchema = z2.strictObject({ runId: id, tokenCap: tokenCapSchema });
324
+ var commandSchema = z2.strictObject({
287
325
  commandId: id,
288
326
  hubEpoch: id,
289
327
  runId: id,
290
328
  expectedRecordRevision: sequence.optional(),
291
- intent: z.discriminatedUnion("kind", [
292
- z.strictObject({
293
- kind: z.literal("start"),
329
+ intent: z2.discriminatedUnion("kind", [
330
+ z2.strictObject({
331
+ kind: z2.literal("start"),
294
332
  sessionId: id,
295
333
  /**
296
334
  * Absent: the Hub resolves the Runner member-first (root ADR-0005): the Session's conversation Runner, else
@@ -306,24 +344,34 @@ var commandSchema = z.strictObject({
306
344
  /** Delegated starts only, and required on them. */
307
345
  parent: runParentIntentSchema.optional()
308
346
  }),
309
- z.strictObject({ kind: z.literal("cancel") }),
310
- z.strictObject({ kind: z.literal("abandon") }),
311
- z.strictObject({ kind: z.literal("steer"), text: z.string().min(1).max(131072) }),
312
- z.strictObject({
313
- kind: z.literal("answer"),
347
+ z2.strictObject({ kind: z2.literal("cancel") }),
348
+ z2.strictObject({ kind: z2.literal("abandon") }),
349
+ z2.strictObject({ kind: z2.literal("steer"), text: z2.string().min(1).max(131072) }),
350
+ z2.strictObject({
351
+ kind: z2.literal("answer"),
314
352
  interruptionId: id,
315
353
  expectedInterruptionRevision: positive,
316
354
  requestId: id.optional(),
317
- answer: z.json()
355
+ answer: z2.json()
318
356
  }),
319
- z.strictObject({
320
- kind: z.literal("resume"),
357
+ z2.strictObject({
358
+ kind: z2.literal("resume"),
321
359
  interruptionId: id,
322
- guidance: z.string().max(131072).optional()
360
+ guidance: z2.string().max(131072).optional()
361
+ }),
362
+ /**
363
+ * A member rewrites an Orchestrator's `delegation.tokenBudget` (root ADR-0011), never below what its children
364
+ * used. With `resume`, a parked Orchestrator with no live child is resumed when the value is strictly greater.
365
+ * Hub-only: never delivered to a Runner.
366
+ */
367
+ z2.strictObject({
368
+ kind: z2.literal("setBudget"),
369
+ tokenBudget: delegationSchema.shape.tokenBudget,
370
+ resume: z2.boolean().optional()
323
371
  })
324
372
  ])
325
373
  });
326
- var grantSchema = z.strictObject({
374
+ var grantSchema = z2.strictObject({
327
375
  commandId: id,
328
376
  hubEpoch: id,
329
377
  runId: id,
@@ -335,121 +383,121 @@ var grantSchema = z.strictObject({
335
383
  baseExecutionRevision: sequence,
336
384
  baseHistorySeq: sequence,
337
385
  cloudHistoryThrough: sequence,
338
- purpose: z.enum(["start", "resume"]),
386
+ purpose: z2.enum(["start", "resume"]),
339
387
  spec: runSpecSchema,
340
- continuation: z.json().optional(),
388
+ continuation: z2.json().optional(),
341
389
  /** A new Run in a durable conversation; never resumes the predecessor's lifecycle. */
342
- previousRun: z.strictObject({
390
+ previousRun: z2.strictObject({
343
391
  runId: id,
344
392
  executionRevision: sequence,
345
393
  historyProduced: sequence,
346
394
  /** Hub-confirmed administrative closure; allows an exact parked predecessor snapshot. */
347
- closeReason: z.literal("abandoned").optional(),
348
- checkpoint: z.strictObject({ checkpointId: id, checksum: z.string().regex(/^[a-f0-9]{64}$/) }).optional()
395
+ closeReason: z2.literal("abandoned").optional(),
396
+ checkpoint: z2.strictObject({ checkpointId: id, checksum: z2.string().regex(/^[a-f0-9]{64}$/) }).optional()
349
397
  }).optional(),
350
- checkpoint: z.strictObject({ checkpointId: id, checksum: z.string().regex(/^[a-f0-9]{64}$/) }).optional(),
398
+ checkpoint: z2.strictObject({ checkpointId: id, checksum: z2.string().regex(/^[a-f0-9]{64}$/) }).optional(),
351
399
  /** This attempt's delegation token: only for a Run started with `delegation`, only to a `run_delegation_v1` Runner. */
352
- delegationToken: z.string().min(32).max(256).optional(),
400
+ delegationToken: z2.string().min(32).max(256).optional(),
353
401
  /** Copied from the start intent of a delegated child. */
354
402
  parent: runParentSchema.optional(),
355
403
  /** The runner reports this attempt's usage: set only for a `run_usage_v1` Runner. */
356
- reportUsage: z.literal(true).optional()
404
+ reportUsage: z2.literal(true).optional()
357
405
  });
358
- var historyRecordSchema = z.strictObject({
406
+ var historyRecordSchema = z2.strictObject({
359
407
  eventId: id,
360
408
  attemptId: id,
361
409
  emittedAt: timestamp,
362
- kind: z.string().min(1).max(128),
363
- data: z.json()
410
+ kind: z2.string().min(1).max(128),
411
+ data: z2.json()
364
412
  });
365
- var runnerFrameSchema = z.discriminatedUnion("type", [
366
- z.strictObject({
367
- type: z.literal("hello"),
368
- role: z.literal("runner"),
369
- protocol: z.strictObject({ major: z.literal(2), minor: sequence }),
413
+ var runnerFrameSchema = z2.discriminatedUnion("type", [
414
+ z2.strictObject({
415
+ type: z2.literal("hello"),
416
+ role: z2.literal("runner"),
417
+ protocol: z2.strictObject({ major: z2.literal(2), minor: sequence }),
370
418
  runnerId: id,
371
419
  installationId: id,
372
- softwareVersion: z.string().max(128),
373
- capabilities: z.array(z.string().max(128)).max(64),
420
+ softwareVersion: z2.string().max(128),
421
+ capabilities: z2.array(z2.string().max(128)).max(64),
374
422
  /** Absent from older runners: the Hub treats the inventory as unknown, never as empty. */
375
423
  workflows: installedWorkflowsSchema.optional(),
376
424
  /** Absent from older runners, and from a runner that has not finished its first check: unknown, not "not ready". */
377
425
  readiness: runnerReadinessSchema.optional(),
378
- control: z.strictObject({ firstRetainedSeq: positive, lastProducedSeq: sequence })
426
+ control: z2.strictObject({ firstRetainedSeq: positive, lastProducedSeq: sequence })
379
427
  }),
380
- z.strictObject({
381
- type: z.literal("control.batch"),
428
+ z2.strictObject({
429
+ type: z2.literal("control.batch"),
382
430
  firstSeq: positive,
383
- records: z.array(controlRecordSchema).min(1).max(128)
431
+ records: z2.array(controlRecordSchema).min(1).max(128)
384
432
  }),
385
- z.strictObject({
386
- type: z.literal("history.batch"),
433
+ z2.strictObject({
434
+ type: z2.literal("history.batch"),
387
435
  runId: id,
388
436
  firstSeq: positive,
389
- records: z.array(historyRecordSchema).min(1).max(128)
437
+ records: z2.array(historyRecordSchema).min(1).max(128)
390
438
  }),
391
- z.strictObject({ type: z.literal("ping"), nonce: id }),
392
- z.strictObject({
393
- type: z.literal("reconcile.page"),
439
+ z2.strictObject({ type: z2.literal("ping"), nonce: id }),
440
+ z2.strictObject({
441
+ type: z2.literal("reconcile.page"),
394
442
  inventoryId: id.default("single-page"),
395
443
  page: sequence.default(0),
396
- complete: z.boolean(),
397
- runs: z.array(
398
- z.strictObject({
444
+ complete: z2.boolean(),
445
+ runs: z2.array(
446
+ z2.strictObject({
399
447
  runId: id,
400
448
  attemptId: id,
401
449
  executionRevision: sequence,
402
- phase: z.enum(["admitted", "prepared", "executing", "parked", "terminal", "recovery"])
450
+ phase: z2.enum(["admitted", "prepared", "executing", "parked", "terminal", "recovery"])
403
451
  })
404
452
  ).max(128)
405
453
  })
406
454
  ]);
407
- var runViewSchema = z.object({
455
+ var runViewSchema = z2.object({
408
456
  runId: id,
409
457
  sessionId: id,
410
458
  runnerId: id,
411
459
  computeProfileId: id.optional(),
412
460
  scope: scopeSchema,
413
461
  recordRevision: positive,
414
- label: z.string().max(160).optional(),
462
+ label: z2.string().max(160).optional(),
415
463
  key: runKeySchema.optional(),
416
464
  parent: runParentSchema.optional(),
417
465
  /**
418
466
  * Not strict, unlike the start intent's: a Hub keeps more on the Run's delegation (`initialTokenBudget`) than it
419
467
  * shows, and a client never refuses a view for a field it does not read.
420
468
  */
421
- delegation: z.object(delegationSchema.shape).optional(),
469
+ delegation: z2.object(delegationSchema.shape).optional(),
422
470
  /** The largest cumulative usage the Run's Runner reported; absent until one does (an older Runner never does). */
423
471
  usage: runUsageSchema.optional(),
424
472
  /** Resolved by the runner at start; absent until the Run starts and for runners that predate reporting. */
425
473
  workflow: workflowIdentitySchema.optional(),
426
- execution: z.object({
427
- status: z.enum(["running", "awaiting_attention", "completed", "failed", "cancelled"]),
474
+ execution: z2.object({
475
+ status: z2.enum(["running", "awaiting_attention", "completed", "failed", "cancelled"]),
428
476
  revision: positive,
429
477
  attemptId: id,
430
- occupancy: z.enum(["held", "released"]),
478
+ occupancy: z2.enum(["held", "released"]),
431
479
  startedAt: timestamp.optional(),
432
480
  endedAt: timestamp.optional(),
433
481
  interruption: interruptionSchema.optional()
434
482
  }).nullable(),
435
- scheduling: z.enum(["queued", "dispatching", "admitted", "idle"]),
436
- closed: z.boolean(),
437
- closeReason: z.string().optional(),
483
+ scheduling: z2.enum(["queued", "dispatching", "admitted", "idle"]),
484
+ closed: z2.boolean(),
485
+ closeReason: z2.string().optional(),
438
486
  cancellation: id.optional(),
439
487
  pendingResume: commandSchema.shape.intent.optional(),
440
488
  /** Derived per viewer; absent on older Hubs. Never grants execution authority. */
441
- runnerStopped: z.boolean().optional(),
442
- canAbandon: z.boolean().optional(),
489
+ runnerStopped: z2.boolean().optional(),
490
+ canAbandon: z2.boolean().optional(),
443
491
  historyThrough: sequence,
444
492
  expectedHistoryThrough: sequence.optional(),
445
493
  createdAt: sequence,
446
- checkpoint: z.object({ id, state: z.enum(["pending", "ready"]), checksum: z.string().optional() }).optional()
494
+ checkpoint: z2.object({ id, state: z2.enum(["pending", "ready"]), checksum: z2.string().optional() }).optional()
447
495
  });
448
- var clientFrameSchema = z.discriminatedUnion("type", [
449
- z.strictObject({ type: z.literal("watch"), hubEpoch: id, runIds: z.array(id).max(100) }),
450
- z.strictObject({ type: z.literal("watch.ack"), subscriptionId: id, through: sequence }),
451
- z.strictObject({ type: z.literal("command.submit"), command: commandSchema }),
452
- z.strictObject({ type: z.literal("ping"), nonce: id })
496
+ var clientFrameSchema = z2.discriminatedUnion("type", [
497
+ z2.strictObject({ type: z2.literal("watch"), hubEpoch: id, runIds: z2.array(id).max(100) }),
498
+ z2.strictObject({ type: z2.literal("watch.ack"), subscriptionId: id, through: sequence }),
499
+ z2.strictObject({ type: z2.literal("command.submit"), command: commandSchema }),
500
+ z2.strictObject({ type: z2.literal("ping"), nonce: id })
453
501
  ]);
454
502
  function canonicalJson(value) {
455
503
  if (value === null || typeof value !== "object") {
@@ -460,76 +508,76 @@ function canonicalJson(value) {
460
508
  if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
461
509
  return `{${Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(",")}}`;
462
510
  }
463
- var checkpointPathSchema = z.string().min(1).max(4096).refine(
511
+ var checkpointPathSchema = z2.string().min(1).max(4096).refine(
464
512
  (path) => !path.startsWith("/") && !path.includes("\\") && path.split("/").every((part) => part !== "" && part !== "." && part !== ".." && part !== ".git")
465
513
  );
466
- var checkpointSchema = z.strictObject({
467
- version: z.literal(1),
468
- checkpointId: z.string().min(1),
469
- orgId: z.string().min(1),
470
- phase: z.enum(["parked", "terminal"]),
471
- runId: z.string().min(1),
472
- sessionId: z.string().min(1),
473
- sourceAttemptId: z.string().min(1),
474
- executionRevision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
475
- historyProduced: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
476
- historyAck: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
514
+ var checkpointSchema = z2.strictObject({
515
+ version: z2.literal(1),
516
+ checkpointId: z2.string().min(1),
517
+ orgId: z2.string().min(1),
518
+ phase: z2.enum(["parked", "terminal"]),
519
+ runId: z2.string().min(1),
520
+ sessionId: z2.string().min(1),
521
+ sourceAttemptId: z2.string().min(1),
522
+ executionRevision: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
523
+ historyProduced: z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
524
+ historyAck: z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
477
525
  grant: grantSchema,
478
- gitHead: z.string().regex(/^[0-9a-f]{40,64}$/),
479
- gitBase: z.string().regex(/^[0-9a-f]{40,64}$/).optional(),
480
- gitBundle: z.string(),
481
- indexPatch: z.string(),
482
- files: z.array(
483
- z.strictObject({ path: checkpointPathSchema, content: z.string(), executable: z.boolean() })
526
+ gitHead: z2.string().regex(/^[0-9a-f]{40,64}$/),
527
+ gitBase: z2.string().regex(/^[0-9a-f]{40,64}$/).optional(),
528
+ gitBundle: z2.string(),
529
+ indexPatch: z2.string(),
530
+ files: z2.array(
531
+ z2.strictObject({ path: checkpointPathSchema, content: z2.string(), executable: z2.boolean() })
484
532
  ).max(1e5),
485
- deleted: z.array(checkpointPathSchema).max(1e5),
486
- sessionRows: z.array(z.strictObject({ kind: z.string(), id: z.string(), payload: z.string() })),
487
- history: z.array(
488
- z.strictObject({ seq: z.number().int().positive(), record: historyRecordSchema })
533
+ deleted: z2.array(checkpointPathSchema).max(1e5),
534
+ sessionRows: z2.array(z2.strictObject({ kind: z2.string(), id: z2.string(), payload: z2.string() })),
535
+ history: z2.array(
536
+ z2.strictObject({ seq: z2.number().int().positive(), record: historyRecordSchema })
489
537
  )
490
538
  });
491
539
  var connectCodeAlphabet = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
492
- var connectCodeSchema = z.string().regex(/^[A-HJKMNP-Z2-9]{8}$/);
493
- var connectCodeRequestSchema = z.strictObject({ hubEpoch: z.string() });
494
- var connectCodeResponseSchema = z.strictObject({
540
+ var connectCodeSchema = z2.string().regex(/^[A-HJKMNP-Z2-9]{8}$/);
541
+ var connectCodeRequestSchema = z2.strictObject({ hubEpoch: z2.string() });
542
+ var connectCodeResponseSchema = z2.strictObject({
495
543
  code: connectCodeSchema,
496
544
  expiresAt: sequence
497
545
  });
498
- var connectRedeemRequestSchema = z.strictObject({
499
- code: z.string().min(8).max(16),
546
+ var connectRedeemRequestSchema = z2.strictObject({
547
+ code: z2.string().min(8).max(16),
500
548
  installationId: id,
501
- hostname: z.string().min(1).max(255),
502
- os: z.string().min(1).max(64),
503
- softwareVersion: z.string().min(1).max(128)
549
+ hostname: z2.string().min(1).max(255),
550
+ os: z2.string().min(1).max(64),
551
+ softwareVersion: z2.string().min(1).max(128)
504
552
  });
505
- var connectRedeemResponseSchema = z.strictObject({
553
+ var connectRedeemResponseSchema = z2.strictObject({
506
554
  orgId: id,
507
- hubEpoch: z.string(),
555
+ hubEpoch: z2.string(),
508
556
  runnerId: id,
509
557
  installationId: id,
510
- name: z.string(),
511
- token: z.string().min(32),
558
+ name: z2.string(),
559
+ token: z2.string().min(32),
512
560
  credentialId: id,
513
561
  expiresAt: sequence
514
562
  });
515
- var connectAlreadyConnectedSchema = z.strictObject({
516
- error: z.literal("runner_already_connected"),
563
+ var connectAlreadyConnectedSchema = z2.strictObject({
564
+ error: z2.literal("runner_already_connected"),
517
565
  orgId: id,
518
566
  runnerId: id,
519
- name: z.string()
567
+ name: z2.string()
520
568
  });
521
- var audienceSchema = z.enum(["personal", "team"]);
522
- var runnerListEntrySchema = z.object({
569
+ var audienceSchema = z2.enum(["personal", "team"]);
570
+ var runnerListEntrySchema = z2.object({
523
571
  id,
524
- online: z.number(),
525
- capacity: z.number(),
526
- managed: z.number(),
527
- draining: z.number(),
528
- stopped: z.number(),
529
- name: z.string().nullable(),
530
- connectedBy: z.string().nullable(),
572
+ online: z2.number(),
573
+ capacity: z2.number(),
574
+ managed: z2.number(),
575
+ draining: z2.number(),
576
+ stopped: z2.number(),
577
+ name: z2.string().nullable(),
578
+ connectedBy: z2.string().nullable(),
531
579
  audience: audienceSchema.nullable(),
532
- softwareVersion: z.string().nullable(),
580
+ softwareVersion: z2.string().nullable(),
533
581
  /** Milliseconds since the epoch of the last hello or disconnect; null before the first connection. */
534
582
  lastSeen: sequence.nullable(),
535
583
  /** Absent when the runner has not reported an inventory: unknown, not none. */
@@ -539,115 +587,121 @@ var runnerListEntrySchema = z.object({
539
587
  * Runner seen by an admin (who may still Disconnect it), or a Runner a member did not connect. Absent from Hubs
540
588
  * older than Audience, like the list's `viewer`, `teamDefault` and `runsGoTo`.
541
589
  */
542
- readOnly: z.boolean().optional(),
590
+ readOnly: z2.boolean().optional(),
543
591
  /** What the Runner last reported; absent when it never has (an older runner, or one not yet connected). */
544
592
  readiness: runnerReadinessSchema.optional(),
545
593
  /**
546
594
  * True when the Runner reported a version below the Hub's minimum: it is listed as "Update required" and takes no
547
595
  * Runs until it is updated (`runnerUpdateCommand`). Absent from Hubs older than Readiness.
548
596
  */
549
- updateRequired: z.boolean().optional(),
597
+ updateRequired: z2.boolean().optional(),
550
598
  /**
551
599
  * True while it is paused as "Needs an owner": the member who connected this Team Runner left the Team, so it
552
600
  * takes no Runs until an admin adopts it (`/runners/{id}/adopt`) or Disconnects it. Absent from older Hubs.
553
601
  */
554
- needsOwner: z.boolean().optional()
602
+ needsOwner: z2.boolean().optional()
555
603
  });
556
- var teamDefaultSchema = z.discriminatedUnion("kind", [
557
- z.strictObject({ kind: z.literal("runner"), runnerId: id }),
558
- z.strictObject({ kind: z.literal("profile"), profileId: id })
604
+ var teamDefaultSchema = z2.discriminatedUnion("kind", [
605
+ z2.strictObject({ kind: z2.literal("runner"), runnerId: id }),
606
+ z2.strictObject({ kind: z2.literal("profile"), profileId: id })
559
607
  ]);
560
- var teamDefaultRequestSchema = z.strictObject({
561
- hubEpoch: z.string(),
608
+ var teamDefaultRequestSchema = z2.strictObject({
609
+ hubEpoch: z2.string(),
562
610
  teamDefault: teamDefaultSchema.nullable()
563
611
  });
564
- var runnerUpdateRequestSchema = z.strictObject({
565
- hubEpoch: z.string(),
566
- name: z.string().max(100).optional(),
567
- capacity: z.number().int().min(1).max(64).optional(),
612
+ var runnerUpdateRequestSchema = z2.strictObject({
613
+ hubEpoch: z2.string(),
614
+ name: z2.string().max(100).optional(),
615
+ capacity: z2.number().int().min(1).max(64).optional(),
568
616
  audience: audienceSchema.optional()
569
617
  }).refine(
570
618
  (update) => update.name !== void 0 || update.capacity !== void 0 || update.audience !== void 0,
571
619
  { message: "nothing to update" }
572
620
  );
573
- var runsGoToSchema = z.union([
621
+ var runsGoToSchema = z2.union([
574
622
  /** The viewer's own Runner: Personal, or one they connected that was widened to Team (DRI-42). */
575
- z.strictObject({ via: z.literal("personal"), runnerId: id }),
576
- z.strictObject({ via: z.literal("team_default"), runnerId: id }),
577
- z.strictObject({ via: z.literal("team_default"), profileId: id }),
623
+ z2.strictObject({ via: z2.literal("personal"), runnerId: id }),
624
+ z2.strictObject({ via: z2.literal("team_default"), runnerId: id }),
625
+ z2.strictObject({ via: z2.literal("team_default"), profileId: id }),
578
626
  /** `runner_needs_owner`: the Team default is a Runner paused because the member who connected it left. */
579
- z.strictObject({ via: z.literal("none"), reason: z.enum(["no_runner_available", "runner_needs_owner"]) })
627
+ z2.strictObject({ via: z2.literal("none"), reason: z2.enum(["no_runner_available", "runner_needs_owner"]) })
580
628
  ]);
581
- var runnerListSchema = z.object({
582
- capabilities: z.record(z.string(), z.boolean()).optional(),
583
- historyRetentionDays: z.number().int().positive().nullable().optional(),
629
+ var runnerListSchema = z2.object({
630
+ capabilities: z2.record(z2.string(), z2.boolean()).optional(),
631
+ historyRetentionDays: z2.number().int().positive().nullable().optional(),
584
632
  /** Who the list was filtered for: a member sees their own and Team Runners, an admin every Runner. */
585
- viewer: z.object({ userId: z.string(), admin: z.boolean() }).optional(),
633
+ viewer: z2.object({ userId: z2.string(), admin: z2.boolean() }).optional(),
586
634
  teamDefault: teamDefaultSchema.nullable().optional(),
587
635
  runsGoTo: runsGoToSchema.optional(),
588
636
  /** The lowest Runner version this Hub sends Runs to. Absent from Hubs older than Readiness. */
589
- minimumRunnerVersion: z.string().optional(),
590
- runners: z.array(runnerListEntrySchema),
591
- profiles: z.array(z.object({
592
- id: z.string(),
593
- label: z.string(),
594
- projectDir: z.string(),
595
- repositoryRequired: z.boolean().optional(),
637
+ minimumRunnerVersion: z2.string().optional(),
638
+ runners: z2.array(runnerListEntrySchema),
639
+ profiles: z2.array(z2.object({
640
+ id: z2.string(),
641
+ label: z2.string(),
642
+ projectDir: z2.string(),
643
+ repositoryRequired: z2.boolean().optional(),
596
644
  /** Marketplace refs baked into the profile's image; absent when the profile declares none. */
597
- workflows: z.array(z.string()).optional(),
598
- workflowSources: z.array(z.string()).optional()
645
+ workflows: z2.array(z2.string()).optional(),
646
+ workflowSources: z2.array(z2.string()).optional()
599
647
  }))
600
648
  });
601
- var runnerDisconnectRequestSchema = z.strictObject({ hubEpoch: z.string() });
649
+ var runnerDisconnectRequestSchema = z2.strictObject({ hubEpoch: z2.string() });
602
650
  var hubEpochRequestSchema = runnerDisconnectRequestSchema;
603
- var runnerDisconnectPreviewSchema = z.object({
651
+ var runnerDisconnectPreviewSchema = z2.object({
604
652
  runnerId: id,
605
- name: z.string().nullable(),
606
- runs: z.array(z.object({
653
+ name: z2.string().nullable(),
654
+ runs: z2.array(z2.object({
607
655
  runId: id,
608
- label: z.string().optional(),
656
+ label: z2.string().optional(),
609
657
  /** Working: executing now. Parked: waiting for a person, Runner released. Queued: not started yet. */
610
- state: z.enum(["working", "parked", "queued"])
658
+ state: z2.enum(["working", "parked", "queued"])
611
659
  })),
612
- hiddenRuns: z.number().int().nonnegative()
660
+ hiddenRuns: z2.number().int().nonnegative()
613
661
  });
614
- var runnerDisconnectResponseSchema = z.object({
615
- disconnected: z.literal(true),
662
+ var runnerDisconnectResponseSchema = z2.object({
663
+ disconnected: z2.literal(true),
616
664
  /** How many Runs were Stopped with the reason `runner_disconnected`. */
617
- stoppedRuns: z.number().int().nonnegative()
665
+ stoppedRuns: z2.number().int().nonnegative()
618
666
  });
619
667
  var runnerAdoptRequestSchema = hubEpochRequestSchema;
620
668
  var connectStartRequestSchema = connectRedeemRequestSchema.omit({ code: true });
621
- var connectStartResponseSchema = z.strictObject({
669
+ var connectStartResponseSchema = z2.strictObject({
622
670
  /** The machine's secret for polling; never shown. */
623
- deviceCode: z.string().min(32).max(160),
671
+ deviceCode: z2.string().min(32).max(160),
624
672
  code: connectCodeSchema,
625
673
  expiresAt: sequence,
626
- intervalSec: z.number().int().positive(),
674
+ intervalSec: z2.number().int().positive(),
627
675
  /** The web console page that approves `code`. */
628
- verificationUrl: z.string().url()
676
+ verificationUrl: z2.string().url()
629
677
  });
630
- var connectPollRequestSchema = z.strictObject({ deviceCode: z.string().min(32).max(160) });
631
- var connectPendingResponseSchema = z.strictObject({
632
- hostname: z.string(),
633
- os: z.string(),
634
- softwareVersion: z.string(),
678
+ var connectPollRequestSchema = z2.strictObject({ deviceCode: z2.string().min(32).max(160) });
679
+ var connectPendingResponseSchema = z2.strictObject({
680
+ hostname: z2.string(),
681
+ os: z2.string(),
682
+ softwareVersion: z2.string(),
635
683
  requestedAt: sequence,
636
684
  expiresAt: sequence
637
685
  });
638
- var connectApproveRequestSchema = z.strictObject({
639
- code: z.string().min(8).max(16),
686
+ var connectApproveRequestSchema = z2.strictObject({
687
+ code: z2.string().min(8).max(16),
640
688
  audience: audienceSchema,
641
- hubEpoch: z.string().optional()
689
+ hubEpoch: z2.string().optional()
642
690
  });
643
- var connectDenyRequestSchema = z.strictObject({ code: z.string().min(8).max(16) });
691
+ var connectDenyRequestSchema = z2.strictObject({ code: z2.string().min(8).max(16) });
644
692
  export {
693
+ CALIBRATION_MIN_RUNS,
694
+ CALIBRATION_WINDOW_DAYS,
645
695
  SIZE_CLASS_CAPS,
646
696
  SIZE_CLASS_FORECASTS,
647
697
  abandonedConversationContinuationCapability,
648
698
  attemptCost,
699
+ attemptForecast,
649
700
  audienceSchema,
701
+ budgetCheck,
650
702
  buildCloseReasonSchema,
703
+ calibrate,
704
+ calibrationSchema,
651
705
  canonicalJson,
652
706
  checkpointPathSchema,
653
707
  checkpointSchema,
@@ -672,6 +726,7 @@ export {
672
726
  delegationSchema,
673
727
  delegationTokenPrefix,
674
728
  forecastOfCap,
729
+ forecastOfClass,
675
730
  grantSchema,
676
731
  harnessReadinessSchema,
677
732
  harnessSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drisp/protocol",
3
- "version": "0.8.4",
3
+ "version": "0.8.6",
4
4
  "description": "Wire contract between a drisp runner and the hub: zod schemas, inferred types, and JSON Schema for the instance-socket frames, Run, Turn, Interruption, and the event stream",
5
5
  "repository": {
6
6
  "type": "git",
@@ -448,6 +448,28 @@
448
448
  "interruptionId"
449
449
  ],
450
450
  "additionalProperties": false
451
+ },
452
+ {
453
+ "type": "object",
454
+ "properties": {
455
+ "kind": {
456
+ "type": "string",
457
+ "const": "setBudget"
458
+ },
459
+ "tokenBudget": {
460
+ "type": "integer",
461
+ "exclusiveMinimum": 0,
462
+ "maximum": 9007199254740991
463
+ },
464
+ "resume": {
465
+ "type": "boolean"
466
+ }
467
+ },
468
+ "required": [
469
+ "kind",
470
+ "tokenBudget"
471
+ ],
472
+ "additionalProperties": false
451
473
  }
452
474
  ]
453
475
  }
@@ -385,6 +385,28 @@
385
385
  "interruptionId"
386
386
  ],
387
387
  "additionalProperties": false
388
+ },
389
+ {
390
+ "type": "object",
391
+ "properties": {
392
+ "kind": {
393
+ "type": "string",
394
+ "const": "setBudget"
395
+ },
396
+ "tokenBudget": {
397
+ "type": "integer",
398
+ "exclusiveMinimum": 0,
399
+ "maximum": 9007199254740991
400
+ },
401
+ "resume": {
402
+ "type": "boolean"
403
+ }
404
+ },
405
+ "required": [
406
+ "kind",
407
+ "tokenBudget"
408
+ ],
409
+ "additionalProperties": false
388
410
  }
389
411
  ]
390
412
  }
@@ -631,6 +631,28 @@
631
631
  "interruptionId"
632
632
  ],
633
633
  "additionalProperties": false
634
+ },
635
+ {
636
+ "type": "object",
637
+ "properties": {
638
+ "kind": {
639
+ "type": "string",
640
+ "const": "setBudget"
641
+ },
642
+ "tokenBudget": {
643
+ "type": "integer",
644
+ "exclusiveMinimum": 0,
645
+ "maximum": 9007199254740991
646
+ },
647
+ "resume": {
648
+ "type": "boolean"
649
+ }
650
+ },
651
+ "required": [
652
+ "kind",
653
+ "tokenBudget"
654
+ ],
655
+ "additionalProperties": false
634
656
  }
635
657
  ]
636
658
  },