deepline 0.3.87 → 0.3.89

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 (69) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +532 -2
  2. package/dist/bundling-sources/sdk/src/config.ts +77 -0
  3. package/dist/bundling-sources/sdk/src/http.ts +76 -30
  4. package/dist/bundling-sources/sdk/src/index.ts +6 -0
  5. package/dist/bundling-sources/sdk/src/play.ts +15 -1
  6. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
  7. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  8. package/dist/bundling-sources/sdk/src/types.ts +83 -4
  9. package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +16 -0
  10. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +263 -0
  11. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +9 -1
  12. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +122 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/activity-observation.ts +6 -11
  14. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +90 -12
  15. package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +78 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/checkpoint-boundaries.ts +70 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +407 -53
  18. package/dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts +1 -32
  19. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +57 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +20 -1
  21. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +6 -0
  22. package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +7 -1
  23. package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +189 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +28 -0
  25. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +23 -0
  27. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +1 -1
  28. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +18 -4
  29. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +68 -0
  30. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +2 -0
  31. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +1 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +10 -8
  33. package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +20 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +6 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +24 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +30 -1
  37. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +6 -3
  38. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +152 -17
  39. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +19 -4
  40. package/dist/bundling-sources/shared_libs/plays/contracts.ts +6 -14
  41. package/dist/bundling-sources/shared_libs/plays/core.ts +11 -6
  42. package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +16 -11
  43. package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +1 -1
  44. package/dist/bundling-sources/shared_libs/plays/slug.ts +115 -0
  45. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +44 -14
  46. package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +877 -0
  47. package/dist/bundling-sources/shared_libs/product-notifications/configuration-draft.ts +456 -0
  48. package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +560 -0
  49. package/dist/bundling-sources/shared_libs/product-notifications/content.ts +28 -0
  50. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +59 -0
  51. package/dist/bundling-sources/shared_libs/product-notifications/email.ts +246 -0
  52. package/dist/bundling-sources/shared_libs/product-notifications/evaluation.ts +280 -0
  53. package/dist/bundling-sources/shared_libs/product-notifications/events.ts +433 -0
  54. package/dist/bundling-sources/shared_libs/product-notifications/legacy-slack.ts +80 -0
  55. package/dist/bundling-sources/shared_libs/product-notifications/workspace.ts +38 -0
  56. package/dist/bundling-sources/shared_libs/security/internal-actor.ts +50 -0
  57. package/dist/cli/index.js +1065 -190
  58. package/dist/cli/index.mjs +1052 -177
  59. package/dist/{compiler-manifest-Dbov16F7.d.mts → compiler-manifest-DsLbQaew.d.mts} +132 -8
  60. package/dist/{compiler-manifest-Dbov16F7.d.ts → compiler-manifest-DsLbQaew.d.ts} +132 -8
  61. package/dist/index.d.mts +833 -11
  62. package/dist/index.d.ts +833 -11
  63. package/dist/index.js +467 -38
  64. package/dist/index.mjs +467 -38
  65. package/dist/install-integrity.json +20 -2
  66. package/dist/plays/bundle-play-file.d.mts +8 -3
  67. package/dist/plays/bundle-play-file.d.ts +8 -3
  68. package/dist/plays/bundle-play-file.mjs +100 -20
  69. package/package.json +1 -1
@@ -28,21 +28,16 @@ export type PlayRuntimeFeature =
28
28
  | 'durable_sleep'
29
29
  | 'packaged_files';
30
30
 
31
- export const PLAY_PUBLIC_API_VERSION = 1;
32
31
  export const PLAY_ARTIFACT_VERSION = CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION;
33
- export const PLAY_MIN_RUNNER_VERSION = 1;
34
- export const PLAY_RUNTIME_FEATURES: PlayRuntimeFeature[] = [
35
- 'artifact_storage',
36
- 'checkpoint_resume',
37
- 'durable_sleep',
38
- 'packaged_files',
39
- ];
40
32
 
