deepline 0.1.23 → 0.1.24

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.
@@ -243,7 +243,7 @@ function saveProjectDeeplineEnvValues(baseUrl, values, startDir = projectEnvStar
243
243
  }
244
244
 
245
245
  // src/version.ts
246
- var SDK_VERSION = "0.1.23";
246
+ var SDK_VERSION = "0.1.24";
247
247
  var SDK_API_CONTRACT = "2026-05-runs-v2";
248
248
 
249
249
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -2330,18 +2330,48 @@ function registerAuthCommands(program) {
2330
2330
  `
2331
2331
  Common commands:
2332
2332
  deepline auth register
2333
+ deepline auth register --no-wait
2334
+ deepline auth wait --timeout 300
2333
2335
  deepline auth status
2334
2336
  deepline auth status --json
2337
+
2338
+ Notes:
2339
+ Registration opens a browser approval page by default. Use --no-wait in CI
2340
+ or agent runs, then finish with deepline auth wait.
2341
+ Auth status shows the target host and active workspace without printing secrets.
2335
2342
  `
2336
2343
  );
2337
- auth.command("register").description("Register this device and open the approval page in your browser.").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) => {
2344
+ auth.command("register").description("Register this device and open the approval page in your browser.").addHelpText(
2345
+ "after",
2346
+ `
2347
+ Notes:
2348
+ Opens a browser approval page and waits for approval unless --no-wait is set.
2349
+ The saved API key is scoped to the selected workspace and host.
2350
+
2351
+ Examples:
2352
+ deepline auth register
2353
+ deepline auth register --org-name Acme --agent-name local-cli
2354
+ deepline auth register --no-wait
2355
+ `
2356
+ ).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) => {
2338
2357
  process.exitCode = await handleRegister([
2339
2358
  ...options.orgName ? ["--org-name", options.orgName] : [],
2340
2359
  ...options.agentName ? ["--agent-name", options.agentName] : [],
2341
2360
  ...options.noWait || options.wait === false ? ["--no-wait"] : []
2342
2361
  ]);
2343
2362
  });
