lua-cli 3.32.1 → 3.32.3

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.
@@ -12,7 +12,9 @@ import { PathOrLiteral } from '@lua/workflow-graph';
12
12
  import { SerializedWorkflowGraph } from '@lua/workflow-graph';
13
13
  import { TemplateBinding } from '@lua/workflow-graph';
14
14
  import { TypedRef } from '@lua/workflow-graph';
15
+ import type { WorkflowExecFn } from '@lua/shared-types/workflow-exec';
15
16
  import { WorkflowGraphEntry } from '@lua/workflow-graph';
17
+ import type { WorkflowShellFn } from '@lua/shared-types/workflow-exec';
16
18
  import type { z } from 'zod';
17
19
  import { ZodType } from 'zod';
18
20
 
@@ -26,13 +28,13 @@ export declare interface AgentStepOptions {
26
28
  };
27
29
  timeoutSeconds?: number;
28
30
  retry?: RetryPolicy;
29
- onError?: 'fail' | 'continue' | 'park';
31
+ onError?: WorkflowOnError;
30
32
  requiredConnections?: string[];
31
33
  /** static-only persona override (§11 S3) */
32
34
  systemPrompt?: string;
33
- tier?: 'job';
35
+ tier?: WorkflowTier;
34
36
  workspace?: WorkflowStepWorkspace;
35
- jobResources?: 'small' | 'medium' | 'large';
37
+ jobResources?: WorkflowJobResources;
36
38
  harness?: WorkflowJobHarness;
37
39
  /** Coding-turn cap for a tier:'job' step (1..500); absent ⇒ the platform default. A monorepo change needs more than the default. */
38
40
  maxTurns?: number;
@@ -41,7 +43,8 @@ export declare interface AgentStepOptions {
41
43
  * attempt (every pass and resumed segment). Crossing one checkpoints the workspace and ends the attempt
42
44
  * `attempt_budget_exhausted` — retryable, so the step's `retry` policy continues from that tree with a fresh
43
45
  * session. `maxMessages` counts harness messages (one per content block; 1..5000, default 400),
44
- * `maxInputTokens` the attempt's input-side tokens (prompt + cache; 1M..500M, default 30M).
46
+ * `maxInputTokens` the attempt's input-side tokens (prompt + cache; 1M..500M, default 4M — LUA-708: the per-attempt
47
+ * cost bound, since `budget.maxCredits` counts attempts, not tokens).
45
48
  */
46
49
  maxMessages?: number;
47
50
  maxInputTokens?: number;
@@ -67,7 +70,7 @@ export declare interface ApprovalOptions {
67
70
  /** 'deny' (default) | 'cancel-run' | 'fail' | a chain of ≤ 3 hops ending in one terminal member */
68
71
  onTimeout?: WorkflowSuspendTimeoutChain;
69
72
  /** default 'continue' (denial is data unless 'fail') */
70
- onDeny?: 'fail' | 'continue';
73
+ onDeny?: WorkflowApprovalOnDeny;
71
74
  businessHours?: WorkflowBusinessHours;
72
75
  editable?: boolean;
73
76
  /** grammar: `drafts`, `drafts[*]`, `drafts[*].body`, `drafts[3].body`, `summary.title` */
@@ -97,7 +100,13 @@ declare interface BuiltWorkflow {
97
100
  }>;
98
101
  }
99
102
 
100
- /** A container arm: a `StepRef`, or (B14 — lands with WF-509) the two-element chain `[mapConfig, stepRef]`. */
103
+ /**
104
+ * A container arm: a `StepRef` — a `createStep` object, or a string naming an entry declared elsewhere in the chain
105
+ * (`agentStep` / `specialistStep` / `toolStep` / `workflow`, and since LUA-684 `approval` / `waitForSignal`, so an
106
+ * approval can run concurrently with another row) — or (B14 — lands with WF-509) the two-element chain
107
+ * `[mapConfig, stepRef]`. A HITL arm takes the previous output as its payload, so it never heads a `[map, step]`
108
+ * chain, and a `loop` body cannot be one until the engine proves it (`node-type-unsupported-in-container`).
109
+ */
101
110
  export declare type ContainerArm = StepRef | [LuaMapConfig, StepRef];
102
111
 
103
112
  export declare function createStep<TIn extends ZodType, TOut extends ZodType, TResume extends ZodType = ZodType>(s: LuaWorkflowStep<TIn, TOut, TResume>): LuaWorkflowStep<TIn, TOut, TResume>;