41
33
  export type PlayContractCompatibilitySnapshot = {
42
- apiVersion: number;
34
+ /** Historical marker. Nothing admits, gates, or branches on it. */
35
+ apiVersion?: number;
43
36
  artifactVersion: number;
44
- minRunnerVersion: number;
45
- runtimeFeatures: PlayRuntimeFeature[];
37
+ /** Historical marker. Every runner reads every artifact. */
38
+ minRunnerVersion?: number;
39
+ /** Historical marker. Capabilities are named per operation, not listed here. */
40
+ runtimeFeatures?: PlayRuntimeFeature[];
46
41
  runtimeBackend?: string | null;
47
42
  /** Every Play run uses the structured tool-error contract. */
48
43
  toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
@@ -142,10 +137,7 @@ export function buildPlayContractCompatibility(input?: {
142
137
  toolResponseReceiptRevision?: string;
143
138
  }): PlayContractCompatibilitySnapshot {
144
139
  return {
145
- apiVersion: PLAY_PUBLIC_API_VERSION,
146
140
  artifactVersion: PLAY_ARTIFACT_VERSION,
147
- minRunnerVersion: PLAY_MIN_RUNNER_VERSION,
148
- runtimeFeatures: [...PLAY_RUNTIME_FEATURES],
149
141
  runtimeBackend: input?.runtimeBackend ?? null,
150
142
  toolErrorSchemaVersion:
151
143
  input?.toolErrorSchemaVersion ?? TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
@@ -13,6 +13,9 @@ import type {
13
13
  PlayAuthoringDefinedPlay,
14
14
  PlayAuthoringInputContract,
15
15
  PlayAuthoringReferenceLike,
16
+ AsyncPlayRunRef as PlayAuthoringAsyncPlayRunRef,
17
+ PlayAuthoringAsyncCallOptions,
18
+ PlayRunId as PlayAuthoringRunId,
16
19
  PlayAuthoringRuntimeContext,
17
20
  PlayAuthoringStepOptions,
18
21
  PlayAuthoringStepProgram,
@@ -125,7 +128,12 @@ export type DatasetBuilder<
125
128
  DeeplinePlayRuntimeContext
126
129
  >;
127
130
 
128
- export type PlayReferenceLike = PlayAuthoringReferenceLike;
131
+ export type PlayReferenceLike<
132
+ TInput extends Record<string, unknown> = Record<string, unknown>,
133
+ > = PlayAuthoringReferenceLike<TInput>;
134
+ export type AsyncPlayRunRef = PlayAuthoringAsyncPlayRunRef;
135
+ export type PlayAsyncCallOptions = PlayAuthoringAsyncCallOptions;
136
+ export type PlayRunId = PlayAuthoringRunId;
129
137
 
130
138
  export type DeeplinePlayRuntimeContext = PlayAuthoringRuntimeContext;
131
139
 
@@ -444,10 +452,7 @@ export function definePlay<TInput, TOutput extends PlayReturnObject>(
444
452
  /** @internal Contextually type unannotated monitor-event handlers as unknown. */
445
453
  export function definePlay<TOutput extends PlayReturnObject>(
446
454
  name: string,
447
- fn: (
448
- context: DeeplinePlayRuntimeContext,
449
- input: unknown,
450
- ) => Promise<TOutput>,
455
+ fn: (context: DeeplinePlayRuntimeContext, input: unknown) => Promise<TOutput>,
451
456
  bindings: PlayBindings<never> & {
452
457
  readonly sqlListeners: readonly SqlListenerDeclaration[];
453
458
  },
@@ -455,7 +460,7 @@ export function definePlay<TOutput extends PlayReturnObject>(
455
460
  /* eslint-disable @typescript-eslint/no-explicit-any -- This constraint must infer a concrete contravariant handler input. */
456
461
  export function definePlay<
457
462
  THandler extends (
458
- context: DeeplinePlayRuntimeContext,
463
+ context: DeeplinePlayRuntimeContext,
459
464
  input: any,
460
465
  ) => Promise<PlayReturnObject>,
461
466
  >(
@@ -61,10 +61,12 @@ export type DocflowOwnerSubstep = Extract<
61
61
  { type: 'dataset' | 'csv' }
62
62
  >;
63
63
  export type DocflowToolSubstep = Extract<PlayStaticSubstep, { type: 'tool' }>;
64
- export type DocflowPlayCallSubstep = Extract<
64
+ export type DocflowChildPlaySubstep = Extract<
65
65
  PlayStaticSubstep,
66
- { type: 'play_call' }
66
+ { type: 'play_call' | 'play_launch' }
67
67
  >;
68
+ /** @deprecated Use `DocflowChildPlaySubstep`; retained for compatibility. */
69
+ export type DocflowPlayCallSubstep = DocflowChildPlaySubstep;
68
70
  export type DocflowStepSuiteSubstep = Extract<
69
71
  PlayStaticSubstep,
70
72
  { type: 'step_suite' }
@@ -332,19 +334,19 @@ export function resolveDocflowBoundTool(
332
334
  }
333
335
 
334
336
  /**
335
- * The `ctx.runPlay` call a `type:"play"` docflow node names. Same join as every
336
- * other binding — symbol first, extent as the fallback — over the FLATTENED
337
- * substep tree, because a child call inside a `.withColumn(...)` body is nested
338
- * under its dataset. A `play_call`'s `field` is the column or variable the child
339
- * result lands in, which is exactly what the node's `out:` names.
337
+ * The `ctx.runPlay` or `ctx.runPlayAsync` call a `type:"play"` docflow node
338
+ * names. Same join as every other binding — symbol first, extent as the fallback
339
+ * — over the FLATTENED substep tree. Its `field` is the column, variable, or
340
+ * launch key the child run lands in, which is exactly what the node's `out:`
341
+ * names.
340
342
  */
341
- export function resolveDocflowBoundPlayCall(
343
+ export function resolveDocflowBoundChildPlay(
342
344
  binding: PlayDocflowBinding,
343
345
  substeps: readonly PlayStaticSubstep[],
344
- ): DocflowBindingJoin<DocflowPlayCallSubstep> {
346
+ ): DocflowBindingJoin<DocflowChildPlaySubstep> {
345
347
  const playCalls = flattenSubsteps(substeps).filter(
346
- (substep): substep is DocflowPlayCallSubstep =>
347
- substep.type === 'play_call',
348
+ (substep): substep is DocflowChildPlaySubstep =>
349
+ substep.type === 'play_call' || substep.type === 'play_launch',
348
350
  );
349
351
  return joinBySymbolThenExtent(
350
352
  binding,
@@ -353,6 +355,9 @@ export function resolveDocflowBoundPlayCall(
353
355
  );
354
356
  }
355
357
 
358
+ /** @deprecated Use `resolveDocflowBoundChildPlay`; retained for compatibility. */
359
+ export const resolveDocflowBoundPlayCall = resolveDocflowBoundChildPlay;
360
+
356
361
  // ── waterfalls: the step suite and its legs ─────────────────────────────────
357
362
  //
358
363
  // `steps().step('hunter_email', …).step('leadmagic_email', …).return(…)` compiles
@@ -136,7 +136,7 @@ async function resolvePipelineSubsteps(input: {
136
136
  return nested satisfies PlayStaticSubstep;
137
137
  }
138
138
 
139
- if (annotated.type !== 'play_call') {
139
+ if (annotated.type !== 'play_call' && annotated.type !== 'play_launch') {
140
140
  return annotated;
141
141
  }
142
142
 
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Canonical slug helpers — the single home for URL-handle normalization and
3
+ * unguessable-suffix generation. Shared by Convex (relative `.//slug`)
4
+ * and the Next app (`.//slug`).
5
+ *
6
+ * Used by:
7
+ * - Organization slugs (the org's stable URL handle)
8
+ * - Share-page slugs (`/p/{shareSlug}`) and version paths
9
+ * - Play-name slug bases
10
+ *
11
+ * Intentionally NOT covered here (different concerns — kept separate so this
12
+ * stays a real seam, not DRY-for-its-own-sake):
13
+ * - URL → durable-scope slugs (parse host:port; playground backend / scripts)
14
+ * - DataForSEO codegen `kebabCase` (underscore-only transform)
15
+ */
16
+
17
+ const SHARE_SLUG_NAME_MAX_LEN = 48;
18
+ const SHARE_SLUG_SUFFIX_LEN = 8;
19
+ const SUFFIX_ALPHABET = 'abcdefghijklmnopqrstuvwxyz0123456789';
20
+
21
+ /**
22
+ * Normalize an arbitrary string into a URL-safe kebab slug: lowercase, NFKD-fold
23
+ * accents, collapse every run of non-`[a-z0-9]` into a single dash, trim edge
24
+ * dashes, and optionally cap length (re-trimming a trailing dash after the cut).
25
+ *
26
+ * Returns `''` for empty/garbage input — callers supply their own domain
27
+ * fallback (`'team'`, `'play'`, `'ci-bootstrap'`, …), since the right default is
28
+ * domain-specific.
29
+ */
30
+ export function normalizeSlug(
31
+ value: string,
32
+ options?: { maxLength?: number },
33
+ ): string {
34
+ let slug = value
35
+ .toLowerCase()
36
+ .normalize('NFKD')
37
+ .replace(/[^a-z0-9]+/g, '-')
38
+ .replace(/^-+|-+$/g, '');
39
+ const maxLength = options?.maxLength;
40
+ if (maxLength !== undefined && slug.length > maxLength) {
41
+ slug = slug.slice(0, maxLength).replace(/-+$/g, '');
42
+ }
43
+ return slug;
44
+ }
45
+
46
+ /**
47
+ * Deterministic unguessable suffix from injected bytes (pure + testable). Each
48
+ * byte maps into a 36-char lowercase-alphanumeric alphabet. `randomBytes` must
49
+ * be at least `length` long.
50
+ */
51
+ export function buildSlugSuffix(
52
+ length: number,
53
+ randomBytes: Uint8Array,
54
+ ): string {
55
+ if (randomBytes.length < length) {
56
+ throw new Error(
57
+ `buildSlugSuffix requires at least ${length} random bytes.`,
58
+ );
59
+ }
60
+ let suffix = '';
61
+ for (let i = 0; i < length; i += 1) {
62
+ suffix += SUFFIX_ALPHABET[randomBytes[i] % SUFFIX_ALPHABET.length];
63
+ }
64
+ return suffix;
65
+ }
66
+
67
+ /** Crypto-backed unguessable suffix (Node / Convex / browser global `crypto`). */
68
+ export function randomSlugSuffix(length: number): string {
69
+ const bytes = new Uint8Array(length);
70
+ crypto.getRandomValues(bytes);
71
+ return buildSlugSuffix(length, bytes);
72
+ }
73
+
74
+ /** Kebab-case the human play name into the readable share-slug stem. */
75
+ export function playNameToSlugBase(name: string): string {
76
+ return normalizeSlug(name, { maxLength: SHARE_SLUG_NAME_MAX_LEN }) || 'play';
77
+ }
78
+
79
+ /**
80
+ * Build a full share slug from a name stem and a source of randomness. Pure +
81
+ * deterministic for tests; callers pass crypto-backed bytes.
82
+ */
83
+ export function buildShareSlug(name: string, randomBytes: Uint8Array): string {
84
+ const suffix = buildSlugSuffix(SHARE_SLUG_SUFFIX_LEN, randomBytes);
85
+ return `${playNameToSlugBase(name)}-${suffix}`;
86
+ }
87
+
88
+ /** Generate a crypto-backed share slug. */
89
+ export function generateShareSlug(name: string): string {
90
+ return `${playNameToSlugBase(name)}-${randomSlugSuffix(SHARE_SLUG_SUFFIX_LEN)}`;
91
+ }
92
+
93
+ /**
94
+ * Public path for a share page — namespaced by org slug + play name.
95
+ *
96
+ * This is the ONLY public URL shape. There is no top-level `/p/{slug}`: org
97
+ * slugs are globally unique (Better Auth) and play names are unique within an
98
+ * org (`by_orgId_name`), so `{org}/{play}` is globally unique on its own. The
99
+ * random `shareSlug` is kept only as an internal record id, never a URL.
100
+ */
101
+ export function buildSharePublicPath(
102
+ orgSlug: string,
103
+ playName: string,
104
+ ): string {
105
+ return `/p/${encodeURIComponent(orgSlug)}/${encodeURIComponent(playName)}`;
106
+ }
107
+
108
+ /** Canonical, version-pinned path for a share page. */
109
+ export function buildShareCanonicalPath(
110
+ orgSlug: string,
111
+ playName: string,
112
+ version: number,
113
+ ): string {
114
+ return `${buildSharePublicPath(orgSlug, playName)}/v/${version}`;
115
+ }
@@ -212,7 +212,10 @@ export function ensureCompiledSheetContract(
212
212
  substeps: PlayStaticSubstep[],
213
213
  ): PlayStaticSubstep[] =>
214
214
  substeps.map((substep) => {
215
- if (substep.type === 'play_call' && substep.pipeline) {
215
+ if (
216
+ (substep.type === 'play_call' || substep.type === 'play_launch') &&
217
+ substep.pipeline
218
+ ) {
216
219
  return {
217
220
  ...substep,
218
221
  pipeline: ensureCompiledSheetContract(substep.pipeline) ?? null,
@@ -409,7 +412,11 @@ function truncateStaticSubstepsForStorage(
409
412
  return truncateStaticSubstepShallowForStorage(base);
410
413
  }
411
414
 
412
- if (base.type !== 'play_call' && 'pipeline' in substepWithoutSourceText) {
415
+ if (
416
+ base.type !== 'play_call' &&
417
+ base.type !== 'play_launch' &&
418
+ 'pipeline' in substepWithoutSourceText
419
+ ) {
413
420
  const nestedPipeline = substepWithoutSourceText.pipeline;
414
421
  (base as { pipeline?: PlayStaticPipeline | null }).pipeline =
415
422
  nestedPipeline
@@ -489,7 +496,7 @@ function truncateStaticSubstepsForStorage(
489
496
  });
490
497
  }
491
498
 
492
- if (base.type !== 'play_call') {
499
+ if (base.type !== 'play_call' && base.type !== 'play_launch') {
493
500
  if (Array.isArray((base as { steps?: unknown }).steps)) {
494
501
  return omitUndefinedProperties({
495
502
  ...base,
@@ -502,9 +509,9 @@ function truncateStaticSubstepsForStorage(
502
509
  return base;
503
510
  }
504
511
 
505
- // A normalized authoring graph intentionally leaves a named play-call's
506
- // child pipeline absent. That is a reference edge, not a failed or
507
- // truncated resolution, so preserve it without inventing an error.
512
+ // A normalized authoring graph may leave a named Play reference's child
513
+ // pipeline absent. That is a reference edge, not a failed or truncated
514
+ // resolution, so preserve it without inventing an error.
508
515
  if (
509
516
  !base.pipeline &&
510
517
  !Object.prototype.hasOwnProperty.call(substep, 'pipeline') &&
@@ -617,11 +624,7 @@ export function createStaticPipelineReferenceProjection(
617
624
  preserveEmbeddedPlayIds?: ReadonlySet<string>;
618
625
  },
619
626
  ): PlayStaticPipeline | null | undefined {
620
- const stored = truncateStaticPipelineForStorage(pipeline, {
621
- maxEmbeddedPlayCallPipelineDepth: Number.POSITIVE_INFINITY,
622
- maxStoredSubstepDepth: Number.POSITIVE_INFINITY,
623
- });
624
- if (!stored) return stored;
627
+ if (!pipeline) return pipeline;
625
628
 
626
629
  const projectSteps = (
627
630
  steps: PlayStaticSubstep[] | undefined,
@@ -653,6 +656,10 @@ export function createStaticPipelineReferenceProjection(
653
656
  }
654
657
  return projected;
655
658
  }
659
+ if (projected.type === 'play_launch' && projected.pipeline) {
660
+ projected.pipeline = projectPipeline(projected.pipeline);
661
+ return projected;
662
+ }
656
663
  if (
657
664
  (projected.type === 'dataset' ||
658
665
  projected.type === 'step_suite' ||
@@ -678,7 +685,13 @@ export function createStaticPipelineReferenceProjection(
678
685
  substeps: projectSteps(candidate.substeps),
679
686
  });
680
687
 
681
- return projectPipeline(stored);
688
+ // Prune named child snapshots before the storage-safe deep copy. Resolved
689
+ // calls can share large child graphs; copying those once per call site only
690
+ // to discard them can exhaust the launch process before run admission.
691
+ return truncateStaticPipelineForStorage(projectPipeline(pipeline), {
692
+ maxEmbeddedPlayCallPipelineDepth: Number.POSITIVE_INFINITY,
693
+ maxStoredSubstepDepth: Number.POSITIVE_INFINITY,
694
+ });
682
695
  }
683
696
 
684
697
  function asStaticRecord(value: unknown): Record<string, unknown> | null {
@@ -1315,6 +1328,19 @@ export type PlayStaticSubstep = PlayStaticSubstepMetadata &
1315
1328
  callDepth?: number;
1316
1329
  callPath?: string[];
1317
1330
  }
1331
+ | {
1332
+ type: 'play_launch';
1333
+ playId: string;
1334
+ field: string;
1335
+ inLoop?: boolean;
1336
+ pipeline?: PlayStaticPipeline | null;
1337
+ cycleDetected?: boolean;
1338
+ resolutionError?: string;
1339
+ description?: string;
1340
+ sourceRange?: PlayStaticSourceRange;
1341
+ callDepth?: number;
1342
+ callPath?: string[];
1343
+ }
1318
1344
  | {
1319
1345
  type: 'control_flow';
1320
1346
  kind: 'conditional' | 'loop';
@@ -1601,7 +1627,7 @@ function columnProducerFromSubstep(
1601
1627
  ? 'stepProgram'
1602
1628
  : substep.type === 'control_flow'
1603
1629
  ? 'controlFlow'
1604
- : substep.type === 'play_call'
1630
+ : substep.type === 'play_call' || substep.type === 'play_launch'
1605
1631
  ? 'playCall'
1606
1632
  : 'transform';
1607
1633
  return {
@@ -1609,7 +1635,9 @@ function columnProducerFromSubstep(
1609
1635
  kind,
1610
1636
  field,
1611
1637
  ...(substep.type === 'tool' ? { toolId: substep.toolId } : {}),
1612
- ...(substep.type === 'play_call' ? { playId: substep.playId } : {}),
1638
+ ...(substep.type === 'play_call' || substep.type === 'play_launch'
1639
+ ? { playId: substep.playId }
1640
+ : {}),
1613
1641
  ...(substep.conditional ? { conditional: true } : {}),
1614
1642
  ...(substep.disabled ? { disabled: true } : {}),
1615
1643
  ...(substep.sourceRange ? { sourceRange: substep.sourceRange } : {}),
@@ -1624,6 +1652,8 @@ function producerId(substep: PlayStaticSubstep, field: string): string {
1624
1652
  return `${field}:waterfall:${substep.id ?? substep.tool ?? 'unknown'}`;
1625
1653
  }
1626
1654
  if (substep.type === 'play_call') return `${field}:play:${substep.playId}`;
1655
+ if (substep.type === 'play_launch')
1656
+ return `${field}:play-launch:${substep.playId}`;
1627
1657
  if (substep.type === 'step_suite') return `${field}:steps`;
1628
1658
  if (substep.type === 'control_flow')
1629
1659
  return `${field}:control:${substep.kind}:${sourceRangeKey(substep.sourceRange)}`;