2344
- auth.command("wait").description("Wait for a pending browser approval and save the API key.").option("--timeout <seconds>", "Maximum seconds to wait", "300").action(async (options) => {
2363
+ auth.command("wait").description("Wait for a pending browser approval and save the API key.").addHelpText(
2364
+ "after",
2365
+ `
2366
+ Notes:
2367
+ Completes a previous deepline auth register --no-wait flow.
2368
+ Saves the approved API key into the host auth file.
2369
+
2370
+ Examples:
2371
+ deepline auth wait
2372
+ deepline auth wait --timeout 120
2373
+ `
2374
+ ).option("--timeout <seconds>", "Maximum seconds to wait", "300").action(async (options) => {
2345
2375
  process.exitCode = await handleWait([
2346
2376
  ...options.timeout ? ["--timeout", options.timeout] : []
2347
2377
  ]);
@@ -2495,15 +2525,116 @@ async function handleRedeemCode(code, options) {
2495
2525
  `);
2496
2526
  }
2497
2527
  function registerBillingCommands(program) {
2498
- const billing = program.command("billing").description("Inspect balance, usage, limits, and checkout flows.");
2499
- billing.command("balance").description("Show current billing balance.").option("--json", "Emit JSON output").action(handleBalance);
2500
- billing.command("usage").description("Show current usage plus recent calls.").option("--limit <n>", "Recent-call page size").option("--offset <n>", "Recent-call offset").option("--json", "Emit JSON output").action(handleUsage);
2501
- billing.command("limit").description("Show configured monthly limit state.").option("--json", "Emit JSON output").action(handleLimit);
2502
- billing.command("set-limit").description("Set monthly credit cap.").argument("<credits>", "Monthly credits limit").option("--json", "Emit JSON output").action(handleSetLimit);
2503
- billing.command("off").description("Disable monthly credit cap.").option("--json", "Emit JSON output").action(handleLimitOff);
2504
- billing.command("history").description("Export billing ledger history to CSV.").requiredOption("--time <window>", "Rolling time window: 1d, 1w, 1m, or 1y").option("--json", "Emit JSON output").action(handleHistory);
2505
- billing.command("checkout").description("Create a checkout session and optionally open it in your browser.").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").action(handleCheckout);
2506
- billing.command("redeem-code").description("Redeem a billing code.").requiredOption("--code <code>", "Code to redeem").option("--no-open", "Do not open a browser").option("--json", "Emit JSON output").action(({ code, ...options }) => handleRedeemCode(code, options));
2528
+ const billing = program.command("billing").description("Inspect balance, usage, limits, and checkout flows.").addHelpText(
2529
+ "after",
2530
+ `
2531
+ Concepts:
2532
+ Billing commands show Deepline credits, not raw provider spend.
2533
+ set-limit/off mutate the monthly workspace cap. checkout/redeem-code can open
2534
+ a browser unless --no-open is set.
2535
+
2536
+ Examples:
2537
+ deepline billing balance --json
2538
+ deepline billing usage --limit 20 --json
2539
+ deepline billing set-limit 500 --json
2540
+ deepline billing checkout --credits 1000 --no-open --json
2541
+ `
2542
+ );
2543
+ billing.command("balance").description("Show current billing balance.").addHelpText(
2544
+ "after",
2545
+ `
2546
+ Notes:
2547
+ Read-only. Shows the current Deepline credit balance for the active workspace.
2548
+
2549
+ Examples:
2550
+ deepline billing balance
2551
+ deepline billing balance --json
2552
+ `
2553
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleBalance);
2554
+ billing.command("usage").description("Show current usage plus recent calls.").addHelpText(
2555
+ "after",
2556
+ `
2557
+ Notes:
2558
+ Read-only. Shows last-30-day Deepline credit usage plus a bounded recent-call
2559
+ page. Use --limit/--offset to paginate the recent-call section.
2560
+
2561
+ Examples:
2562
+ deepline billing usage
2563
+ deepline billing usage --limit 50 --offset 50 --json
2564
+ `
2565
+ ).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);
2566
+ billing.command("limit").description("Show configured monthly limit state.").addHelpText(
2567
+ "after",
2568
+ `
2569
+ Notes:
2570
+ Read-only. Shows whether the monthly workspace cap is enabled and how many
2571
+ Deepline credits remain before the cap.
2572
+
2573
+ Examples:
2574
+ deepline billing limit
2575
+ deepline billing limit --json
2576
+ `
2577
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLimit);
2578
+ billing.command("set-limit").description("Set monthly credit cap.").addHelpText(
2579
+ "after",
2580
+ `
2581
+ Notes:
2582
+ Mutates workspace billing settings. The argument is a Deepline credit amount,
2583
+ not dollars and not provider credits.
2584
+
2585
+ Examples:
2586
+ deepline billing set-limit 500
2587
+ deepline billing set-limit 500 --json
2588
+ `
2589
+ ).argument("<credits>", "Monthly credits limit").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleSetLimit);
2590
+ billing.command("off").description("Disable monthly credit cap.").addHelpText(
2591
+ "after",
2592
+ `
2593
+ Notes:
2594
+ Mutates workspace billing settings by removing the monthly Deepline credit cap.
2595
+
2596
+ Examples:
2597
+ deepline billing off
2598
+ deepline billing off --json
2599
+ `
2600
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLimitOff);
2601
+ billing.command("history").description("Export billing ledger history to CSV.").addHelpText(
2602
+ "after",
2603
+ `
2604
+ Notes:
2605
+ Read-only server query that writes a local CSV file. With --json, stdout is a
2606
+ summary containing the output path and row count.
2607
+
2608
+ Examples:
2609
+ deepline billing history --time 1m
2610
+ deepline billing history --time 1y --json
2611
+ `
2612
+ ).requiredOption("--time <window>", "Rolling time window: 1d, 1w, 1m, or 1y").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleHistory);
2613
+ billing.command("checkout").description("Create a checkout session and optionally open it in your browser.").addHelpText(
2614
+ "after",
2615
+ `
2616
+ Notes:
2617
+ Creates a payment checkout session. Opens the checkout URL in a browser unless
2618
+ --no-open is set. Use --json for automation.
2619
+
2620
+ Examples:
2621
+ deepline billing checkout --tier pro
2622
+ deepline billing checkout --credits 1000 --no-open --json
2623
+ deepline billing checkout --credits 1000 --discount-code LAUNCH --no-open
2624
+ `
2625
+ ).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);
2626
+ billing.command("redeem-code").description("Redeem a billing code.").addHelpText(
2627
+ "after",
2628
+ `
2629
+ Notes:
2630
+ Redeems a workspace billing code and may open a browser for completion unless
2631
+ --no-open is set.
2632
+
2633
+ Examples:
2634
+ deepline billing redeem-code --code ABC123
2635
+ deepline billing redeem-code --code ABC123 --no-open --json
2636
+ `
2637
+ ).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));
2507
2638
  }
2508
2639
 
2509
2640
  // src/cli/dataset-stats.ts
@@ -2934,8 +3065,31 @@ async function handleCsvShow(options) {
2934
3065
  `);
2935
3066
  }
2936
3067
  function registerCsvCommands(program) {
2937
- const csv = program.command("csv").description("Inspect local CSV files.");
2938
- csv.command("show").description("Display rows from a CSV file in json, csv, or table form.").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);
3068
+ const csv = program.command("csv").description("Inspect local CSV files.").addHelpText(
3069
+ "after",
3070
+ `
3071
+ Notes:
3072
+ Local-only inspection helpers. These commands do not upload CSV files or call
3073
+ Deepline APIs.
3074
+
3075
+ Examples:
3076
+ deepline csv show --csv leads.csv --rows 0:10 --format table
3077
+ deepline csv show --csv leads.csv --summary
3078
+ `
3079
+ );
3080
+ csv.command("show").description("Display rows from a CSV file in json, csv, or table form.").addHelpText(
3081
+ "after",
3082
+ `
3083
+ Notes:
3084
+ Reads a local CSV path and prints a bounded row range. --rows uses inclusive
3085
+ start:end indexes, so 0:19 prints the first 20 rows. JSON is the default format.
3086
+
3087
+ Examples:
3088
+ deepline csv show --csv leads.csv
3089
+ deepline csv show --csv leads.csv --rows 20:39 --columns name,email --format table
3090
+ deepline csv show --csv leads.csv --summary
3091
+ `
3092
+ ).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);
2939
3093
  }
2940
3094
 
2941
3095
  // src/cli/commands/db.ts
@@ -3015,8 +3169,32 @@ async function handleDbQuery(args) {
3015
3169
  return 0;
3016
3170
  }
3017
3171
  function registerDbCommands(program) {
3018
- const db = program.command("db").alias("customer-db").description("Query the tenant customer database.");
3019
- db.command("query").alias("psql").description("Run SQL against the tenant customer database.").requiredOption("--sql <sql>", "SQL statement").option("--max-rows <n>", "Maximum returned rows").option("--json", "Emit raw JSON response").action(async (options) => {
3172
+ const db = program.command("db").alias("customer-db").description("Query the tenant customer database.").addHelpText(
3173
+ "after",
3174
+ `
3175
+ Notes:
3176
+ Runs SQL against the active workspace customer database through Deepline APIs.
3177
+ Results are bounded by the server and --max-rows. Use --json for stable output.
3178
+
3179
+ Examples:
3180
+ deepline db query --sql "select * from companies limit 20"
3181
+ deepline db query --sql "select domain, name from companies limit 20" --json
3182
+ deepline db query --sql "select * from contacts" --max-rows 100 --json
3183
+ `
3184
+ );
3185
+ db.command("query").alias("psql").description("Run SQL against the tenant customer database.").addHelpText(
3186
+ "after",
3187
+ `
3188
+ Notes:
3189
+ Requires --sql. Output is a compact table in a terminal and raw JSON with
3190
+ --json or when stdout is piped. The active auth workspace determines scope.
3191
+
3192
+ Examples:
3193
+ deepline db query --sql "select * from companies limit 20"
3194
+ deepline db query --sql "select domain, name from companies limit 20" --json
3195
+ deepline db psql --sql "select count(*) from contacts" --json
3196
+ `
3197
+ ).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) => {
3020
3198
  process.exitCode = await handleDbQuery([
3021
3199
  "--sql",
3022
3200
  options.sql,
@@ -3042,9 +3220,29 @@ async function handleFeedback(text, options) {
3042
3220
  process.stdout.write("Feedback submitted. Thank you.\n");
3043
3221
  }
3044
3222
  function registerFeedbackCommands(program) {
3045
- const feedback = program.command("feedback").description("Submit CLI feedback to Deepline.");
3223
+ const feedback = program.command("feedback").description("Submit CLI feedback to Deepline.").addHelpText(
3224
+ "after",
3225
+ `
3226
+ Notes:
3227
+ Sends the feedback text plus local CLI environment info to Deepline support.
3228
+ Use --command and --payload to attach a reproducible command shape.
3229
+
3230
+ Examples:
3231
+ deepline feedback "plays run failed after upload" --command "deepline plays run my.play.ts --watch"
3232
+ deepline feedback "unexpected billing output" --payload '{"command":"billing usage"}' --json
3233
+ `
3234
+ );
3046
3235
  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);
3047
- program.command("provide-feedback").description("Legacy alias for `deepline 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);
3236
+ program.command("provide-feedback").description("Legacy alias for `deepline feedback`.").addHelpText(
3237
+ "after",
3238
+ `
3239
+ Notes:
3240
+ Compatibility alias. Prefer deepline feedback in new scripts and docs.
3241
+
3242
+ Examples:
3243
+ deepline feedback "tools search returned stale results" --json
3244
+ `
3245
+ ).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);
3048
3246
  }
3049
3247
 
3050
3248
  // src/cli/commands/org.ts
@@ -3124,9 +3322,43 @@ async function handleOrgSwitch(selection, options) {
3124
3322
  `);
3125
3323
  }
3126
3324
  function registerOrgCommands(program) {
3127
- const org = program.command("org").description("List and switch organizations.");
3128
- org.command("list").description("List your organizations.").option("--json", "Emit JSON output").action(handleOrgList);
3129
- org.command("switch [selection]").description("Switch to another organization and save the new API key in the host auth file.").option("--org-id <id>", "Switch using an explicit organization id").option("--json", "Emit JSON output").action(handleOrgSwitch);
3325
+ const org = program.command("org").description("List and switch organizations.").addHelpText(
3326
+ "after",
3327
+ `
3328
+ Notes:
3329
+ Organizations are workspaces. Switching organizations mutates the saved host
3330
+ auth file so later CLI commands target the selected workspace.
3331
+
3332
+ Examples:
3333
+ deepline org list --json
3334
+ deepline org switch 2
3335
+ deepline org switch --org-id org_123 --json
3336
+ `
3337
+ );
3338
+ org.command("list").description("List your organizations.").addHelpText(
3339
+ "after",
3340
+ `
3341
+ Notes:
3342
+ Read-only. Marks the active organization when the server returns that metadata.
3343
+
3344
+ Examples:
3345
+ deepline org list
3346
+ deepline org list --json
3347
+ `
3348
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgList);
3349
+ org.command("switch [selection]").description("Switch to another organization and save the new API key in the host auth file.").addHelpText(
3350
+ "after",
3351
+ `
3352
+ Notes:
3353
+ Mutates the saved host auth file. Selection can be a list number, exact
3354
+ organization name, or organization id. Without a selection, prints choices.
3355
+
3356
+ Examples:
3357
+ deepline org switch
3358
+ deepline org switch 2
3359
+ deepline org switch --org-id org_123 --json
3360
+ `
3361
+ ).option("--org-id <id>", "Switch using an explicit organization id").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgSwitch);
3130
3362
  }
3131
3363
 
3132
3364
  // src/cli/commands/play.ts
@@ -6072,7 +6304,7 @@ function parsePlayRunOptions(args) {
6072
6304
  let input = null;
6073
6305
  let revisionId = null;
6074
6306
  let revisionSelector = null;
6075
- const watch = args.includes("--watch");
6307
+ const watch = args.includes("--watch") || args.includes("--wait");
6076
6308
  let jsonOutput = watch ? args.includes("--json") : argsWantJson(args);
6077
6309
  const emitLogs = !jsonOutput || args.includes("--logs");
6078
6310
  const force = args.includes("--force");
@@ -6122,15 +6354,13 @@ function parsePlayRunOptions(args) {
6122
6354
  if (arg === "--watch") {
6123
6355
  continue;
6124
6356
  }
6357
+ if (arg === "--wait") {
6358
+ continue;
6359
+ }
6125
6360
  if (arg === "--json") {
6126
6361
  jsonOutput = true;
6127
6362
  continue;
6128
6363
  }
6129
- if (arg === "--wait") {
6130
- throw new Error(
6131
- "--wait is removed for `plays run`; use `--watch` to stream completion output."
6132
- );
6133
- }
6134
6364
  if (arg === "--tail") {
6135
6365
  throw new Error(
6136
6366
  "--tail is removed for `plays run`; use `--watch` to stream completion output."
@@ -7245,12 +7475,15 @@ Concepts:
7245
7475
  Plays are durable cloud workflows.
7246
7476
  Stable ctx.tools.execute({ id, tool, input }) calls are replay-safe.
7247
7477
  ctx.map adds row keys and row progress.
7478
+ Named play runs use the live revision unless --latest or --revision-id is set.
7479
+ Running a local file does not make it live; use set-live/publish explicitly.
7248
7480
 
7249
7481
  Common commands:
7250
7482
  deepline plays search email --json
7251
7483
  deepline plays describe person-linkedin-to-email --json
7252
7484
  deepline plays check my.play.ts
7253
7485
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
7486
+ deepline plays set-live my.play.ts --json
7254
7487
  deepline plays get person-linkedin-to-email --json
7255
7488
  `
7256
7489
  );
@@ -7280,9 +7513,11 @@ Notes:
7280
7513
  Unknown --foo and --foo.bar flags are treated as play input args.
7281
7514
  File args accept local paths; the CLI stages files before submit.
7282
7515
  --watch prints logs, previews, stats, and next commands.
7516
+ --wait is accepted as a compatibility alias for --watch.
7283
7517
  The play page opens in your browser as soon as the run starts; use --no-open
7284
7518
  to only print the URL.
7285
7519
  --force supersedes active runs; it does not bypass completed reuse.
7520
+ This command starts cloud work and may spend Deepline credits through tool calls.
7286
7521
 
7287
7522
  Idempotent execution:
7288
7523
  Stable tool call ids are the reuse key:
@@ -7307,6 +7542,7 @@ Idempotent execution:
7307
7542
 
7308
7543
  Examples:
7309
7544
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
7545
+ deepline plays run my.play.ts --input @input.json --wait --json
7310
7546
  deepline plays run person-linkedin-to-email --input '{"linkedin_url":"..."}' --watch
7311
7547
  deepline plays run enrich.play.ts --csv leads.csv --watch --out leads-enriched.csv
7312
7548
  deepline plays run cto-search.play.ts --limit 5 --watch
@@ -7318,7 +7554,7 @@ Examples:
7318
7554
  ).option(
7319
7555
  "--out <path>",
7320
7556
  "Write the completed row output to CSV; requires --watch"
7321
- ).option("--watch", "Stream logs until completion").option(
7557
+ ).option("--watch", "Stream logs until completion").option("--wait", "Alias for --watch; stream logs until completion").option(
7322
7558
  "--logs",
7323
7559
  "When output is non-interactive, stream play logs to stderr while waiting"
7324
7560
  ).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) => {
@@ -7341,7 +7577,7 @@ Examples:
7341
7577
  ...options.latest ? ["--latest"] : [],
7342
7578
  ...options.revisionId ? ["--revision-id", options.revisionId] : [],
7343
7579
  ...options.out ? ["--out", options.out] : [],
7344
- ...options.watch ? ["--watch"] : [],
7580
+ ...options.watch || options.wait ? ["--watch"] : [],
7345
7581
  ...options.logs ? ["--logs"] : [],
7346
7582
  ...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
7347
7583
  ...options.force ? ["--force"] : [],
@@ -7372,12 +7608,36 @@ Examples:
7372
7608
  ...options.out ? ["--out", options.out] : []
7373
7609
  ]);
7374
7610
  });
