lua-cli 3.32.1 → 3.32.2

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,19 @@ 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` counts agent steps, never tokens (LUA-708): an inline agent step settles a flat 1 credit when it
369
+ * completes, a `tier:'job'` attempt a flat 4 at its first claim (a retry is a new attempt). The run parks on a
370
+ * budget gate (`nextAction:'raise_budget'`, `lua workflows raise-budget`) when what remains is under the next agent
371
+ * step's reserve — so `maxCredits: 40` buys ten Job-tier attempts, and a value under 4 never dispatches one. Each
372
+ * attempt then runs to its own wall (`timeoutSeconds`), `maxInputTokens` (default 4M ≈ $1–13 on a Sonnet-class
373
+ * model), `maxMessages` and `maxTurns`; nothing meters its tokens against the credits mid-attempt. Size
374
+ * `maxInputTokens` for what one attempt may cost and `maxCredits` for how many attempts the run may make.
375
+ */
376
+ budget?: Pick<WorkflowDefinitionBudget, 'maxCredits' | 'maxSteps' | 'maxDurationSeconds'>;
354
377
  /** verbatim LuaJob union (D12) → Job{kind:'workflow'} on publish */
355
378
  schedule?: JobSchedule;
356
379
  backfillOnEnable?: {
@@ -383,16 +406,16 @@ export declare interface LuaWorkflowStep<TIn extends ZodType = ZodType, TOut ext
383
406
  /** 1..600 (D19); default 300 — on `tier:'job'` 1..86 400, default 3600. */
384
407
  timeoutSeconds?: number;
385
408
  /** Run this step as a k8s Job (hours tier). Implied by `workspace`. */
386
- tier?: 'job';
409
+ tier?: WorkflowTier;
387
410
  workspace?: WorkflowStepWorkspace;
388
- jobResources?: 'small' | 'medium' | 'large';
411
+ jobResources?: WorkflowJobResources;
389
412
  jobTools?: WorkflowJobToolId[];
390
413
  /** default { maxAttempts: 1 } */
391
414
  retry?: RetryPolicy;
392
415
  /** default 'none'; 'external' ⇒ park on platform-fault reclaim. */
393
- sideEffects?: 'none' | 'external';
416
+ sideEffects?: WorkflowSideEffects;
394
417
  /** What the FINAL failure of this step does to the run (default 'fail'). */
395
- onError?: 'fail' | 'continue' | 'park';
418
+ onError?: WorkflowOnError;
396
419
  requiredConnections?: string[];
397
420
  /** Deadline for a `ctx.suspend()` suspension; default 168, max 720. */
398
421
  resumeTimeoutHours?: number;
@@ -404,6 +427,18 @@ export { MapDescriptor }
404
427
 
405
428
  export declare const ne: <T>(l: TypedRef<T>, r: TypedRef<T> | Literal<T>) => LuaPredicate;
406
429
 
430
+ /** `.workflow(id, ref, input?, opts?)` — a nested run (a `subrun` row). */
431
+ export declare interface NestedWorkflowOptions {
432
+ /** Mount the PARENT's run workspace in the child (05 §5.17.5; LUA-650) — the parent must declare one. */
433
+ workspace?: 'inherit';
434
+ /**
435
+ * LUA-669 (#2446): the same policy a code / agent / tool step carries — the row re-arms when the child run ends
436
+ * `failed` or `timed_out` on its own (a child the parent side ended — cancelled, abandoned — is never retried),
437
+ * behind the WF-222 backoff, and every attempt starts a FRESH child run. Default `{ maxAttempts: 1 }`.
438
+ */
439
+ retry?: RetryPolicy;
440
+ }
441
+
407
442
  export declare const not: (arg: LuaPredicate) => LuaPredicate;
408
443
 
409
444
  export declare const notExists: (ref: TypedRef<unknown>) => LuaPredicate;
@@ -419,15 +454,10 @@ export declare type PathValue<T, P extends string> = P extends `${infer H}.${inf
419
454
 
420
455
  export declare type ReplyChannel = 'whatsapp' | 'sms' | 'email' | 'webchat' | 'slack';
421
456
 
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
- }
457
+ /** The ONE retry shape (`@lua/shared-types` `WorkflowRetryPolicy`): `maxAttempts` ≥ 1; `backoffSeconds` (default 0 =
458
+ * immediate) — an engine timer, never a sleep inside the step VM (P1-10); `backoff` 'fixed' (default) | 'exponential';
459
+ * `maxBackoffSeconds` (default 3600) only meaningful with 'exponential' (`backoff-invalid` otherwise). */
460
+ export declare type RetryPolicy = WorkflowRetryPolicy;
431
461
 
