deepline 0.1.23 → 0.1.25
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/cli/index.js +741 -152
- package/dist/cli/index.mjs +703 -114
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +95 -81
- package/dist/repo/apps/play-runner-workers/src/dedup-do.ts +18 -5
- package/dist/repo/apps/play-runner-workers/src/entry.ts +37 -32
- package/dist/repo/apps/play-runner-workers/src/runtime/live-progress.ts +18 -0
- package/dist/repo/sdk/src/plays/harness-stub.ts +2 -0
- package/dist/repo/sdk/src/version.ts +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/cli/index.ts
|
|
27
|
-
var
|
|
27
|
+
var import_commander2 = require("commander");
|
|
28
28
|
|
|
29
29
|
// src/config.ts
|
|
30
30
|
var import_node_fs = require("fs");
|
|
@@ -266,7 +266,7 @@ function saveProjectDeeplineEnvValues(baseUrl, values, startDir = projectEnvStar
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
// src/version.ts
|
|
269
|
-
var SDK_VERSION = "0.1.
|
|
269
|
+
var SDK_VERSION = "0.1.25";
|
|
270
270
|
var SDK_API_CONTRACT = "2026-05-runs-v2";
|
|
271
271
|
|
|
272
272
|
// ../shared_libs/play-runtime/coordinator-headers.ts
|
|
@@ -548,7 +548,7 @@ function decodeSseFrame(frame) {
|
|
|
548
548
|
return parsed;
|
|
549
549
|
}
|
|
550
550
|
function sleep(ms) {
|
|
551
|
-
return new Promise((
|
|
551
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
552
552
|
}
|
|
553
553
|
|
|
554
554
|
// src/client.ts
|
|
@@ -556,7 +556,7 @@ var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "ca
|
|
|
556
556
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
557
557
|
var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
|
|
558
558
|
function sleep2(ms) {
|
|
559
|
-
return new Promise((
|
|
559
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
560
560
|
}
|
|
561
561
|
function isTransientCompileManifestError(error) {
|
|
562
562
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
@@ -2041,7 +2041,7 @@ function buildCandidateUrls2(url) {
|
|
|
2041
2041
|
}
|
|
2042
2042
|
}
|
|
2043
2043
|
function sleep3(ms) {
|
|
2044
|
-
return new Promise((
|
|
2044
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
2045
2045
|
}
|
|
2046
2046
|
function printDeeplineLogo() {
|
|
2047
2047
|
if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
|
|
@@ -2348,18 +2348,48 @@ function registerAuthCommands(program) {
|
|
|
2348
2348
|
`
|
|
2349
2349
|
Common commands:
|
|
2350
2350
|
deepline auth register
|
|
2351
|
+
deepline auth register --no-wait
|
|
2352
|
+
deepline auth wait --timeout 300
|
|
2351
2353
|
deepline auth status
|
|
2352
2354
|
deepline auth status --json
|
|
2355
|
+
|
|
2356
|
+
Notes:
|
|
2357
|
+
Registration opens a browser approval page by default. Use --no-wait in CI
|
|
2358
|
+
or agent runs, then finish with deepline auth wait.
|
|
2359
|
+
Auth status shows the target host and active workspace without printing secrets.
|
|
2353
2360
|
`
|
|
2354
2361
|
);
|
|
2355
|
-
auth.command("register").description("Register this device and open the approval page in your browser.").
|
|
2362
|
+
auth.command("register").description("Register this device and open the approval page in your browser.").addHelpText(
|
|
2363
|
+
"after",
|
|
2364
|
+
`
|
|
2365
|
+
Notes:
|
|
2366
|
+
Opens a browser approval page and waits for approval unless --no-wait is set.
|
|
2367
|
+
The saved API key is scoped to the selected workspace and host.
|
|
2368
|
+
|
|
2369
|
+
Examples:
|
|
2370
|
+
deepline auth register
|
|
2371
|
+
deepline auth register --org-name Acme --agent-name local-cli
|
|
2372
|
+
deepline auth register --no-wait
|
|
2373
|
+
`
|
|
2374
|
+
).option("--org-name <name>", "Workspace name to prefill").option("--agent-name <name>", "Agent name to register").option("--no-wait", "Return immediately after opening the approval page").action(async (options) => {
|
|
2356
2375
|
process.exitCode = await handleRegister([
|
|
2357
2376
|
...options.orgName ? ["--org-name", options.orgName] : [],
|
|
2358
2377
|
...options.agentName ? ["--agent-name", options.agentName] : [],
|
|
2359
2378
|
...options.noWait || options.wait === false ? ["--no-wait"] : []
|
|
2360
2379
|
]);
|
|
2361
2380
|
});
|
|
2362
|
-
auth.command("wait").description("Wait for a pending browser approval and save the API key.").
|
|
2381
|
+
auth.command("wait").description("Wait for a pending browser approval and save the API key.").addHelpText(
|
|
2382
|
+
"after",
|
|
2383
|
+
`
|
|
2384
|
+
Notes:
|
|
2385
|
+
Completes a previous deepline auth register --no-wait flow.
|
|
2386
|
+
Saves the approved API key into the host auth file.
|
|
2387
|
+
|
|
2388
|
+
Examples:
|
|
2389
|
+
deepline auth wait
|
|
2390
|
+
deepline auth wait --timeout 120
|
|
2391
|
+
`
|
|
2392
|
+
).option("--timeout <seconds>", "Maximum seconds to wait", "300").action(async (options) => {
|
|
2363
2393
|
process.exitCode = await handleWait([
|
|
2364
2394
|
...options.timeout ? ["--timeout", options.timeout] : []
|
|
2365
2395
|
]);
|
|
@@ -2385,6 +2415,10 @@ Examples:
|
|
|
2385
2415
|
}
|
|
2386
2416
|
|
|
2387
2417
|
// src/cli/commands/billing.ts
|
|
2418
|
+
var import_commander = require("commander");
|
|
2419
|
+
var import_promises2 = require("fs/promises");
|
|
2420
|
+
var import_node_path4 = require("path");
|
|
2421
|
+
var import_sync3 = require("csv-stringify/sync");
|
|
2388
2422
|
function humanize(value) {
|
|
2389
2423
|
return String(value || "").split("_").filter(Boolean).map((token) => token[0]?.toUpperCase() + token.slice(1)).join(" ") || "Unknown";
|
|
2390
2424
|
}
|
|
@@ -2402,6 +2436,54 @@ function printRecentUsage(entries) {
|
|
|
2402
2436
|
`);
|
|
2403
2437
|
}
|
|
2404
2438
|
}
|
|
2439
|
+
function summarizeLedgerRows(summary, rows) {
|
|
2440
|
+
const netDelta = rows.reduce((sum, row) => {
|
|
2441
|
+
const value = Number.parseFloat(String(row.delta_credits ?? "").trim());
|
|
2442
|
+
return Number.isFinite(value) ? sum + value : sum;
|
|
2443
|
+
}, summary.net_delta_credits);
|
|
2444
|
+
return {
|
|
2445
|
+
row_count: summary.row_count + rows.length,
|
|
2446
|
+
net_delta_credits: Math.round((netDelta + Number.EPSILON) * 100) / 100
|
|
2447
|
+
};
|
|
2448
|
+
}
|
|
2449
|
+
function ledgerApiEntryToRow(entry) {
|
|
2450
|
+
const metadata = typeof entry.metadata === "object" && entry.metadata !== null ? entry.metadata : {};
|
|
2451
|
+
return {
|
|
2452
|
+
created_at: entry.created_at ?? "",
|
|
2453
|
+
delta_credits: entry.delta ?? "",
|
|
2454
|
+
reason: entry.reason ?? "",
|
|
2455
|
+
provider: metadata.provider ?? "",
|
|
2456
|
+
operation: metadata.operation ?? "",
|
|
2457
|
+
request_id: metadata.requestId ?? metadata.request_id ?? "",
|
|
2458
|
+
run_id: metadata.runId ?? metadata.run_id ?? "",
|
|
2459
|
+
api_key_id: entry.api_key_id ?? "",
|
|
2460
|
+
stripe_session_id: entry.stripe_session_id ?? ""
|
|
2461
|
+
};
|
|
2462
|
+
}
|
|
2463
|
+
function ledgerRowsToCsv(rows, header) {
|
|
2464
|
+
return (0, import_sync3.stringify)(rows, {
|
|
2465
|
+
header,
|
|
2466
|
+
columns: [
|
|
2467
|
+
"created_at",
|
|
2468
|
+
"delta_credits",
|
|
2469
|
+
"reason",
|
|
2470
|
+
"provider",
|
|
2471
|
+
"operation",
|
|
2472
|
+
"request_id",
|
|
2473
|
+
"run_id",
|
|
2474
|
+
"api_key_id",
|
|
2475
|
+
"stripe_session_id"
|
|
2476
|
+
]
|
|
2477
|
+
});
|
|
2478
|
+
}
|
|
2479
|
+
function defaultLedgerExportPath() {
|
|
2480
|
+
return (0, import_node_path4.resolve)(
|
|
2481
|
+
process.cwd(),
|
|
2482
|
+
"deepline",
|
|
2483
|
+
"data",
|
|
2484
|
+
`billing-ledger-all-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.csv`
|
|
2485
|
+
);
|
|
2486
|
+
}
|
|
2405
2487
|
async function handleBalance(options) {
|
|
2406
2488
|
const { http } = getAuthedHttpClient();
|
|
2407
2489
|
const payload = await http.get("/api/v2/billing/balance");
|
|
@@ -2490,6 +2572,51 @@ async function handleHistory(options) {
|
|
|
2490
2572
|
process.stdout.write(`${rows.length} row(s) exported.
|
|
2491
2573
|
`);
|
|
2492
2574
|
}
|
|
2575
|
+
async function handleLedgerExportAll(options) {
|
|
2576
|
+
const { http } = getAuthedHttpClient();
|
|
2577
|
+
const outputPath = options.output ? (0, import_node_path4.resolve)(String(options.output)) : defaultLedgerExportPath();
|
|
2578
|
+
let summary = { row_count: 0, net_delta_credits: 0 };
|
|
2579
|
+
let cursor = null;
|
|
2580
|
+
let initializedOutput = false;
|
|
2581
|
+
for (; ; ) {
|
|
2582
|
+
const params = new URLSearchParams({ limit: "5000" });
|
|
2583
|
+
if (cursor !== null) params.set("cursor", cursor);
|
|
2584
|
+
const payload = await http.get(
|
|
2585
|
+
`/api/v2/billing/ledger?${params.toString()}`
|
|
2586
|
+
);
|
|
2587
|
+
const entries = Array.isArray(payload.entries) ? payload.entries : [];
|
|
2588
|
+
const rows = entries.map(ledgerApiEntryToRow);
|
|
2589
|
+
if (!initializedOutput) {
|
|
2590
|
+
await (0, import_promises2.mkdir)((0, import_node_path4.dirname)(outputPath), { recursive: true });
|
|
2591
|
+
await (0, import_promises2.writeFile)(outputPath, ledgerRowsToCsv([], true), "utf-8");
|
|
2592
|
+
initializedOutput = true;
|
|
2593
|
+
}
|
|
2594
|
+
if (rows.length > 0) {
|
|
2595
|
+
await (0, import_promises2.appendFile)(outputPath, ledgerRowsToCsv(rows, false), "utf-8");
|
|
2596
|
+
summary = summarizeLedgerRows(summary, rows);
|
|
2597
|
+
}
|
|
2598
|
+
const nextCursor = typeof payload.next_cursor === "string" && payload.next_cursor.length > 0 ? payload.next_cursor : null;
|
|
2599
|
+
if (rows.length === 0 || payload.has_more !== true || nextCursor === null) {
|
|
2600
|
+
break;
|
|
2601
|
+
}
|
|
2602
|
+
if (nextCursor === cursor) break;
|
|
2603
|
+
cursor = nextCursor;
|
|
2604
|
+
}
|
|
2605
|
+
if (shouldEmitJson(options.json)) {
|
|
2606
|
+
return printJson({
|
|
2607
|
+
output_path: outputPath,
|
|
2608
|
+
row_count: summary.row_count,
|
|
2609
|
+
net_delta_credits: summary.net_delta_credits,
|
|
2610
|
+
scope: "current_auth_context"
|
|
2611
|
+
});
|
|
2612
|
+
}
|
|
2613
|
+
process.stdout.write(`Billing ledger written to ${outputPath}
|
|
2614
|
+
`);
|
|
2615
|
+
process.stdout.write(`${summary.row_count} row(s) exported for the current auth context.
|
|
2616
|
+
`);
|
|
2617
|
+
process.stdout.write(`Net ledger delta: ${summary.net_delta_credits} Deepline Credits
|
|
2618
|
+
`);
|
|
2619
|
+
}
|
|
2493
2620
|
async function handleCheckout(options) {
|
|
2494
2621
|
const { http } = getAuthedHttpClient();
|
|
2495
2622
|
const payload = await http.post("/api/v2/billing/checkout", {
|
|
@@ -2513,20 +2640,156 @@ async function handleRedeemCode(code, options) {
|
|
|
2513
2640
|
`);
|
|
2514
2641
|
}
|
|
2515
2642
|
function registerBillingCommands(program) {
|
|
2516
|
-
const billing = program.command("billing").description("Inspect balance, usage, limits, and checkout flows.")
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2643
|
+
const billing = program.command("billing").description("Inspect balance, usage, limits, and checkout flows.").addHelpText(
|
|
2644
|
+
"after",
|
|
2645
|
+
`
|
|
2646
|
+
Concepts:
|
|
2647
|
+
Billing commands show Deepline credits, not raw provider spend.
|
|
2648
|
+
set-limit/off mutate the monthly workspace cap. checkout/redeem-code can open
|
|
2649
|
+
a browser unless --no-open is set.
|
|
2650
|
+
|
|
2651
|
+
Examples:
|
|
2652
|
+
deepline billing balance --json
|
|
2653
|
+
deepline billing usage --limit 20 --json
|
|
2654
|
+
deepline billing set-limit 500 --json
|
|
2655
|
+
deepline billing checkout --credits 1000 --no-open --json
|
|
2656
|
+
`
|
|
2657
|
+
);
|
|
2658
|
+
billing.command("balance").description("Show current billing balance.").addHelpText(
|
|
2659
|
+
"after",
|
|
2660
|
+
`
|
|
2661
|
+
Notes:
|
|
2662
|
+
Read-only. Shows the current Deepline credit balance for the active workspace.
|
|
2663
|
+
|
|
2664
|
+
Examples:
|
|
2665
|
+
deepline billing balance
|
|
2666
|
+
deepline billing balance --json
|
|
2667
|
+
`
|
|
2668
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleBalance);
|
|
2669
|
+
billing.command("usage").description("Show current usage plus recent calls.").addHelpText(
|
|
2670
|
+
"after",
|
|
2671
|
+
`
|
|
2672
|
+
Notes:
|
|
2673
|
+
Read-only. Shows last-30-day Deepline credit usage plus a bounded recent-call
|
|
2674
|
+
page. Use --limit/--offset to paginate the recent-call section.
|
|
2675
|
+
|
|
2676
|
+
Examples:
|
|
2677
|
+
deepline billing usage
|
|
2678
|
+
deepline billing usage --limit 50 --offset 50 --json
|
|
2679
|
+
`
|
|
2680
|
+
).option("--limit <n>", "Recent-call page size").option("--offset <n>", "Recent-call offset").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleUsage);
|
|
2681
|
+
billing.command("limit").description("Show configured monthly limit state.").addHelpText(
|
|
2682
|
+
"after",
|
|
2683
|
+
`
|
|
2684
|
+
Notes:
|
|
2685
|
+
Read-only. Shows whether the monthly workspace cap is enabled and how many
|
|
2686
|
+
Deepline credits remain before the cap.
|
|
2687
|
+
|
|
2688
|
+
Examples:
|
|
2689
|
+
deepline billing limit
|
|
2690
|
+
deepline billing limit --json
|
|
2691
|
+
`
|
|
2692
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLimit);
|
|
2693
|
+
billing.command("set-limit").description("Set monthly credit cap.").addHelpText(
|
|
2694
|
+
"after",
|
|
2695
|
+
`
|
|
2696
|
+
Notes:
|
|
2697
|
+
Mutates workspace billing settings. The argument is a Deepline credit amount,
|
|
2698
|
+
not dollars and not provider credits.
|
|
2699
|
+
|
|
2700
|
+
Examples:
|
|
2701
|
+
deepline billing set-limit 500
|
|
2702
|
+
deepline billing set-limit 500 --json
|
|
2703
|
+
`
|
|
2704
|
+
).argument("<credits>", "Monthly credits limit").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleSetLimit);
|
|
2705
|
+
billing.command("off").description("Disable monthly credit cap.").addHelpText(
|
|
2706
|
+
"after",
|
|
2707
|
+
`
|
|
2708
|
+
Notes:
|
|
2709
|
+
Mutates workspace billing settings by removing the monthly Deepline credit cap.
|
|
2710
|
+
|
|
2711
|
+
Examples:
|
|
2712
|
+
deepline billing off
|
|
2713
|
+
deepline billing off --json
|
|
2714
|
+
`
|
|
2715
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLimitOff);
|
|
2716
|
+
billing.command("ledger").description("Inspect and export billing ledger rows.").addHelpText(
|
|
2717
|
+
"after",
|
|
2718
|
+
`
|
|
2719
|
+
Notes:
|
|
2720
|
+
Read-only. Exports ledger rows for the current auth context. API-key auth is
|
|
2721
|
+
scoped by the server to that API key; session auth is scoped to the active
|
|
2722
|
+
workspace.
|
|
2723
|
+
|
|
2724
|
+
Examples:
|
|
2725
|
+
deepline billing ledger export all
|
|
2726
|
+
deepline billing ledger export all --output ./ledger.csv
|
|
2727
|
+
deepline billing ledger export all --json
|
|
2728
|
+
`
|
|
2729
|
+
).addCommand(
|
|
2730
|
+
new import_commander.Command("export").description("Export billing ledger rows.").addHelpText(
|
|
2731
|
+
"after",
|
|
2732
|
+
`
|
|
2733
|
+
Examples:
|
|
2734
|
+
deepline billing ledger export all
|
|
2735
|
+
`
|
|
2736
|
+
).addCommand(
|
|
2737
|
+
new import_commander.Command("all").description("Export all available billing ledger rows to CSV.").addHelpText(
|
|
2738
|
+
"after",
|
|
2739
|
+
`
|
|
2740
|
+
Notes:
|
|
2741
|
+
Pages through the ledger for the current auth context, writes CSV locally,
|
|
2742
|
+
then reports the row count and the net delta computed from delta_credits.
|
|
2743
|
+
|
|
2744
|
+
Examples:
|
|
2745
|
+
deepline billing ledger export all
|
|
2746
|
+
deepline billing ledger export all --json
|
|
2747
|
+
`
|
|
2748
|
+
).option("--output <path>", "Write CSV to an explicit path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLedgerExportAll)
|
|
2749
|
+
)
|
|
2750
|
+
);
|
|
2751
|
+
billing.command("history").description("Export billing ledger history to CSV.").addHelpText(
|
|
2752
|
+
"after",
|
|
2753
|
+
`
|
|
2754
|
+
Notes:
|
|
2755
|
+
Read-only server query that writes a local CSV file. With --json, stdout is a
|
|
2756
|
+
summary containing the output path and row count.
|
|
2757
|
+
|
|
2758
|
+
Examples:
|
|
2759
|
+
deepline billing history --time 1m
|
|
2760
|
+
deepline billing history --time 1y --json
|
|
2761
|
+
`
|
|
2762
|
+
).requiredOption("--time <window>", "Rolling time window: 1d, 1w, 1m, or 1y").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleHistory);
|
|
2763
|
+
billing.command("checkout").description("Create a checkout session and optionally open it in your browser.").addHelpText(
|
|
2764
|
+
"after",
|
|
2765
|
+
`
|
|
2766
|
+
Notes:
|
|
2767
|
+
Creates a payment checkout session. Opens the checkout URL in a browser unless
|
|
2768
|
+
--no-open is set. Use --json for automation.
|
|
2769
|
+
|
|
2770
|
+
Examples:
|
|
2771
|
+
deepline billing checkout --tier pro
|
|
2772
|
+
deepline billing checkout --credits 1000 --no-open --json
|
|
2773
|
+
deepline billing checkout --credits 1000 --discount-code LAUNCH --no-open
|
|
2774
|
+
`
|
|
2775
|
+
).option("--tier <tierId>", "Named pricing tier").option("--credits <credits>", "Custom credit amount").option("--discount-code <code>", "Apply a discount code").option("--no-open", "Print the checkout URL without opening a browser").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleCheckout);
|
|
2776
|
+
billing.command("redeem-code").description("Redeem a billing code.").addHelpText(
|
|
2777
|
+
"after",
|
|
2778
|
+
`
|
|
2779
|
+
Notes:
|
|
2780
|
+
Redeems a workspace billing code and may open a browser for completion unless
|
|
2781
|
+
--no-open is set.
|
|
2782
|
+
|
|
2783
|
+
Examples:
|
|
2784
|
+
deepline billing redeem-code --code ABC123
|
|
2785
|
+
deepline billing redeem-code --code ABC123 --no-open --json
|
|
2786
|
+
`
|
|
2787
|
+
).requiredOption("--code <code>", "Code to redeem").option("--no-open", "Do not open a browser").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(({ code, ...options }) => handleRedeemCode(code, options));
|
|
2525
2788
|
}
|
|
2526
2789
|
|
|
2527
2790
|
// src/cli/dataset-stats.ts
|
|
2528
2791
|
var import_node_fs4 = require("fs");
|
|
2529
|
-
var
|
|
2792
|
+
var import_node_path5 = require("path");
|
|
2530
2793
|
var CSV_PROJECTED_FIELDS_KEY = "__deeplineCsvProjectedFields";
|
|
2531
2794
|
function csvProjectedFields(row) {
|
|
2532
2795
|
const serialized = row[CSV_PROJECTED_FIELDS_KEY];
|
|
@@ -2856,7 +3119,7 @@ function writeCanonicalRowsCsv(rowsInfo, outPath) {
|
|
|
2856
3119
|
rows: rowsInfo.rows,
|
|
2857
3120
|
columns: rowsInfo.columns
|
|
2858
3121
|
});
|
|
2859
|
-
const resolved = (0,
|
|
3122
|
+
const resolved = (0, import_node_path5.resolve)(outPath);
|
|
2860
3123
|
(0, import_node_fs4.writeFileSync)(
|
|
2861
3124
|
resolved,
|
|
2862
3125
|
csvStringFromRows(sanitized.rows, sanitized.columns),
|
|
@@ -2952,8 +3215,31 @@ async function handleCsvShow(options) {
|
|
|
2952
3215
|
`);
|
|
2953
3216
|
}
|
|
2954
3217
|
function registerCsvCommands(program) {
|
|
2955
|
-
const csv = program.command("csv").description("Inspect local CSV files.")
|
|
2956
|
-
|
|
3218
|
+
const csv = program.command("csv").description("Inspect local CSV files.").addHelpText(
|
|
3219
|
+
"after",
|
|
3220
|
+
`
|
|
3221
|
+
Notes:
|
|
3222
|
+
Local-only inspection helpers. These commands do not upload CSV files or call
|
|
3223
|
+
Deepline APIs.
|
|
3224
|
+
|
|
3225
|
+
Examples:
|
|
3226
|
+
deepline csv show --csv leads.csv --rows 0:10 --format table
|
|
3227
|
+
deepline csv show --csv leads.csv --summary
|
|
3228
|
+
`
|
|
3229
|
+
);
|
|
3230
|
+
csv.command("show").description("Display rows from a CSV file in json, csv, or table form.").addHelpText(
|
|
3231
|
+
"after",
|
|
3232
|
+
`
|
|
3233
|
+
Notes:
|
|
3234
|
+
Reads a local CSV path and prints a bounded row range. --rows uses inclusive
|
|
3235
|
+
start:end indexes, so 0:19 prints the first 20 rows. JSON is the default format.
|
|
3236
|
+
|
|
3237
|
+
Examples:
|
|
3238
|
+
deepline csv show --csv leads.csv
|
|
3239
|
+
deepline csv show --csv leads.csv --rows 20:39 --columns name,email --format table
|
|
3240
|
+
deepline csv show --csv leads.csv --summary
|
|
3241
|
+
`
|
|
3242
|
+
).requiredOption("--csv <path>", "Input CSV path").option("--format <format>", "Output format: json, csv, or table", "json").option("--rows <range>", "Row range start:end", "0:19").option("--columns <names>", "Comma-separated column names to include").option("--summary", "Print a summary payload instead of row output").option("--verbose", "Do not truncate long values in table output").action(handleCsvShow);
|
|
2957
3243
|
}
|
|
2958
3244
|
|
|
2959
3245
|
// src/cli/commands/db.ts
|
|
@@ -3033,8 +3319,32 @@ async function handleDbQuery(args) {
|
|
|
3033
3319
|
return 0;
|
|
3034
3320
|
}
|
|
3035
3321
|
function registerDbCommands(program) {
|
|
3036
|
-
const db = program.command("db").alias("customer-db").description("Query the tenant customer database.")
|
|
3037
|
-
|
|
3322
|
+
const db = program.command("db").alias("customer-db").description("Query the tenant customer database.").addHelpText(
|
|
3323
|
+
"after",
|
|
3324
|
+
`
|
|
3325
|
+
Notes:
|
|
3326
|
+
Runs SQL against the active workspace customer database through Deepline APIs.
|
|
3327
|
+
Results are bounded by the server and --max-rows. Use --json for stable output.
|
|
3328
|
+
|
|
3329
|
+
Examples:
|
|
3330
|
+
deepline db query --sql "select * from companies limit 20"
|
|
3331
|
+
deepline db query --sql "select domain, name from companies limit 20" --json
|
|
3332
|
+
deepline db query --sql "select * from contacts" --max-rows 100 --json
|
|
3333
|
+
`
|
|
3334
|
+
);
|
|
3335
|
+
db.command("query").alias("psql").description("Run SQL against the tenant customer database.").addHelpText(
|
|
3336
|
+
"after",
|
|
3337
|
+
`
|
|
3338
|
+
Notes:
|
|
3339
|
+
Requires --sql. Output is a compact table in a terminal and raw JSON with
|
|
3340
|
+
--json or when stdout is piped. The active auth workspace determines scope.
|
|
3341
|
+
|
|
3342
|
+
Examples:
|
|
3343
|
+
deepline db query --sql "select * from companies limit 20"
|
|
3344
|
+
deepline db query --sql "select domain, name from companies limit 20" --json
|
|
3345
|
+
deepline db psql --sql "select count(*) from contacts" --json
|
|
3346
|
+
`
|
|
3347
|
+
).requiredOption("--sql <sql>", "SQL statement").option("--max-rows <n>", "Maximum returned rows").option("--json", "Emit raw JSON response. Also automatic when stdout is piped").action(async (options) => {
|
|
3038
3348
|
process.exitCode = await handleDbQuery([
|
|
3039
3349
|
"--sql",
|
|
3040
3350
|
options.sql,
|
|
@@ -3060,9 +3370,29 @@ async function handleFeedback(text, options) {
|
|
|
3060
3370
|
process.stdout.write("Feedback submitted. Thank you.\n");
|
|
3061
3371
|
}
|
|
3062
3372
|
function registerFeedbackCommands(program) {
|
|
3063
|
-
const feedback = program.command("feedback").description("Submit CLI feedback to Deepline.")
|
|
3373
|
+
const feedback = program.command("feedback").description("Submit CLI feedback to Deepline.").addHelpText(
|
|
3374
|
+
"after",
|
|
3375
|
+
`
|
|
3376
|
+
Notes:
|
|
3377
|
+
Sends the feedback text plus local CLI environment info to Deepline support.
|
|
3378
|
+
Use --command and --payload to attach a reproducible command shape.
|
|
3379
|
+
|
|
3380
|
+
Examples:
|
|
3381
|
+
deepline feedback "plays run failed after upload" --command "deepline plays run my.play.ts --watch"
|
|
3382
|
+
deepline feedback "unexpected billing output" --payload '{"command":"billing usage"}' --json
|
|
3383
|
+
`
|
|
3384
|
+
);
|
|
3064
3385
|
feedback.argument("<text>", "Feedback text").option("--command <command>", "Command that reproduced the issue").option("--payload <payload>", "JSON or plain-text payload for the repro").option("--json", "Emit JSON output").action(handleFeedback);
|
|
3065
|
-
program.command("provide-feedback").description("Legacy alias for `deepline feedback`.").
|
|
3386
|
+
program.command("provide-feedback").description("Legacy alias for `deepline feedback`.").addHelpText(
|
|
3387
|
+
"after",
|
|
3388
|
+
`
|
|
3389
|
+
Notes:
|
|
3390
|
+
Compatibility alias. Prefer deepline feedback in new scripts and docs.
|
|
3391
|
+
|
|
3392
|
+
Examples:
|
|
3393
|
+
deepline feedback "tools search returned stale results" --json
|
|
3394
|
+
`
|
|
3395
|
+
).argument("<text>", "Feedback text").option("--command <command>", "Command that reproduced the issue").option("--payload <payload>", "JSON or plain-text payload for the repro").option("--json", "Emit JSON output").action(handleFeedback);
|
|
3066
3396
|
}
|
|
3067
3397
|
|
|
3068
3398
|
// src/cli/commands/org.ts
|
|
@@ -3142,27 +3472,61 @@ async function handleOrgSwitch(selection, options) {
|
|
|
3142
3472
|
`);
|
|
3143
3473
|
}
|
|
3144
3474
|
function registerOrgCommands(program) {
|
|
3145
|
-
const org = program.command("org").description("List and switch organizations.")
|
|
3146
|
-
|
|
3147
|
-
|
|
3475
|
+
const org = program.command("org").description("List and switch organizations.").addHelpText(
|
|
3476
|
+
"after",
|
|
3477
|
+
`
|
|
3478
|
+
Notes:
|
|
3479
|
+
Organizations are workspaces. Switching organizations mutates the saved host
|
|
3480
|
+
auth file so later CLI commands target the selected workspace.
|
|
3481
|
+
|
|
3482
|
+
Examples:
|
|
3483
|
+
deepline org list --json
|
|
3484
|
+
deepline org switch 2
|
|
3485
|
+
deepline org switch --org-id org_123 --json
|
|
3486
|
+
`
|
|
3487
|
+
);
|
|
3488
|
+
org.command("list").description("List your organizations.").addHelpText(
|
|
3489
|
+
"after",
|
|
3490
|
+
`
|
|
3491
|
+
Notes:
|
|
3492
|
+
Read-only. Marks the active organization when the server returns that metadata.
|
|
3493
|
+
|
|
3494
|
+
Examples:
|
|
3495
|
+
deepline org list
|
|
3496
|
+
deepline org list --json
|
|
3497
|
+
`
|
|
3498
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgList);
|
|
3499
|
+
org.command("switch [selection]").description("Switch to another organization and save the new API key in the host auth file.").addHelpText(
|
|
3500
|
+
"after",
|
|
3501
|
+
`
|
|
3502
|
+
Notes:
|
|
3503
|
+
Mutates the saved host auth file. Selection can be a list number, exact
|
|
3504
|
+
organization name, or organization id. Without a selection, prints choices.
|
|
3505
|
+
|
|
3506
|
+
Examples:
|
|
3507
|
+
deepline org switch
|
|
3508
|
+
deepline org switch 2
|
|
3509
|
+
deepline org switch --org-id org_123 --json
|
|
3510
|
+
`
|
|
3511
|
+
).option("--org-id <id>", "Switch using an explicit organization id").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgSwitch);
|
|
3148
3512
|
}
|
|
3149
3513
|
|
|
3150
3514
|
// src/cli/commands/play.ts
|
|
3151
3515
|
var import_node_crypto3 = require("crypto");
|
|
3152
3516
|
var import_node_fs6 = require("fs");
|
|
3153
|
-
var
|
|
3517
|
+
var import_node_path9 = require("path");
|
|
3154
3518
|
|
|
3155
3519
|
// src/plays/bundle-play-file.ts
|
|
3156
3520
|
var import_node_os5 = require("os");
|
|
3157
|
-
var
|
|
3521
|
+
var import_node_path8 = require("path");
|
|
3158
3522
|
var import_node_url = require("url");
|
|
3159
3523
|
var import_node_fs5 = require("fs");
|
|
3160
3524
|
|
|
3161
3525
|
// ../shared_libs/plays/bundling/index.ts
|
|
3162
3526
|
var import_node_crypto = require("crypto");
|
|
3163
|
-
var
|
|
3527
|
+
var import_promises3 = require("fs/promises");
|
|
3164
3528
|
var import_node_os4 = require("os");
|
|
3165
|
-
var
|
|
3529
|
+
var import_node_path6 = require("path");
|
|
3166
3530
|
var import_node_module = require("module");
|
|
3167
3531
|
var import_esbuild = require("esbuild");
|
|
3168
3532
|
|
|
@@ -3223,7 +3587,7 @@ var playArtifactRequire = (0, import_node_module.createRequire)(import_meta.url)
|
|
|
3223
3587
|
var PLAY_BUNDLE_CACHE_VERSION = 24;
|
|
3224
3588
|
var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
|
|
3225
3589
|
var MAX_ESM_WORKERS_BUNDLE_BYTES = 115e4;
|
|
3226
|
-
var PLAY_ARTIFACT_CACHE_DIR = (0,
|
|
3590
|
+
var PLAY_ARTIFACT_CACHE_DIR = (0, import_node_path6.join)(
|
|
3227
3591
|
(0, import_node_os4.tmpdir)(),
|
|
3228
3592
|
`deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`
|
|
3229
3593
|
);
|
|
@@ -3254,15 +3618,15 @@ function isLocalSpecifier(specifier) {
|
|
|
3254
3618
|
}
|
|
3255
3619
|
async function normalizeLocalPath(filePath) {
|
|
3256
3620
|
try {
|
|
3257
|
-
return await (0,
|
|
3621
|
+
return await (0, import_promises3.realpath)(filePath);
|
|
3258
3622
|
} catch {
|
|
3259
|
-
return (0,
|
|
3623
|
+
return (0, import_node_path6.resolve)(filePath);
|
|
3260
3624
|
}
|
|
3261
3625
|
}
|
|
3262
3626
|
function createPlayWorkspace(entryFile) {
|
|
3263
3627
|
return {
|
|
3264
3628
|
entryFile,
|
|
3265
|
-
rootDir: (0,
|
|
3629
|
+
rootDir: (0, import_node_path6.dirname)(entryFile)
|
|
3266
3630
|
};
|
|
3267
3631
|
}
|
|
3268
3632
|
function isPathInsideDirectory(filePath, directory) {
|
|
@@ -3416,7 +3780,7 @@ function extractDefinedPlayName(sourceCode, _filePath) {
|
|
|
3416
3780
|
function getPackageRequireCandidates(fromFile) {
|
|
3417
3781
|
const candidates = [
|
|
3418
3782
|
(0, import_node_module.createRequire)(fromFile),
|
|
3419
|
-
(0, import_node_module.createRequire)((0,
|
|
3783
|
+
(0, import_node_module.createRequire)((0, import_node_path6.join)(process.cwd(), "package.json")),
|
|
3420
3784
|
playArtifactRequire
|
|
3421
3785
|
];
|
|
3422
3786
|
return candidates;
|
|
@@ -3463,7 +3827,7 @@ function workersNamedPlayEntryAliasPlugin(playFilePath, exportName) {
|
|
|
3463
3827
|
contents: `export { ${exportName} as default } from ${JSON.stringify(playFilePath)};
|
|
3464
3828
|
`,
|
|
3465
3829
|
loader: "ts",
|
|
3466
|
-
resolveDir: (0,
|
|
3830
|
+
resolveDir: (0, import_node_path6.dirname)(playFilePath)
|
|
3467
3831
|
})
|
|
3468
3832
|
);
|
|
3469
3833
|
}
|
|
@@ -3627,7 +3991,7 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
|
|
|
3627
3991
|
return {
|
|
3628
3992
|
contents: buildImportedPlayProxyModule(dependency.playName),
|
|
3629
3993
|
loader: "ts",
|
|
3630
|
-
resolveDir: (0,
|
|
3994
|
+
resolveDir: (0, import_node_path6.dirname)(args.path)
|
|
3631
3995
|
};
|
|
3632
3996
|
});
|
|
3633
3997
|
}
|
|
@@ -3635,7 +3999,7 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
|
|
|
3635
3999
|
}
|
|
3636
4000
|
async function fileExists(filePath) {
|
|
3637
4001
|
try {
|
|
3638
|
-
await (0,
|
|
4002
|
+
await (0, import_promises3.stat)(filePath);
|
|
3639
4003
|
return true;
|
|
3640
4004
|
} catch {
|
|
3641
4005
|
return false;
|
|
@@ -3645,12 +4009,12 @@ async function resolveLocalImport(fromFile, specifier) {
|
|
|
3645
4009
|
if (specifier.startsWith("file:")) {
|
|
3646
4010
|
return normalizeLocalPath(new URL(specifier).pathname);
|
|
3647
4011
|
}
|
|
3648
|
-
const base = (0,
|
|
4012
|
+
const base = (0, import_node_path6.isAbsolute)(specifier) ? (0, import_node_path6.resolve)(specifier) : (0, import_node_path6.resolve)((0, import_node_path6.dirname)(fromFile), specifier);
|
|
3649
4013
|
const candidates = [base];
|
|
3650
|
-
const explicitExtension = (0,
|
|
4014
|
+
const explicitExtension = (0, import_node_path6.extname)(base).toLowerCase();
|
|
3651
4015
|
if (!explicitExtension) {
|
|
3652
4016
|
candidates.push(...SOURCE_EXTENSIONS.map((extension) => `${base}${extension}`));
|
|
3653
|
-
candidates.push(...SOURCE_EXTENSIONS.map((extension) => (0,
|
|
4017
|
+
candidates.push(...SOURCE_EXTENSIONS.map((extension) => (0, import_node_path6.join)(base, `index${extension}`)));
|
|
3654
4018
|
} else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
|
|
3655
4019
|
const stem = base.slice(0, -explicitExtension.length);
|
|
3656
4020
|
candidates.push(...SOURCE_EXTENSIONS.map((extension) => `${stem}${extension}`));
|
|
@@ -3716,9 +4080,9 @@ async function analyzeSourceGraph(entryFile, adapter) {
|
|
|
3716
4080
|
return;
|
|
3717
4081
|
}
|
|
3718
4082
|
visited.add(absolutePath);
|
|
3719
|
-
const sourceCode2 = await (0,
|
|
4083
|
+
const sourceCode2 = await (0, import_promises3.readFile)(absolutePath, "utf-8");
|
|
3720
4084
|
localFiles.set(absolutePath, sourceCode2);
|
|
3721
|
-
if ((0,
|
|
4085
|
+
if ((0, import_node_path6.extname)(absolutePath).toLowerCase() === ".json") {
|
|
3722
4086
|
return;
|
|
3723
4087
|
}
|
|
3724
4088
|
const handleSpecifier = async (specifier, line, column, kind) => {
|
|
@@ -3742,7 +4106,7 @@ async function analyzeSourceGraph(entryFile, adapter) {
|
|
|
3742
4106
|
column
|
|
3743
4107
|
});
|
|
3744
4108
|
if (resolved !== absoluteEntryFile && isPlaySourceFile(resolved)) {
|
|
3745
|
-
const importedSource = await (0,
|
|
4109
|
+
const importedSource = await (0, import_promises3.readFile)(resolved, "utf-8");
|
|
3746
4110
|
const importedPlayName = extractDefinedPlayName(importedSource, resolved);
|
|
3747
4111
|
if (!importedPlayName) {
|
|
3748
4112
|
throw new Error(
|
|
@@ -3822,20 +4186,20 @@ async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
|
|
|
3822
4186
|
const tsFiles = entries.filter((e) => e.isFile() && /\.[cm]?ts$/.test(e.name)).map((e) => e.name).sort();
|
|
3823
4187
|
const parts = [];
|
|
3824
4188
|
for (const name of tsFiles) {
|
|
3825
|
-
const contents = await (0,
|
|
4189
|
+
const contents = await (0, import_promises3.readFile)((0, import_node_path6.join)(adapter.workersHarnessFilesDir, name), "utf-8");
|
|
3826
4190
|
parts.push({ name, hash: sha256(contents) });
|
|
3827
4191
|
}
|
|
3828
4192
|
return sha256(JSON.stringify(parts));
|
|
3829
4193
|
}
|
|
3830
4194
|
function artifactCachePath(graphHash, artifactKind, adapter) {
|
|
3831
|
-
return (0,
|
|
4195
|
+
return (0, import_node_path6.join)(
|
|
3832
4196
|
adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR,
|
|
3833
4197
|
`${graphHash}.${artifactKind}.json`
|
|
3834
4198
|
);
|
|
3835
4199
|
}
|
|
3836
4200
|
async function readArtifactCache(graphHash, artifactKind, adapter) {
|
|
3837
4201
|
try {
|
|
3838
|
-
const serialized = await (0,
|
|
4202
|
+
const serialized = await (0, import_promises3.readFile)(
|
|
3839
4203
|
artifactCachePath(graphHash, artifactKind, adapter),
|
|
3840
4204
|
"utf-8"
|
|
3841
4205
|
);
|
|
@@ -3846,8 +4210,8 @@ async function readArtifactCache(graphHash, artifactKind, adapter) {
|
|
|
3846
4210
|
}
|
|
3847
4211
|
async function writeArtifactCache(artifact, adapter) {
|
|
3848
4212
|
const cacheDir = adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR;
|
|
3849
|
-
await (0,
|
|
3850
|
-
await (0,
|
|
4213
|
+
await (0, import_promises3.mkdir)(cacheDir, { recursive: true });
|
|
4214
|
+
await (0, import_promises3.writeFile)(
|
|
3851
4215
|
artifactCachePath(
|
|
3852
4216
|
artifact.graphHash,
|
|
3853
4217
|
artifact.artifactKind ?? PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
@@ -3863,7 +4227,7 @@ function normalizeSourceMapForRuntime(sourceMapText) {
|
|
|
3863
4227
|
if (sourcePath.startsWith("data:") || sourcePath.startsWith("node:") || sourcePath.startsWith("/") || /^[a-zA-Z]+:\/\//.test(sourcePath)) {
|
|
3864
4228
|
return sourcePath;
|
|
3865
4229
|
}
|
|
3866
|
-
return (0,
|
|
4230
|
+
return (0, import_node_path6.resolve)(process.cwd(), sourcePath);
|
|
3867
4231
|
});
|
|
3868
4232
|
parsed.sourceRoot = void 0;
|
|
3869
4233
|
return JSON.stringify(parsed);
|
|
@@ -3895,8 +4259,8 @@ async function runEsbuildForCjsNode(entryFile, importedPlayDependencies, adapter
|
|
|
3895
4259
|
...namedExportShim ? {
|
|
3896
4260
|
stdin: {
|
|
3897
4261
|
contents: namedExportShim,
|
|
3898
|
-
resolveDir: (0,
|
|
3899
|
-
sourcefile: `${(0,
|
|
4262
|
+
resolveDir: (0, import_node_path6.dirname)(entryFile),
|
|
4263
|
+
sourcefile: `${(0, import_node_path6.basename)(entryFile)}.${exportName}.entry.ts`,
|
|
3900
4264
|
loader: "ts"
|
|
3901
4265
|
}
|
|
3902
4266
|
} : { entryPoints: [entryFile] },
|
|
@@ -4072,10 +4436,10 @@ workers-harness:${harnessFingerprint}`
|
|
|
4072
4436
|
}
|
|
4073
4437
|
const { bundledCode, sourceMapText, outputExtension } = buildOutcome;
|
|
4074
4438
|
const normalizedSourceMap = normalizeSourceMapForRuntime(sourceMapText);
|
|
4075
|
-
const virtualBaseName = exportName === "default" ? (0,
|
|
4439
|
+
const virtualBaseName = exportName === "default" ? (0, import_node_path6.basename)(absolutePath).replace(/\.[^.]+$/, "") : `${(0, import_node_path6.basename)(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
|
|
4076
4440
|
const virtualFilename = `/virtual/deepline-plays/${analysis.graphHash}/${virtualBaseName}.${outputExtension}`;
|
|
4077
4441
|
const executableCode = `${bundledCode}
|
|
4078
|
-
//# sourceMappingURL=${(0,
|
|
4442
|
+
//# sourceMappingURL=${(0, import_node_path6.basename)(virtualFilename)}.map
|
|
4079
4443
|
`;
|
|
4080
4444
|
const bundleSizeError = getBundleSizeError(
|
|
4081
4445
|
absolutePath,
|
|
@@ -4184,14 +4548,14 @@ function resolveExecutionProfile(override) {
|
|
|
4184
4548
|
|
|
4185
4549
|
// src/plays/local-file-discovery.ts
|
|
4186
4550
|
var import_node_crypto2 = require("crypto");
|
|
4187
|
-
var
|
|
4188
|
-
var
|
|
4551
|
+
var import_promises4 = require("fs/promises");
|
|
4552
|
+
var import_node_path7 = require("path");
|
|
4189
4553
|
var SOURCE_EXTENSIONS2 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
|
|
4190
4554
|
function sha2562(buffer) {
|
|
4191
4555
|
return (0, import_node_crypto2.createHash)("sha256").update(buffer).digest("hex");
|
|
4192
4556
|
}
|
|
4193
4557
|
function contentTypeForFile(filePath) {
|
|
4194
|
-
const extension = (0,
|
|
4558
|
+
const extension = (0, import_node_path7.extname)(filePath).toLowerCase();
|
|
4195
4559
|
if (extension === ".csv") return "text/csv";
|
|
4196
4560
|
if (extension === ".json") return "application/json";
|
|
4197
4561
|
if (extension === ".txt") return "text/plain";
|
|
@@ -4375,23 +4739,23 @@ function localImportSpecifiers(sourceCode) {
|
|
|
4375
4739
|
}
|
|
4376
4740
|
async function fileExists2(filePath) {
|
|
4377
4741
|
try {
|
|
4378
|
-
await (0,
|
|
4742
|
+
await (0, import_promises4.stat)(filePath);
|
|
4379
4743
|
return true;
|
|
4380
4744
|
} catch {
|
|
4381
4745
|
return false;
|
|
4382
4746
|
}
|
|
4383
4747
|
}
|
|
4384
4748
|
function isPathInsideDirectory2(filePath, directory) {
|
|
4385
|
-
const relativePath = (0,
|
|
4386
|
-
return relativePath === "" || !relativePath.startsWith("..") && !(0,
|
|
4749
|
+
const relativePath = (0, import_node_path7.relative)(directory, filePath);
|
|
4750
|
+
return relativePath === "" || !relativePath.startsWith("..") && !(0, import_node_path7.isAbsolute)(relativePath);
|
|
4387
4751
|
}
|
|
4388
4752
|
async function resolveLocalImport2(fromFile, specifier) {
|
|
4389
|
-
const base = (0,
|
|
4753
|
+
const base = (0, import_node_path7.isAbsolute)(specifier) ? (0, import_node_path7.resolve)(specifier) : (0, import_node_path7.resolve)((0, import_node_path7.dirname)(fromFile), specifier);
|
|
4390
4754
|
const candidates = [base];
|
|
4391
|
-
const explicitExtension = (0,
|
|
4755
|
+
const explicitExtension = (0, import_node_path7.extname)(base).toLowerCase();
|
|
4392
4756
|
if (!explicitExtension) {
|
|
4393
4757
|
candidates.push(...SOURCE_EXTENSIONS2.map((extension) => `${base}${extension}`));
|
|
4394
|
-
candidates.push(...SOURCE_EXTENSIONS2.map((extension) => (0,
|
|
4758
|
+
candidates.push(...SOURCE_EXTENSIONS2.map((extension) => (0, import_node_path7.join)(base, `index${extension}`)));
|
|
4395
4759
|
} else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
|
|
4396
4760
|
const stem = base.slice(0, -explicitExtension.length);
|
|
4397
4761
|
candidates.push(...SOURCE_EXTENSIONS2.map((extension) => `${stem}${extension}`));
|
|
@@ -4404,18 +4768,18 @@ async function resolveLocalImport2(fromFile, specifier) {
|
|
|
4404
4768
|
throw new Error(`Could not resolve local import "${specifier}" from ${fromFile}`);
|
|
4405
4769
|
}
|
|
4406
4770
|
async function discoverPackagedLocalFiles(entryFile) {
|
|
4407
|
-
const absoluteEntryFile = (0,
|
|
4408
|
-
const packagingRoot = (0,
|
|
4771
|
+
const absoluteEntryFile = (0, import_node_path7.resolve)(entryFile);
|
|
4772
|
+
const packagingRoot = (0, import_node_path7.dirname)(absoluteEntryFile);
|
|
4409
4773
|
const files = /* @__PURE__ */ new Map();
|
|
4410
4774
|
const unresolved = [];
|
|
4411
4775
|
const visitedFiles = /* @__PURE__ */ new Set();
|
|
4412
4776
|
const visitSourceFile = async (filePath) => {
|
|
4413
|
-
const absolutePath = (0,
|
|
4777
|
+
const absolutePath = (0, import_node_path7.resolve)(filePath);
|
|
4414
4778
|
if (visitedFiles.has(absolutePath)) {
|
|
4415
4779
|
return;
|
|
4416
4780
|
}
|
|
4417
4781
|
visitedFiles.add(absolutePath);
|
|
4418
|
-
const sourceCode = await (0,
|
|
4782
|
+
const sourceCode = await (0, import_promises4.readFile)(absolutePath, "utf-8");
|
|
4419
4783
|
const scanSource = stripCommentsToSpaces2(sourceCode);
|
|
4420
4784
|
const constants = collectTopLevelStringConstants(sourceCode);
|
|
4421
4785
|
const childVisits = [];
|
|
@@ -4442,16 +4806,16 @@ async function discoverPackagedLocalFiles(entryFile) {
|
|
|
4442
4806
|
message: "Could not resolve this ctx.csv(...) path at submit time. Use a string literal, a top-level const string, or pass a runtime input like input.file."
|
|
4443
4807
|
});
|
|
4444
4808
|
} else {
|
|
4445
|
-
const absoluteCsvPath = (0,
|
|
4446
|
-
if ((0,
|
|
4809
|
+
const absoluteCsvPath = (0, import_node_path7.resolve)((0, import_node_path7.dirname)(absolutePath), resolvedPath);
|
|
4810
|
+
if ((0, import_node_path7.isAbsolute)(resolvedPath) || !isPathInsideDirectory2(absoluteCsvPath, packagingRoot)) {
|
|
4447
4811
|
unresolved.push({
|
|
4448
4812
|
sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
|
|
4449
4813
|
message: "ctx.csv(...) packaged file paths must be relative paths inside the play directory. Pass external files at runtime with input.file instead."
|
|
4450
4814
|
});
|
|
4451
4815
|
continue;
|
|
4452
4816
|
}
|
|
4453
|
-
const buffer = await (0,
|
|
4454
|
-
const stats = await (0,
|
|
4817
|
+
const buffer = await (0, import_promises4.readFile)(absoluteCsvPath);
|
|
4818
|
+
const stats = await (0, import_promises4.stat)(absoluteCsvPath);
|
|
4455
4819
|
files.set(absoluteCsvPath, {
|
|
4456
4820
|
sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
|
|
4457
4821
|
logicalPath: resolvedPath,
|
|
@@ -4482,24 +4846,24 @@ async function discoverPackagedLocalFiles(entryFile) {
|
|
|
4482
4846
|
// src/plays/bundle-play-file.ts
|
|
4483
4847
|
var import_meta2 = {};
|
|
4484
4848
|
var PLAY_BUNDLE_CACHE_VERSION2 = 26;
|
|
4485
|
-
var MODULE_DIR = (0,
|
|
4486
|
-
var SDK_PACKAGE_ROOT = (0,
|
|
4487
|
-
var SOURCE_REPO_ROOT = (0,
|
|
4849
|
+
var MODULE_DIR = (0, import_node_path8.dirname)((0, import_node_url.fileURLToPath)(import_meta2.url));
|
|
4850
|
+
var SDK_PACKAGE_ROOT = (0, import_node_path8.resolve)(MODULE_DIR, "..", "..");
|
|
4851
|
+
var SOURCE_REPO_ROOT = (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "..");
|
|
4488
4852
|
var HAS_SOURCE_BUNDLING_SOURCES = (0, import_node_fs5.existsSync)(
|
|
4489
|
-
(0,
|
|
4853
|
+
(0, import_node_path8.resolve)(SOURCE_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
|
|
4490
4854
|
);
|
|
4491
|
-
var PACKAGED_REPO_ROOT = (0,
|
|
4855
|
+
var PACKAGED_REPO_ROOT = (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "dist", "repo");
|
|
4492
4856
|
var HAS_PACKAGED_BUNDLING_SOURCES = (0, import_node_fs5.existsSync)(
|
|
4493
|
-
(0,
|
|
4857
|
+
(0, import_node_path8.resolve)(PACKAGED_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
|
|
4494
4858
|
);
|
|
4495
|
-
var PROJECT_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? SOURCE_REPO_ROOT : HAS_PACKAGED_BUNDLING_SOURCES ? PACKAGED_REPO_ROOT : (0,
|
|
4496
|
-
var SDK_SOURCE_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? (0,
|
|
4497
|
-
var SDK_PACKAGE_JSON = (0,
|
|
4498
|
-
var SDK_ENTRY_FILE = (0,
|
|
4499
|
-
var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : (0,
|
|
4500
|
-
var SDK_WORKERS_ENTRY_FILE = (0,
|
|
4501
|
-
var WORKERS_HARNESS_ENTRY_FILE = (0,
|
|
4502
|
-
var WORKERS_HARNESS_FILES_DIR = (0,
|
|
4859
|
+
var PROJECT_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? SOURCE_REPO_ROOT : HAS_PACKAGED_BUNDLING_SOURCES ? PACKAGED_REPO_ROOT : (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "..");
|
|
4860
|
+
var SDK_SOURCE_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? (0, import_node_path8.resolve)(SOURCE_REPO_ROOT, "sdk", "src") : HAS_PACKAGED_BUNDLING_SOURCES ? (0, import_node_path8.resolve)(PACKAGED_REPO_ROOT, "sdk", "src") : (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "src");
|
|
4861
|
+
var SDK_PACKAGE_JSON = (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "package.json");
|
|
4862
|
+
var SDK_ENTRY_FILE = (0, import_node_path8.resolve)(SDK_SOURCE_ROOT, "index.ts");
|
|
4863
|
+
var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "dist", "index.d.ts");
|
|
4864
|
+
var SDK_WORKERS_ENTRY_FILE = (0, import_node_path8.resolve)(SDK_SOURCE_ROOT, "worker-play-entry.ts");
|
|
4865
|
+
var WORKERS_HARNESS_ENTRY_FILE = (0, import_node_path8.resolve)(PROJECT_ROOT, "apps", "play-runner-workers", "src", "entry.ts");
|
|
4866
|
+
var WORKERS_HARNESS_FILES_DIR = (0, import_node_path8.resolve)(PROJECT_ROOT, "apps", "play-runner-workers", "src");
|
|
4503
4867
|
var hasWarnedAboutNonDevelopmentBundling = false;
|
|
4504
4868
|
function warnAboutNonDevelopmentBundling(filePath) {
|
|
4505
4869
|
if (hasWarnedAboutNonDevelopmentBundling) {
|
|
@@ -4523,8 +4887,8 @@ function defaultPlayBundleTarget() {
|
|
|
4523
4887
|
function createSdkPlayBundlingAdapter() {
|
|
4524
4888
|
return {
|
|
4525
4889
|
projectRoot: PROJECT_ROOT,
|
|
4526
|
-
nodeModulesDir: (0,
|
|
4527
|
-
cacheDir: (0,
|
|
4890
|
+
nodeModulesDir: (0, import_node_path8.resolve)(PROJECT_ROOT, "node_modules"),
|
|
4891
|
+
cacheDir: (0, import_node_path8.join)((0, import_node_os5.tmpdir)(), `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION2}`),
|
|
4528
4892
|
sdkSourceRoot: SDK_SOURCE_ROOT,
|
|
4529
4893
|
sdkPackageJson: SDK_PACKAGE_JSON,
|
|
4530
4894
|
sdkEntryFile: SDK_ENTRY_FILE,
|
|
@@ -4804,7 +5168,7 @@ function formatPlayListReference(play) {
|
|
|
4804
5168
|
function defaultMaterializedPlayPath(reference) {
|
|
4805
5169
|
const playName = parseReferencedPlayTarget(reference).unqualifiedPlayName;
|
|
4806
5170
|
const safeName = playName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
4807
|
-
return (0,
|
|
5171
|
+
return (0, import_node_path9.resolve)(`${safeName || "play"}.play.ts`);
|
|
4808
5172
|
}
|
|
4809
5173
|
function materializeRemotePlaySource(input) {
|
|
4810
5174
|
if (isFileTarget(input.target)) {
|
|
@@ -4867,7 +5231,7 @@ function extractPlayName(code, filePath) {
|
|
|
4867
5231
|
throw buildMissingDefinePlayError(filePath);
|
|
4868
5232
|
}
|
|
4869
5233
|
function isFileTarget(target) {
|
|
4870
|
-
return (0, import_node_fs6.existsSync)((0,
|
|
5234
|
+
return (0, import_node_fs6.existsSync)((0, import_node_path9.resolve)(target));
|
|
4871
5235
|
}
|
|
4872
5236
|
function looksLikeFilePath(target) {
|
|
4873
5237
|
if (target.trim().toLowerCase().startsWith("prebuilt/")) {
|
|
@@ -4886,7 +5250,7 @@ function parsePositiveInteger2(value, flagName) {
|
|
|
4886
5250
|
return parsed;
|
|
4887
5251
|
}
|
|
4888
5252
|
function parseJsonInput(raw) {
|
|
4889
|
-
const source = raw.startsWith("@") ? (0, import_node_fs6.readFileSync)((0,
|
|
5253
|
+
const source = raw.startsWith("@") ? (0, import_node_fs6.readFileSync)((0, import_node_path9.resolve)(raw.slice(1)), "utf-8") : raw;
|
|
4890
5254
|
const parsed = JSON.parse(source);
|
|
4891
5255
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
4892
5256
|
throw new Error("--input must be a JSON object.");
|
|
@@ -4996,7 +5360,7 @@ function applyCsvShortcutInput(input) {
|
|
|
4996
5360
|
function isLocalFilePathValue(value) {
|
|
4997
5361
|
if (typeof value !== "string" || !value.trim()) return false;
|
|
4998
5362
|
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(value.trim())) return false;
|
|
4999
|
-
return (0, import_node_fs6.existsSync)((0,
|
|
5363
|
+
return (0, import_node_fs6.existsSync)((0, import_node_path9.resolve)(value));
|
|
5000
5364
|
}
|
|
5001
5365
|
function inputContainsLocalFilePath(value) {
|
|
5002
5366
|
if (isLocalFilePathValue(value)) {
|
|
@@ -5022,8 +5386,8 @@ async function stageFileInputArgs(input) {
|
|
|
5022
5386
|
const localFiles = uniqueBindings.flatMap((binding) => {
|
|
5023
5387
|
const value = getDottedInputValue(input.runtimeInput, binding.inputPath);
|
|
5024
5388
|
if (!isLocalFilePathValue(value)) return [];
|
|
5025
|
-
const absolutePath = (0,
|
|
5026
|
-
return [{ binding, absolutePath, logicalPath: (0,
|
|
5389
|
+
const absolutePath = (0, import_node_path9.resolve)(value);
|
|
5390
|
+
return [{ binding, absolutePath, logicalPath: (0, import_node_path9.basename)(absolutePath) }];
|
|
5027
5391
|
});
|
|
5028
5392
|
if (localFiles.length === 0) {
|
|
5029
5393
|
return { inputFile: null, packagedFiles: [] };
|
|
@@ -5058,9 +5422,9 @@ function stageFile(logicalPath, absolutePath) {
|
|
|
5058
5422
|
}
|
|
5059
5423
|
function normalizePlayPath(filePath) {
|
|
5060
5424
|
try {
|
|
5061
|
-
return import_node_fs6.realpathSync.native((0,
|
|
5425
|
+
return import_node_fs6.realpathSync.native((0, import_node_path9.resolve)(filePath));
|
|
5062
5426
|
} catch {
|
|
5063
|
-
return (0,
|
|
5427
|
+
return (0, import_node_path9.resolve)(filePath);
|
|
5064
5428
|
}
|
|
5065
5429
|
}
|
|
5066
5430
|
function formatBundlingErrors(filePath, errors) {
|
|
@@ -6086,7 +6450,7 @@ function parsePlayRunOptions(args) {
|
|
|
6086
6450
|
let input = null;
|
|
6087
6451
|
let revisionId = null;
|
|
6088
6452
|
let revisionSelector = null;
|
|
6089
|
-
const watch = args.includes("--watch");
|
|
6453
|
+
const watch = args.includes("--watch") || args.includes("--wait");
|
|
6090
6454
|
let jsonOutput = watch ? args.includes("--json") : argsWantJson(args);
|
|
6091
6455
|
const emitLogs = !jsonOutput || args.includes("--logs");
|
|
6092
6456
|
const force = args.includes("--force");
|
|
@@ -6120,7 +6484,7 @@ function parsePlayRunOptions(args) {
|
|
|
6120
6484
|
continue;
|
|
6121
6485
|
}
|
|
6122
6486
|
if (arg === "--out" && args[index + 1]) {
|
|
6123
|
-
outPath = (0,
|
|
6487
|
+
outPath = (0, import_node_path9.resolve)(args[++index]);
|
|
6124
6488
|
continue;
|
|
6125
6489
|
}
|
|
6126
6490
|
if (arg === "--poll-interval-ms" || arg === "--interval-ms") {
|
|
@@ -6136,15 +6500,13 @@ function parsePlayRunOptions(args) {
|
|
|
6136
6500
|
if (arg === "--watch") {
|
|
6137
6501
|
continue;
|
|
6138
6502
|
}
|
|
6503
|
+
if (arg === "--wait") {
|
|
6504
|
+
continue;
|
|
6505
|
+
}
|
|
6139
6506
|
if (arg === "--json") {
|
|
6140
6507
|
jsonOutput = true;
|
|
6141
6508
|
continue;
|
|
6142
6509
|
}
|
|
6143
|
-
if (arg === "--wait") {
|
|
6144
|
-
throw new Error(
|
|
6145
|
-
"--wait is removed for `plays run`; use `--watch` to stream completion output."
|
|
6146
|
-
);
|
|
6147
|
-
}
|
|
6148
6510
|
if (arg === "--tail") {
|
|
6149
6511
|
throw new Error(
|
|
6150
6512
|
"--tail is removed for `plays run`; use `--watch` to stream completion output."
|
|
@@ -6222,11 +6584,11 @@ function shouldUseLocalOnlyPlayCheck() {
|
|
|
6222
6584
|
async function handlePlayCheck(args) {
|
|
6223
6585
|
const options = parsePlayCheckOptions(args);
|
|
6224
6586
|
if (!isFileTarget(options.target)) {
|
|
6225
|
-
const resolved = (0,
|
|
6587
|
+
const resolved = (0, import_node_path9.resolve)(options.target);
|
|
6226
6588
|
console.error(`File not found: ${resolved}`);
|
|
6227
6589
|
return 1;
|
|
6228
6590
|
}
|
|
6229
|
-
const absolutePlayPath = (0,
|
|
6591
|
+
const absolutePlayPath = (0, import_node_path9.resolve)(options.target);
|
|
6230
6592
|
const sourceCode = (0, import_node_fs6.readFileSync)(absolutePlayPath, "utf-8");
|
|
6231
6593
|
let graph;
|
|
6232
6594
|
try {
|
|
@@ -6290,7 +6652,7 @@ async function handleFileBackedRun(options) {
|
|
|
6290
6652
|
}
|
|
6291
6653
|
const client = new DeeplineClient();
|
|
6292
6654
|
const progress = getActiveCliProgress() ?? createCliProgress(!options.jsonOutput);
|
|
6293
|
-
const absolutePlayPath = (0,
|
|
6655
|
+
const absolutePlayPath = (0, import_node_path9.resolve)(options.target.path);
|
|
6294
6656
|
progress.phase("compiling play");
|
|
6295
6657
|
const sourceCode = traceCliSync(
|
|
6296
6658
|
"cli.play_file_read_source",
|
|
@@ -6579,11 +6941,11 @@ async function handlePlayRun(args) {
|
|
|
6579
6941
|
if (isFileTarget(options.target.path)) {
|
|
6580
6942
|
return handleFileBackedRun(options);
|
|
6581
6943
|
}
|
|
6582
|
-
const resolved = (0,
|
|
6944
|
+
const resolved = (0, import_node_path9.resolve)(options.target.path);
|
|
6583
6945
|
console.error(`File not found: ${resolved}`);
|
|
6584
|
-
const dir = (0,
|
|
6946
|
+
const dir = (0, import_node_path9.dirname)(resolved);
|
|
6585
6947
|
if ((0, import_node_fs6.existsSync)(dir)) {
|
|
6586
|
-
const base = (0,
|
|
6948
|
+
const base = (0, import_node_path9.basename)(resolved);
|
|
6587
6949
|
try {
|
|
6588
6950
|
const siblings = (0, import_node_fs6.readdirSync)(dir).filter(
|
|
6589
6951
|
(f) => f.includes(base.replace(/\.(play\.)?ts$/, "")) || f.endsWith(".play.ts")
|
|
@@ -6591,7 +6953,7 @@ async function handlePlayRun(args) {
|
|
|
6591
6953
|
if (siblings.length > 0) {
|
|
6592
6954
|
console.error(`Did you mean one of these?`);
|
|
6593
6955
|
for (const s of siblings.slice(0, 5)) {
|
|
6594
|
-
console.error(` ${(0,
|
|
6956
|
+
console.error(` ${(0, import_node_path9.join)(dir, s)}`);
|
|
6595
6957
|
}
|
|
6596
6958
|
}
|
|
6597
6959
|
} catch {
|
|
@@ -6737,7 +7099,7 @@ async function handleRunLogs(args) {
|
|
|
6737
7099
|
continue;
|
|
6738
7100
|
}
|
|
6739
7101
|
if (arg === "--out" && args[index + 1]) {
|
|
6740
|
-
outPath = (0,
|
|
7102
|
+
outPath = (0, import_node_path9.resolve)(args[++index]);
|
|
6741
7103
|
}
|
|
6742
7104
|
}
|
|
6743
7105
|
const client = new DeeplineClient();
|
|
@@ -6824,7 +7186,7 @@ async function handleRunExport(args) {
|
|
|
6824
7186
|
for (let index = 0; index < args.length; index += 1) {
|
|
6825
7187
|
const arg = args[index];
|
|
6826
7188
|
if (arg === "--out" && args[index + 1]) {
|
|
6827
|
-
outPath = (0,
|
|
7189
|
+
outPath = (0, import_node_path9.resolve)(args[++index]);
|
|
6828
7190
|
}
|
|
6829
7191
|
}
|
|
6830
7192
|
if (!outPath) {
|
|
@@ -6864,10 +7226,10 @@ async function handlePlayGet(args) {
|
|
|
6864
7226
|
for (let index = 1; index < args.length; index += 1) {
|
|
6865
7227
|
const arg = args[index];
|
|
6866
7228
|
if (arg === "--out" && args[index + 1]) {
|
|
6867
|
-
outPath = (0,
|
|
7229
|
+
outPath = (0, import_node_path9.resolve)(args[++index]);
|
|
6868
7230
|
}
|
|
6869
7231
|
}
|
|
6870
|
-
const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs6.readFileSync)((0,
|
|
7232
|
+
const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs6.readFileSync)((0, import_node_path9.resolve)(target), "utf-8"), (0, import_node_path9.resolve)(target)) : parseReferencedPlayTarget(target).playName;
|
|
6871
7233
|
const detail = isFileTarget(target) ? await client.getPlay(playName) : await assertCanonicalNamedPlayReference(client, target);
|
|
6872
7234
|
const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
|
|
6873
7235
|
const materializedFile = outPath ? materializeRemotePlaySource({
|
|
@@ -7159,7 +7521,7 @@ async function handlePlayPublish(args) {
|
|
|
7159
7521
|
}
|
|
7160
7522
|
let graph;
|
|
7161
7523
|
try {
|
|
7162
|
-
graph = await collectBundledPlayGraph((0,
|
|
7524
|
+
graph = await collectBundledPlayGraph((0, import_node_path9.resolve)(playName));
|
|
7163
7525
|
await compileBundledPlayGraphManifests(client, graph);
|
|
7164
7526
|
await publishImportedPlayDependencies(client, graph);
|
|
7165
7527
|
} catch (error) {
|
|
@@ -7259,12 +7621,15 @@ Concepts:
|
|
|
7259
7621
|
Plays are durable cloud workflows.
|
|
7260
7622
|
Stable ctx.tools.execute({ id, tool, input }) calls are replay-safe.
|
|
7261
7623
|
ctx.map adds row keys and row progress.
|
|
7624
|
+
Named play runs use the live revision unless --latest or --revision-id is set.
|
|
7625
|
+
Running a local file does not make it live; use set-live/publish explicitly.
|
|
7262
7626
|
|
|
7263
7627
|
Common commands:
|
|
7264
7628
|
deepline plays search email --json
|
|
7265
7629
|
deepline plays describe person-linkedin-to-email --json
|
|
7266
7630
|
deepline plays check my.play.ts
|
|
7267
7631
|
deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
|
|
7632
|
+
deepline plays set-live my.play.ts --json
|
|
7268
7633
|
deepline plays get person-linkedin-to-email --json
|
|
7269
7634
|
`
|
|
7270
7635
|
);
|
|
@@ -7294,9 +7659,11 @@ Notes:
|
|
|
7294
7659
|
Unknown --foo and --foo.bar flags are treated as play input args.
|
|
7295
7660
|
File args accept local paths; the CLI stages files before submit.
|
|
7296
7661
|
--watch prints logs, previews, stats, and next commands.
|
|
7662
|
+
--wait is accepted as a compatibility alias for --watch.
|
|
7297
7663
|
The play page opens in your browser as soon as the run starts; use --no-open
|
|
7298
7664
|
to only print the URL.
|
|
7299
7665
|
--force supersedes active runs; it does not bypass completed reuse.
|
|
7666
|
+
This command starts cloud work and may spend Deepline credits through tool calls.
|
|
7300
7667
|
|
|
7301
7668
|
Idempotent execution:
|
|
7302
7669
|
Stable tool call ids are the reuse key:
|
|
@@ -7321,6 +7688,7 @@ Idempotent execution:
|
|
|
7321
7688
|
|
|
7322
7689
|
Examples:
|
|
7323
7690
|
deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
|
|
7691
|
+
deepline plays run my.play.ts --input @input.json --wait --json
|
|
7324
7692
|
deepline plays run person-linkedin-to-email --input '{"linkedin_url":"..."}' --watch
|
|
7325
7693
|
deepline plays run enrich.play.ts --csv leads.csv --watch --out leads-enriched.csv
|
|
7326
7694
|
deepline plays run cto-search.play.ts --limit 5 --watch
|
|
@@ -7332,7 +7700,7 @@ Examples:
|
|
|
7332
7700
|
).option(
|
|
7333
7701
|
"--out <path>",
|
|
7334
7702
|
"Write the completed row output to CSV; requires --watch"
|
|
7335
|
-
).option("--watch", "Stream logs until completion").option(
|
|
7703
|
+
).option("--watch", "Stream logs until completion").option("--wait", "Alias for --watch; stream logs until completion").option(
|
|
7336
7704
|
"--logs",
|
|
7337
7705
|
"When output is non-interactive, stream play logs to stderr while waiting"
|
|
7338
7706
|
).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Supersede any active runs for this play").option("--no-open", "Print the play page URL without opening a browser").option("--json", "Emit JSON output").action(async (target, options, command) => {
|
|
@@ -7355,7 +7723,7 @@ Examples:
|
|
|
7355
7723
|
...options.latest ? ["--latest"] : [],
|
|
7356
7724
|
...options.revisionId ? ["--revision-id", options.revisionId] : [],
|
|
7357
7725
|
...options.out ? ["--out", options.out] : [],
|
|
7358
|
-
...options.watch ? ["--watch"] : [],
|
|
7726
|
+
...options.watch || options.wait ? ["--watch"] : [],
|
|
7359
7727
|
...options.logs ? ["--logs"] : [],
|
|
7360
7728
|
...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
|
|
7361
7729
|
...options.force ? ["--force"] : [],
|
|
@@ -7386,12 +7754,36 @@ Examples:
|
|
|
7386
7754
|
...options.out ? ["--out", options.out] : []
|
|
7387
7755
|
]);
|
|
7388
7756
|
});
|
|
7389
|
-
play.command("list").description("List saved and prebuilt plays.").
|
|
7757
|
+
play.command("list").description("List saved and prebuilt plays.").addHelpText(
|
|
7758
|
+
"after",
|
|
7759
|
+
`
|
|
7760
|
+
Notes:
|
|
7761
|
+
Inventory command for saved org plays and prebuilt plays. Use search for
|
|
7762
|
+
ranked discovery by task or schema.
|
|
7763
|
+
|
|
7764
|
+
Examples:
|
|
7765
|
+
deepline plays list
|
|
7766
|
+
deepline plays list --json
|
|
7767
|
+
deepline plays search email --origin prebuilt --json
|
|
7768
|
+
`
|
|
7769
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
|
|
7390
7770
|
process.exitCode = await handlePlayList([
|
|
7391
7771
|
...options.json ? ["--json"] : []
|
|
7392
7772
|
]);
|
|
7393
7773
|
});
|
|
7394
|
-
play.command("search <query>").description("Search saved and prebuilt plays.").
|
|
7774
|
+
play.command("search <query>").description("Search saved and prebuilt plays.").addHelpText(
|
|
7775
|
+
"after",
|
|
7776
|
+
`
|
|
7777
|
+
Notes:
|
|
7778
|
+
Ranked discovery for workflows. Use --origin prebuilt or --origin owned when
|
|
7779
|
+
you need to narrow results. Use describe on a result before running it.
|
|
7780
|
+
|
|
7781
|
+
Examples:
|
|
7782
|
+
deepline plays search email
|
|
7783
|
+
deepline plays search "linkedin to email" --origin prebuilt --compact --json
|
|
7784
|
+
deepline plays describe person-linkedin-to-email --json
|
|
7785
|
+
`
|
|
7786
|
+
).option("--origin <origin>", "Filter to prebuilt or owned plays").option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
|
|
7395
7787
|
process.exitCode = await handlePlaySearch([
|
|
7396
7788
|
query,
|
|
7397
7789
|
...options.origin ? ["--origin", options.origin] : [],
|
|
@@ -7417,13 +7809,43 @@ Examples:
|
|
|
7417
7809
|
...options.json ? ["--json"] : []
|
|
7418
7810
|
]);
|
|
7419
7811
|
});
|
|
7420
|
-
play.command("versions").description("List revisions for a named play.").
|
|
7812
|
+
play.command("versions").description("List revisions for a named play.").addHelpText(
|
|
7813
|
+
"after",
|
|
7814
|
+
`
|
|
7815
|
+
Notes:
|
|
7816
|
+
Shows saved revisions for an org-owned play, including which revision is live
|
|
7817
|
+
when that metadata is available. Named runs use the live revision by default.
|
|
7818
|
+
|
|
7819
|
+
Examples:
|
|
7820
|
+
deepline plays versions --name my-play
|
|
7821
|
+
deepline plays versions --name my-play --json
|
|
7822
|
+
deepline plays run my-play --revision-id <revision-id> --watch
|
|
7823
|
+
`
|
|
7824
|
+
).option("--name <name>", "Saved play name").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
|
|
7421
7825
|
process.exitCode = await handlePlayVersions([
|
|
7422
7826
|
...options.name ? ["--name", options.name] : [],
|
|
7423
7827
|
...options.json ? ["--json"] : []
|
|
7424
7828
|
]);
|
|
7425
7829
|
});
|
|
7426
|
-
|
|
7830
|
+
const addPublishHelp = (command) => command.addHelpText(
|
|
7831
|
+
"after",
|
|
7832
|
+
`
|
|
7833
|
+
Notes:
|
|
7834
|
+
Mutates cloud state. For a local file, this bundles, validates, saves a new
|
|
7835
|
+
revision, and promotes that revision live. For a saved play, --latest or
|
|
7836
|
+
--revision-id promotes an existing saved revision live.
|
|
7837
|
+
Running a local file with plays run does not publish it.
|
|
7838
|
+
|
|
7839
|
+
Examples:
|
|
7840
|
+
deepline plays set-live my.play.ts --json
|
|
7841
|
+
deepline plays set-live my-play --latest --json
|
|
7842
|
+
deepline plays set-live my-play --revision-id <revision-id> --json
|
|
7843
|
+
deepline plays publish my.play.ts --json
|
|
7844
|
+
`
|
|
7845
|
+
);
|
|
7846
|
+
addPublishHelp(
|
|
7847
|
+
play.command("publish <target>").description("Bundle, validate, save, and promote a play revision live.")
|
|
7848
|
+
).option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
|
|
7427
7849
|
process.exitCode = await handlePlayPublish([
|
|
7428
7850
|
target,
|
|
7429
7851
|
...options.latest ? ["--latest"] : [],
|
|
@@ -7431,7 +7853,28 @@ Examples:
|
|
|
7431
7853
|
...options.json ? ["--json"] : []
|
|
7432
7854
|
]);
|
|
7433
7855
|
});
|
|
7434
|
-
|
|
7856
|
+
addPublishHelp(
|
|
7857
|
+
play.command("set-live <target>").description("Promote a local file or saved revision as the live play revision.")
|
|
7858
|
+
).option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
|
|
7859
|
+
process.exitCode = await handlePlayPublish([
|
|
7860
|
+
target,
|
|
7861
|
+
...options.latest ? ["--latest"] : [],
|
|
7862
|
+
...options.revisionId ? ["--revision-id", options.revisionId] : [],
|
|
7863
|
+
...options.json ? ["--json"] : []
|
|
7864
|
+
]);
|
|
7865
|
+
});
|
|
7866
|
+
play.command("delete <target>").description("Delete an org-owned play and its saved revisions/runs.").addHelpText(
|
|
7867
|
+
"after",
|
|
7868
|
+
`
|
|
7869
|
+
Notes:
|
|
7870
|
+
Destructive mutation. Deletes an org-owned play plus saved revisions and run
|
|
7871
|
+
records. Prebuilt/read-only plays are refused. Use --yes for noninteractive runs.
|
|
7872
|
+
|
|
7873
|
+
Examples:
|
|
7874
|
+
deepline plays delete my-play
|
|
7875
|
+
deepline plays delete my-play --yes --json
|
|
7876
|
+
`
|
|
7877
|
+
).option("-y, --yes", "Confirm deletion").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
|
|
7435
7878
|
process.exitCode = await handlePlayDelete([
|
|
7436
7879
|
target,
|
|
7437
7880
|
...options.yes ? ["--yes"] : [],
|
|
@@ -7441,6 +7884,12 @@ Examples:
|
|
|
7441
7884
|
const runs = program.command("runs").description("Inspect, tail, stop, and export play runs.").addHelpText(
|
|
7442
7885
|
"after",
|
|
7443
7886
|
`
|
|
7887
|
+
Concepts:
|
|
7888
|
+
A run is one execution instance of a play. It has status, progress, logs,
|
|
7889
|
+
preview output, recovery metadata, and optional full row export.
|
|
7890
|
+
tail reads the live stream. logs fetches persisted logs after the fact.
|
|
7891
|
+
stop mutates cloud state by requesting cancellation.
|
|
7892
|
+
|
|
7444
7893
|
Examples:
|
|
7445
7894
|
deepline runs get play/my-play/run/20260501t000000-000 --json
|
|
7446
7895
|
deepline runs tail play/my-play/run/20260501t000000-000
|
|
@@ -7450,14 +7899,36 @@ Examples:
|
|
|
7450
7899
|
deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
|
|
7451
7900
|
`
|
|
7452
7901
|
);
|
|
7453
|
-
runs.command("get <runId>").description("Get status, progress, outputs, errors, and recovery metadata for a play run.").
|
|
7902
|
+
runs.command("get <runId>").description("Get status, progress, outputs, errors, and recovery metadata for a play run.").addHelpText(
|
|
7903
|
+
"after",
|
|
7904
|
+
`
|
|
7905
|
+
Notes:
|
|
7906
|
+
Full run status read. Use --full --json when debugging raw stream/status fields.
|
|
7907
|
+
|
|
7908
|
+
Examples:
|
|
7909
|
+
deepline runs get play/my-play/run/20260501t000000-000
|
|
7910
|
+
deepline runs get play/my-play/run/20260501t000000-000 --json
|
|
7911
|
+
deepline runs get play/my-play/run/20260501t000000-000 --full --json
|
|
7912
|
+
`
|
|
7913
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").option("--full", "Debug only: with --json, emit the raw status payload").action(async (runId, options) => {
|
|
7454
7914
|
process.exitCode = await handleRunGet([
|
|
7455
7915
|
runId,
|
|
7456
7916
|
...options.json ? ["--json"] : [],
|
|
7457
7917
|
...options.full ? ["--full"] : []
|
|
7458
7918
|
]);
|
|
7459
7919
|
});
|
|
7460
|
-
runs.command("list").description("List play runs.").
|
|
7920
|
+
runs.command("list").description("List play runs.").addHelpText(
|
|
7921
|
+
"after",
|
|
7922
|
+
`
|
|
7923
|
+
Notes:
|
|
7924
|
+
Bounded inventory for a play's recent runs. Use --compact for agent loops.
|
|
7925
|
+
Common statuses include running, completed, failed, and stopped.
|
|
7926
|
+
|
|
7927
|
+
Examples:
|
|
7928
|
+
deepline runs list --play my-play
|
|
7929
|
+
deepline runs list --play my-play --status failed --compact --json
|
|
7930
|
+
`
|
|
7931
|
+
).requiredOption("--play <name>", "Play name to filter runs").option("--status <status>", "Filter by run status").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
|
|
7461
7932
|
process.exitCode = await handleRunsList([
|
|
7462
7933
|
"--play",
|
|
7463
7934
|
options.play,
|
|
@@ -7466,14 +7937,37 @@ Examples:
|
|
|
7466
7937
|
...options.json ? ["--json"] : []
|
|
7467
7938
|
]);
|
|
7468
7939
|
});
|
|
7469
|
-
runs.command("tail <runId>").description("Read the canonical live stream for a play run.").
|
|
7940
|
+
runs.command("tail <runId>").description("Read the canonical live stream for a play run.").addHelpText(
|
|
7941
|
+
"after",
|
|
7942
|
+
`
|
|
7943
|
+
Notes:
|
|
7944
|
+
Streams live run events until the stream ends. Use get for current status and
|
|
7945
|
+
logs for persisted log history.
|
|
7946
|
+
|
|
7947
|
+
Examples:
|
|
7948
|
+
deepline runs tail play/my-play/run/20260501t000000-000
|
|
7949
|
+
deepline runs tail play/my-play/run/20260501t000000-000 --compact --json
|
|
7950
|
+
`
|
|
7951
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").option("--compact", "Drop verbose fields from JSON output").action(async (runId, options) => {
|
|
7470
7952
|
process.exitCode = await handleRunTail([
|
|
7471
7953
|
runId,
|
|
7472
7954
|
...options.json ? ["--json"] : [],
|
|
7473
7955
|
...options.compact ? ["--compact"] : []
|
|
7474
7956
|
]);
|
|
7475
7957
|
});
|
|
7476
|
-
runs.command("logs <runId>").description("Fetch persisted logs for a play run.").
|
|
7958
|
+
runs.command("logs <runId>").description("Fetch persisted logs for a play run.").addHelpText(
|
|
7959
|
+
"after",
|
|
7960
|
+
`
|
|
7961
|
+
Notes:
|
|
7962
|
+
Prints a bounded recent log preview by default. Use --out to write the full
|
|
7963
|
+
persisted log stream to a local file.
|
|
7964
|
+
|
|
7965
|
+
Examples:
|
|
7966
|
+
deepline runs logs play/my-play/run/20260501t000000-000
|
|
7967
|
+
deepline runs logs play/my-play/run/20260501t000000-000 --limit 500
|
|
7968
|
+
deepline runs logs play/my-play/run/20260501t000000-000 --out run.log --json
|
|
7969
|
+
`
|
|
7970
|
+
).option("--limit <count>", "Maximum recent log lines to print without --out", "200").option("--out <path>", "Write the full persisted log stream to a file").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
|
|
7477
7971
|
process.exitCode = await handleRunLogs([
|
|
7478
7972
|
runId,
|
|
7479
7973
|
...options.limit ? ["--limit", options.limit] : [],
|
|
@@ -7481,14 +7975,36 @@ Examples:
|
|
|
7481
7975
|
...options.json ? ["--json"] : []
|
|
7482
7976
|
]);
|
|
7483
7977
|
});
|
|
7484
|
-
runs.command("stop <runId>").description("Stop a play run.").
|
|
7978
|
+
runs.command("stop <runId>").description("Stop a play run.").addHelpText(
|
|
7979
|
+
"after",
|
|
7980
|
+
`
|
|
7981
|
+
Notes:
|
|
7982
|
+
Mutates cloud state by requesting cancellation for an active run. Already
|
|
7983
|
+
terminal runs are returned as no-ops by the server when applicable.
|
|
7984
|
+
|
|
7985
|
+
Examples:
|
|
7986
|
+
deepline runs stop play/my-play/run/20260501t000000-000 --reason "stale lock"
|
|
7987
|
+
deepline runs stop play/my-play/run/20260501t000000-000 --json
|
|
7988
|
+
`
|
|
7989
|
+
).option("--reason <text>", "Reason to include with the stop request").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
|
|
7485
7990
|
process.exitCode = await handleRunStop([
|
|
7486
7991
|
runId,
|
|
7487
7992
|
...options.reason ? ["--reason", options.reason] : [],
|
|
7488
7993
|
...options.json ? ["--json"] : []
|
|
7489
7994
|
]);
|
|
7490
7995
|
});
|
|
7491
|
-
runs.command("export <runId>").description("Export the completed row output for a play run to CSV.").
|
|
7996
|
+
runs.command("export <runId>").description("Export the completed row output for a play run to CSV.").addHelpText(
|
|
7997
|
+
"after",
|
|
7998
|
+
`
|
|
7999
|
+
Notes:
|
|
8000
|
+
Writes the completed row output to the requested local CSV path. Use runs get
|
|
8001
|
+
first when you need to confirm the run is complete or inspect preview output.
|
|
8002
|
+
|
|
8003
|
+
Examples:
|
|
8004
|
+
deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
|
|
8005
|
+
deepline runs export play/my-play/run/20260501t000000-000 --out output.csv --json
|
|
8006
|
+
`
|
|
8007
|
+
).requiredOption("--out <path>", "Output CSV path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
|
|
7492
8008
|
process.exitCode = await handleRunExport([
|
|
7493
8009
|
runId,
|
|
7494
8010
|
"--out",
|
|
@@ -7501,12 +8017,12 @@ Examples:
|
|
|
7501
8017
|
// src/cli/commands/tools.ts
|
|
7502
8018
|
var import_node_fs8 = require("fs");
|
|
7503
8019
|
var import_node_os7 = require("os");
|
|
7504
|
-
var
|
|
8020
|
+
var import_node_path11 = require("path");
|
|
7505
8021
|
|
|
7506
8022
|
// src/tool-output.ts
|
|
7507
8023
|
var import_node_fs7 = require("fs");
|
|
7508
8024
|
var import_node_os6 = require("os");
|
|
7509
|
-
var
|
|
8025
|
+
var import_node_path10 = require("path");
|
|
7510
8026
|
function isPlainObject(value) {
|
|
7511
8027
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
7512
8028
|
}
|
|
@@ -7581,19 +8097,19 @@ function tryConvertToList(payload, options) {
|
|
|
7581
8097
|
return null;
|
|
7582
8098
|
}
|
|
7583
8099
|
function ensureOutputDir() {
|
|
7584
|
-
const outputDir = (0,
|
|
8100
|
+
const outputDir = (0, import_node_path10.join)((0, import_node_os6.homedir)(), ".local", "share", "deepline", "data");
|
|
7585
8101
|
(0, import_node_fs7.mkdirSync)(outputDir, { recursive: true });
|
|
7586
8102
|
return outputDir;
|
|
7587
8103
|
}
|
|
7588
8104
|
function writeJsonOutputFile(payload, stem) {
|
|
7589
8105
|
const outputDir = ensureOutputDir();
|
|
7590
|
-
const outputPath = (0,
|
|
8106
|
+
const outputPath = (0, import_node_path10.join)(outputDir, `${stem}_${Date.now()}.json`);
|
|
7591
8107
|
(0, import_node_fs7.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
7592
8108
|
return outputPath;
|
|
7593
8109
|
}
|
|
7594
8110
|
function writeCsvOutputFile(rows, stem) {
|
|
7595
8111
|
const outputDir = ensureOutputDir();
|
|
7596
|
-
const outputPath = (0,
|
|
8112
|
+
const outputPath = (0, import_node_path10.join)(outputDir, `${stem}_${Date.now()}.csv`);
|
|
7597
8113
|
const seen = /* @__PURE__ */ new Set();
|
|
7598
8114
|
const columns = [];
|
|
7599
8115
|
for (const row of rows) {
|
|
@@ -7732,16 +8248,44 @@ Concepts:
|
|
|
7732
8248
|
|
|
7733
8249
|
Common commands:
|
|
7734
8250
|
deepline tools search email --json
|
|
7735
|
-
deepline tools
|
|
8251
|
+
deepline tools describe hunter_email_verifier --json
|
|
7736
8252
|
deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
|
|
8253
|
+
|
|
8254
|
+
Output:
|
|
8255
|
+
Search/list output is bounded. Use describe for a compact contract and get for
|
|
8256
|
+
the full machine-readable metadata available for the tool.
|
|
7737
8257
|
`
|
|
7738
8258
|
);
|
|
7739
|
-
tools.command("list").description("List available tools.").
|
|
8259
|
+
tools.command("list").description("List available tools.").addHelpText(
|
|
8260
|
+
"after",
|
|
8261
|
+
`
|
|
8262
|
+
Notes:
|
|
8263
|
+
Inventory command for known tool ids. Use search for ranked discovery by
|
|
8264
|
+
intent, aliases, descriptions, and schema fields.
|
|
8265
|
+
|
|
8266
|
+
Examples:
|
|
8267
|
+
deepline tools list
|
|
8268
|
+
deepline tools list --json
|
|
8269
|
+
deepline tools search email --json
|
|
8270
|
+
`
|
|
8271
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
|
|
7740
8272
|
process.exitCode = await listTools([
|
|
7741
8273
|
...options.json ? ["--json"] : []
|
|
7742
8274
|
]);
|
|
7743
8275
|
});
|
|
7744
|
-
tools.command("search <query>").description("Search available tools.").
|
|
8276
|
+
tools.command("search <query>").description("Search available tools.").addHelpText(
|
|
8277
|
+
"after",
|
|
8278
|
+
`
|
|
8279
|
+
Notes:
|
|
8280
|
+
Ranked discovery for atomic provider/API operations. Results include tool ids
|
|
8281
|
+
that can be passed to deepline tools describe or deepline tools call.
|
|
8282
|
+
|
|
8283
|
+
Examples:
|
|
8284
|
+
deepline tools search email
|
|
8285
|
+
deepline tools search "company enrichment" --categories enrichment --json
|
|
8286
|
+
deepline tools search verifier --search-mode v2 --json
|
|
8287
|
+
`
|
|
8288
|
+
).option("--categories <categories>", "Comma-separated categories to filter ranked search").option("--search_terms <terms>", "Structured search terms for ranked search").option("--search-terms <terms>", "Structured search terms for ranked search").option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
|
|
7745
8289
|
process.exitCode = await searchTools(query, {
|
|
7746
8290
|
json: options.json,
|
|
7747
8291
|
categories: options.categories,
|
|
@@ -7750,15 +8294,18 @@ Common commands:
|
|
|
7750
8294
|
includeSearchDebug: Boolean(options.includeSearchDebug)
|
|
7751
8295
|
});
|
|
7752
8296
|
});
|
|
7753
|
-
|
|
8297
|
+
const addToolMetadataCommand = (command, preferredExample) => command.description("Show metadata for a tool.").addHelpText(
|
|
7754
8298
|
"after",
|
|
7755
8299
|
`
|
|
7756
8300
|
Notes:
|
|
7757
|
-
Shows the tool contract, input schema, output schema,
|
|
8301
|
+
Shows the tool contract, input schema, output schema, Deepline cost, aliases,
|
|
8302
|
+
and metadata. describe is the preferred discovery verb; get is kept as a
|
|
8303
|
+
compatibility command for the same metadata surface.
|
|
7758
8304
|
|
|
7759
8305
|
Examples:
|
|
7760
|
-
deepline tools
|
|
7761
|
-
deepline tools
|
|
8306
|
+
deepline tools ${preferredExample} hunter_email_verifier
|
|
8307
|
+
deepline tools ${preferredExample} hunter_email_verifier --json | jq '.inputSchema'
|
|
8308
|
+
deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
|
|
7762
8309
|
`
|
|
7763
8310
|
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (toolId, options) => {
|
|
7764
8311
|
process.exitCode = await getTool([
|
|
@@ -7766,12 +8313,16 @@ Examples:
|
|
|
7766
8313
|
...options.json ? ["--json"] : []
|
|
7767
8314
|
]);
|
|
7768
8315
|
});
|
|
8316
|
+
addToolMetadataCommand(tools.command("describe <toolId>"), "describe");
|
|
8317
|
+
addToolMetadataCommand(tools.command("get <toolId>"), "get");
|
|
7769
8318
|
tools.command("call <toolId>").alias("execute").alias("run").description("Execute a tool by id.").addHelpText(
|
|
7770
8319
|
"after",
|
|
7771
8320
|
`
|
|
7772
8321
|
Notes:
|
|
7773
8322
|
Use tools for one atomic provider/API operation. Use plays for composed workflows,
|
|
7774
8323
|
waterfalls, row maps, checkpoints, and retries.
|
|
8324
|
+
Calling a provider-backed tool can spend Deepline credits. Use --json for the
|
|
8325
|
+
stable result payload and --full-output when debugging response metadata.
|
|
7775
8326
|
|
|
7776
8327
|
Examples:
|
|
7777
8328
|
deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
|
|
@@ -8118,9 +8669,9 @@ function powerShellQuote(value) {
|
|
|
8118
8669
|
function seedToolListScript(input) {
|
|
8119
8670
|
const stem = safeFileStem(input.toolId);
|
|
8120
8671
|
const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
|
|
8121
|
-
const scriptDir = (0, import_node_fs8.mkdtempSync)((0,
|
|
8672
|
+
const scriptDir = (0, import_node_fs8.mkdtempSync)((0, import_node_path11.join)((0, import_node_os7.tmpdir)(), "deepline-workflow-seed-"));
|
|
8122
8673
|
(0, import_node_fs8.chmodSync)(scriptDir, 448);
|
|
8123
|
-
const scriptPath = (0,
|
|
8674
|
+
const scriptPath = (0, import_node_path11.join)(scriptDir, fileName);
|
|
8124
8675
|
const projectDir = `deepline/projects/${stem}-workflow`;
|
|
8125
8676
|
const playName = `${stem}-workflow`;
|
|
8126
8677
|
const sampleRows = input.rows.length > 0 ? `${JSON.stringify(input.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
|
|
@@ -8263,7 +8814,7 @@ async function executeTool(args) {
|
|
|
8263
8814
|
var import_node_child_process2 = require("child_process");
|
|
8264
8815
|
var import_node_fs9 = require("fs");
|
|
8265
8816
|
var import_node_os8 = require("os");
|
|
8266
|
-
var
|
|
8817
|
+
var import_node_path12 = require("path");
|
|
8267
8818
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
8268
8819
|
var SDK_SKILL_NAME = "deepline-sdk";
|
|
8269
8820
|
var SKILL_AGENTS = ["codex", "claude-code", "cursor"];
|
|
@@ -8274,7 +8825,7 @@ function shouldSkipSkillsSync() {
|
|
|
8274
8825
|
}
|
|
8275
8826
|
function sdkSkillsVersionPath(baseUrl) {
|
|
8276
8827
|
const home = process.env.HOME?.trim() || (0, import_node_os8.homedir)();
|
|
8277
|
-
return (0,
|
|
8828
|
+
return (0, import_node_path12.join)(home, ".local", "deepline", baseUrlSlug(baseUrl), "sdk-skills", ".version");
|
|
8278
8829
|
}
|
|
8279
8830
|
function readLocalSkillsVersion(baseUrl) {
|
|
8280
8831
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
@@ -8287,7 +8838,7 @@ function readLocalSkillsVersion(baseUrl) {
|
|
|
8287
8838
|
}
|
|
8288
8839
|
function writeLocalSkillsVersion(baseUrl, version) {
|
|
8289
8840
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
8290
|
-
(0, import_node_fs9.mkdirSync)((0,
|
|
8841
|
+
(0, import_node_fs9.mkdirSync)((0, import_node_path12.dirname)(path), { recursive: true });
|
|
8291
8842
|
(0, import_node_fs9.writeFileSync)(path, `${version}
|
|
8292
8843
|
`, "utf-8");
|
|
8293
8844
|
}
|
|
@@ -8382,7 +8933,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
8382
8933
|
return [npxInstall];
|
|
8383
8934
|
}
|
|
8384
8935
|
function runOneSkillsInstall(install) {
|
|
8385
|
-
return new Promise((
|
|
8936
|
+
return new Promise((resolve9) => {
|
|
8386
8937
|
const child = (0, import_node_child_process2.spawn)(install.command, install.args, {
|
|
8387
8938
|
stdio: ["ignore", "ignore", "pipe"],
|
|
8388
8939
|
env: process.env
|
|
@@ -8392,7 +8943,7 @@ function runOneSkillsInstall(install) {
|
|
|
8392
8943
|
stderr += chunk.toString("utf-8");
|
|
8393
8944
|
});
|
|
8394
8945
|
child.on("error", (error) => {
|
|
8395
|
-
|
|
8946
|
+
resolve9({
|
|
8396
8947
|
ok: false,
|
|
8397
8948
|
detail: `failed to start ${install.command}: ${error.message}`,
|
|
8398
8949
|
manualCommand: install.manualCommand
|
|
@@ -8400,11 +8951,11 @@ function runOneSkillsInstall(install) {
|
|
|
8400
8951
|
});
|
|
8401
8952
|
child.on("close", (code) => {
|
|
8402
8953
|
if (code === 0) {
|
|
8403
|
-
|
|
8954
|
+
resolve9({ ok: true, detail: "", manualCommand: install.manualCommand });
|
|
8404
8955
|
return;
|
|
8405
8956
|
}
|
|
8406
8957
|
const detail = stderr.trim();
|
|
8407
|
-
|
|
8958
|
+
resolve9({
|
|
8408
8959
|
ok: false,
|
|
8409
8960
|
detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
|
|
8410
8961
|
manualCommand: install.manualCommand
|
|
@@ -8457,6 +9008,9 @@ function shouldPrintStartupPhase() {
|
|
|
8457
9008
|
return false;
|
|
8458
9009
|
}
|
|
8459
9010
|
const args = process.argv.slice(2);
|
|
9011
|
+
if (args.includes("-h") || args.includes("--help")) {
|
|
9012
|
+
return false;
|
|
9013
|
+
}
|
|
8460
9014
|
const command = args[0];
|
|
8461
9015
|
const subcommand = args[1];
|
|
8462
9016
|
return (command === "play" || command === "plays") && subcommand === "run";
|
|
@@ -8478,7 +9032,7 @@ async function main() {
|
|
|
8478
9032
|
if (printStartupPhase) {
|
|
8479
9033
|
progress?.phase("loading deepline cli");
|
|
8480
9034
|
}
|
|
8481
|
-
const program = new
|
|
9035
|
+
const program = new import_commander2.Command();
|
|
8482
9036
|
program.name("deepline").description("Deepline CLI (TypeScript SDK)").version(SDK_VERSION, "-v, --version", "Show version").showHelpAfterError().showSuggestionAfterError(true).addHelpText(
|
|
8483
9037
|
"after",
|
|
8484
9038
|
`
|
|
@@ -8490,9 +9044,23 @@ Common commands:
|
|
|
8490
9044
|
deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
|
|
8491
9045
|
deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
|
|
8492
9046
|
|
|
9047
|
+
Product model:
|
|
9048
|
+
Tools are atomic provider/API operations that may spend credits.
|
|
9049
|
+
Plays are durable workflows backed by source code or saved cloud revisions.
|
|
9050
|
+
Runs are execution instances with logs, status, outputs, and cancellation.
|
|
9051
|
+
Live plays are promoted revisions used by named play runs.
|
|
9052
|
+
|
|
8493
9053
|
Output:
|
|
8494
9054
|
Structured commands print human-readable output in a terminal and JSON when stdout is piped.
|
|
8495
9055
|
Use --json to force JSON in an interactive terminal.
|
|
9056
|
+
|
|
9057
|
+
Safety:
|
|
9058
|
+
Commands that mutate state, open a browser, write files, stop work, or spend credits say so in their help.
|
|
9059
|
+
Use --no-open where available for CI and agent runs.
|
|
9060
|
+
|
|
9061
|
+
Exit codes:
|
|
9062
|
+
0 success; 2 usage/local input error; 3 auth/permission error; 4 not found;
|
|
9063
|
+
5 server/runtime/provider failure; 7 validation/check failed.
|
|
8496
9064
|
`
|
|
8497
9065
|
);
|
|
8498
9066
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
@@ -8527,7 +9095,17 @@ Output:
|
|
|
8527
9095
|
registerCsvCommands(program);
|
|
8528
9096
|
registerDbCommands(program);
|
|
8529
9097
|
registerFeedbackCommands(program);
|
|
8530
|
-
program.command("health").description("Check server health.").
|
|
9098
|
+
program.command("health").description("Check server health.").addHelpText(
|
|
9099
|
+
"after",
|
|
9100
|
+
`
|
|
9101
|
+
Notes:
|
|
9102
|
+
Read-only connectivity check for the configured Deepline host. Prints the raw
|
|
9103
|
+
server health payload as JSON.
|
|
9104
|
+
|
|
9105
|
+
Examples:
|
|
9106
|
+
deepline health
|
|
9107
|
+
`
|
|
9108
|
+
).action(async () => {
|
|
8531
9109
|
try {
|
|
8532
9110
|
const client = new DeeplineClient();
|
|
8533
9111
|
const data = await client.health();
|
|
@@ -8539,7 +9117,18 @@ Output:
|
|
|
8539
9117
|
);
|
|
8540
9118
|
}
|
|
8541
9119
|
});
|
|
8542
|
-
program.command("version").description("Show version.").
|
|
9120
|
+
program.command("version").description("Show version.").addHelpText(
|
|
9121
|
+
"after",
|
|
9122
|
+
`
|
|
9123
|
+
Notes:
|
|
9124
|
+
Prints the SDK CLI package version. The top-level -v/--version flag returns
|
|
9125
|
+
the same version.
|
|
9126
|
+
|
|
9127
|
+
Examples:
|
|
9128
|
+
deepline version
|
|
9129
|
+
deepline --version
|
|
9130
|
+
`
|
|
9131
|
+
).action(() => {
|
|
8543
9132
|
process.stdout.write(`deepline ${SDK_VERSION}
|
|
8544
9133
|
`);
|
|
8545
9134
|
});
|