@@ -276,20 +285,28 @@ export declare type LuaWorkflowBuildCode = 'duplicate-step-id' | 'unknown-step-r
276
285
  * verdict (deferred for an inherit child, 03 §3.1 table). Kept for one minor so a consumer switching on the union still
277
286
  * compiles; removed in the next.
278
287
  */
279
- | 'workspace-not-declared' | 'workspace-inherit-without-parent-workspace' | 'workspace-inherit-conflict' | 'harness-requires-job-tier' | 'max-turns-requires-job-tier' | 'max-turns-invalid' | 'cap-exceeded' | 'chunk-size-invalid' | 'rate-limit-invalid' | 'backoff-invalid' | 'loop-interval-out-of-range' | 'mapping-placement' | 'container-arm-empty' | 'approval-inside-container' | 'empty-graph' | 'ephemeral-role-too-long' | 'role-ref-and-inline' | 'approver-excludes-only-candidate' | 'four-eyes-requires-editable' | 'escalation-chain-not-terminal' | 'escalation-chain-too-long' | 'editable-path-invalid' | 'env-template-secret-key' | 'invalid-envelope' | 'invalid-step' | 'invalid-step-id' | 'invalid-workflow-name' | 'schedule-input-required' | 'schedule-input-invalid' | 'hitl-duration-defaulted' | 'WORKFLOW_UNPLACED_STEP';
288
+ | 'workspace-not-declared' | 'workspace-inherit-without-parent-workspace' | 'workspace-inherit-conflict' | 'harness-requires-job-tier' | 'max-turns-requires-job-tier' | 'max-turns-invalid' | 'cap-exceeded' | 'chunk-size-invalid' | 'rate-limit-invalid' | 'backoff-invalid' | 'loop-interval-out-of-range' | 'mapping-placement' | 'container-arm-empty'
289
+ /**
290
+ * @deprecated LUA-684 — the builder no longer throws it: an `approval` / `waitForSignal` IS a container arm
291
+ * (`parallel(['approve', …])`). Where the engine cannot run one — a `loop` body, the step of a `[map, step]`
292
+ * chain — the code is `node-type-unsupported-in-container`. Kept for one minor so a consumer switching on the
293
+ * union still compiles; removed in the next.
294
+ */
295
+ | 'approval-inside-container' | 'node-type-unsupported-in-container' | 'empty-graph' | 'ephemeral-role-too-long' | 'role-ref-and-inline' | 'approver-excludes-only-candidate' | 'four-eyes-requires-editable' | 'escalation-chain-not-terminal' | 'escalation-chain-too-long' | 'editable-path-invalid' | 'env-template-secret-key' | 'invalid-envelope' | 'invalid-step' | 'invalid-step-id' | 'invalid-workflow-name' | 'schedule-input-required' | 'schedule-input-invalid' | 'hitl-duration-defaulted' | 'WORKFLOW_UNPLACED_STEP';
280
296
 