432
462
  export declare const rows: (s: LuaWorkflowStep<any, any, any> | string, path: string, page: {
433
463
  offset: number;
@@ -446,7 +476,7 @@ export declare interface SpecialistStepOptions {
446
476
  toolScope?: AgentToolScope;
447
477
  timeoutSeconds?: number;
448
478
  retry?: RetryPolicy;
449
- onError?: 'fail' | 'continue' | 'park';
479
+ onError?: WorkflowOnError;
450
480
  requiredConnections?: string[];
451
481
  }
452
482
 
@@ -538,8 +568,8 @@ export declare interface ToolStepOptions {
538
568
  input?: LuaMapConfig;
539
569
  timeoutSeconds?: number;
540
570
  retry?: RetryPolicy;
541
- sideEffects?: 'none' | 'external';
542
- onError?: 'fail' | 'continue' | 'park';
571
+ sideEffects?: WorkflowSideEffects;
572
+ onError?: WorkflowOnError;
543
573
  requiredConnections?: string[];
544
574
  }
545
575
 
@@ -554,16 +584,42 @@ export declare interface WaitForSignalOptions {
554
584
  schema?: ZodType;
555
585
  timeoutHours?: number | TemplateBinding;
556
586
  /** default 'fail'; 'continue' ⇒ output {received:false,timedOut:true} */
557
- onTimeout?: 'fail' | 'continue';
587
+ onTimeout?: WorkflowSignalOnTimeout;
558
588
  businessHours?: WorkflowBusinessHours;
559
589
  /** default ['webhook','api','user'] */
560
590
  acceptedSources?: Array<'webhook' | 'api' | 'user' | 'agent'>;
561
591
  }
562
592
 
593
+ /** `approval.onDeny` (§6.4.11 deny-as-data): `'fail'` fails the step on a denial; default `'continue'`. */
594
+ declare const WORKFLOW_APPROVAL_ON_DENY: readonly ["fail", "continue"];
595
+
563
596
  export declare const WORKFLOW_DEFAULT_MAX_DURATION_SECONDS = 604800;
564
597
 
565
598
  export declare const WORKFLOW_HITL_MAX_DURATION_SECONDS = 2592000;
566
599
 
600
+ /** D19-r2 (B22; 05 §5.17.6 Harness row) — both behind one `CodingHarness { run(turn) }`. */
601
+ declare const WORKFLOW_JOB_HARNESSES: readonly ["claude-code", "generic"];
602
+
603
+ /** `jobResources` (05 §5.17): the Job-tier pod size class. Default `'small'` at spawn. */
604
+ declare const WORKFLOW_JOB_RESOURCES: readonly ["small", "medium", "large"];
605
+
606
+ /** What the FINAL failure of a step does to the run: `'park'` → the §06 §6.3.5 exception gate. Default `'fail'`. */
607
+ declare const WORKFLOW_ON_ERROR: readonly ["fail", "continue", "park"];
608
+
609
+ /** `backoff` absent ⇒ `'fixed'`; `'exponential'` = backoffSeconds·2^(attempt−1) capped at `maxBackoffSeconds`. */
610
+ declare const WORKFLOW_RETRY_BACKOFFS: readonly ["fixed", "exponential"];
611
+
612
+ /** `sideEffects` (03 §3.1): `'external'` ⇒ park on platform-fault reclaim instead of retrying. Default `'none'`. */
613
+ declare const WORKFLOW_SIDE_EFFECTS: readonly ["none", "external"];
614
+
615
+ /** `waitForSignal.onTimeout`: default `'fail'`; `'continue'` ⇒ output `{received:false, timedOut:true}`. */
616
+ declare const WORKFLOW_SIGNAL_ON_TIMEOUT: readonly ["fail", "continue"];
617
+
618
+ /** The only tier a node may DECLARE (`tier:'job'`, implied by `workspace`); the worker tier is the absence. */
619
+ declare const WORKFLOW_TIERS: readonly ["job"];
620
+
621
+ declare type WorkflowApprovalOnDeny = (typeof WORKFLOW_APPROVAL_ON_DENY)[number];
622
+
567
623
  export declare type WorkflowApproverSpec = 'creator' | 'org-admins' | {
568
624
  users: string[] | TemplateBinding;
569
625
  } | {
@@ -607,15 +663,37 @@ export declare interface WorkflowBusinessHours {
607
663
  };
608
664
  }
609
665
 
610
- declare interface WorkflowConnectionDeclaration {
666
+ /** The ONE `connections[]` declaration shape (`@lua/shared-types`): `key` /^[a-z][a-z0-9_-]{0,63}$/ unique per workflow,
667
+ * `integrationType` the catalog type (`'github'`, `'linear'`, …), optional `required` / `description`. */
668
+ declare type WorkflowConnectionDeclaration = WorkflowConnectionDeclaration_2;
669
+
670
+ declare interface WorkflowConnectionDeclaration_2 {
611
671
  /** /^[a-z][a-z0-9_-]{0,63}$/ — unique per workflow. */
612
672
  key: string;
613
- /** Catalog integration type (`'github'`, `'linear'`, …). */
673
+ /** Catalog integration type (`github`, `linear`, …) the key resolves within. */
614
674
  integrationType: string;
615
675
  required?: boolean;
616
676
  description?: string;
617
677
  }
618
678
 
679
+ /** The declared budget (10 §10.7.1) — every member optional on the DEFINITION; the server resolves
680
+ * `maxDurationSeconds` onto the version (`WorkflowVersion.budget`) and the run. */
681
+ declare interface WorkflowDefinitionBudget {
682
+ /**
683
+ * The run's credit ceiling — it counts agent steps, never tokens (LUA-708). An inline agent step settles a flat
684
+ * 1 credit when it completes; a `tier:'job'` attempt settles a flat 4 at its first claim (a retry is a new
685
+ * attempt). The engine parks the run on a budget gate (`nextAction:'raise_budget'`) when what remains is under
686
+ * the next agent step's reserve, so `maxCredits: 40` is ten Job-tier attempts and a value under 4 never
687
+ * dispatches one. A Job-tier attempt's own spend is bounded by its wall / `maxInputTokens` / `maxMessages`.
688
+ */
689
+ maxCredits?: number;
690
+ maxSteps?: number;
691
+ /** Job-tier seconds across the run (05 §5.17). */
692
+ maxJobSeconds?: number;
693
+ /** default 604 800; 2 592 000 when the graph contains an approval / waitForSignal / suspend-capable step (P1-4). */
694
+ maxDurationSeconds?: number;
695
+ }
696
+
619
697
  export declare interface WorkflowFourEyes {
620
698
  edit: WorkflowApproverSpec;
621
699
  approve: WorkflowApproverSpec;
@@ -635,7 +713,11 @@ export declare interface WorkflowGoalEnvelope {
635
713
  initialState?: Record<string, unknown>;
636
714
  }
637
715
 
638
- export declare type WorkflowJobHarness = 'claude-code' | 'generic';
716
+ export declare type WorkflowJobHarness = WorkflowJobHarness_2;
717
+
718
+ declare type WorkflowJobHarness_2 = (typeof WORKFLOW_JOB_HARNESSES)[number];
719
+
720
+ declare type WorkflowJobResources = (typeof WORKFLOW_JOB_RESOURCES)[number];
639
721
 
640
722
  export declare type WorkflowJobToolId = 'shell' | 'read' | 'write' | 'edit' | 'glob' | 'grep' | 'git' | 'gh' | 'fetch';
641
723
 
@@ -644,14 +726,32 @@ export declare interface WorkflowMergePolicy {
644
726
  onConflict: 'fail' | 'agent';
645
727
  }
646
728
 
729
+ declare type WorkflowOnError = (typeof WORKFLOW_ON_ERROR)[number];
730
+
647
731
  export declare interface WorkflowOutputVisibility {
648
732
  roles: string[];
649
733
  users?: string[];
650
734
  ownerBypass?: boolean;
651
735
  }
652
736
 
737
+ declare type WorkflowRetryBackoff = (typeof WORKFLOW_RETRY_BACKOFFS)[number];
738
+
739
+ declare interface WorkflowRetryPolicy {
740
+ maxAttempts: number;
741
+ /** delay before attempt 2 (default 0 = immediate) — an engine timer, never a sleep inside the step VM (P1-10). */
742
+ backoffSeconds?: number;
743
+ /** `'fixed'` (default) | `'exponential'` */
744
+ backoff?: WorkflowRetryBackoff;
745
+ /** default 3600; only meaningful with `'exponential'` (`backoff-invalid` otherwise). */
746
+ maxBackoffSeconds?: number;
747
+ }
748
+
653
749
  export declare type WorkflowRunTrigger = 'chat' | 'sdk' | 'api' | 'schedule' | 'webhook' | 'template' | 'workflow' | 'device';
654
750
 
751
+ declare type WorkflowSideEffects = (typeof WORKFLOW_SIDE_EFFECTS)[number];
752
+
753
+ declare type WorkflowSignalOnTimeout = (typeof WORKFLOW_SIGNAL_ON_TIMEOUT)[number];
754
+
655
755
  export declare interface WorkflowSpecialistRole {
656
756
  name: string;
657
757
  instructions: string;
@@ -675,7 +775,11 @@ export declare interface WorkflowStepContext<TIn = unknown, TResume = unknown, T
675
775
  /** What the prior invocation passed to `suspend()`. */
676
776
  suspendData?: unknown;
677
777
  getInitData<T = unknown>(): T;
678
- /** Output of an UPSTREAM step. Throws `WorkflowStepResultError{ code:'STEP_RESULT_NOT_ANCESTOR' }` for a non-ancestor. */
778
+ /**
779
+ * Output of an UPSTREAM step. Throws `WorkflowStepResultError` — `code:'STEP_RESULT_NOT_ANCESTOR'` for a
780
+ * non-ancestor (or unknown) id, `'STEP_RESULT_TOO_LARGE'` / `'STEP_RESULT_OFFLOADED'` for an output the claim
781
+ * could not carry (see the error's doc for `bytes` / `reason`) — never `undefined`, never a raw ref object.
782
+ */
679
783
  getStepResult<T = unknown>(stepId: string): T;
680
784
  /** Run-scoped KV, ledger-backed, ≤ 64KB total. `set` is durable when the step terminalizes. */
681
785
  state: {
@@ -694,17 +798,65 @@ export declare interface WorkflowStepContext<TIn = unknown, TResume = unknown, T
694
798
  signal: AbortSignal;
695
799
  /** Sub-agent env, exactly as jobs receive it. */
696
800
  env: Record<string, string>;
697
- /** EXACTLY-ONCE effect keyed on `{occurrenceId, key}` (P1-18). Claim → run `fn` → settle. */
801
+ /**
802
+ * EXACTLY-ONCE effect keyed on `{occurrenceId, key}` (P1-18). Claim → run `fn` → settle. Served on every tier:
803
+ * worker-tier steps and the offline driver, and (LUA-722) Job-tier code steps — the pod relays the claim / settle
804
+ * under its own attempt token, so the key is scoped to the step's run / row / attempt server-side. A replayed key
805
+ * (a retried attempt, a repair run) returns the settled result without running `fn`; a key a previous attempt
806
+ * claimed and never settled throws `EFFECT_IN_DOUBT` (fail closed — `fn` never runs on an unknown claim state).
807
+ * The result is JSON-serialised on settle, exactly like a step output: a `Date` replays as its ISO string, a
808
+ * `BigInt` (or a cycle) fails the settle — `EFFECT_SETTLE_FAILED`, the key stays claimed — and a result over the
809
+ * platform's cap (32 KB) is `EFFECT_SETTLE_FAILED` naming `EFFECT_RESULT_TOO_LARGE`. Calling `once` again for the
810
+ * same key while its `fn` is still running (re-entrantly) throws `EFFECT_KEY_INVALID` at once.
811
+ */
698
812
  once<T>(key: string, fn: () => Promise<T>): Promise<T>;
699
- /** Job-tier steps only: the mounted run workspace. */
813
+ /**
814
+ * Job-tier steps only: the mounted run workspace, exactly as the Job pod hands it to `execute` (`ctx.workspace` in
815
+ * `packages/lua-workflow-job/src/code-step.ts`): `root` is the absolute directory of the checkout (`/workspace`),
816
+ * `branch` the run branch it is on, `headSha` the commit it was restored at, `mount` this step's declared mount,
817
+ * `isolation` whether the step got its own worktree. LUA-679: the name is `root` — the 3.32.1 type and both
818
+ * `lua init` examples said `path`, the pod never served it, and a copied definition died `ENOENT /workspace/undefined`.
819
+ */
700
820
  workspace?: {
701
- path: string;
821
+ root: string;
702
822
  mount: 'rw' | 'ro';
703
823
  branch?: string;
824
+ headSha?: string;
825
+ isolation?: 'shared' | 'worktree';
826
+ /**
827
+ * @deprecated LUA-679 — read `root`. The Job pod serves `path` as an alias (a getter that returns `root` and warns
828
+ * once per step) for one minor after 3.32 and then removes it; it never appears on `Object.keys(ctx.workspace)`.
829
+ */
830
+ readonly path?: string;
831
+ /**
832
+ * The run workspace's stamps, served when the pod hands them to the step (LUA-706): `baseSha` is the commit the
833
+ * run's base ref resolved to at provision (a git workspace — `headSha` is where THIS step's checkout is), `arm`
834
+ * the worktree arm id when the step runs in its own worktree (`isolation:'worktree'`), `backend` the volume
835
+ * backend. Absent on an `empty` workspace, a shared-mount step, or a pod that predates them.
836
+ */
704
837
  baseSha?: string;
705
838
  arm?: string;
706
839
  backend?: WorkflowWorkspaceBackend;
707
840
  };
841
+ /**
842
+ * Job-tier steps only (LUA-682): run one of `WORKFLOW_EXEC_BINARIES` (`git`, `gh`, `pnpm`, `npm`, `npx`, `node`,
843
+ * `yarn`, `python3`, `pytest`, `make`) in the workspace — `exec(['git', 'status'], { cwd?, timeoutMs?, env? })`.
844
+ * Argv only, never a shell: no `&&`, pipes, globs or `$VAR`; `cwd` must stay inside the workspace; the timeout
845
+ * (default 10 min) is capped by the step's remaining wall; stdout / stderr are kept to 1 MiB each (`truncated`);
846
+ * one command at a time. A non-zero exit is RETURNED (`result.code`) — `exec.strict` throws `WorkflowExecError`.
847
+ * The Job pod spawns the command itself with a scrubbed env (no token, no `LUA_WF_*`; git goes through the
848
+ * credential proxy exactly as the coding turn's does); `child_process` is not available to a code step and fails
849
+ * `lua compile` with `node-capability-unavailable`. Worker-tier steps have neither `exec` nor `$`. Offline,
850
+ * `lua workflows run --workspace <dir>` provides both with the same allowlist against your own PATH.
851
+ */
852
+ exec?: WorkflowExecFn;
853
+ /**
854
+ * Job-tier steps only (LUA-682): `exec` as a tagged template — `$\`gh pr create --title ${title} --body ${body}\``.
855
+ * Literal text splits on whitespace (with `'…'` / `"…"` quoting); every `${value}` is exactly ONE argument, never
856
+ * re-parsed (a title with spaces, a body with newlines); an array spreads into one argument per item; `undefined`
857
+ * is refused rather than stringified. `$.strict` throws on a non-zero exit.
858
+ */
859
+ $?: WorkflowShellFn;
708
860
  /** The run artefact store (P1-8). */
709
861
  artefacts: {
710
862
  put(name: string, data: Uint8Array | string | ReadableStream, opts: {
@@ -739,7 +891,12 @@ export declare interface WorkflowStepContext<TIn = unknown, TResume = unknown, T
739
891
  }>;
740
892
  list(): Promise<WorkflowArtefactMeta[]>;
741
893
  };
742
- /** Stamped by the executor for observability; read-only. */
894
+ /**
895
+ * Stamped by the executor for observability; read-only (frozen). Served on both tiers from the run's stamps
896
+ * (LUA-706): `trigger` / `principalKind`, plus `parentRunId` / `traceparent` / `correlationKey` / `tags` /
897
+ * `replyTo` when the run carries them; `agentVersion` is not stamped today. A run created before the stamps
898
+ * existed reads `{}`. Offline, `lua workflows run` serves `{ trigger:'sdk', principalKind:'user' }`.
899
+ */
743
900
  runtime: {
744
901
  trigger: WorkflowRunTrigger;
745
902
  parentRunId?: string;
@@ -755,10 +912,26 @@ export declare interface WorkflowStepContext<TIn = unknown, TResume = unknown, T
755
912
  };
756
913
  }
757
914
 
758
- /** Thrown by `ctx.getStepResult` for a non-ancestor / unknown id — never `undefined` (03 §3.1). */
915
+ /**
916
+ * Thrown by `ctx.getStepResult` — never `undefined`, never a raw ref object (03 §3.1). Check `err.code`, never
917
+ * `instanceof` (a step runs in its own realm on every tier):
918
+ * - `STEP_RESULT_NOT_ANCESTOR` — `stepId` is not an upstream step of this one (or is unknown);
919
+ * - `STEP_RESULT_TOO_LARGE` — the ancestor's output could not ride the claim beside its siblings (the 4 MiB
920
+ * `stepResults` wire budget, dropped largest-first); `bytes` is its serialized size;
921
+ * - `STEP_RESULT_OFFLOADED` — the ledger holds the output offloaded (> 256 KB) and the claim could not carry it
922
+ * hydrated; `bytes` is its size, `reason` why: `over_wire_cap` (it would break the budget), `hydrate_timeout`
923
+ * (the per-claim hydration deadline passed), or the control plane's code (`CDN_REF_MISSING`, `CDN_REF_CORRUPT`,
924
+ * `CDN_REF_FOREIGN`, …).
925
+ * For the last two, bind the value through the step's input instead, or read it via `ctx.artefacts` /
926
+ * `ctx.datasets`. The offline driver (`lua workflows execute`) only ever throws the first.
927
+ */
759
928
  export declare interface WorkflowStepResultError extends Error {
760
- code: 'STEP_RESULT_NOT_ANCESTOR';
929
+ code: 'STEP_RESULT_NOT_ANCESTOR' | 'STEP_RESULT_TOO_LARGE' | 'STEP_RESULT_OFFLOADED';
761
930
  stepId: string;
931
+ /** `STEP_RESULT_TOO_LARGE` / `STEP_RESULT_OFFLOADED`: the output's serialized size. */
932
+ bytes?: number;
933
+ /** `STEP_RESULT_OFFLOADED`: why the claim could not carry it. */
934
+ reason?: string;
762
935
  }
763
936
 
764
937
  export declare interface WorkflowStepWorkspace {
@@ -777,6 +950,8 @@ export declare type WorkflowSuspendTimeoutChainMember = 'deny' | 'cancel-run' |
777
950
  timeoutHours: number;
778
951
  };
779
952
 
953
+ declare type WorkflowTier = (typeof WORKFLOW_TIERS)[number];
954
+
780
955
  export declare type WorkflowWorkspaceBackend = 'ebs' | 'efs' | 's3';
781
956
 
782
957
  export declare type WorkspaceSpec = {
@@ -793,6 +968,10 @@ export declare type WorkspaceSpec = {
793
968
  kind: 'empty';
794
969
  sizeGb?: number;
795
970
  ttlHours?: number;
971
+ /**
972
+ * Keep the volume after the run completes: held until `ttlHours` (24 h when undeclared), then expired. A kept
973
+ * volume holds one of the organisation's workspace slots (`maxWorkspacesPerOrg`, 10 by default) until then.
974
+ */
796
975
  keepArtefacts?: boolean;
797
976
  backend?: WorkflowWorkspaceBackend;
798
977
  };