@indigoai-us/hq-cli 5.125.0 → 5.127.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +329 -0
  2. package/assets/bot-workers/setup/skills/joining-a-team.md +125 -0
  3. package/assets/bot-workers/setup/skills/your-business.md +270 -0
  4. package/assets/bot-workers/setup/worker.yaml +189 -58
  5. package/assets/lanes-hooks/hq-lanes-drain.json +15 -0
  6. package/assets/lanes-hooks/hq-lanes-drain.mjs +254 -0
  7. package/assets/lanes-hooks/hq-lanes-drain.sh +21 -0
  8. package/assets/lanes-reconcile/hq-lanes-reconcile.service +11 -0
  9. package/assets/lanes-reconcile/hq-lanes-reconcile.timer +12 -0
  10. package/dist/command-catalog.generated.d.ts +643 -6
  11. package/dist/command-catalog.generated.js +836 -6
  12. package/dist/command-registration-plan.d.ts +7 -0
  13. package/dist/command-registration-plan.js +11 -1
  14. package/dist/commands/agents.d.ts +12 -0
  15. package/dist/commands/agents.js +46 -2
  16. package/dist/commands/bot.d.ts +10 -0
  17. package/dist/commands/bot.js +6 -0
  18. package/dist/commands/lanes.d.ts +114 -0
  19. package/dist/commands/lanes.js +2969 -0
  20. package/dist/commands/mesh.js +287 -24
  21. package/dist/commands/onboard-create-identity.d.ts +26 -0
  22. package/dist/commands/onboard-create-identity.js +23 -0
  23. package/dist/commands/onboard.js +13 -4
  24. package/dist/lib/bot/progress.d.ts +6 -0
  25. package/dist/lib/bot/progress.js +16 -0
  26. package/dist/lib/bot/runtime/grok.d.ts +30 -7
  27. package/dist/lib/bot/runtime/grok.js +86 -8
  28. package/dist/lib/bot/runtime/index.js +15 -8
  29. package/dist/lib/bot/runtime/messages-stream.d.ts +12 -3
  30. package/dist/lib/bot/runtime/messages-stream.js +49 -3
  31. package/dist/lib/lanes/accounts.d.ts +103 -0
  32. package/dist/lib/lanes/accounts.js +318 -0
  33. package/dist/lib/lanes/compaction.d.ts +96 -0
  34. package/dist/lib/lanes/compaction.js +197 -0
  35. package/dist/lib/lanes/config.d.ts +71 -0
  36. package/dist/lib/lanes/config.js +408 -0
  37. package/dist/lib/lanes/delivery.d.ts +151 -0
  38. package/dist/lib/lanes/delivery.js +354 -0
  39. package/dist/lib/lanes/dropbox.d.ts +96 -0
  40. package/dist/lib/lanes/dropbox.js +408 -0
  41. package/dist/lib/lanes/effort.d.ts +50 -0
  42. package/dist/lib/lanes/effort.js +109 -0
  43. package/dist/lib/lanes/errors.d.ts +39 -0
  44. package/dist/lib/lanes/errors.js +72 -0
  45. package/dist/lib/lanes/hooks-install.d.ts +81 -0
  46. package/dist/lib/lanes/hooks-install.js +326 -0
  47. package/dist/lib/lanes/hq-root.d.ts +19 -0
  48. package/dist/lib/lanes/hq-root.js +28 -0
  49. package/dist/lib/lanes/index.d.ts +49 -0
  50. package/dist/lib/lanes/index.js +27 -0
  51. package/dist/lib/lanes/liveness.d.ts +95 -0
  52. package/dist/lib/lanes/liveness.js +332 -0
  53. package/dist/lib/lanes/machine-identity.d.ts +34 -0
  54. package/dist/lib/lanes/machine-identity.js +92 -0
  55. package/dist/lib/lanes/mesh-events.d.ts +109 -0
  56. package/dist/lib/lanes/mesh-events.js +275 -0
  57. package/dist/lib/lanes/outpost-dispatch.d.ts +65 -0
  58. package/dist/lib/lanes/outpost-dispatch.js +90 -0
  59. package/dist/lib/lanes/questions.d.ts +75 -0
  60. package/dist/lib/lanes/questions.js +243 -0
  61. package/dist/lib/lanes/quota.d.ts +95 -0
  62. package/dist/lib/lanes/quota.js +320 -0
  63. package/dist/lib/lanes/reconcile-install.d.ts +69 -0
  64. package/dist/lib/lanes/reconcile-install.js +221 -0
  65. package/dist/lib/lanes/reconcile.d.ts +102 -0
  66. package/dist/lib/lanes/reconcile.js +985 -0
  67. package/dist/lib/lanes/registry.d.ts +116 -0
  68. package/dist/lib/lanes/registry.js +521 -0
  69. package/dist/lib/lanes/spawn.d.ts +274 -0
  70. package/dist/lib/lanes/spawn.js +1363 -0
  71. package/dist/lib/lanes/store.d.ts +68 -0
  72. package/dist/lib/lanes/store.js +745 -0
  73. package/dist/lib/lanes/throttle.d.ts +89 -0
  74. package/dist/lib/lanes/throttle.js +297 -0
  75. package/dist/lib/lanes/types.d.ts +535 -0
  76. package/dist/lib/lanes/types.js +350 -0
  77. package/dist/lib/lanes/watcher-main.d.ts +9 -0
  78. package/dist/lib/lanes/watcher-main.js +22 -0
  79. package/dist/lib/lanes/watcher.d.ts +216 -0
  80. package/dist/lib/lanes/watcher.js +859 -0
  81. package/dist/lib/mesh/api.d.ts +71 -7
  82. package/dist/lib/mesh/api.js +167 -28
  83. package/dist/lib/mesh/live/backfill-held.d.ts +18 -7
  84. package/dist/lib/mesh/live/backfill-held.js +66 -21
  85. package/dist/lib/mesh/live/daemon/config.d.ts +27 -0
  86. package/dist/lib/mesh/live/daemon/config.js +75 -0
  87. package/dist/lib/mesh/live/daemon/index.d.ts +4 -3
  88. package/dist/lib/mesh/live/daemon/index.js +3 -3
  89. package/dist/lib/mesh/live/daemon/install.d.ts +143 -1
  90. package/dist/lib/mesh/live/daemon/install.js +444 -2
  91. package/dist/lib/mesh/live/daemon/paths.d.ts +2 -0
  92. package/dist/lib/mesh/live/daemon/paths.js +2 -0
  93. package/dist/lib/mesh/live/daemon/run.d.ts +2 -0
  94. package/dist/lib/mesh/live/daemon/run.js +111 -54
  95. package/dist/lib/mesh/live/daemon/state.d.ts +2 -0
  96. package/dist/lib/mesh/live/daemon/transcript-watch.d.ts +3 -0
  97. package/dist/lib/mesh/live/daemon/transcript-watch.js +31 -8
  98. package/dist/lib/scan-packages/index.d.ts +2 -0
  99. package/dist/lib/scan-packages/index.js +18 -13
  100. package/dist/lib/work-context/config.d.ts +20 -0
  101. package/dist/lib/work-context/config.js +26 -5
  102. package/dist/lib/work-context/reconcile.js +28 -7
  103. package/dist/lib/work-context/state.d.ts +12 -0
  104. package/dist/lib/work-context/state.js +131 -3
  105. package/dist/lib/work-context/windows-acl.d.ts +123 -0
  106. package/dist/lib/work-context/windows-acl.js +425 -0
  107. package/dist/utils/pack-contributions.js +5 -4
  108. package/package.json +3 -1