7375
- play.command("list").description("List saved and prebuilt plays.").option("--json", "Emit JSON output").action(async (options) => {
7611
+ play.command("list").description("List saved and prebuilt plays.").addHelpText(
7612
+ "after",
7613
+ `
7614
+ Notes:
7615
+ Inventory command for saved org plays and prebuilt plays. Use search for
7616
+ ranked discovery by task or schema.
7617
+
7618
+ Examples:
7619
+ deepline plays list
7620
+ deepline plays list --json
7621
+ deepline plays search email --origin prebuilt --json
7622
+ `
7623
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
7376
7624
  process.exitCode = await handlePlayList([
7377
7625
  ...options.json ? ["--json"] : []
7378
7626
  ]);
7379
7627
  });
7380
- play.command("search <query>").description("Search saved and prebuilt plays.").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) => {
7628
+ play.command("search <query>").description("Search saved and prebuilt plays.").addHelpText(
7629
+ "after",
7630
+ `
7631
+ Notes:
7632
+ Ranked discovery for workflows. Use --origin prebuilt or --origin owned when
7633
+ you need to narrow results. Use describe on a result before running it.
7634
+
7635
+ Examples:
7636
+ deepline plays search email
7637
+ deepline plays search "linkedin to email" --origin prebuilt --compact --json
7638
+ deepline plays describe person-linkedin-to-email --json
7639
+ `
7640
+ ).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) => {
7381
7641
  process.exitCode = await handlePlaySearch([
7382
7642
  query,
7383
7643
  ...options.origin ? ["--origin", options.origin] : [],
@@ -7403,13 +7663,53 @@ Examples:
7403
7663
  ...options.json ? ["--json"] : []
7404
7664
  ]);
7405
7665
  });
