deepline 0.2.53 → 0.2.55

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 (44) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +17 -1
  2. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
  3. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  4. package/dist/bundling-sources/sdk/src/types.ts +43 -1
  5. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +30 -1
  6. package/dist/bundling-sources/shared_libs/play-runtime/cell-provenance.ts +231 -0
  7. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1094 -128
  8. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +178 -9
  9. package/dist/bundling-sources/shared_libs/play-runtime/docflow-node-io.ts +634 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/docflow-observation.ts +64 -0
  11. package/dist/bundling-sources/shared_libs/play-runtime/dynamic-worker-version.ts +1 -1
  12. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +18 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +33 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/log-provenance.ts +251 -0
  15. package/dist/bundling-sources/shared_libs/play-runtime/play-node-scope.ts +160 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +6 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +27 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +43 -5
  19. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +12 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +26 -4
  21. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +6 -1
  22. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +83 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +3 -0
  24. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +49 -1
  25. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +375 -29
  26. package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +636 -0
  27. package/dist/bundling-sources/shared_libs/plays/docflow-binding.ts +598 -0
  28. package/dist/bundling-sources/shared_libs/plays/docflow.ts +1645 -0
  29. package/dist/bundling-sources/shared_libs/plays/play-exports.ts +202 -0
  30. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +16 -1
  31. package/dist/bundling-sources/shared_libs/plays/ts-ast.ts +48 -0
  32. package/dist/cli/index.js +994 -312
  33. package/dist/cli/index.mjs +994 -312
  34. package/dist/{compiler-manifest-Cj3--4ZJ.d.mts → compiler-manifest-Bl8kmLx9.d.mts} +118 -0
  35. package/dist/{compiler-manifest-Cj3--4ZJ.d.ts → compiler-manifest-Bl8kmLx9.d.ts} +118 -0
  36. package/dist/index.d.mts +47 -2
  37. package/dist/index.d.ts +47 -2
  38. package/dist/index.js +419 -59
  39. package/dist/index.mjs +419 -59
  40. package/dist/install-integrity.json +12 -2
  41. package/dist/plays/bundle-play-file.d.mts +2 -2
  42. package/dist/plays/bundle-play-file.d.ts +2 -2
  43. package/dist/plays/bundle-play-file.mjs +1361 -45
  44. package/package.json +1 -1
@@ -14,6 +14,8 @@ import {
14
14
  normalizePlayRunLifecycleStatus,
15
15
  type PlayRunLifecycleStatus,
16
16
  } from './run-lifecycle-policy';
17
+ import type { PlayDocflowNodeIoState } from './docflow-node-io';
18
+ import type { PlayVisualNodeUsageSnapshot } from './live-state-contract';
17
19
  import {
18
20
  projectPlayRunActivity,
19
21
  type PlayActivityObservation,
@@ -46,6 +48,7 @@ export type PlayRunStreamNodeProgress = {
46
48
  startedAt?: number | null;
47
49
  completedAt?: number | null;
48
50
  artifactTableNamespace?: string | null;
51
+ nodeIo?: PlayDocflowNodeIoState;
49
52
  };
50
53
 
51
54
  export type PlayRunStreamNodeState = {
@@ -57,6 +60,13 @@ export type PlayRunStreamNodeState = {
57
60
  startedAt?: number | null;
58
61
  completedAt?: number | null;
59
62
  updatedAt?: number | null;
63
+ nodeIo?: PlayDocflowNodeIoState;
64
+ /**
65
+ * Observed provider usage (ADR 0018). Attached by the read path, not by the
66
+ * ledger projection — settlement lags finalize, so this is always computed
67
+ * at read time.
68
+ */
69
+ usage?: PlayVisualNodeUsageSnapshot;
60
70
  };
61
71
 
62
72
  export type PlayRunLiveSnapshot = {
@@ -202,11 +212,13 @@ function buildSnapshotFromLedger(
202
212
  startedAt: step.startedAt ?? null,
203
213
  completedAt: step.completedAt ?? null,
204
214
  updatedAt: step.progress.updatedAt ?? step.updatedAt ?? null,
215
+ nodeIo: step.progress.nodeIo,
205
216
  }
206
217
  : null,
207
218
  startedAt: step.startedAt ?? null,
208
219
  completedAt: step.completedAt ?? null,
209
220
  updatedAt: step.updatedAt ?? null,
221
+ ...(step.progress?.nodeIo ? { nodeIo: step.progress.nodeIo } : {}),
210
222
  }));
211
223
  const liveStatus = normalizePlayRunLiveStatus(snapshot.status);
212
224
  // Only surface the row-outcome aggregate once the run is terminal and it
@@ -91,11 +91,29 @@ async function runCommand(
91
91
  return;
92
92
  }
