deepline 0.3.274 → 0.3.276

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 (29) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +148 -19
  2. package/dist/bundling-sources/sdk/src/index.ts +3 -0
  3. package/dist/bundling-sources/sdk/src/play.ts +4 -10
  4. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  5. package/dist/bundling-sources/sdk/src/runs/log-cursor.ts +35 -0
  6. package/dist/bundling-sources/sdk/src/types.ts +10 -3
  7. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -26
  8. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +7 -3
  9. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +15 -7
  10. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +18 -18
  11. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1 -0
  12. package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +7 -4
  13. package/dist/bundling-sources/shared_libs/plays/table-csv.ts +152 -0
  14. package/dist/cli/index.js +411 -284
  15. package/dist/cli/index.mjs +411 -284
  16. package/dist/{client-2rIHKJiq.d.mts → client-C0EhEIQO.d.mts} +78 -13
  17. package/dist/{client-D6fRwhnE.d.ts → client-HxPrGPbv.d.ts} +78 -13
  18. package/dist/index.d.mts +6 -12
  19. package/dist/index.d.ts +6 -12
  20. package/dist/index.js +87 -9
  21. package/dist/index.mjs +87 -9
  22. package/dist/install-integrity.json +4 -2
  23. package/dist/plays/run-request.d.mts +1 -1
  24. package/dist/plays/run-request.d.ts +1 -1
  25. package/dist/release.d.mts +1 -1
  26. package/dist/release.d.ts +1 -1
  27. package/dist/release.js +1 -1
  28. package/dist/release.mjs +1 -1
  29. package/package.json +1 -1