7406
- play.command("versions").description("List revisions for a named play.").option("--name <name>", "Saved play name").option("--json", "Emit JSON output").action(async (options) => {
7666
+ play.command("versions").description("List revisions for a named play.").addHelpText(
7667
+ "after",
7668
+ `
7669
+ Notes:
7670
+ Shows saved revisions for an org-owned play, including which revision is live
7671
+ when that metadata is available. Named runs use the live revision by default.
7672
+
7673
+ Examples:
7674
+ deepline plays versions --name my-play
7675
+ deepline plays versions --name my-play --json
7676
+ deepline plays run my-play --revision-id <revision-id> --watch
7677
+ `
7678
+ ).option("--name <name>", "Saved play name").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
7407
7679
  process.exitCode = await handlePlayVersions([
7408
7680
  ...options.name ? ["--name", options.name] : [],
7409
7681
  ...options.json ? ["--json"] : []
7410
7682
  ]);
7411
7683
  });
7412
- play.command("publish <target>").description("Bundle, validate, save, and publish a play.").option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output").action(async (target, options) => {
7684
+ const addPublishHelp = (command) => command.addHelpText(
7685
+ "after",
7686
+ `
7687
+ Notes:
7688
+ Mutates cloud state. For a local file, this bundles, validates, saves a new
7689
+ revision, and promotes that revision live. For a saved play, --latest or
7690
+ --revision-id promotes an existing saved revision live.
7691
+ Running a local file with plays run does not publish it.
7692
+
7693
+ Examples:
7694
+ deepline plays set-live my.play.ts --json
7695
+ deepline plays set-live my-play --latest --json
7696
+ deepline plays set-live my-play --revision-id <revision-id> --json
7697
+ deepline plays publish my.play.ts --json
7698
+ `
7699
+ );
7700
+ addPublishHelp(
7701
+ play.command("publish <target>").description("Bundle, validate, save, and promote a play revision live.")
7702
+ ).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) => {
7703
+ process.exitCode = await handlePlayPublish([
7704
+ target,
7705
+ ...options.latest ? ["--latest"] : [],
7706
+ ...options.revisionId ? ["--revision-id", options.revisionId] : [],
7707
+ ...options.json ? ["--json"] : []
7708
+ ]);
7709
+ });
7710
+ addPublishHelp(
7711
+ play.command("set-live <target>").description("Promote a local file or saved revision as the live play revision.")
7712
+ ).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) => {
7413
7713
  process.exitCode = await handlePlayPublish([
7414
7714
  target,
7415
7715
  ...options.latest ? ["--latest"] : [],
@@ -7417,7 +7717,18 @@ Examples:
7417
7717
  ...options.json ? ["--json"] : []
7418
7718
  ]);
7419
7719
  });