281
297
  export declare interface LuaWorkflowBuilder {
282
298
  then(step: StepRef): this;
283
- /** 2..16 arms; output = { [stepId]: output } */
299
+ /** 2..16 arms; output = { [stepId]: output }. An `approval` / `waitForSignal` arm (by id) parks beside its siblings. */
284
300
  parallel(steps: ContainerArm[], opts?: {
285
301
  merge?: WorkflowMergePolicy;
286
302
  }): this;
287
- /** all-true arms run (Mastra); exclusive:true ≡ switch() */
303
+ /** all-true arms run (Mastra); exclusive:true ≡ switch(). An arm may name a declared `approval` / `waitForSignal`. */
288
304
  branch(arms: Array<[LuaPredicate, StepRef]>, opts?: {
289
305
  exclusive?: boolean;
290
306
  }): this;
291
307
  /** first true arm only ⇒ conditional{ exclusive:true, otherwise } */
292
308
  switch(arms: Array<[LuaPredicate, StepRef]>, otherwise?: StepRef): this;
309
+ /** one body run per item; an `approval` / `waitForSignal` body (by id) is one approval / wait per item */
293
310
  foreach(step: ContainerArm, opts?: ForeachOptions): this;
294
311
  dowhile(step: ContainerArm, predicate: LuaPredicate, opts?: LoopOptions): this;
295
312
  dountil(step: ContainerArm, predicate: LuaPredicate, opts?: LoopOptions): this;
@@ -312,12 +329,11 @@ export declare interface LuaWorkflowBuilder {
312
329
  /** D25 ephemeral specialist: runs AS THE OWNING AGENT (`agentId:'$self'`) with an additive role block. */
313
330
  specialistStep(id: string, opts: SpecialistStepOptions): this;
314
331
  toolStep(id: string, tool: LuaTool<any>, opts?: ToolStepOptions): this;
332
+ /** a declaration like `agentStep` (LUA-684): placed where called unless a container claims the id — `parallel(['approve', …])` */
315
333
  approval(id: string, opts: ApprovalOptions): this;
316
334
  waitForSignal(id: string, opts: WaitForSignalOptions): this;
317
335
  /** nested run; depth ≤ 3 — declares `id`, so a container may place it by string ref (03 §3.2.0) */
318
- workflow(id: string, ref: LuaWorkflow | string, input?: LuaMapConfig, opts?: {
319
- workspace?: 'inherit';
320
- }): this;
336
+ workflow(id: string, ref: LuaWorkflow | string, input?: LuaMapConfig, opts?: NestedWorkflowOptions): this;
321
337
  commit(): LuaWorkflow;
322
338
  }
323
339
 
@@ -345,12 +361,23 @@ export declare interface LuaWorkflowConfig {
345
361
  concurrencyPolicy?: 'allow' | 'forbid';
346
362
  /** Who may READ this workflow's run outputs beyond `workflows:read-outputs` holders (B44). Envelope member outside `graphHash`. */
347
363
  outputVisibility?: WorkflowOutputVisibility;
348
- /** `maxDurationSeconds` default 604 800; 2 592 000 when the graph contains an approval / waitForSignal / suspend-capable step (P1-4). */
349
- budget?: {
350
- maxCredits?: number;
351
- maxSteps?: number;
352
- maxDurationSeconds?: number;
353
- };
364
+ /**
365
+ * `maxDurationSeconds` default 604 800; 2 592 000 when the graph contains an approval / waitForSignal / suspend-capable
366
+ * step (P1-4). The three members the SDK forwards, spelled by the ONE definition budget (`WorkflowDefinitionBudget`).
367
+ *
368
+ * `maxCredits` never meters tokens (LUA-708). Flat metering (every run while `LUA_WORKFLOWS_METERING_V2` is off):
369
+ * an inline agent step settles a flat 1 credit when it completes, a `tier:'job'` attempt a flat 4 at its first
370
+ * claim (a retry is a new attempt) — so `maxCredits: 40` buys ten Job-tier attempts, and a value under 4 never
371
+ * dispatches one. Priced metering (LUA-724, the flag on): an inline agent step settles what chat charged for the
372
+ * turn — one credit per model call on the legacy plan, `tier × model multiplier` actions on a seat plan (then the
373
+ * cap is compared in actions) — and `lua workflows status` says which mode a run used (`usage.metering`). Either
374
+ * way the run parks on a budget gate (`nextAction:'raise_budget'`, `lua workflows raise-budget`) when what remains
375
+ * is under the next agent step's reserve. Each Job-tier attempt then runs to its own wall (`timeoutSeconds`),
376
+ * `maxInputTokens` (default 4M ≈ $1–13 on a Sonnet-class model), `maxMessages` and `maxTurns`; nothing meters its
377
+ * tokens against the credits mid-attempt. Size `maxInputTokens` for what one attempt may cost and `maxCredits`
378
+ * for how many attempts the run may make.
379
+ */
380
+ budget?: Pick<WorkflowDefinitionBudget, 'maxCredits' | 'maxSteps' | 'maxDurationSeconds'>;
354
381
  /** verbatim LuaJob union (D12) → Job{kind:'workflow'} on publish */
355
382
  schedule?: JobSchedule;
356
383
  backfillOnEnable?: {
@@ -383,16 +410,16 @@ export declare interface LuaWorkflowStep<TIn extends ZodType = ZodType, TOut ext
383
410
  /** 1..600 (D19); default 300 — on `tier:'job'` 1..86 400, default 3600. */
384
411
  timeoutSeconds?: number;
385
412
  /** Run this step as a k8s Job (hours tier). Implied by `workspace`. */
386
- tier?: 'job';
413
+ tier?: WorkflowTier;
387
414
  workspace?: WorkflowStepWorkspace;
388
- jobResources?: 'small' | 'medium' | 'large';
415
+ jobResources?: WorkflowJobResources;
389
416
  jobTools?: WorkflowJobToolId[];
390
417
  /** default { maxAttempts: 1 } */
391
418
  retry?: RetryPolicy;
392
419
  /** default 'none'; 'external' ⇒ park on platform-fault reclaim. */
393
- sideEffects?: 'none' | 'external';
420
+ sideEffects?: WorkflowSideEffects;
394
421
  /** What the FINAL failure of this step does to the run (default 'fail'). */
395
- onError?: 'fail' | 'continue' | 'park';
422
+ onError?: WorkflowOnError;
396
423
  requiredConnections?: string[];
397
424
  /** Deadline for a `ctx.suspend()` suspension; default 168, max 720. */
398
425
  resumeTimeoutHours?: number;
@@ -404,6 +431,18 @@ export { MapDescriptor }
404
431
 
405
432
  export declare const ne: <T>(l: TypedRef<T>, r: TypedRef<T> | Literal<T>) => LuaPredicate;
406
433
 
434
+ /** `.workflow(id, ref, input?, opts?)` — a nested run (a `subrun` row). */
435
+ export declare interface NestedWorkflowOptions {
436
+ /** Mount the PARENT's run workspace in the child (05 §5.17.5; LUA-650) — the parent must declare one. */
437
+ workspace?: 'inherit';
438
+ /**
439
+ * LUA-669 (#2446): the same policy a code / agent / tool step carries — the row re-arms when the child run ends
440
+ * `failed` or `timed_out` on its own (a child the parent side ended — cancelled, abandoned — is never retried),
441
+ * behind the WF-222 backoff, and every attempt starts a FRESH child run. Default `{ maxAttempts: 1 }`.
442
+ */
443
+ retry?: RetryPolicy;
444
+ }
445
+
407
446
  export declare const not: (arg: LuaPredicate) => LuaPredicate;
408
447
 
409
448
  export declare const notExists: (ref: TypedRef<unknown>) => LuaPredicate;
@@ -419,15 +458,10 @@ export declare type PathValue<T, P extends string> = P extends `${infer H}.${inf
419
458
 
420
459
  export declare type ReplyChannel = 'whatsapp' | 'sms' | 'email' | 'webchat' | 'slack';
421
460
 
422
- export declare interface RetryPolicy {
423
- maxAttempts: number;
424
- /** delay before attempt 2 (default 0 = immediate) */
425
- backoffSeconds?: number;
426
- /** 'fixed' (default) | 'exponential' — an engine timer, never a sleep inside the step VM (P1-10). */
427
- backoff?: 'fixed' | 'exponential';
428
- /** default 3600; only meaningful with 'exponential' (`backoff-invalid` otherwise). */
429
- maxBackoffSeconds?: number;
430
- }
461
+ /** The ONE retry shape (`@lua/shared-types` `WorkflowRetryPolicy`): `maxAttempts` ≥ 1; `backoffSeconds` (default 0 =
462
+ * immediate) — an engine timer, never a sleep inside the step VM (P1-10); `backoff` 'fixed' (default) | 'exponential';
463
+ * `maxBackoffSeconds` (default 3600) only meaningful with 'exponential' (`backoff-invalid` otherwise). */
464
+ export declare type RetryPolicy = WorkflowRetryPolicy;
431
465
 
432
466
  export declare const rows: (s: LuaWorkflowStep<any, any, any> | string, path: string, page: {
433
467
  offset: number;
@@ -446,7 +480,7 @@ export declare interface SpecialistStepOptions {
446
480
  toolScope?: AgentToolScope;
447
481
  timeoutSeconds?: number;
448
482
  retry?: RetryPolicy;
449
- onError?: 'fail' | 'continue' | 'park';
483
+ onError?: WorkflowOnError;
450
484
  requiredConnections?: string[];
451
485
  }
452
486
 
@@ -538,8 +572,8 @@ export declare interface ToolStepOptions {
538
572
  input?: LuaMapConfig;
539
573
  timeoutSeconds?: number;
540
574
  retry?: RetryPolicy;
541
- sideEffects?: 'none' | 'external';
542
- onError?: 'fail' | 'continue' | 'park';
575
+ sideEffects?: WorkflowSideEffects;
576
+ onError?: WorkflowOnError;
543
577
  requiredConnections?: string[];
544
578
  }
545
579
 
@@ -554,16 +588,42 @@ export declare interface WaitForSignalOptions {
554
588
  schema?: ZodType;
555
589
  timeoutHours?: number | TemplateBinding;
556
590
  /** default 'fail'; 'continue' ⇒ output {received:false,timedOut:true} */
557
- onTimeout?: 'fail' | 'continue';
591
+ onTimeout?: WorkflowSignalOnTimeout;
558
592
  businessHours?: WorkflowBusinessHours;
559
593
  /** default ['webhook','api','user'] */
560
594
  acceptedSources?: Array<'webhook' | 'api' | 'user' | 'agent'>;
561
595
  }
562
596
 
597
+ /** `approval.onDeny` (§6.4.11 deny-as-data): `'fail'` fails the step on a denial; default `'continue'`. */
598
+ declare const WORKFLOW_APPROVAL_ON_DENY: readonly ["fail", "continue"];
599
+
563
600
  export declare const WORKFLOW_DEFAULT_MAX_DURATION_SECONDS = 604800;
564
601
 
565
602
  export declare const WORKFLOW_HITL_MAX_DURATION_SECONDS = 2592000;
566
603
 
604
+ /** D19-r2 (B22; 05 §5.17.6 Harness row) — both behind one `CodingHarness { run(turn) }`. */
605
+ declare const WORKFLOW_JOB_HARNESSES: readonly ["claude-code", "generic"];
606
+
607
+ /** `jobResources` (05 §5.17): the Job-tier pod size class. Default `'small'` at spawn. */
608
+ declare const WORKFLOW_JOB_RESOURCES: readonly ["small", "medium", "large"];
609
+
610
+ /** What the FINAL failure of a step does to the run: `'park'` → the §06 §6.3.5 exception gate. Default `'fail'`. */
611
+ declare const WORKFLOW_ON_ERROR: readonly ["fail", "continue", "park"];
612
+
613
+ /** `backoff` absent ⇒ `'fixed'`; `'exponential'` = backoffSeconds·2^(attempt−1) capped at `maxBackoffSeconds`. */
614
+ declare const WORKFLOW_RETRY_BACKOFFS: readonly ["fixed", "exponential"];
615
+
616
+ /** `sideEffects` (03 §3.1): `'external'` ⇒ park on platform-fault reclaim instead of retrying. Default `'none'`. */
617
+ declare const WORKFLOW_SIDE_EFFECTS: readonly ["none", "external"];
618
+
619
+ /** `waitForSignal.onTimeout`: default `'fail'`; `'continue'` ⇒ output `{received:false, timedOut:true}`. */
620
+ declare const WORKFLOW_SIGNAL_ON_TIMEOUT: readonly ["fail", "continue"];
621
+
622
+ /** The only tier a node may DECLARE (`tier:'job'`, implied by `workspace`); the worker tier is the absence. */
623
+ declare const WORKFLOW_TIERS: readonly ["job"];
624
+
625
+ declare type WorkflowApprovalOnDeny = (typeof WORKFLOW_APPROVAL_ON_DENY)[number];
626
+
567
627
  export declare type WorkflowApproverSpec = 'creator' | 'org-admins' | {
568
628
  users: string[] | TemplateBinding;
569
629
  } | {
@@ -607,15 +667,37 @@ export declare interface WorkflowBusinessHours {
607
667
  };
608
668
  }
609
669
 
610
- declare interface WorkflowConnectionDeclaration {
670
+ /** The ONE `connections[]` declaration shape (`@lua/shared-types`): `key` /^[a-z][a-z0-9_-]{0,63}$/ unique per workflow,
671
+ * `integrationType` the catalog type (`'github'`, `'linear'`, …), optional `required` / `description`. */
672
+ declare type WorkflowConnectionDeclaration = WorkflowConnectionDeclaration_2;
673
+
674
+ declare interface WorkflowConnectionDeclaration_2 {
611
675
  /** /^[a-z][a-z0-9_-]{0,63}$/ — unique per workflow. */
612
676
  key: string;
613
- /** Catalog integration type (`'github'`, `'linear'`, …). */
677
+ /** Catalog integration type (`github`, `linear`, …) the key resolves within. */
614
678
  integrationType: string;
615
679
  required?: boolean;
616
680
  description?: string;
617
681
  }
618
682
 
683
+ /** The declared budget (10 §10.7.1) — every member optional on the DEFINITION; the server resolves
684
+ * `maxDurationSeconds` onto the version (`WorkflowVersion.budget`) and the run. */
685
+ declare interface WorkflowDefinitionBudget {
686
+ /**
687
+ * The run's credit ceiling — it counts agent steps, never tokens (LUA-708). An inline agent step settles a flat
688
+ * 1 credit when it completes; a `tier:'job'` attempt settles a flat 4 at its first claim (a retry is a new
689
+ * attempt). The engine parks the run on a budget gate (`nextAction:'raise_budget'`) when what remains is under
690
+ * the next agent step's reserve, so `maxCredits: 40` is ten Job-tier attempts and a value under 4 never
691
+ * dispatches one. A Job-tier attempt's own spend is bounded by its wall / `maxInputTokens` / `maxMessages`.
692
+ */
693
+ maxCredits?: number;
694
+ maxSteps?: number;
695
+ /** Job-tier seconds across the run (05 §5.17). */
696
+ maxJobSeconds?: number;
697
+ /** default 604 800; 2 592 000 when the graph contains an approval / waitForSignal / suspend-capable step (P1-4). */
698
+ maxDurationSeconds?: number;
699
+ }
700
+
619
701
  export declare interface WorkflowFourEyes {
620
702
  edit: WorkflowApproverSpec;
621
703
  approve: WorkflowApproverSpec;
@@ -635,7 +717,11 @@ export declare interface WorkflowGoalEnvelope {
635
717
  initialState?: Record<string, unknown>;
636
718
  }
637
719
 
638
- export declare type WorkflowJobHarness = 'claude-code' | 'generic';
720
+ export declare type WorkflowJobHarness = WorkflowJobHarness_2;
721
+
722
+ declare type WorkflowJobHarness_2 = (typeof WORKFLOW_JOB_HARNESSES)[number];
723
+
724
+ declare type WorkflowJobResources = (typeof WORKFLOW_JOB_RESOURCES)[number];
639
725
 
640
726
  export declare type WorkflowJobToolId = 'shell' | 'read' | 'write' | 'edit' | 'glob' | 'grep' | 'git' | 'gh' | 'fetch';
641
727
 
@@ -644,14 +730,32 @@ export declare interface WorkflowMergePolicy {
644
730
  onConflict: 'fail' | 'agent';
645
731
  }
646
732
 
733
+ declare type WorkflowOnError = (typeof WORKFLOW_ON_ERROR)[number];
734
+
647
735
  export declare interface WorkflowOutputVisibility {
648
736
  roles: string[];
649
737
  users?: string[];
650
738
  ownerBypass?: boolean;
651
739
  }
652
740
 
741
+ declare type WorkflowRetryBackoff = (typeof WORKFLOW_RETRY_BACKOFFS)[number];
742
+
743
+ declare interface WorkflowRetryPolicy {
744
+ maxAttempts: number;
745
+ /** delay before attempt 2 (default 0 = immediate) — an engine timer, never a sleep inside the step VM (P1-10). */
746
+ backoffSeconds?: number;
747
+ /** `'fixed'` (default) | `'exponential'` */
748
+ backoff?: WorkflowRetryBackoff;
749
+ /** default 3600; only meaningful with `'exponential'` (`backoff-invalid` otherwise). */
750
+ maxBackoffSeconds?: number;
751
+ }
752
+
653
753
  export declare type WorkflowRunTrigger = 'chat' | 'sdk' | 'api' | 'schedule' | 'webhook' | 'template' | 'workflow' | 'device';
654
754
 
755
+ declare type WorkflowSideEffects = (typeof WORKFLOW_SIDE_EFFECTS)[number];
756
+
757
+ declare type WorkflowSignalOnTimeout = (typeof WORKFLOW_SIGNAL_ON_TIMEOUT)[number];
758
+
655
759
  export declare interface WorkflowSpecialistRole {
656
760
  name: string;
657
761
  instructions: string;
@@ -675,7 +779,11 @@ export declare interface WorkflowStepContext<TIn = unknown, TResume = unknown, T
675
779
  /** What the prior invocation passed to `suspend()`. */
676
780
  suspendData?: unknown;
677
781
  getInitData<T = unknown>(): T;
678
- /** Output of an UPSTREAM step. Throws `WorkflowStepResultError{ code:'STEP_RESULT_NOT_ANCESTOR' }` for a non-ancestor. */
782
+ /**
783
+ * Output of an UPSTREAM step. Throws `WorkflowStepResultError` — `code:'STEP_RESULT_NOT_ANCESTOR'` for a
784
+ * non-ancestor (or unknown) id, `'STEP_RESULT_TOO_LARGE'` / `'STEP_RESULT_OFFLOADED'` for an output the claim
785
+ * could not carry (see the error's doc for `bytes` / `reason`) — never `undefined`, never a raw ref object.
786
+ */
679
787
  getStepResult<T = unknown>(stepId: string): T;
680
788
  /** Run-scoped KV, ledger-backed, ≤ 64KB total. `set` is durable when the step terminalizes. */
681
789
  state: {
@@ -694,17 +802,65 @@ export declare interface WorkflowStepContext<TIn = unknown, TResume = unknown, T
694
802
  signal: AbortSignal;
695
803
  /** Sub-agent env, exactly as jobs receive it. */
696
804
  env: Record<string, string>;
697
- /** EXACTLY-ONCE effect keyed on `{occurrenceId, key}` (P1-18). Claim → run `fn` → settle. */
805
+ /**
806
+ * EXACTLY-ONCE effect keyed on `{occurrenceId, key}` (P1-18). Claim → run `fn` → settle. Served on every tier:
807
+ * worker-tier steps and the offline driver, and (LUA-722) Job-tier code steps — the pod relays the claim / settle
808
+ * under its own attempt token, so the key is scoped to the step's run / row / attempt server-side. A replayed key
809
+ * (a retried attempt, a repair run) returns the settled result without running `fn`; a key a previous attempt
810
+ * claimed and never settled throws `EFFECT_IN_DOUBT` (fail closed — `fn` never runs on an unknown claim state).
811
+ * The result is JSON-serialised on settle, exactly like a step output: a `Date` replays as its ISO string, a
812
+ * `BigInt` (or a cycle) fails the settle — `EFFECT_SETTLE_FAILED`, the key stays claimed — and a result over the
813
+ * platform's cap (32 KB) is `EFFECT_SETTLE_FAILED` naming `EFFECT_RESULT_TOO_LARGE`. Calling `once` again for the
814
+ * same key while its `fn` is still running (re-entrantly) throws `EFFECT_KEY_INVALID` at once.
815
+ */
698
816
  once<T>(key: string, fn: () => Promise<T>): Promise<T>;
699
- /** Job-tier steps only: the mounted run workspace. */
817
+ /**
818
+ * Job-tier steps only: the mounted run workspace, exactly as the Job pod hands it to `execute` (`ctx.workspace` in
819
+ * `packages/lua-workflow-job/src/code-step.ts`): `root` is the absolute directory of the checkout (`/workspace`),
820
+ * `branch` the run branch it is on, `headSha` the commit it was restored at, `mount` this step's declared mount,
821
+ * `isolation` whether the step got its own worktree. LUA-679: the name is `root` — the 3.32.1 type and both
822
+ * `lua init` examples said `path`, the pod never served it, and a copied definition died `ENOENT /workspace/undefined`.
823
+ */
700
824
  workspace?: {
701
- path: string;
825
+ root: string;
702
826
  mount: 'rw' | 'ro';
703
827
  branch?: string;
828
+ headSha?: string;
829
+ isolation?: 'shared' | 'worktree';
830
+ /**
831
+ * @deprecated LUA-679 — read `root`. The Job pod serves `path` as an alias (a getter that returns `root` and warns
832
+ * once per step) for one minor after 3.32 and then removes it; it never appears on `Object.keys(ctx.workspace)`.
833
+ */
834
+ readonly path?: string;
835
+ /**
836
+ * The run workspace's stamps, served when the pod hands them to the step (LUA-706): `baseSha` is the commit the
837
+ * run's base ref resolved to at provision (a git workspace — `headSha` is where THIS step's checkout is), `arm`
838
+ * the worktree arm id when the step runs in its own worktree (`isolation:'worktree'`), `backend` the volume
839
+ * backend. Absent on an `empty` workspace, a shared-mount step, or a pod that predates them.
840
+ */
704
841
  baseSha?: string;
705
842
  arm?: string;
706
843
  backend?: WorkflowWorkspaceBackend;
707
844
  };
845
+ /**
846
+ * Job-tier steps only (LUA-682): run one of `WORKFLOW_EXEC_BINARIES` (`git`, `gh`, `pnpm`, `npm`, `npx`, `node`,
847
+ * `yarn`, `python3`, `pytest`, `make`) in the workspace — `exec(['git', 'status'], { cwd?, timeoutMs?, env? })`.
848
+ * Argv only, never a shell: no `&&`, pipes, globs or `$VAR`; `cwd` must stay inside the workspace; the timeout
849
+ * (default 10 min) is capped by the step's remaining wall; stdout / stderr are kept to 1 MiB each (`truncated`);
850
+ * one command at a time. A non-zero exit is RETURNED (`result.code`) — `exec.strict` throws `WorkflowExecError`.
851
+ * The Job pod spawns the command itself with a scrubbed env (no token, no `LUA_WF_*`; git goes through the
852
+ * credential proxy exactly as the coding turn's does); `child_process` is not available to a code step and fails
853
+ * `lua compile` with `node-capability-unavailable`. Worker-tier steps have neither `exec` nor `$`. Offline,
854
+ * `lua workflows run --workspace <dir>` provides both with the same allowlist against your own PATH.
855
+ */
856
+ exec?: WorkflowExecFn;
857
+ /**
858
+ * Job-tier steps only (LUA-682): `exec` as a tagged template — `$\`gh pr create --title ${title} --body ${body}\``.
859
+ * Literal text splits on whitespace (with `'…'` / `"…"` quoting); every `${value}` is exactly ONE argument, never
860
+ * re-parsed (a title with spaces, a body with newlines); an array spreads into one argument per item; `undefined`
861
+ * is refused rather than stringified. `$.strict` throws on a non-zero exit.
862
+ */
863
+ $?: WorkflowShellFn;
708
864
  /** The run artefact store (P1-8). */
709
865
  artefacts: {
710
866
  put(name: string, data: Uint8Array | string | ReadableStream, opts: {
@@ -739,7 +895,12 @@ export declare interface WorkflowStepContext<TIn = unknown, TResume = unknown, T
739
895
  }>;
740
896
  list(): Promise<WorkflowArtefactMeta[]>;
741
897
  };
742
- /** Stamped by the executor for observability; read-only. */
898
+ /**
899
+ * Stamped by the executor for observability; read-only (frozen). Served on both tiers from the run's stamps
900
+ * (LUA-706): `trigger` / `principalKind`, plus `parentRunId` / `traceparent` / `correlationKey` / `tags` /
901
+ * `replyTo` when the run carries them; `agentVersion` is not stamped today. A run created before the stamps
902
+ * existed reads `{}`. Offline, `lua workflows run` serves `{ trigger:'sdk', principalKind:'user' }`.
903
+ */
743
904
  runtime: {
744
905
  trigger: WorkflowRunTrigger;
745
906
  parentRunId?: string;
@@ -755,10 +916,26 @@ export declare interface WorkflowStepContext<TIn = unknown, TResume = unknown, T
755
916
  };
756
917
  }
757
918
 
758
- /** Thrown by `ctx.getStepResult` for a non-ancestor / unknown id — never `undefined` (03 §3.1). */
919
+ /**
920
+ * Thrown by `ctx.getStepResult` — never `undefined`, never a raw ref object (03 §3.1). Check `err.code`, never
921
+ * `instanceof` (a step runs in its own realm on every tier):
922
+ * - `STEP_RESULT_NOT_ANCESTOR` — `stepId` is not an upstream step of this one (or is unknown);
923
+ * - `STEP_RESULT_TOO_LARGE` — the ancestor's output could not ride the claim beside its siblings (the 4 MiB
924
+ * `stepResults` wire budget, dropped largest-first); `bytes` is its serialized size;
925
+ * - `STEP_RESULT_OFFLOADED` — the ledger holds the output offloaded (> 256 KB) and the claim could not carry it
926
+ * hydrated; `bytes` is its size, `reason` why: `over_wire_cap` (it would break the budget), `hydrate_timeout`
927
+ * (the per-claim hydration deadline passed), or the control plane's code (`CDN_REF_MISSING`, `CDN_REF_CORRUPT`,
928
+ * `CDN_REF_FOREIGN`, …).
929
+ * For the last two, bind the value through the step's input instead, or read it via `ctx.artefacts` /
930
+ * `ctx.datasets`. The offline driver (`lua workflows execute`) only ever throws the first.
931
+ */
759
932
  export declare interface WorkflowStepResultError extends Error {
760
- code: 'STEP_RESULT_NOT_ANCESTOR';
933
+ code: 'STEP_RESULT_NOT_ANCESTOR' | 'STEP_RESULT_TOO_LARGE' | 'STEP_RESULT_OFFLOADED';
761
934
  stepId: string;
935
+ /** `STEP_RESULT_TOO_LARGE` / `STEP_RESULT_OFFLOADED`: the output's serialized size. */
936
+ bytes?: number;
937
+ /** `STEP_RESULT_OFFLOADED`: why the claim could not carry it. */
938
+ reason?: string;
762
939
  }
763
940
 
764
941
  export declare interface WorkflowStepWorkspace {
@@ -777,6 +954,8 @@ export declare type WorkflowSuspendTimeoutChainMember = 'deny' | 'cancel-run' |
777
954
  timeoutHours: number;
778
955
  };
779
956
 
957
+ declare type WorkflowTier = (typeof WORKFLOW_TIERS)[number];
958
+
780
959
  export declare type WorkflowWorkspaceBackend = 'ebs' | 'efs' | 's3';
781
960
 
782
961
  export declare type WorkspaceSpec = {
@@ -793,6 +972,10 @@ export declare type WorkspaceSpec = {
793
972
  kind: 'empty';
794
973
  sizeGb?: number;
795
974
  ttlHours?: number;
975
+ /**
976
+ * Keep the volume after the run completes: held until `ttlHours` (24 h when undeclared), then expired. A kept
977
+ * volume holds one of the organisation's workspace slots (`maxWorkspacesPerOrg`, 10 by default) until then.
978
+ */
796
979
  keepArtefacts?: boolean;
797
980
  backend?: WorkflowWorkspaceBackend;
798
981
  };