93
93
 
94
+ // POSIX: run the command as its own process-group leader so cancellation
95
+ // can signal the entire tree. The watchdog child spawns the runner (which
96
+ // may spawn further descendants) with inherited stdio; killing only the
97
+ // direct child leaves orphans holding our pipes and 'close' never fires.
98
+ const useProcessGroup = process.platform !== 'win32';
94
99
  const child = spawn(command, args, {
95
100
  stdio: ['ignore', 'pipe', 'pipe'],
101
+ detached: useProcessGroup,
96
102
  ...options,
97
103
  });
98
104
 
105
+ const killTree = (signal: NodeJS.Signals) => {
106
+ if (useProcessGroup && child.pid) {
107
+ try {
108
+ process.kill(-child.pid, signal);
109
+ return;
110
+ } catch {
111
+ // Group already gone or not yet created — fall through.
112
+ }
113
+ }
114
+ child.kill(signal);
115
+ };
116
+
99
117
  let stderr = '';
100
118
  let stdoutBuffer = '';
101
119
  let stdoutLineCount = 0;
@@ -142,11 +160,15 @@ async function runCommand(
142
160
  typeof reason === 'string' && reason.trim()
143
161
  ? reason.trim()
144
162
  : LOCAL_PROCESS_CANCELLED_ERROR;
145
- child.kill('SIGTERM');
163
+ killTree('SIGTERM');
146
164
  cancelKillTimer = setTimeout(() => {
147
- if (child.exitCode === null && child.signalCode === null) {
148
- child.kill('SIGKILL');
149
- }
165
+ // Kill the whole group even if the direct child already exited: a
166
+ // descendant may have survived it and still hold our stdio pipes.
167
+ killTree('SIGKILL');
168
+ // Backstop: release our read ends so 'close' can fire even if some
169
+ // descendant escaped the group (e.g. via setsid) and never dies.
170
+ child.stdout?.destroy();
171
+ child.stderr?.destroy();
150
172
  }, LOCAL_PROCESS_CANCEL_GRACE_MS);
151
173
  cancelKillTimer.unref?.();
152
174
  }
@@ -5,6 +5,7 @@ import type { PlaySheetContract } from '../plays/static-pipeline';
5
5
  import type { PlayRunLedgerEvent } from './run-ledger';
6
6
  import type { WorkReceiptFailureKind } from './work-receipts';
7
7
  import type { ToolExecutionFailureV1 } from '../tool-execution-error';
8
+ import type { DocflowObservationUpsert } from './docflow-observation';
8
9
 
9
10
  export type RuntimeAppendRunEventsAction = {
10
11
  action: 'append_run_events';
@@ -218,7 +219,11 @@ export type RuntimeReceiptAction =
218
219
  leaseId?: string;
219
220
  leaseIds?: string[];
220
221
  keys: string[];
221
- };
222
+ }
223
+ | ({
224
+ action: 'observe_docflow_node';
225
+ playName: string;
226
+ } & DocflowObservationUpsert);
222
227
 