7420
- play.command("delete <target>").description("Delete an org-owned play and its saved revisions/runs.").option("-y, --yes", "Confirm deletion").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
7720
+ play.command("delete <target>").description("Delete an org-owned play and its saved revisions/runs.").addHelpText(
7721
+ "after",
7722
+ `
7723
+ Notes:
7724
+ Destructive mutation. Deletes an org-owned play plus saved revisions and run
7725
+ records. Prebuilt/read-only plays are refused. Use --yes for noninteractive runs.
7726
+
7727
+ Examples:
7728
+ deepline plays delete my-play
7729
+ deepline plays delete my-play --yes --json
7730
+ `
7731
+ ).option("-y, --yes", "Confirm deletion").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
7421
7732
  process.exitCode = await handlePlayDelete([
7422
7733
  target,
7423
7734
  ...options.yes ? ["--yes"] : [],
@@ -7427,6 +7738,12 @@ Examples:
7427
7738
  const runs = program.command("runs").description("Inspect, tail, stop, and export play runs.").addHelpText(
7428
7739
  "after",
7429
7740
  `
7741
+ Concepts:
7742
+ A run is one execution instance of a play. It has status, progress, logs,
7743
+ preview output, recovery metadata, and optional full row export.
7744
+ tail reads the live stream. logs fetches persisted logs after the fact.
7745
+ stop mutates cloud state by requesting cancellation.
7746
+
7430
7747
  Examples:
7431
7748
  deepline runs get play/my-play/run/20260501t000000-000 --json
7432
7749
  deepline runs tail play/my-play/run/20260501t000000-000
@@ -7436,14 +7753,36 @@ Examples:
7436
7753
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
7437
7754
  `
7438
7755
  );
7439
- runs.command("get <runId>").description("Get status, progress, outputs, errors, and recovery metadata for a play run.").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) => {
7756
+ runs.command("get <runId>").description("Get status, progress, outputs, errors, and recovery metadata for a play run.").addHelpText(
7757
+ "after",
7758
+ `
7759
+ Notes:
7760
+ Full run status read. Use --full --json when debugging raw stream/status fields.
7761
+
7762
+ Examples:
7763
+ deepline runs get play/my-play/run/20260501t000000-000
7764
+ deepline runs get play/my-play/run/20260501t000000-000 --json
7765
+ deepline runs get play/my-play/run/20260501t000000-000 --full --json
7766
+ `
7767
+ ).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) => {
7440
7768
  process.exitCode = await handleRunGet([
7441
7769
  runId,
7442
7770
  ...options.json ? ["--json"] : [],
7443
7771
  ...options.full ? ["--full"] : []
7444
7772
  ]);
7445
7773
  });