@@ -228,9 +228,7 @@ export function substepOwnSourceExtent(
228
228
  * another module, where the callee's own range is not even comparable to a line
229
229
  * number in this file.
230
230
  */
231
- function callSiteExtent(
232
- substep: PlayStaticSubstep,
233
- ): DocflowLineExtent | null {
231
+ function callSiteExtent(substep: PlayStaticSubstep): DocflowLineExtent | null {
234
232
  const range = substep.callSiteRange;
235
233
  return range ? { startLine: range.startLine, endLine: range.endLine } : null;
236
234
  }
@@ -350,7 +348,12 @@ export function resolveDocflowOwnerSubstep(
350
348
  binding: PlayDocflowBinding,
351
349
  substeps: readonly PlayStaticSubstep[],
352
350
  ): DocflowBindingJoin<DocflowOwnerSubstep> {
353
- const owners = substeps.filter(
351
+ // Docflow bindings are attached to diagram nodes, which may describe work
352
+ // inside a conditional arm, a row map, or a nested play. Resolve against the
353
+ // compiled tree rather than just its top-level entries; otherwise a branch
354
+ // dataset renders without its schema/row namespace and its cards can lose
355
+ // the exact run data needed by the inspector and row badges.
356
+ const owners = flattenSubsteps(substeps).filter(
354
357
  (substep): substep is DocflowOwnerSubstep =>
355
358
  substep.type === 'dataset' || substep.type === 'csv',
356
359
  );
@@ -0,0 +1,152 @@
1
+ /**
2
+ * The one CSV writer for a Play table export, shared by the dashboard download
3
+ * (`GET /api/v2/plays/{name}/sheet/export`) and the CLI
4
+ * (`deepline runs export`), so the same table reads the same in either file.
5
+ * Pure: it runs on the server, in the browser (clipboard copy) and in the CLI.
6
+ *
7
+ * Cell rules: an empty value is an empty field, booleans are `true`/`false`,
8
+ * objects and arrays are compact JSON, and a field is quoted only when it has
9
+ * to be (RFC 4180).
10
+ *
11
+ * A failed row exports as written, and says why it failed: when any row of the
12
+ * export failed, every record ends with an `_error` column holding the row's
13
+ * failure reason (empty on a row that did not fail).
14
+ */
15
+
16
+ /** The trailing column carrying a failed row's reason. */
17
+ export const TABLE_EXPORT_ERROR_COLUMN = '_error';
18
+
19
+ /** Legacy settled-sheet columns retained for existing CSV consumers. */
20
+ export const TABLE_EXPORT_STATUS_COLUMN = 'row_status';
21
+ export const TABLE_EXPORT_ROW_ERROR_COLUMN = 'row_error';
22
+
23
+ /** What a failed row says when its writer recorded no reason. */
24
+ const UNRECORDED_FAILURE_REASON = 'Row failed without a recorded reason.';
25
+
26
+ /** A cell's raw value as text: objects as JSON, empty as ''. */
27
+ export function tableCellText(value: unknown): string {
28
+ if (value === null || value === undefined) return '';
29
+ if (typeof value === 'string') return value;
30
+ if (
31
+ typeof value === 'number' ||
32
+ typeof value === 'bigint' ||
33
+ typeof value === 'boolean'
34
+ )
35
+ return String(value);
36
+ if (value instanceof Date) return value.toISOString();
37
+ if (typeof value === 'symbol' || typeof value === 'function') return '';
38
+ try {
39
+ return (
40
+ JSON.stringify(value, (_key, nested: unknown) =>
41
+ typeof nested === 'bigint' ? nested.toString() : nested,
42
+ ) ?? ''
43
+ );
44
+ } catch {
45
+ return String(value);
46
+ }
47
+ }
48
+
49
+ /** One RFC 4180 field: quoted (quotes doubled) when it holds `,` `"` or a newline. */
50
+ export function csvField(value: unknown): string {
51
+ const text = tableCellText(value);
52
+ return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
53
+ }
54
+
55
+ /** One CSV record, newline-terminated. */
56
+ export function csvRecord(values: readonly unknown[]): string {
57
+ return `${values.map(csvField).join(',')}\n`;
58
+ }
59
+
60
+ /** A sheet row as an export reads it: its data, its status, its error. */
61
+ export type TableExportRow = {
62
+ data: Record<string, unknown>;
63
+ status?: unknown;
64
+ error?: unknown;
65
+ };
66
+
67
+ function isFailedRow(row: { status?: unknown }): boolean {
68
+ return row.status === 'failed';
69
+ }
70
+
71
+ /** Whether any of these rows failed, so the export carries `_error`. */
72
+ export function tableExportHasFailedRows(
73
+ rows: Iterable<{ status?: unknown }>,
74
+ ): boolean {
75
+ for (const row of rows) if (isFailedRow(row)) return true;
76
+ return false;
77
+ }
78
+
79
+ /** The `_error` cell of one row: its failure reason, or '' when it did not fail. */
80
+ export function tableExportErrorCell(row: {
81
+ status?: unknown;
82
+ error?: unknown;
83
+ }): string {
84
+ if (!isFailedRow(row)) return '';
85
+ const reason = typeof row.error === 'string' ? row.error.trim() : '';
86
+ return reason || UNRECORDED_FAILURE_REASON;
87
+ }
88
+
89
+ /** The export header: the table's columns, then `_error` when a row failed. */
90
+ export function tableExportColumns(
91
+ columns: readonly string[],
92
+ withError: boolean,
93
+ ): string[] {
94
+ if (!withError) return [...columns];
95
+ return [
96
+ ...columns.filter((column) => column !== TABLE_EXPORT_ERROR_COLUMN),
97
+ TABLE_EXPORT_ERROR_COLUMN,
98
+ ];
99
+ }
100
+
101
+ /** One row's cells, in `tableExportColumns(columns, withError)` order. */
102
+ export function tableExportCells(
103
+ row: TableExportRow,
104
+ columns: readonly string[],
105
+ withError: boolean,
106
+ ): unknown[] {
107
+ return tableExportColumns(columns, withError).map((column) =>
108
+ column === TABLE_EXPORT_ERROR_COLUMN && withError
109
+ ? tableExportErrorCell(row)
110
+ : Object.hasOwn(row.data, column)
111
+ ? row.data[column]
112
+ : undefined,
113
+ );
114
+ }
115
+
116
+ /**
117
+ * Settled dashboard downloads keep their established status/reason columns.
118
+ * The CLI's newer `_error` projection is separate; both use this module's CSV
119
+ * encoding so spreadsheet escaping and cell formatting stay consistent.
120
+ */
121
+ export function tableExportSettledColumns(
122
+ columns: readonly string[],
123
+ withFailureDetails: boolean,
124
+ ): string[] {
125
+ return withFailureDetails
126
+ ? [...columns, TABLE_EXPORT_STATUS_COLUMN, TABLE_EXPORT_ROW_ERROR_COLUMN]
127
+ : [...columns];
128
+ }
129
+
130
+ /** A settled dashboard row, preserving the public `row_status,row_error` contract. */
131
+ export function tableExportSettledCells(
132
+ row: TableExportRow,
133
+ columns: readonly string[],
134
+ withFailureDetails: boolean,
135
+ ): unknown[] {
136
+ const values = columns.map((column) =>
137
+ Object.hasOwn(row.data, column) ? row.data[column] : undefined,
138
+ );
139
+ return withFailureDetails
140
+ ? [...values, row.status, row.status === 'failed' ? (row.error ?? '') : '']
141
+ : values;
142
+ }
143
+
144
+ /** A whole table as CSV text: the header record, then one record per row. */
145
+ export function tableCsvText(
146
+ header: readonly string[],
147
+ records: Iterable<readonly unknown[]>,
148
+ ): string {
149
+ let text = csvRecord(header);
150
+ for (const record of records) text += csvRecord(record);
151
+ return text;
152
+ }