223
228
  export type RuntimeReceiptLease = {
224
229
  key: string;
@@ -8118,6 +8118,89 @@ export async function readRuntimeSheetDatasetRowKeys(
8118
8118
  return { keys: rows.map((row) => row._key) };
8119
8119
  }
8120
8120
 
8121
+ export type RuntimeSheetRowOutcomeCounts = {
8122
+ completed: number;
8123
+ failed: number;
8124
+ total: number;
8125
+ };
8126
+
8127
+ /**
8128
+ * Count settled row outcomes for one physical runtime sheet (ADR 0016 rule 3).
8129
+ *
8130
+ * The sheet rows ARE the data plane: `_status = 'enriched'` is a durably
8131
+ * persisted success, `'failed'` a settled row failure, and everything except
8132
+ * `'stale'` counts toward the denominator. Split from the session wrapper so
8133
+ * the counting SQL runs identically against a test PGlite client and a
8134
+ * production tenant runtime Postgres.
8135
+ */
8136
+ export async function countRuntimeSheetRowOutcomes(
8137
+ client: {
8138
+ query<Row extends Record<string, unknown> = Record<string, unknown>>(
8139
+ sql: string,
8140
+ params?: unknown[],
8141
+ ): Promise<{ rows: Row[] }>;
8142
+ },
8143
+ input: { schema: string; table: string; runId: string },
8144
+ ): Promise<RuntimeSheetRowOutcomeCounts> {
8145
+ const { rows } = await client.query<{
8146
+ completed: number | string;
8147
+ failed: number | string;
8148
+ total: number | string;
8149
+ }>(
8150
+ `SELECT
8151
+ count(*) FILTER (WHERE _status = 'enriched')::int AS completed,
8152
+ count(*) FILTER (WHERE _status = 'failed')::int AS failed,
8153
+ count(*) FILTER (WHERE _status <> 'stale')::int AS total
8154
+ FROM ${quoteIdentifier(input.schema)}.${quoteIdentifier(input.table)}
8155
+ WHERE _run_id = $1::text`,
8156
+ [input.runId],
8157
+ );
8158
+ const row = rows[0];
8159
+ return {
8160
+ completed: Math.max(0, Number(row?.completed ?? 0) || 0),
8161
+ failed: Math.max(0, Number(row?.failed ?? 0) || 0),
8162
+ total: Math.max(0, Number(row?.total ?? 0) || 0),
8163
+ };
8164
+ }
8165
+
8166
+ /**
8167
+ * Read the settled row-outcome counts for a dataset's runtime sheet through the
8168
+ * run's preloaded DB session. Used by the scheduler worker at terminal finalize
8169
+ * as the reconciliation of record for per-map progress: sheet counts exist
8170
+ * regardless of runner mode (in-worker, detached Daytona push), unlike
8171
+ * checkpoint map frames or streamed events. Requires a direct session strategy
8172
+ * (`preloaded`/`trusted_dynamic`); there is deliberately no gateway action —
8173
+ * the worker holds the launch's preloaded sessions itself.
8174
+ */
8175
+ export async function readRuntimeSheetRowOutcomeCounts(
8176
+ context: RuntimeApiContext & { playName: string; runId: string },
8177
+ input: { tableNamespace: string },
8178
+ ): Promise<RuntimeSheetRowOutcomeCounts> {
8179
+ if (context.dbSessionStrategy === 'gateway_only') {
8180
+ throw new Error(
8181
+ 'readRuntimeSheetRowOutcomeCounts requires a direct DB session strategy.',
8182
+ );
8183
+ }
8184
+ const session = requireRuntimePostgresSession(
8185
+ await getRuntimeDbSession(
8186
+ { ...context, playName: context.playName },
8187
+ {
8188
+ tableNamespace: input.tableNamespace,
8189
+ logicalTable: 'sheet_rows',
8190
+ operations: ['rows.read'],
8191
+ limits: { maxRows: runtimeDbSessionRowLimit(1) },
8192
+ },
8193
+ ),
8194
+ );
8195
+ return await withRuntimePostgres(session, (client) =>
8196
+ countRuntimeSheetRowOutcomes(client, {
8197
+ schema: session.postgres.schema,
8198
+ table: session.postgres.sheetTable,
8199
+ runId: context.runId,
8200
+ }),
8201
+ );
8202
+ }
8203
+
8121
8204
  export async function persistRuntimeCsvDataset(
8122
8205
  context: RuntimeApiContext & { playName: string },
8123
8206
  input: {
@@ -1,3 +1,5 @@
1
+ import type { PlayDocflowNodeIoState } from './docflow-node-io';
2
+
1
3
  export type PlayStagedFileRef = {
2
4
  storageKind: 'r2';
3
5
  storageKey: string;
@@ -21,6 +23,7 @@ export type PlayVisualNodeProgress = {
21
23
  startedAt?: number;
22
24
  completedAt?: number;
23
25
  artifactTableNamespace?: string | null;
26
+ nodeIo?: PlayDocflowNodeIoState;
24
27
  };
25
28
 
26
29
  export type PlayVisualNodeProgressMap = Record<string, PlayVisualNodeProgress>;
@@ -71,6 +71,28 @@ export const PLAY_AUTHORING_CONTRACT_ISSUE_CODES = [
71
71
  'play_authoring_fetch_key_reused_in_loop',
72
72
  'play_authoring_binding_invalid',
73
73
  'play_authoring_input_schema_unresolved',
74
+ 'check_error',
75
+ 'docflow_compile_error',
76
+ 'docflow_binding_drift',
77
+ 'docflow_branch_labels_required',
78
+ 'docflow_branch_requires_decision',
79
+ 'docflow_direction_not_top_down',
80
+ 'docflow_directive_ignored',
81
+ 'docflow_dataset_unrepresented',
82
+ 'docflow_loop_ambiguous',
83
+ 'docflow_loop_foreign_step',
84
+ 'docflow_loop_incomplete',
85
+ 'docflow_dataset_column_undrawn',
86
+ 'docflow_undrawn_declaration_invalid',
87
+ 'docflow_layout_complexity',
88
+ 'docflow_topology_invalid',
89
+ 'docflow_io_ambiguous',
90
+ 'docflow_input_not_found',
91
+ 'docflow_output_not_found',
92
+ 'docflow_label_counts_rows',
93
+ 'docflow_node_kind_unsupported',
94
+ 'docflow_child_play_undrawn',
95
+ 'docflow_waterfall_region_invalid',
74
96
  ] as const;
75
97
 
76
98
  export type PlayAuthoringContractIssueCode =
@@ -572,6 +594,13 @@ export type PlayAuthoringDatasetRunOptions<InputRow extends object> = {
572
594
  key?: PlayAuthoringDatasetRowKey<InputRow>;
573
595
  onRowError?: 'isolate' | 'fail';
574
596
  mode?: 'upsert' | 'net_new';
597
+ /**
598
+ * Computed columns this dataset produces that the authored `@mermaid`
599
+ * diagram deliberately does not draw. A diagrammed Play must account for
600
+ * every column it computes: draw it inside the dataset's `subgraph` loop
601
+ * region, or name it here. Nothing else opts a column out.
602
+ */
603
+ undrawnColumns?: readonly string[];
575
604
  };
576
605
 
577
606
  export const PLAY_AUTHORING_DATASET_RUN_OPTION_FIELDS = [
@@ -579,6 +608,7 @@ export const PLAY_AUTHORING_DATASET_RUN_OPTION_FIELDS = [
579
608
  'key',
580
609
  'onRowError',
581
610
  'mode',
611
+ 'undrawnColumns',
582
612
  ] as const;
583
613
 
584
614
  export type PlayAuthoringDatasetBuilder<
@@ -1711,6 +1741,24 @@ export const PLAY_AUTHORING_FIELD_REGISTRY = {
1711
1741
  'Whether the dataset returns all rows or only newly admitted rows.',
1712
1742
  errorMessage: 'ctx.dataset run mode must be "upsert" or "net_new".',
1713
1743
  },
1744
+ 'ctx.dataset.run.undrawnColumns': {
1745
+ schema: Type.Array(Type.String({ minLength: 1 }), { minItems: 1 }),
1746
+ fixtures: {
1747
+ valid: ['miss_reason'],
1748
+ invalid: [],
1749
+ absent: undefined,
1750
+ unresolved: { expression: 'undrawnColumns' },
1751
+ edition1: ['miss_reason'],
1752
+ },
1753
+ referenceType: 'readonly string[]',
1754
+ required: false,
1755
+ resolution: 'static-when-present',
1756
+ issueCode: 'play_authoring_dataset_option_invalid',
1757
+ description:
1758
+ 'Computed columns deliberately left out of the authored @mermaid diagram.',
1759
+ errorMessage:
1760
+ 'ctx.dataset run undrawnColumns must be a non-empty array of static column-name strings.',
1761
+ },
1714
1762
  'ctx.step.id': {
1715
1763
  schema: Type.String({ minLength: 1 }),
1716
1764
  fixtures: {
@@ -2339,7 +2387,7 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
2339
2387
  'export type StepProgramOutput<TProgram> = TProgram extends StepProgram<unknown, infer Output, unknown> ? Output : never;',
2340
2388
  'export type DatasetRowKey<InputRow extends object> = (keyof InputRow & string) | readonly (keyof InputRow & string)[] | ((row: InputRow, index: number) => string | number | readonly unknown[]);',
2341
2389
  'export type DatasetDefinitionOptions<InputRow extends object> = { key?: DatasetRowKey<InputRow> };',
2342
- `export type DatasetRunOptions<InputRow extends object> = { description?: ${cloudReferenceType('ctx.dataset.run.description')}; key?: DatasetRowKey<InputRow>; onRowError?: ${cloudReferenceType('ctx.dataset.run.onRowError')}; mode?: ${cloudReferenceType('ctx.dataset.run.mode')} };`,
2390
+ `export type DatasetRunOptions<InputRow extends object> = { description?: ${cloudReferenceType('ctx.dataset.run.description')}; key?: DatasetRowKey<InputRow>; onRowError?: ${cloudReferenceType('ctx.dataset.run.onRowError')}; mode?: ${cloudReferenceType('ctx.dataset.run.mode')}; undrawnColumns?: ${cloudReferenceType('ctx.dataset.run.undrawnColumns')} };`,
2343
2391
  'export type DatasetBuilder<InputRow extends object, OutputRow extends object> = {',
2344
2392
  ' withColumn<Name extends string, Value>(name: Name, resolver: ColumnResolver<OutputRow, Value>): DatasetBuilder<InputRow, OutputRow & Record<Name, Value>>;',
2345
2393
  ' withColumn<Name extends string, Value>(name: Name, definition: DatasetColumnDefinition<OutputRow, Value> & { readonly runIf: (row: OutputRow, index: number) => boolean | Promise<boolean> }): DatasetBuilder<InputRow, OutputRow & Record<Name, Value | null>>;',