7446
- runs.command("list").description("List play runs.").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) => {
7774
+ runs.command("list").description("List play runs.").addHelpText(
7775
+ "after",
7776
+ `
7777
+ Notes:
7778
+ Bounded inventory for a play's recent runs. Use --compact for agent loops.
7779
+ Common statuses include running, completed, failed, and stopped.
7780
+
7781
+ Examples:
7782
+ deepline runs list --play my-play
7783
+ deepline runs list --play my-play --status failed --compact --json
7784
+ `
7785
+ ).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) => {
7447
7786
  process.exitCode = await handleRunsList([
7448
7787
  "--play",
7449
7788
  options.play,
@@ -7452,14 +7791,37 @@ Examples:
7452
7791
  ...options.json ? ["--json"] : []
7453
7792
  ]);
7454
7793
  });
7455
- runs.command("tail <runId>").description("Read the canonical live stream for a play run.").option("--json", "Emit JSON output. Also automatic when stdout is piped").option("--compact", "Drop verbose fields from JSON output").action(async (runId, options) => {
7794
+ runs.command("tail <runId>").description("Read the canonical live stream for a play run.").addHelpText(
7795
+ "after",
7796
+ `
7797
+ Notes:
7798
+ Streams live run events until the stream ends. Use get for current status and
7799
+ logs for persisted log history.
7800
+
7801
+ Examples:
7802
+ deepline runs tail play/my-play/run/20260501t000000-000
7803
+ deepline runs tail play/my-play/run/20260501t000000-000 --compact --json
7804
+ `
7805
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").option("--compact", "Drop verbose fields from JSON output").action(async (runId, options) => {
7456
7806
  process.exitCode = await handleRunTail([
7457
7807
  runId,
7458
7808
  ...options.json ? ["--json"] : [],
7459
7809
  ...options.compact ? ["--compact"] : []
7460
7810
  ]);
7461
7811
  });
7462
- runs.command("logs <runId>").description("Fetch persisted logs for a play run.").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) => {
7812
+ runs.command("logs <runId>").description("Fetch persisted logs for a play run.").addHelpText(
7813
+ "after",
7814
+ `
7815
+ Notes:
7816
+ Prints a bounded recent log preview by default. Use --out to write the full
7817
+ persisted log stream to a local file.
7818
+
7819
+ Examples:
7820
+ deepline runs logs play/my-play/run/20260501t000000-000
7821
+ deepline runs logs play/my-play/run/20260501t000000-000 --limit 500
7822
+ deepline runs logs play/my-play/run/20260501t000000-000 --out run.log --json
7823
+ `
7824
+ ).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) => {
7463
7825
  process.exitCode = await handleRunLogs([
7464
7826
  runId,
7465
7827
  ...options.limit ? ["--limit", options.limit] : [],
@@ -7467,14 +7829,36 @@ Examples:
7467
7829
  ...options.json ? ["--json"] : []
7468
7830
  ]);
7469
7831
  });
