deepline 0.1.146 → 0.1.148
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.
- package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +205 -75
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/dataset-handles.ts +8 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/output-datasets.ts +363 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/result-dataset-persistence.ts +50 -0
- package/dist/bundling-sources/sdk/src/release.ts +54 -21
- package/dist/bundling-sources/sdk/src/tool-output.ts +18 -7
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +2 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +81 -5
- package/dist/cli/index.js +198 -41
- package/dist/cli/index.mjs +210 -53
- package/dist/index.d.mts +91 -89
- package/dist/index.d.ts +91 -89
- package/dist/index.js +545 -31
- package/dist/index.mjs +546 -32
- package/package.json +2 -2
package/dist/cli/index.mjs
CHANGED
|
@@ -604,10 +604,11 @@ var SDK_RELEASE = {
|
|
|
604
604
|
// 0.1.108 ships explicit dataset column/tool recompute policy and removes
|
|
605
605
|
// the SDK enrich generator's one-second stale policy.
|
|
606
606
|
// 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
|
|
607
|
-
|
|
608
|
-
|
|
607
|
+
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
608
|
+
version: "0.1.148",
|
|
609
|
+
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
609
610
|
supportPolicy: {
|
|
610
|
-
latest: "0.1.
|
|
611
|
+
latest: "0.1.148",
|
|
611
612
|
minimumSupported: "0.1.53",
|
|
612
613
|
deprecatedBelow: "0.1.53",
|
|
613
614
|
commandMinimumSupported: [
|
|
@@ -618,52 +619,79 @@ var SDK_RELEASE = {
|
|
|
618
619
|
},
|
|
619
620
|
{
|
|
620
621
|
command: "plays",
|
|
621
|
-
minimumSupported: "0.1.
|
|
622
|
-
reason: "Play file commands now
|
|
622
|
+
minimumSupported: "0.1.111",
|
|
623
|
+
reason: "Play file commands now use dataset-native list getters and result row datasets."
|
|
623
624
|
},
|
|
624
625
|
{
|
|
625
626
|
command: "plays run",
|
|
626
|
-
minimumSupported: "0.1.
|
|
627
|
-
reason: "Play
|
|
627
|
+
minimumSupported: "0.1.111",
|
|
628
|
+
reason: "Play run results now promote row-shaped outputs into dataset handles for safe export."
|
|
628
629
|
},
|
|
629
630
|
{
|
|
630
631
|
command: "run",
|
|
631
632
|
displayCommand: "plays run",
|
|
632
|
-
minimumSupported: "0.1.
|
|
633
|
-
reason: "Play
|
|
633
|
+
minimumSupported: "0.1.111",
|
|
634
|
+
reason: "Play run results now promote row-shaped outputs into dataset handles for safe export."
|
|
634
635
|
},
|
|
635
636
|
{
|
|
636
637
|
command: "plays check",
|
|
637
|
-
minimumSupported: "0.1.
|
|
638
|
-
reason: "Play file
|
|
638
|
+
minimumSupported: "0.1.111",
|
|
639
|
+
reason: "Play file checks now validate dataset-native list getter authoring."
|
|
639
640
|
},
|
|
640
641
|
{
|
|
641
642
|
command: "check",
|
|
642
643
|
displayCommand: "plays check",
|
|
643
|
-
minimumSupported: "0.1.
|
|
644
|
-
reason: "Play file
|
|
644
|
+
minimumSupported: "0.1.111",
|
|
645
|
+
reason: "Play file checks now validate dataset-native list getter authoring."
|
|
645
646
|
},
|
|
646
647
|
{
|
|
647
648
|
command: "plays publish",
|
|
648
|
-
minimumSupported: "0.1.
|
|
649
|
-
reason: "
|
|
649
|
+
minimumSupported: "0.1.111",
|
|
650
|
+
reason: "Published play artifacts now target dataset-native list getters and result row datasets."
|
|
650
651
|
},
|
|
651
652
|
{
|
|
652
653
|
command: "publish",
|
|
653
654
|
displayCommand: "plays publish",
|
|
654
|
-
minimumSupported: "0.1.
|
|
655
|
-
reason: "
|
|
655
|
+
minimumSupported: "0.1.111",
|
|
656
|
+
reason: "Published play artifacts now target dataset-native list getters and result row datasets."
|
|
656
657
|
},
|
|
657
658
|
{
|
|
658
659
|
command: "plays set-live",
|
|
659
|
-
minimumSupported: "0.1.
|
|
660
|
-
reason: "
|
|
660
|
+
minimumSupported: "0.1.111",
|
|
661
|
+
reason: "Published play artifacts now target dataset-native list getters and result row datasets."
|
|
661
662
|
},
|
|
662
663
|
{
|
|
663
664
|
command: "set-live",
|
|
664
665
|
displayCommand: "plays set-live",
|
|
665
|
-
minimumSupported: "0.1.
|
|
666
|
-
reason: "
|
|
666
|
+
minimumSupported: "0.1.111",
|
|
667
|
+
reason: "Published play artifacts now target dataset-native list getters and result row datasets."
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
command: "runs",
|
|
671
|
+
minimumSupported: "0.1.111",
|
|
672
|
+
reason: "Run result rows now render as dataset handles with explicit export commands."
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
command: "runs get",
|
|
676
|
+
minimumSupported: "0.1.111",
|
|
677
|
+
reason: "Run result rows now render as dataset handles with explicit export commands."
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
command: "get",
|
|
681
|
+
displayCommand: "runs get",
|
|
682
|
+
minimumSupported: "0.1.111",
|
|
683
|
+
reason: "Run result rows now render as dataset handles with explicit export commands."
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
command: "runs export",
|
|
687
|
+
minimumSupported: "0.1.111",
|
|
688
|
+
reason: "Run result row datasets now use the dataset-handle export contract."
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
command: "export",
|
|
692
|
+
displayCommand: "runs export",
|
|
693
|
+
minimumSupported: "0.1.111",
|
|
694
|
+
reason: "Run result row datasets now use the dataset-handle export contract."
|
|
667
695
|
}
|
|
668
696
|
],
|
|
669
697
|
autoUpdatePatchLag: 2
|
|
@@ -8319,9 +8347,10 @@ function generateProviderSourceBlock(input2) {
|
|
|
8319
8347
|
input: ${inputName},
|
|
8320
8348
|
description: ${jsString(`Seed ${input2.entity} rows from ${input2.provider}.`)},
|
|
8321
8349
|
});
|
|
8322
|
-
// extractedLists.${getter}.get() returns provider-shaped rows. Do not assume canonical fields;
|
|
8350
|
+
// extractedLists.${getter}.get() returns a dataset handle of provider-shaped rows. Do not assume canonical fields;
|
|
8323
8351
|
// inspect source_${input2.index}.extractedLists.${getter}.keys or the provider output schema, then map explicitly below.
|
|
8324
|
-
const
|
|
8352
|
+
const sourceRowsDataset_${input2.index} = ${accessorExpression(`source_${input2.index}.extractedLists`, getter)}.get();
|
|
8353
|
+
const sourceRows_${input2.index} = (await sourceRowsDataset_${input2.index}.peek(limit)) as ${input2.collectionType}[];`;
|
|
8325
8354
|
}
|
|
8326
8355
|
function generateProviderSourceRowsBlock(input2) {
|
|
8327
8356
|
const blocks = input2.source.values.map(
|
|
@@ -11007,6 +11036,9 @@ function formatPlayLogLine(line, status, state) {
|
|
|
11007
11036
|
}
|
|
11008
11037
|
return `${prefix}${message}`;
|
|
11009
11038
|
}
|
|
11039
|
+
function isDatasetResultEnvelope(value) {
|
|
11040
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && value.kind === "dataset";
|
|
11041
|
+
}
|
|
11010
11042
|
function compactReturnValue(value, depth = 0) {
|
|
11011
11043
|
if (depth >= 4) {
|
|
11012
11044
|
return value && typeof value === "object" ? "[Object]" : value;
|
|
@@ -11018,6 +11050,7 @@ function compactReturnValue(value, depth = 0) {
|
|
|
11018
11050
|
if (!value || typeof value !== "object") {
|
|
11019
11051
|
return value;
|
|
11020
11052
|
}
|
|
11053
|
+
const isDatasetEnvelope = isDatasetResultEnvelope(value);
|
|
11021
11054
|
const output2 = {};
|
|
11022
11055
|
for (const [key, entry] of Object.entries(value)) {
|
|
11023
11056
|
if (depth === 0 && key === "_metadata") {
|
|
@@ -11026,13 +11059,41 @@ function compactReturnValue(value, depth = 0) {
|
|
|
11026
11059
|
if (BULKY_RETURN_KEYS.has(key)) {
|
|
11027
11060
|
continue;
|
|
11028
11061
|
}
|
|
11029
|
-
if (key === "access") {
|
|
11062
|
+
if (isDatasetEnvelope && key === "access") {
|
|
11063
|
+
continue;
|
|
11064
|
+
}
|
|
11065
|
+
if (isDatasetEnvelope && (key === "queryDatasetCommand" || key === "cliCommand")) {
|
|
11066
|
+
continue;
|
|
11067
|
+
}
|
|
11068
|
+
if (isDatasetEnvelope && key === "slowExportAsCsvCommand") {
|
|
11069
|
+
output2.fullExportCommand = entry;
|
|
11030
11070
|
continue;
|
|
11031
11071
|
}
|
|
11032
11072
|
output2[key] = compactReturnValue(entry, depth + 1);
|
|
11033
11073
|
}
|
|
11034
11074
|
return output2;
|
|
11035
11075
|
}
|
|
11076
|
+
function defaultResultForEnvelope(value, depth = 0) {
|
|
11077
|
+
if (depth > 20 || value == null || typeof value !== "object") {
|
|
11078
|
+
return value;
|
|
11079
|
+
}
|
|
11080
|
+
if (Array.isArray(value)) {
|
|
11081
|
+
return value.map((entry) => defaultResultForEnvelope(entry, depth + 1));
|
|
11082
|
+
}
|
|
11083
|
+
const isDatasetEnvelope = isDatasetResultEnvelope(value);
|
|
11084
|
+
const output2 = {};
|
|
11085
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
11086
|
+
if (isDatasetEnvelope && (key === "queryDatasetCommand" || key === "cliCommand")) {
|
|
11087
|
+
continue;
|
|
11088
|
+
}
|
|
11089
|
+
if (isDatasetEnvelope && key === "slowExportAsCsvCommand") {
|
|
11090
|
+
output2.fullExportCommand = entry;
|
|
11091
|
+
continue;
|
|
11092
|
+
}
|
|
11093
|
+
output2[key] = defaultResultForEnvelope(entry, depth + 1);
|
|
11094
|
+
}
|
|
11095
|
+
return output2;
|
|
11096
|
+
}
|
|
11036
11097
|
function formatJsonPreview(value) {
|
|
11037
11098
|
const json = JSON.stringify(value, null, 2);
|
|
11038
11099
|
if (!json || json === "{}") {
|
|
@@ -11076,9 +11137,6 @@ function collectDatasetHandleLines(value, path = "result", datasetStats) {
|
|
|
11076
11137
|
if (datasetStats && (datasetStats.source === path || datasetStats.source === record.path)) {
|
|
11077
11138
|
lines2.push(...formatDatasetStatsLines(datasetStats.stats, " "));
|
|
11078
11139
|
}
|
|
11079
|
-
if (typeof record.queryDatasetCommand === "string") {
|
|
11080
|
-
lines2.push(` query dataset: ${record.queryDatasetCommand}`);
|
|
11081
|
-
}
|
|
11082
11140
|
if (typeof record.slowExportAsCsvCommand === "string") {
|
|
11083
11141
|
lines2.push(` export CSV: ${record.slowExportAsCsvCommand}`);
|
|
11084
11142
|
}
|
|
@@ -11489,7 +11547,7 @@ function compactPlayStatus(status) {
|
|
|
11489
11547
|
logs: normalizeLogsForEnvelope(status),
|
|
11490
11548
|
...displayError ? { error: displayError } : {},
|
|
11491
11549
|
...warnings.length > 0 ? { warnings } : {},
|
|
11492
|
-
...result !== void 0 ? { result } : {},
|
|
11550
|
+
...result !== void 0 ? { result: defaultResultForEnvelope(result) } : {},
|
|
11493
11551
|
...billing ? { billing } : {},
|
|
11494
11552
|
next: buildRunNextCommands(status)
|
|
11495
11553
|
};
|
|
@@ -20372,7 +20430,7 @@ import { join as join10, resolve as resolve10 } from "path";
|
|
|
20372
20430
|
// src/tool-output.ts
|
|
20373
20431
|
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync11 } from "fs";
|
|
20374
20432
|
import { homedir as homedir9 } from "os";
|
|
20375
|
-
import { join as join9 } from "path";
|
|
20433
|
+
import { dirname as dirname9, join as join9 } from "path";
|
|
20376
20434
|
function isPlainObject(value) {
|
|
20377
20435
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
20378
20436
|
}
|
|
@@ -20445,16 +20503,24 @@ function tryConvertToList(payload, options) {
|
|
|
20445
20503
|
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
20446
20504
|
) : [];
|
|
20447
20505
|
if (listExtractorPaths.length > 0) {
|
|
20506
|
+
let emptyMatch = null;
|
|
20448
20507
|
for (const root of candidateRoots(payload)) {
|
|
20449
20508
|
for (const extractorPath of listExtractorPaths) {
|
|
20450
20509
|
const resolved = getByDottedPath(root.value, extractorPath);
|
|
20451
20510
|
const rows = normalizeRows(resolved);
|
|
20452
|
-
if (rows
|
|
20453
|
-
|
|
20511
|
+
if (!rows) {
|
|
20512
|
+
continue;
|
|
20513
|
+
}
|
|
20514
|
+
const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
|
|
20515
|
+
if (rows.length > 0) {
|
|
20454
20516
|
return { rows, strategy: "configured_paths", sourcePath };
|
|
20455
20517
|
}
|
|
20518
|
+
emptyMatch ??= { rows, strategy: "configured_paths", sourcePath };
|
|
20456
20519
|
}
|
|
20457
20520
|
}
|
|
20521
|
+
if (emptyMatch) {
|
|
20522
|
+
return emptyMatch;
|
|
20523
|
+
}
|
|
20458
20524
|
}
|
|
20459
20525
|
for (const root of candidateRoots(payload)) {
|
|
20460
20526
|
const candidate = findBestArrayCandidate(root.value, root.path ?? "");
|
|
@@ -20478,9 +20544,9 @@ function writeJsonOutputFile(payload, stem) {
|
|
|
20478
20544
|
writeFileSync11(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
20479
20545
|
return outputPath;
|
|
20480
20546
|
}
|
|
20481
|
-
function writeCsvOutputFile(rows, stem) {
|
|
20482
|
-
const
|
|
20483
|
-
|
|
20547
|
+
function writeCsvOutputFile(rows, stem, options) {
|
|
20548
|
+
const outputPath = options?.outPath ? options.outPath : join9(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
|
|
20549
|
+
mkdirSync7(dirname9(outputPath), { recursive: true });
|
|
20484
20550
|
const seen = /* @__PURE__ */ new Set();
|
|
20485
20551
|
const columns = [];
|
|
20486
20552
|
for (const row of rows) {
|
|
@@ -21009,6 +21075,7 @@ Examples:
|
|
|
21009
21075
|
deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
|
|
21010
21076
|
deepline tools execute hunter_email_verifier -p email=a@b.com
|
|
21011
21077
|
deepline tools execute test_rate_limit --input '{"key":"smoke"}' --json | jq '.status'
|
|
21078
|
+
deepline tools execute free_simple_company_search --input '{"sql":"SELECT company_name FROM companies LIMIT 10"}' --out companies.csv
|
|
21012
21079
|
`
|
|
21013
21080
|
).option(
|
|
21014
21081
|
"-p, --param <key=value>",
|
|
@@ -21030,6 +21097,9 @@ Examples:
|
|
|
21030
21097
|
).option(
|
|
21031
21098
|
"--output-format <format>",
|
|
21032
21099
|
"Output format: auto, csv, csv_file, json, or json_file"
|
|
21100
|
+
).option(
|
|
21101
|
+
"-o, --out <path>",
|
|
21102
|
+
"Write row-shaped tool output to this CSV path"
|
|
21033
21103
|
).option(
|
|
21034
21104
|
"--no-preview",
|
|
21035
21105
|
"Only print the extracted output path when applicable"
|
|
@@ -21042,6 +21112,7 @@ Examples:
|
|
|
21042
21112
|
...options.input ? ["--input", options.input] : [],
|
|
21043
21113
|
...options.payload ? ["--payload", options.payload] : [],
|
|
21044
21114
|
...options.outputFormat ? ["--output-format", options.outputFormat] : [],
|
|
21115
|
+
...options.out ? ["--out", options.out] : [],
|
|
21045
21116
|
...options.preview === false ? ["--no-preview"] : []
|
|
21046
21117
|
];
|
|
21047
21118
|
process.exitCode = await executeTool(args);
|
|
@@ -21492,7 +21563,7 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
21492
21563
|
invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
|
|
21493
21564
|
observeActualShape: observedOutputCommand,
|
|
21494
21565
|
observedOutput: observedOutputCommand,
|
|
21495
|
-
forPlayGetterBugs: "Run a tiny play, inspect `deepline runs get <run-id> --full --json`,
|
|
21566
|
+
forPlayGetterBugs: "Run a tiny play, inspect returned handles with `deepline runs get <run-id> --full --json`, then export row datasets with `deepline runs export`.",
|
|
21496
21567
|
executeOutputFields: "tools execute JSON may include output_preview for this direct probe only; play debugging uses run output and returned dataset handles."
|
|
21497
21568
|
},
|
|
21498
21569
|
...starterScript ? { starterScript } : {}
|
|
@@ -21699,12 +21770,13 @@ function parseExecuteOptions(args) {
|
|
|
21699
21770
|
const toolId = args[0];
|
|
21700
21771
|
if (!toolId) {
|
|
21701
21772
|
throw new Error(
|
|
21702
|
-
`Usage: deepline tools execute <toolId> [--param key=value ...] [--input '{"k":"v"}'] [--output-format auto|csv|csv_file|json|json_file] [--no-preview]`
|
|
21773
|
+
`Usage: deepline tools execute <toolId> [--param key=value ...] [--input '{"k":"v"}'] [--out rows.csv] [--output-format auto|csv|csv_file|json|json_file] [--no-preview]`
|
|
21703
21774
|
);
|
|
21704
21775
|
}
|
|
21705
21776
|
const params = {};
|
|
21706
21777
|
let outputFormat = "auto";
|
|
21707
21778
|
let noPreview = false;
|
|
21779
|
+
let outPath = null;
|
|
21708
21780
|
for (let index = 1; index < args.length; index += 1) {
|
|
21709
21781
|
const arg = args[index];
|
|
21710
21782
|
if ((arg === "--param" || arg === "-p") && args[index + 1]) {
|
|
@@ -21736,9 +21808,13 @@ function parseExecuteOptions(args) {
|
|
|
21736
21808
|
noPreview = true;
|
|
21737
21809
|
continue;
|
|
21738
21810
|
}
|
|
21811
|
+
if ((arg === "--out" || arg === "-o") && args[index + 1]) {
|
|
21812
|
+
outPath = resolve10(args[++index]);
|
|
21813
|
+
continue;
|
|
21814
|
+
}
|
|
21739
21815
|
throw new Error(`Unknown option: ${arg}`);
|
|
21740
21816
|
}
|
|
21741
|
-
return { toolId, params, outputFormat, noPreview };
|
|
21817
|
+
return { toolId, params, outputFormat, noPreview, outPath };
|
|
21742
21818
|
}
|
|
21743
21819
|
function safeFileStem(value) {
|
|
21744
21820
|
return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
|
|
@@ -21782,9 +21858,14 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
21782
21858
|
});
|
|
21783
21859
|
|
|
21784
21860
|
const list = Object.values(result.extractedLists)[0];
|
|
21785
|
-
|
|
21861
|
+
if (!list) {
|
|
21862
|
+
throw new Error('Expected ${input2.toolId} to expose an extracted list getter.');
|
|
21863
|
+
}
|
|
21864
|
+
const rows = list.get();
|
|
21786
21865
|
// ${sampleRows}
|
|
21787
21866
|
// columns: ${columns}
|
|
21867
|
+
// extractedLists.<name>.get() returns a dataset handle for row-shaped list outputs.
|
|
21868
|
+
// Pass it to ctx.dataset; use rows.peek/count/materialize only for deliberate bounded inspection.
|
|
21788
21869
|
// .withColumn('email_waterfall', (row, rowCtx) => rowCtx.runPlay('name_domain_email', 'name-and-domain-to-email', { first_name: String(row.first_name ?? ''), last_name: String(row.last_name ?? ''), domain: String(row.domain ?? '') }, { description: 'Resolve email.' }))
|
|
21789
21870
|
// .withColumn('phone_waterfall', (row, rowCtx) => rowCtx.runPlay('contact_phone', 'contact-to-phone', { first_name: String(row.first_name ?? ''), last_name: String(row.last_name ?? ''), email: String(row.email ?? '') }, { description: 'Resolve phone.' }))
|
|
21790
21871
|
// ctx.dataset is idempotent by dataset key + row key; reruns reuse completed rows.
|
|
@@ -21844,7 +21925,7 @@ function buildToolExecuteBaseEnvelope(input2) {
|
|
|
21844
21925
|
...summaryEntries.length > 0 ? { summary: input2.summary } : {},
|
|
21845
21926
|
next: {
|
|
21846
21927
|
inspect: inspectCommand,
|
|
21847
|
-
playDebugging: "When fixing a play getter, inspect
|
|
21928
|
+
playDebugging: "When fixing a play getter, inspect returned dataset handles with runs get and export rows with runs export; do not copy CLI preview paths blindly.",
|
|
21848
21929
|
...input2.listConversion ? {
|
|
21849
21930
|
expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
|
|
21850
21931
|
listSourcePath: input2.listConversion.sourcePath ?? "auto-detected list in the CLI response preview"
|
|
@@ -21856,7 +21937,7 @@ function buildToolExecuteBaseEnvelope(input2) {
|
|
|
21856
21937
|
title: "output",
|
|
21857
21938
|
lines: [
|
|
21858
21939
|
`${input2.listConversion.rows.length} row(s) extracted from ${input2.listConversion.sourcePath ?? "auto-detected list"}`,
|
|
21859
|
-
"paths above are observed from this execute response; use
|
|
21940
|
+
"paths above are observed from this execute response; use runs get and runs export to validate play output",
|
|
21860
21941
|
`columns: ${JSON.stringify(Object.keys(input2.listConversion.rows[0] ?? {}))}`,
|
|
21861
21942
|
`preview: ${JSON.stringify(input2.listConversion.rows.slice(0, 5))}`
|
|
21862
21943
|
]
|
|
@@ -21936,7 +22017,7 @@ async function executeTool(args) {
|
|
|
21936
22017
|
listConversion,
|
|
21937
22018
|
summary
|
|
21938
22019
|
});
|
|
21939
|
-
if (parsed.outputFormat === "json" || parsed.outputFormat === "auto" && shouldEmitJson()) {
|
|
22020
|
+
if (!parsed.outPath && (parsed.outputFormat === "json" || parsed.outputFormat === "auto" && shouldEmitJson())) {
|
|
21940
22021
|
printCommandEnvelope(baseEnvelope, { json: true });
|
|
21941
22022
|
return 0;
|
|
21942
22023
|
}
|
|
@@ -21958,6 +22039,17 @@ async function executeTool(args) {
|
|
|
21958
22039
|
return 0;
|
|
21959
22040
|
}
|
|
21960
22041
|
if (!listConversion) {
|
|
22042
|
+
if (parsed.outPath) {
|
|
22043
|
+
const error = new Error(
|
|
22044
|
+
`${parsed.toolId} did not expose row-shaped output to write as CSV. Re-run with --json to inspect the raw tool response.`
|
|
22045
|
+
);
|
|
22046
|
+
if (argsWantJson(args)) {
|
|
22047
|
+
printJsonError(error);
|
|
22048
|
+
} else {
|
|
22049
|
+
console.error(error.message);
|
|
22050
|
+
}
|
|
22051
|
+
return 1;
|
|
22052
|
+
}
|
|
21961
22053
|
if (parsed.outputFormat === "csv" || parsed.outputFormat === "csv_file") {
|
|
21962
22054
|
const jsonPath = writeJsonOutputFile(
|
|
21963
22055
|
rawResponse,
|
|
@@ -21979,7 +22071,8 @@ async function executeTool(args) {
|
|
|
21979
22071
|
}
|
|
21980
22072
|
const csv = writeCsvOutputFile(
|
|
21981
22073
|
listConversion.rows,
|
|
21982
|
-
`${parsed.toolId}_output
|
|
22074
|
+
`${parsed.toolId}_output`,
|
|
22075
|
+
parsed.outPath ? { outPath: parsed.outPath } : void 0
|
|
21983
22076
|
);
|
|
21984
22077
|
const seededScript = seedToolListScript({
|
|
21985
22078
|
toolId: parsed.toolId,
|
|
@@ -22052,6 +22145,27 @@ async function executeTool(args) {
|
|
|
22052
22145
|
);
|
|
22053
22146
|
return 0;
|
|
22054
22147
|
}
|
|
22148
|
+
if (parsed.outPath) {
|
|
22149
|
+
printCommandEnvelope(
|
|
22150
|
+
{
|
|
22151
|
+
...materializedEnvelope,
|
|
22152
|
+
csv_path: csv.path,
|
|
22153
|
+
row_count: csv.rowCount,
|
|
22154
|
+
row_count_returned: csv.rowCount,
|
|
22155
|
+
columns: csv.columns,
|
|
22156
|
+
preview: csv.preview,
|
|
22157
|
+
list_strategy: listConversion.strategy,
|
|
22158
|
+
list_source_path: listConversion.sourcePath,
|
|
22159
|
+
summary
|
|
22160
|
+
},
|
|
22161
|
+
{
|
|
22162
|
+
json: argsWantJson(args) || shouldEmitJson(),
|
|
22163
|
+
text: `Wrote ${csv.rowCount} row(s) to ${csv.path}
|
|
22164
|
+
`
|
|
22165
|
+
}
|
|
22166
|
+
);
|
|
22167
|
+
return 0;
|
|
22168
|
+
}
|
|
22055
22169
|
if (parsed.noPreview) {
|
|
22056
22170
|
printCommandEnvelope(
|
|
22057
22171
|
{
|
|
@@ -22072,7 +22186,7 @@ async function executeTool(args) {
|
|
|
22072
22186
|
|
|
22073
22187
|
// src/cli/commands/workflow.ts
|
|
22074
22188
|
import { mkdir as mkdir4, readFile as readFile2, writeFile as writeFile4 } from "fs/promises";
|
|
22075
|
-
import { dirname as
|
|
22189
|
+
import { dirname as dirname10, join as join11, resolve as resolve11 } from "path";
|
|
22076
22190
|
|
|
22077
22191
|
// src/cli/workflow-to-play.ts
|
|
22078
22192
|
import { createHash as createHash3 } from "crypto";
|
|
@@ -22351,7 +22465,7 @@ async function transformOne(api, workflowId, outDir, publish) {
|
|
|
22351
22465
|
{ workflowName: workflow.name, version: revision.version }
|
|
22352
22466
|
);
|
|
22353
22467
|
const file = join11(resolve11(outDir), `${compiled.playName}.play.ts`);
|
|
22354
|
-
await mkdir4(
|
|
22468
|
+
await mkdir4(dirname10(file), { recursive: true });
|
|
22355
22469
|
await writeFile4(file, compiled.sourceCode, "utf8");
|
|
22356
22470
|
let published = false;
|
|
22357
22471
|
if (publish) {
|
|
@@ -22609,12 +22723,12 @@ import {
|
|
|
22609
22723
|
writeFileSync as writeFileSync14
|
|
22610
22724
|
} from "fs";
|
|
22611
22725
|
import { homedir as homedir10 } from "os";
|
|
22612
|
-
import { dirname as
|
|
22726
|
+
import { dirname as dirname12, isAbsolute as isAbsolute2, join as join13, relative as relative2, resolve as resolve12 } from "path";
|
|
22613
22727
|
|
|
22614
22728
|
// src/cli/skills-sync.ts
|
|
22615
22729
|
import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
|
|
22616
22730
|
import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync13 } from "fs";
|
|
22617
|
-
import { dirname as
|
|
22731
|
+
import { dirname as dirname11, join as join12 } from "path";
|
|
22618
22732
|
|
|
22619
22733
|
// ../shared_libs/cli/install-commands.json
|
|
22620
22734
|
var install_commands_default = {
|
|
@@ -22748,7 +22862,7 @@ function sdkSkillsVersionPath(baseUrl) {
|
|
|
22748
22862
|
return join12(sdkCliStateDirPath(baseUrl), "skills-version");
|
|
22749
22863
|
}
|
|
22750
22864
|
function legacySdkSkillsVersionPath(baseUrl) {
|
|
22751
|
-
return join12(
|
|
22865
|
+
return join12(dirname11(sdkCliStateDirPath(baseUrl)), "sdk-skills", ".version");
|
|
22752
22866
|
}
|
|
22753
22867
|
function readSdkSkillsLocalVersion(baseUrl) {
|
|
22754
22868
|
const pluginVersion = readPluginSkillsVersion();
|
|
@@ -22763,7 +22877,7 @@ function readSdkSkillsLocalVersion(baseUrl) {
|
|
|
22763
22877
|
}
|
|
22764
22878
|
function writeLocalSkillsVersion(baseUrl, version) {
|
|
22765
22879
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
22766
|
-
mkdirSync8(
|
|
22880
|
+
mkdirSync8(dirname11(path), { recursive: true });
|
|
22767
22881
|
writeFileSync13(path, `${version}
|
|
22768
22882
|
`, "utf-8");
|
|
22769
22883
|
}
|
|
@@ -23092,7 +23206,7 @@ function findRepoBackedSdkRoot(startPath) {
|
|
|
23092
23206
|
if (existsSync11(join13(current, "sdk", "package.json")) && existsSync11(join13(current, "sdk", "bin", "deepline-dev.ts"))) {
|
|
23093
23207
|
return current;
|
|
23094
23208
|
}
|
|
23095
|
-
const parent =
|
|
23209
|
+
const parent = dirname12(current);
|
|
23096
23210
|
if (parent === current) return null;
|
|
23097
23211
|
current = parent;
|
|
23098
23212
|
}
|
|
@@ -23122,7 +23236,7 @@ function resolveUpdatePlan(options = {}) {
|
|
|
23122
23236
|
const env = options.env ?? process.env;
|
|
23123
23237
|
const homeDir2 = options.homeDir ?? homedir10();
|
|
23124
23238
|
const entrypoint = options.entrypoint ?? (process.argv[1] ? resolve12(process.argv[1]) : "");
|
|
23125
|
-
const sourceRoot = entrypoint ? findRepoBackedSdkRoot(
|
|
23239
|
+
const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname12(entrypoint)) : null;
|
|
23126
23240
|
if (sourceRoot) {
|
|
23127
23241
|
return {
|
|
23128
23242
|
kind: "source",
|
|
@@ -23201,7 +23315,7 @@ function writeAutoUpdateFailure(plan, exitCode) {
|
|
|
23201
23315
|
manualCommand: plan.manualCommand
|
|
23202
23316
|
};
|
|
23203
23317
|
try {
|
|
23204
|
-
mkdirSync9(
|
|
23318
|
+
mkdirSync9(dirname12(path), { recursive: true });
|
|
23205
23319
|
writeFileSync14(path, `${JSON.stringify(marker, null, 2)}
|
|
23206
23320
|
`, "utf8");
|
|
23207
23321
|
} catch {
|
|
@@ -23288,7 +23402,7 @@ function runCommand(command, args, env = process.env) {
|
|
|
23288
23402
|
});
|
|
23289
23403
|
}
|
|
23290
23404
|
function writeSidecarLauncher(input2) {
|
|
23291
|
-
mkdirSync9(
|
|
23405
|
+
mkdirSync9(dirname12(input2.path), { recursive: true });
|
|
23292
23406
|
if (process.platform === "win32") {
|
|
23293
23407
|
writeFileSync14(
|
|
23294
23408
|
input2.path,
|
|
@@ -23325,7 +23439,7 @@ async function runPythonSidecarUpdatePlan(plan) {
|
|
|
23325
23439
|
writeFileSync14(join13(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
|
|
23326
23440
|
const env = {
|
|
23327
23441
|
...process.env,
|
|
23328
|
-
PATH: `${
|
|
23442
|
+
PATH: `${dirname12(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
|
|
23329
23443
|
};
|
|
23330
23444
|
const installExitCode = await runCommand(
|
|
23331
23445
|
plan.npmCommand,
|
|
@@ -23602,6 +23716,40 @@ function isCi() {
|
|
|
23602
23716
|
function shouldSkipSelfUpdate() {
|
|
23603
23717
|
return envTruthy("DEEPLINE_SKIP_SELF_UPDATE") || envTruthy("DEEPLINE_NO_AUTO_UPDATE") || envTruthy("DEEPLINE_SKIP_SDK_AUTO_UPDATE") || envTruthy("DEEPLINE_DISABLE_AUTO_UPDATE") || isCi();
|
|
23604
23718
|
}
|
|
23719
|
+
function parseSemver(version) {
|
|
23720
|
+
const trimmed = version?.trim();
|
|
23721
|
+
if (!trimmed) return null;
|
|
23722
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(
|
|
23723
|
+
trimmed
|
|
23724
|
+
);
|
|
23725
|
+
if (!match) return null;
|
|
23726
|
+
return {
|
|
23727
|
+
major: Number(match[1]),
|
|
23728
|
+
minor: Number(match[2]),
|
|
23729
|
+
patch: Number(match[3]),
|
|
23730
|
+
prerelease: match[4] ?? ""
|
|
23731
|
+
};
|
|
23732
|
+
}
|
|
23733
|
+
function compareSemver(left, right) {
|
|
23734
|
+
const a = parseSemver(left);
|
|
23735
|
+
const b = parseSemver(right);
|
|
23736
|
+
if (!a || !b) {
|
|
23737
|
+
return left.localeCompare(right);
|
|
23738
|
+
}
|
|
23739
|
+
for (const key of ["major", "minor", "patch"]) {
|
|
23740
|
+
if (a[key] !== b[key]) return a[key] > b[key] ? 1 : -1;
|
|
23741
|
+
}
|
|
23742
|
+
if (a.prerelease === b.prerelease) return 0;
|
|
23743
|
+
if (!a.prerelease) return 1;
|
|
23744
|
+
if (!b.prerelease) return -1;
|
|
23745
|
+
return a.prerelease.localeCompare(b.prerelease);
|
|
23746
|
+
}
|
|
23747
|
+
function isDowngradeAutoUpdateResponse(response) {
|
|
23748
|
+
const target = response?.latest?.trim();
|
|
23749
|
+
const current = response?.current?.trim() || SDK_VERSION;
|
|
23750
|
+
if (!target) return false;
|
|
23751
|
+
return compareSemver(target, current) < 0;
|
|
23752
|
+
}
|
|
23605
23753
|
function relaunchCurrentCommand(plan) {
|
|
23606
23754
|
return new Promise((resolve13) => {
|
|
23607
23755
|
const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
|
|
@@ -23629,6 +23777,15 @@ async function maybeAutoUpdateAndRelaunch(response) {
|
|
|
23629
23777
|
if (!response || !autoUpdate?.should_auto_update || shouldSkipSelfUpdate()) {
|
|
23630
23778
|
return false;
|
|
23631
23779
|
}
|
|
23780
|
+
if (isDowngradeAutoUpdateResponse(response)) {
|
|
23781
|
+
const target = response.latest;
|
|
23782
|
+
const current = response.current?.trim() || SDK_VERSION;
|
|
23783
|
+
process.stderr.write(
|
|
23784
|
+
`Deepline SDK/CLI auto-update refused: server advertised older ${target} than current ${current}. Continuing without mutating the CLI.
|
|
23785
|
+
`
|
|
23786
|
+
);
|
|
23787
|
+
return false;
|
|
23788
|
+
}
|
|
23632
23789
|
const packageSpec = response.latest ? `deepline@${response.latest}` : void 0;
|
|
23633
23790
|
const plan = resolveUpdatePlan({ packageSpec });
|
|
23634
23791
|
if (plan.kind === "source") {
|