@@ -0,0 +1,535 @@
1
+ /**
2
+ * Lane record, question routing record, envelope, and config types (spec §3,
3
+ * §4, §5.5, §6.2). Finite sets are string-literal unions plus `const` arrays
4
+ * so the command layer can validate flags explicitly.
5
+ */
6
+ export declare const LANE_SCHEMA_VERSION: "hq-lane.v1";
7
+ export declare const QUESTION_SCHEMA_VERSION: "hq-lane-question.v1";
8
+ export declare const ENVELOPE_SCHEMA_VERSION: "hq-lane-envelope.v1";
9
+ export declare const CONFIG_SCHEMA_VERSION: "hq-lanes-config.v1";
10
+ /**
11
+ * The envelope contract as a JSON schema. `parseLaneEnvelope` is the runtime
12
+ * check; this is the text handed to a worker on the repair turn (spec §4) so
13
+ * the two never drift apart in what they name.
14
+ */
15
+ export declare const LANE_ENVELOPE_JSON_SCHEMA: {
16
+ readonly $schema: "https://json-schema.org/draft/2020-12/schema";
17
+ readonly title: "hq-lane-envelope.v1";
18
+ readonly type: "object";
19
+ readonly additionalProperties: false;
20
+ readonly required: readonly ["schema_version", "decision", "summary", "story_status", "artifacts"];
21
+ readonly properties: {
22
+ readonly schema_version: {
23
+ readonly const: "hq-lane-envelope.v1";
24
+ };
25
+ readonly decision: {
26
+ readonly enum: readonly ["done", "ask", "blocked"];
27
+ };
28
+ readonly summary: {
29
+ readonly type: "string";
30
+ readonly minLength: 1;
31
+ };
32
+ readonly questions: {
33
+ readonly type: "array";
34
+ readonly items: {
35
+ readonly type: "object";
36
+ readonly additionalProperties: false;
37
+ readonly required: readonly ["question", "context", "options"];
38
+ readonly properties: {
39
+ readonly question: {
40
+ readonly type: "string";
41
+ };
42
+ readonly context: {
43
+ readonly type: "string";
44
+ };
45
+ readonly options: {
46
+ readonly type: "array";
47
+ readonly items: {
48
+ readonly type: "string";
49
+ };
50
+ };
51
+ readonly recommended: {
52
+ readonly type: "string";
53
+ };
54
+ };
55
+ };
56
+ };
57
+ readonly story_status: {
58
+ readonly enum: readonly ["queued", "in_progress", "review", "done"];
59
+ };
60
+ readonly artifacts: {
61
+ readonly type: "array";
62
+ };
63
+ readonly blocked_reason: {
64
+ readonly type: "string";
65
+ };
66
+ readonly story_complete: {
67
+ readonly type: "boolean";
68
+ };
69
+ readonly story_complete_reason: {
70
+ readonly type: "string";
71
+ readonly minLength: 1;
72
+ };
73
+ };
74
+ readonly allOf: readonly [{
75
+ readonly if: {
76
+ readonly properties: {
77
+ readonly decision: {
78
+ readonly const: "ask";
79
+ };
80
+ };
81
+ };
82
+ readonly then: {
83
+ readonly required: readonly ["questions"];
84
+ readonly properties: {
85
+ readonly questions: {
86
+ readonly minItems: 1;
87
+ };
88
+ };
89
+ };
90
+ readonly else: {
91
+ readonly not: {
92
+ readonly required: readonly ["questions"];
93
+ };
94
+ };
95
+ }, {
96
+ readonly if: {
97
+ readonly properties: {
98
+ readonly decision: {
99
+ readonly const: "blocked";
100
+ };
101
+ };
102
+ };
103
+ readonly then: {
104
+ readonly required: readonly ["blocked_reason"];
105
+ readonly properties: {
106
+ readonly blocked_reason: {
107
+ readonly minLength: 1;
108
+ };
109
+ };
110
+ };
111
+ readonly else: {
112
+ readonly not: {
113
+ readonly required: readonly ["blocked_reason"];
114
+ };
115
+ };
116
+ }, {
117
+ readonly if: {
118
+ readonly required: readonly ["story_complete"];
119
+ readonly properties: {
120
+ readonly story_complete: {
121
+ readonly const: true;
122
+ };
123
+ };
124
+ };
125
+ readonly then: {
126
+ readonly required: readonly ["story_complete_reason"];
127
+ readonly properties: {
128
+ readonly story_status: {
129
+ readonly const: "done";
130
+ };
131
+ readonly story_complete_reason: {
132
+ readonly minLength: 1;
133
+ };
134
+ };
135
+ };
136
+ readonly else: {
137
+ readonly if: {
138
+ readonly required: readonly ["story_complete"];
139
+ };
140
+ readonly then: {
141
+ readonly required: readonly ["story_complete_reason"];
142
+ readonly properties: {
143
+ readonly story_status: {
144
+ readonly not: {
145
+ readonly const: "done";
146
+ };
147
+ };
148
+ readonly story_complete_reason: {
149
+ readonly minLength: 1;
150
+ };
151
+ };
152
+ };
153
+ readonly else: {
154
+ readonly not: {
155
+ readonly required: readonly ["story_complete_reason"];
156
+ };
157
+ };
158
+ };
159
+ }];
160
+ readonly description: string;
161
+ };
162
+ export declare const LANE_STATES: readonly ["queued", "running", "awaiting_input", "blocked", "done", "failed", "interrupted", "cancelled", "killed"];
163
+ export type LaneState = (typeof LANE_STATES)[number];
164
+ /** Exact terminal set from spec §6.7. `awaiting_input` and `blocked` are not terminal. */
165
+ export declare const TERMINAL_LANE_STATES: readonly ["done", "failed", "interrupted", "cancelled", "killed"];
166
+ export type TerminalLaneState = (typeof TERMINAL_LANE_STATES)[number];
167
+ export declare const LANE_PROVIDERS: readonly ["claude", "codex", "grok"];
168
+ export type LaneProvider = (typeof LANE_PROVIDERS)[number];
169
+ export declare const QUEUED_REASONS: readonly ["cap", "queue_position", "throttle", "provider_binary_missing"];
170
+ export type QueuedReason = (typeof QUEUED_REASONS)[number];
171
+ export declare const HOST_KINDS: readonly ["local", "outpost"];
172
+ export type HostKind = (typeof HOST_KINDS)[number];
173
+ export declare const SENIOR_KINDS: readonly ["session", "lane", "user"];
174
+ export type SeniorKind = (typeof SENIOR_KINDS)[number];
175
+ export declare const ENVELOPE_DECISIONS: readonly ["done", "ask", "blocked"];
176
+ export type EnvelopeDecision = (typeof ENVELOPE_DECISIONS)[number];
177
+ export declare const STORY_STATUSES: readonly ["queued", "in_progress", "review", "done"];
178
+ export type StoryStatus = (typeof STORY_STATUSES)[number];
179
+ /**
180
+ * `expired` is accepted on read for records that already carry it. Spec §9
181
+ * ageing advances hop with `unanswered_timeout` and never expires a question,
182
+ * so reconcile (the only writer that may age without an operator) does not
183
+ * write this value. Kept in the enum so `--status expired` and old files parse.
184
+ */
185
+ export declare const QUESTION_STATUSES: readonly ["pending", "answered", "cancelled", "expired"];
186
+ export type QuestionStatus = (typeof QUESTION_STATUSES)[number];
187
+ export declare const RAISED_VIA: readonly ["cli", "envelope"];
188
+ export type RaisedVia = (typeof RAISED_VIA)[number];
189
+ export declare const ROUTING_REASONS: readonly ["asked", "escalated", "audience_ended", "reparented", "unanswered_timeout", "cancelled"];
190
+ export type RoutingReason = (typeof ROUTING_REASONS)[number];
191
+ export declare const QUESTION_BODY_STORES: readonly ["company", "personal"];
192
+ export type QuestionBodyStore = (typeof QUESTION_BODY_STORES)[number];
193
+ export declare const LIVENESS_STATES: readonly ["live", "idle", "ended", "lost"];
194
+ export type LivenessState = (typeof LIVENESS_STATES)[number];
195
+ export declare const HISTORY_CAP = 50;
196
+ export declare function isLaneState(value: unknown): value is LaneState;
197
+ export declare function isTerminalLaneState(value: unknown): value is TerminalLaneState;
198
+ export declare function isLaneProvider(value: unknown): value is LaneProvider;
199
+ export declare function isSeniorKind(value: unknown): value is SeniorKind;
200
+ export declare function isHostKind(value: unknown): value is HostKind;
201
+ export declare function isEnvelopeDecision(value: unknown): value is EnvelopeDecision;
202
+ export declare function isQuestionStatus(value: unknown): value is QuestionStatus;
203
+ export declare function isLivenessState(value: unknown): value is LivenessState;
204
+ export declare function parseLaneProvider(value: unknown): LaneProvider;
205
+ export declare function parseLaneState(value: unknown): LaneState;
206
+ export declare function parseQuestionStatus(value: unknown): QuestionStatus;
207
+ export declare function parseLivenessState(value: unknown): LivenessState;
208
+ export declare function parseSeniorKind(value: unknown): SeniorKind;
209
+ export interface LaneCompanyRef {
210
+ slug: string;
211
+ uid: string;
212
+ }
213
+ export interface SeniorRef {
214
+ kind: SeniorKind;
215
+ /** Required for session and lane; omitted for the user terminal. */
216
+ id?: string;
217
+ }
218
+ export interface LaneHost {
219
+ kind: HostKind;
220
+ id: string;
221
+ }
222
+ export interface SeniorHistoryEntry {
223
+ from: SeniorRef;
224
+ to: SeniorRef;
225
+ at: string;
226
+ by: string;
227
+ reason: string;
228
+ }
229
+ export interface AttributionHistoryEntry {
230
+ project_id: string;
231
+ story_id: string;
232
+ message_id: string;
233
+ at: string;
234
+ }
235
+ export interface LastEnvelopeRef {
236
+ ref: string;
237
+ decision: EnvelopeDecision;
238
+ at: string;
239
+ }
240
+ export interface LaneRecord {
241
+ schema_version: typeof LANE_SCHEMA_VERSION | string;
242
+ lane_id: string;
243
+ /** `null` is a core/personal lane (spec §6.2 / §10). Not an empty slug. */
244
+ company: LaneCompanyRef | null;
245
+ project_id: string;
246
+ story_id: string;
247
+ thread_id?: string;
248
+ depth: number;
249
+ senior: SeniorRef;
250
+ senior_history: SeniorHistoryEntry[];
251
+ state: LaneState;
252
+ queued_reason?: QueuedReason;
253
+ priority: number;
254
+ worker?: string;
255
+ /** Registry-relative directory of the resolved worker, when --worker was set. */
256
+ worker_path?: string;
257
+ /** Package name when the worker's realpath is under core/packages. */
258
+ worker_pack?: string;
259
+ provider: LaneProvider;
260
+ account?: string;
261
+ host: LaneHost;
262
+ /**
263
+ * Creating machine's identity when `host.kind` is `outpost` (spec §5.2).
264
+ * Distinct from `host`, which names where the lane is meant to run.
265
+ */
266
+ origin_host?: string;
267
+ /** How `origin_host` was resolved. Required to compare like-with-like. */
268
+ origin_host_source?: "imds" | "hostname";
269
+ version: number;
270
+ created_at: string;
271
+ updated_at: string;
272
+ attribution_history: AttributionHistoryEntry[];
273
+ last_envelope?: LastEnvelopeRef;
274
+ /** Effective model id recorded at create/spawn. Omitted when the provider chooses. */
275
+ model?: string;
276
+ /** Effective effort level passed to the provider at the last spawn (effort.ts). */
277
+ effort?: string;
278
+ /** Where `effort` came from. `cli` pins it across later spawns. */
279
+ effort_source?: "cli" | "account" | "provider" | "default_rule" | "none";
280
+ /** Time of the last operator message accepted for this lane. Drives compaction. */
281
+ last_message_at?: string;
282
+ /** Last automatic compaction of a resumed session (compaction.ts). */
283
+ last_compaction?: LaneCompactionRecord;
284
+ /**
285
+ * Copied from the last ingested envelope. Omitted when no envelope has
286
+ * been ingested — absence is not false.
287
+ */
288
+ story_complete?: boolean;
289
+ story_complete_reason?: string;
290
+ /** Copied from the last ingested envelope when present. */
291
+ story_status?: StoryStatus;
292
+ /** Set by the reconcile pass when `--timeout` has passed (spec §5.7). */
293
+ overdue?: boolean;
294
+ overdue_at?: string;
295
+ /** Executing-host heartbeat; stale values mean the host stopped reporting. */
296
+ last_host_report_at?: string;
297
+ /**
298
+ * Set by the watcher when a running worker has made no tool call and
299
+ * produced no output for the silence window; cleared on the next progress
300
+ * signal or terminal write. Not a verdict: a long single tool call looks
301
+ * the same as a hang. See watcher.ts.
302
+ */
303
+ stalled?: boolean;
304
+ stalled_at?: string;
305
+ stalled_reason?: string;
306
+ /** Set when the reconcile pass force-admits under the starvation bound. */
307
+ admitted_reason?: string;
308
+ terminal_reason?: string;
309
+ /**
310
+ * Structured detail behind a named `terminal_reason` (dispatch, pickup and
311
+ * spawn failures), or the missing-binary search path behind
312
+ * `provider_binary_missing`. Written by the command and spawn writers.
313
+ */
314
+ terminal_details?: Record<string, unknown>;
315
+ /** SSM command id of the `hq outposts exec` pickup that started this lane. */
316
+ outpost_command_id?: string;
317
+ /**
318
+ * Provider reset time copied from a 429 result. Absent when the text
319
+ * named none. Distinct from the operator's account enabled switch.
320
+ */
321
+ quota_reset_at?: string;
322
+ /** Set when a 429 refused one model for credits, e.g. "needs credits for claude-fable-5-1". */
323
+ model_quota_marker?: string;
324
+ /**
325
+ * Provider session id parsed from the worker's own stdout when a resumable
326
+ * provider exits: Claude's JSON `result.session_id`, Codex's
327
+ * `thread.started.thread_id`. Absent when the provider has none or the
328
+ * output carried none; `provider_session_id_absent` names why. Never a
329
+ * guessed or path-derived value.
330
+ */
331
+ provider_session_id?: string;
332
+ provider_session_id_absent?: string;
333
+ /** Set at spawn when this run continued a recorded session instead of starting fresh. */
334
+ last_resume?: LaneResumeRecord;
335
+ /** Cache counters from the last exited run's result. Nothing else from the payload. */
336
+ last_run_usage?: LaneRunUsage;
337
+ /**
338
+ * Spec §4: one repair turn when the final output fails parseLaneEnvelope.
339
+ * Written by the watcher before the repair spawn, updated on the repair
340
+ * run's exit. Absent when every envelope this lane wrote parsed first time.
341
+ */
342
+ envelope_repair?: LaneEnvelopeRepair;
343
+ /** Last successful lane_progress mesh delivery, preserved across watcher restarts. */
344
+ last_progress_event_at?: string;
345
+ }
346
+ /** The v1 fields that must exist on every durable lane record (spec §3). */
347
+ export declare const REQUIRED_LANE_RECORD_FIELDS: readonly ["schema_version", "lane_id", "company", "project_id", "story_id", "depth", "senior", "senior_history", "state", "priority", "provider", "host", "version", "created_at", "updated_at", "attribution_history"];
348
+ export declare const LANE_WRITERS: readonly ["creator", "command", "watcher", "reconcile", "spawn"];
349
+ export type LaneWriter = (typeof LANE_WRITERS)[number];
350
+ /** Field ownership at the durable-record mutation boundary (spec §10.1). */
351
+ export declare const LANE_FIELD_WRITERS: Readonly<Record<keyof LaneRecord, readonly LaneWriter[]>>;
352
+ export interface LaneEnvelopeRepair {
353
+ /** False when the parse failed but no repair turn could run (see `skipped_reason`). */
354
+ attempted: boolean;
355
+ /**
356
+ * How the repair turn ran: `resume` continues the recorded session (claude,
357
+ * codex); `fresh_turn` is a new single-turn invocation carrying the raw
358
+ * output (grok). Absent when no repair ran.
359
+ */
360
+ mode?: "resume" | "fresh_turn";
361
+ succeeded: boolean;
362
+ first_error: string;
363
+ /** Parser error from the repair run's output, when that also failed. */
364
+ second_error?: string;
365
+ /** Why no repair turn ran: the provider cannot resume, or no session id was recorded. */
366
+ skipped_reason?: string;
367
+ /** Envelope slot the repair was asked to rewrite. */
368
+ envelope_ref?: string;
369
+ at: string;
370
+ }
371
+ export interface LaneResumeRecord {
372
+ session_id: string;
373
+ at: string;
374
+ trigger: "answered_questions" | "message" | "resume";
375
+ message_id?: string;
376
+ /**
377
+ * `hq lanes resume` only: the state the lane was in when the operator
378
+ * resumed it (`interrupted`, `done` or `blocked`) and the text they sent.
379
+ */
380
+ resumed_from?: "interrupted" | "done" | "blocked";
381
+ text?: string;
382
+ }
383
+ export interface LaneRunUsage {
384
+ cache_read_input_tokens: number | null;
385
+ cache_creation_input_tokens: number | null;
386
+ }
387
+ export interface LaneCompactionRecord {
388
+ at: string;
389
+ /** `claude_print_compact`: `claude -p --resume <sid> "/compact"` before the resume. */
390
+ mechanism: "claude_print_compact";
391
+ session_id: string;
392
+ /** `compacted` only when the session transcript gained a compact boundary. */
393
+ outcome: "compacted" | "no_effect" | "failed";
394
+ reason?: string;
395
+ duration_ms: number;
396
+ /** Milliseconds between the reference time and the resume that compacted. */
397
+ elapsed_ms: number;
398
+ /** `last_message_at`, or `created_at` when no message was ever sent. */
399
+ reference_at: string;
400
+ /** Context size the provider recorded at the compact boundary. */
401
+ pre_tokens: number | null;
402
+ /** Usage of the last run before compaction. */
403
+ before: LaneRunUsage | null;
404
+ /** Usage of the first run after compaction, once that run has exited. */
405
+ after: LaneRunUsage | null;
406
+ /** `last_resume.at` of the run that followed this compaction. */
407
+ resume_at?: string;
408
+ }
409
+ export interface QuestionBodyRef {
410
+ store: QuestionBodyStore;
411
+ ref: string;
412
+ digest: string;
413
+ }
414
+ export interface RoutingHistoryEntry {
415
+ hop: number;
416
+ audience: SeniorRef;
417
+ at: string;
418
+ reason: RoutingReason;
419
+ }
420
+ export interface QuestionAnswer {
421
+ choice: string;
422
+ /** Whether the answer selected an offered option or supplied new text. */
423
+ answer_kind?: "option" | "freeform";
424
+ notes_ref?: string;
425
+ answered_by: string;
426
+ answered_at: string;
427
+ answered_level: number;
428
+ }
429
+ /**
430
+ * A question whose options amount to "continue" or "stop" the brief's own
431
+ * work. The brief already authorises finishing everything it lists, so such a
432
+ * question is flagged for the operator; nothing answers it automatically.
433
+ */
434
+ export type QuestionKind = "continue";
435
+ export interface QuestionRecord {
436
+ schema_version: typeof QUESTION_SCHEMA_VERSION | string;
437
+ question_id: string;
438
+ lane_id: string;
439
+ /** Set by the raiser when the options are only continue/stop. */
440
+ question_kind?: QuestionKind;
441
+ /** `null` when the originating lane has no company. */
442
+ company: LaneCompanyRef | null;
443
+ project_id: string;
444
+ story_id: string;
445
+ thread_id?: string;
446
+ raised_via: RaisedVia;
447
+ asked_at: string;
448
+ origin: {
449
+ kind: "lane";
450
+ id: string;
451
+ };
452
+ hop: number;
453
+ status: QuestionStatus;
454
+ version: number;
455
+ body: QuestionBodyRef;
456
+ routing_history: RoutingHistoryEntry[];
457
+ answer?: QuestionAnswer;
458
+ /** Merge-on-read preservation of answers retained by conflict sidecars. */
459
+ answer_history?: QuestionAnswer[];
460
+ }
461
+ export interface EnvelopeQuestion {
462
+ question: string;
463
+ context: string;
464
+ options: string[];
465
+ recommended?: string;
466
+ }
467
+ export interface LaneEnvelope {
468
+ schema_version: typeof ENVELOPE_SCHEMA_VERSION;
469
+ decision: EnvelopeDecision;
470
+ summary: string;
471
+ questions?: EnvelopeQuestion[];
472
+ story_status: StoryStatus;
473
+ artifacts: unknown[];
474
+ blocked_reason?: string;
475
+ story_complete?: boolean;
476
+ story_complete_reason?: string;
477
+ }
478
+ export interface AccountConfig {
479
+ home: string;
480
+ enabled: boolean;
481
+ disabled_reason?: string;
482
+ max_running?: number;
483
+ /** Default model for this account. Beats the provider default; beaten by --model. */
484
+ model?: string;
485
+ /** Default effort for this account. Beats the provider default; beaten by --effort. */
486
+ effort?: string;
487
+ }
488
+ export interface ProviderConfig {
489
+ max_running: number;
490
+ max_queued: number;
491
+ /**
492
+ * Accepted and ignored for selection. Kept so existing config files parse.
493
+ * Account pick is least-loaded among enabled, logged-in accounts.
494
+ */
495
+ default_account?: string;
496
+ /** Default model for this provider when the account does not set one. */
497
+ model?: string;
498
+ /** Default effort for this provider when the account does not set one. */
499
+ effort?: string;
500
+ /**
501
+ * Resume-time compaction threshold: a resumed session whose last message is
502
+ * at least this old is compacted first. Absent means the one-hour default.
503
+ */
504
+ compact_after_ms?: number;
505
+ /**
506
+ * Watcher throttle for `lane_progress` thread events: at most one per this
507
+ * interval, and only on a tick that saw new tool activity or output. Absent
508
+ * means the five-minute default.
509
+ */
510
+ progress_event_min_interval_ms?: number;
511
+ accounts: Record<string, AccountConfig>;
512
+ }
513
+ export interface ThrottleConfig {
514
+ cpu_busy_pause: number;
515
+ cpu_busy_resume: number;
516
+ min_available_mem_mb: number;
517
+ }
518
+ /** Session liveness windows from spec §9. Missing keys keep these documented defaults. */
519
+ export interface LivenessWindows {
520
+ /** Last event within this window (or connected presence) → live. Default 10 minutes. */
521
+ live_within_ms: number;
522
+ /** `turn_start` with no later `turn_end` after this window → lost. Default 2 hours. */
523
+ turn_start_lost_ms: number;
524
+ /** No event at all for this window (and no `session_end`) → lost. Default 12 hours. */
525
+ silent_lost_ms: number;
526
+ }
527
+ export interface LanesConfig {
528
+ schema_version: typeof CONFIG_SCHEMA_VERSION | string;
529
+ providers: Record<LaneProvider, ProviderConfig>;
530
+ throttle: ThrottleConfig;
531
+ liveness: LivenessWindows;
532
+ }
533
+ export declare function parseMajorSchema(schemaVersion: string, expectedPrefix: string, expectedMajor: number): void;
534
+ export declare function parseLaneEnvelope(raw: unknown): LaneEnvelope;
535
+ //# sourceMappingURL=types.d.ts.map