7470
- runs.command("stop <runId>").description("Stop a play run.").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) => {
7832
+ runs.command("stop <runId>").description("Stop a play run.").addHelpText(
7833
+ "after",
7834
+ `
7835
+ Notes:
7836
+ Mutates cloud state by requesting cancellation for an active run. Already
7837
+ terminal runs are returned as no-ops by the server when applicable.
7838
+
7839
+ Examples:
7840
+ deepline runs stop play/my-play/run/20260501t000000-000 --reason "stale lock"
7841
+ deepline runs stop play/my-play/run/20260501t000000-000 --json
7842
+ `
7843
+ ).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) => {
7471
7844
  process.exitCode = await handleRunStop([
7472
7845
  runId,
7473
7846
  ...options.reason ? ["--reason", options.reason] : [],
7474
7847
  ...options.json ? ["--json"] : []
7475
7848
  ]);
7476
7849
  });
7477
- runs.command("export <runId>").description("Export the completed row output for a play run to CSV.").requiredOption("--out <path>", "Output CSV path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
7850
+ runs.command("export <runId>").description("Export the completed row output for a play run to CSV.").addHelpText(
7851
+ "after",
7852
+ `
7853
+ Notes:
7854
+ Writes the completed row output to the requested local CSV path. Use runs get
7855
+ first when you need to confirm the run is complete or inspect preview output.
7856
+
7857
+ Examples:
7858
+ deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
7859
+ deepline runs export play/my-play/run/20260501t000000-000 --out output.csv --json
7860
+ `
7861
+ ).requiredOption("--out <path>", "Output CSV path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
7478
7862
  process.exitCode = await handleRunExport([
7479
7863
  runId,
7480
7864
  "--out",
@@ -7718,16 +8102,44 @@ Concepts:
7718
8102
 
7719
8103
  Common commands:
7720
8104
  deepline tools search email --json
7721
- deepline tools get hunter_email_verifier --json
8105
+ deepline tools describe hunter_email_verifier --json
7722
8106
  deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
8107
+
8108
+ Output:
8109
+ Search/list output is bounded. Use describe for a compact contract and get for
8110
+ the full machine-readable metadata available for the tool.
7723
8111
  `
7724
8112
  );
7725
- tools.command("list").description("List available tools.").option("--json", "Emit JSON output").action(async (options) => {
8113
+ tools.command("list").description("List available tools.").addHelpText(
8114
+ "after",
8115
+ `
8116
+ Notes:
8117
+ Inventory command for known tool ids. Use search for ranked discovery by
8118
+ intent, aliases, descriptions, and schema fields.
8119
+
8120
+ Examples:
8121
+ deepline tools list
8122
+ deepline tools list --json
8123
+ deepline tools search email --json
8124
+ `
8125
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
7726
8126
  process.exitCode = await listTools([
7727
8127
  ...options.json ? ["--json"] : []
7728
8128
  ]);
7729
8129
  });
7730
- tools.command("search <query>").description("Search available tools.").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) => {
8130
+ tools.command("search <query>").description("Search available tools.").addHelpText(
8131
+ "after",
8132
+ `
8133
+ Notes:
8134
+ Ranked discovery for atomic provider/API operations. Results include tool ids
8135
+ that can be passed to deepline tools describe or deepline tools call.
8136
+
8137
+ Examples:
8138
+ deepline tools search email
8139
+ deepline tools search "company enrichment" --categories enrichment --json
8140
+ deepline tools search verifier --search-mode v2 --json
8141
+ `
8142
+ ).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) => {
7731
8143
  process.exitCode = await searchTools(query, {
7732
8144
  json: options.json,
7733
8145
  categories: options.categories,
@@ -7736,15 +8148,18 @@ Common commands:
7736
8148
  includeSearchDebug: Boolean(options.includeSearchDebug)
7737
8149
  });
7738
8150
  });
7739
- tools.command("get <toolId>").alias("describe").description("Show metadata for a tool.").addHelpText(
8151
+ const addToolMetadataCommand = (command, preferredExample) => command.description("Show metadata for a tool.").addHelpText(
7740
8152
  "after",
7741
8153
  `
7742
8154
  Notes:
7743
- Shows the tool contract, input schema, output schema, costs, aliases, and metadata.
8155
+ Shows the tool contract, input schema, output schema, Deepline cost, aliases,
8156
+ and metadata. describe is the preferred discovery verb; get is kept as a
8157
+ compatibility command for the same metadata surface.
7744
8158
 
7745
8159
  Examples:
7746
- deepline tools get hunter_email_verifier
7747
- deepline tools get hunter_email_verifier --json | jq '.inputSchema'
8160
+ deepline tools ${preferredExample} hunter_email_verifier
8161
+ deepline tools ${preferredExample} hunter_email_verifier --json | jq '.inputSchema'
8162
+ deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
7748
8163
  `
7749
8164
  ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (toolId, options) => {
7750
8165
  process.exitCode = await getTool([
@@ -7752,12 +8167,16 @@ Examples:
7752
8167
  ...options.json ? ["--json"] : []
7753
8168
  ]);
7754
8169
  });
8170
+ addToolMetadataCommand(tools.command("describe <toolId>"), "describe");
8171
+ addToolMetadataCommand(tools.command("get <toolId>"), "get");
7755
8172
  tools.command("call <toolId>").alias("execute").alias("run").description("Execute a tool by id.").addHelpText(
7756
8173
  "after",
7757
8174
  `
7758
8175
  Notes:
7759
8176
  Use tools for one atomic provider/API operation. Use plays for composed workflows,
7760
8177
  waterfalls, row maps, checkpoints, and retries.
8178
+ Calling a provider-backed tool can spend Deepline credits. Use --json for the
8179
+ stable result payload and --full-output when debugging response metadata.
7761
8180
 
7762
8181
  Examples:
7763
8182
  deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
@@ -8443,6 +8862,9 @@ function shouldPrintStartupPhase() {
8443
8862
  return false;
8444
8863
  }
8445
8864
  const args = process.argv.slice(2);
8865
+ if (args.includes("-h") || args.includes("--help")) {
8866
+ return false;
8867
+ }
8446
8868
  const command = args[0];
8447
8869
  const subcommand = args[1];
8448
8870
  return (command === "play" || command === "plays") && subcommand === "run";
@@ -8476,9 +8898,23 @@ Common commands:
8476
8898
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
8477
8899
  deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
8478
8900
 
8901
+ Product model:
8902
+ Tools are atomic provider/API operations that may spend credits.
8903
+ Plays are durable workflows backed by source code or saved cloud revisions.
8904
+ Runs are execution instances with logs, status, outputs, and cancellation.
8905
+ Live plays are promoted revisions used by named play runs.
8906
+
8479
8907
  Output:
8480
8908
  Structured commands print human-readable output in a terminal and JSON when stdout is piped.
8481
8909
  Use --json to force JSON in an interactive terminal.
8910
+
8911
+ Safety:
8912
+ Commands that mutate state, open a browser, write files, stop work, or spend credits say so in their help.
8913
+ Use --no-open where available for CI and agent runs.
8914
+
8915
+ Exit codes:
8916
+ 0 success; 2 usage/local input error; 3 auth/permission error; 4 not found;
8917
+ 5 server/runtime/provider failure; 7 validation/check failed.
8482
8918
  `
8483
8919
  );
8484
8920
  program.hook("preAction", async (_thisCommand, actionCommand) => {
@@ -8513,7 +8949,17 @@ Output:
8513
8949
  registerCsvCommands(program);
8514
8950
  registerDbCommands(program);
8515
8951
  registerFeedbackCommands(program);
8516
- program.command("health").description("Check server health.").action(async () => {
8952
+ program.command("health").description("Check server health.").addHelpText(
8953
+ "after",
8954
+ `
8955
+ Notes:
8956
+ Read-only connectivity check for the configured Deepline host. Prints the raw
8957
+ server health payload as JSON.
8958
+
8959
+ Examples:
8960
+ deepline health
8961
+ `
8962
+ ).action(async () => {
8517
8963
  try {
8518
8964
  const client = new DeeplineClient();
8519
8965
  const data = await client.health();
@@ -8525,7 +8971,18 @@ Output:
8525
8971
  );
8526
8972
  }
8527
8973
  });
8528
- program.command("version").description("Show version.").action(() => {
8974
+ program.command("version").description("Show version.").addHelpText(
8975
+ "after",
8976
+ `
8977
+ Notes:
8978
+ Prints the SDK CLI package version. The top-level -v/--version flag returns
8979
+ the same version.
8980
+
8981
+ Examples:
8982
+ deepline version
8983
+ deepline --version
8984
+ `
8985
+ ).action(() => {
8529
8986
  process.stdout.write(`deepline ${SDK_VERSION}
8530
8987
  `);
8531
8988
  });