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.
package/dist/cli/index.js CHANGED
@@ -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.23";
269
+ var SDK_VERSION = "0.1.24";
270
270
  var SDK_API_CONTRACT = "2026-05-runs-v2";
271
271
 
272
272
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -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.").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) => {
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.").option("--timeout <seconds>", "Maximum seconds to wait", "300").action(async (options) => {
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
  ]);
@@ -2513,15 +2543,116 @@ async function handleRedeemCode(code, options) {
2513
2543
  `);
2514
2544
  }
2515
2545
  function registerBillingCommands(program) {
2516
- const billing = program.command("billing").description("Inspect balance, usage, limits, and checkout flows.");
2517
- billing.command("balance").description("Show current billing balance.").option("--json", "Emit JSON output").action(handleBalance);
2518
- 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);
2519
- billing.command("limit").description("Show configured monthly limit state.").option("--json", "Emit JSON output").action(handleLimit);
2520
- billing.command("set-limit").description("Set monthly credit cap.").argument("<credits>", "Monthly credits limit").option("--json", "Emit JSON output").action(handleSetLimit);
2521
- billing.command("off").description("Disable monthly credit cap.").option("--json", "Emit JSON output").action(handleLimitOff);
2522
- 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);
2523
- 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);
2524
- 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));
2546
+ const billing = program.command("billing").description("Inspect balance, usage, limits, and checkout flows.").addHelpText(
2547
+ "after",
2548
+ `
2549
+ Concepts:
2550
+ Billing commands show Deepline credits, not raw provider spend.
2551
+ set-limit/off mutate the monthly workspace cap. checkout/redeem-code can open
2552
+ a browser unless --no-open is set.
2553
+
2554
+ Examples:
2555
+ deepline billing balance --json
2556
+ deepline billing usage --limit 20 --json
2557
+ deepline billing set-limit 500 --json
2558
+ deepline billing checkout --credits 1000 --no-open --json
2559
+ `
2560
+ );
2561
+ billing.command("balance").description("Show current billing balance.").addHelpText(
2562
+ "after",
2563
+ `
2564
+ Notes:
2565
+ Read-only. Shows the current Deepline credit balance for the active workspace.
2566
+
2567
+ Examples:
2568
+ deepline billing balance
2569
+ deepline billing balance --json
2570
+ `
2571
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleBalance);
2572
+ billing.command("usage").description("Show current usage plus recent calls.").addHelpText(
2573
+ "after",
2574
+ `
2575
+ Notes:
2576
+ Read-only. Shows last-30-day Deepline credit usage plus a bounded recent-call
2577
+ page. Use --limit/--offset to paginate the recent-call section.
2578
+
2579
+ Examples:
2580
+ deepline billing usage
2581
+ deepline billing usage --limit 50 --offset 50 --json
2582
+ `
2583
+ ).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);
2584
+ billing.command("limit").description("Show configured monthly limit state.").addHelpText(
2585
+ "after",
2586
+ `
2587
+ Notes:
2588
+ Read-only. Shows whether the monthly workspace cap is enabled and how many
2589
+ Deepline credits remain before the cap.
2590
+
2591
+ Examples:
2592
+ deepline billing limit
2593
+ deepline billing limit --json
2594
+ `
2595
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLimit);
2596
+ billing.command("set-limit").description("Set monthly credit cap.").addHelpText(
2597
+ "after",
2598
+ `
2599
+ Notes:
2600
+ Mutates workspace billing settings. The argument is a Deepline credit amount,
2601
+ not dollars and not provider credits.
2602
+
2603
+ Examples:
2604
+ deepline billing set-limit 500
2605
+ deepline billing set-limit 500 --json
2606
+ `
2607
+ ).argument("<credits>", "Monthly credits limit").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleSetLimit);
2608
+ billing.command("off").description("Disable monthly credit cap.").addHelpText(
2609
+ "after",
2610
+ `
2611
+ Notes:
2612
+ Mutates workspace billing settings by removing the monthly Deepline credit cap.
2613
+
2614
+ Examples:
2615
+ deepline billing off
2616
+ deepline billing off --json
2617
+ `
2618
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLimitOff);
2619
+ billing.command("history").description("Export billing ledger history to CSV.").addHelpText(
2620
+ "after",
2621
+ `
2622
+ Notes:
2623
+ Read-only server query that writes a local CSV file. With --json, stdout is a
2624
+ summary containing the output path and row count.
2625
+
2626
+ Examples:
2627
+ deepline billing history --time 1m
2628
+ deepline billing history --time 1y --json
2629
+ `
2630
+ ).requiredOption("--time <window>", "Rolling time window: 1d, 1w, 1m, or 1y").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleHistory);
2631
+ billing.command("checkout").description("Create a checkout session and optionally open it in your browser.").addHelpText(
2632
+ "after",
2633
+ `
2634
+ Notes:
2635
+ Creates a payment checkout session. Opens the checkout URL in a browser unless
2636
+ --no-open is set. Use --json for automation.
2637
+
2638
+ Examples:
2639
+ deepline billing checkout --tier pro
2640
+ deepline billing checkout --credits 1000 --no-open --json
2641
+ deepline billing checkout --credits 1000 --discount-code LAUNCH --no-open
2642
+ `
2643
+ ).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);
2644
+ billing.command("redeem-code").description("Redeem a billing code.").addHelpText(
2645
+ "after",
2646
+ `
2647
+ Notes:
2648
+ Redeems a workspace billing code and may open a browser for completion unless
2649
+ --no-open is set.
2650
+
2651
+ Examples:
2652
+ deepline billing redeem-code --code ABC123
2653
+ deepline billing redeem-code --code ABC123 --no-open --json
2654
+ `
2655
+ ).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
2656
  }
2526
2657
 
2527
2658
  // src/cli/dataset-stats.ts
@@ -2952,8 +3083,31 @@ async function handleCsvShow(options) {
2952
3083
  `);
2953
3084
  }
2954
3085
  function registerCsvCommands(program) {
2955
- const csv = program.command("csv").description("Inspect local CSV files.");
2956
- 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);
3086
+ const csv = program.command("csv").description("Inspect local CSV files.").addHelpText(
3087
+ "after",
3088
+ `
3089
+ Notes:
3090
+ Local-only inspection helpers. These commands do not upload CSV files or call
3091
+ Deepline APIs.
3092
+
3093
+ Examples:
3094
+ deepline csv show --csv leads.csv --rows 0:10 --format table
3095
+ deepline csv show --csv leads.csv --summary
3096
+ `
3097
+ );
3098
+ csv.command("show").description("Display rows from a CSV file in json, csv, or table form.").addHelpText(
3099
+ "after",
3100
+ `
3101
+ Notes:
3102
+ Reads a local CSV path and prints a bounded row range. --rows uses inclusive
3103
+ start:end indexes, so 0:19 prints the first 20 rows. JSON is the default format.
3104
+
3105
+ Examples:
3106
+ deepline csv show --csv leads.csv
3107
+ deepline csv show --csv leads.csv --rows 20:39 --columns name,email --format table
3108
+ deepline csv show --csv leads.csv --summary
3109
+ `
3110
+ ).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
3111
  }
2958
3112
 
2959
3113
  // src/cli/commands/db.ts
@@ -3033,8 +3187,32 @@ async function handleDbQuery(args) {
3033
3187
  return 0;
3034
3188
  }
3035
3189
  function registerDbCommands(program) {
3036
- const db = program.command("db").alias("customer-db").description("Query the tenant customer database.");
3037
- 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) => {
3190
+ const db = program.command("db").alias("customer-db").description("Query the tenant customer database.").addHelpText(
3191
+ "after",
3192
+ `
3193
+ Notes:
3194
+ Runs SQL against the active workspace customer database through Deepline APIs.
3195
+ Results are bounded by the server and --max-rows. Use --json for stable output.
3196
+
3197
+ Examples:
3198
+ deepline db query --sql "select * from companies limit 20"
3199
+ deepline db query --sql "select domain, name from companies limit 20" --json
3200
+ deepline db query --sql "select * from contacts" --max-rows 100 --json
3201
+ `
3202
+ );
3203
+ db.command("query").alias("psql").description("Run SQL against the tenant customer database.").addHelpText(
3204
+ "after",
3205
+ `
3206
+ Notes:
3207
+ Requires --sql. Output is a compact table in a terminal and raw JSON with
3208
+ --json or when stdout is piped. The active auth workspace determines scope.
3209
+
3210
+ Examples:
3211
+ deepline db query --sql "select * from companies limit 20"
3212
+ deepline db query --sql "select domain, name from companies limit 20" --json
3213
+ deepline db psql --sql "select count(*) from contacts" --json
3214
+ `
3215
+ ).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
3216
  process.exitCode = await handleDbQuery([
3039
3217
  "--sql",
3040
3218
  options.sql,
@@ -3060,9 +3238,29 @@ async function handleFeedback(text, options) {
3060
3238
  process.stdout.write("Feedback submitted. Thank you.\n");
3061
3239
  }
3062
3240
  function registerFeedbackCommands(program) {
3063
- const feedback = program.command("feedback").description("Submit CLI feedback to Deepline.");
3241
+ const feedback = program.command("feedback").description("Submit CLI feedback to Deepline.").addHelpText(
3242
+ "after",
3243
+ `
3244
+ Notes:
3245
+ Sends the feedback text plus local CLI environment info to Deepline support.
3246
+ Use --command and --payload to attach a reproducible command shape.
3247
+
3248
+ Examples:
3249
+ deepline feedback "plays run failed after upload" --command "deepline plays run my.play.ts --watch"
3250
+ deepline feedback "unexpected billing output" --payload '{"command":"billing usage"}' --json
3251
+ `
3252
+ );
3064
3253
  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`.").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);
3254
+ program.command("provide-feedback").description("Legacy alias for `deepline feedback`.").addHelpText(
3255
+ "after",
3256
+ `
3257
+ Notes:
3258
+ Compatibility alias. Prefer deepline feedback in new scripts and docs.
3259
+
3260
+ Examples:
3261
+ deepline feedback "tools search returned stale results" --json
3262
+ `
3263
+ ).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
3264
  }
3067
3265
 
3068
3266
  // src/cli/commands/org.ts
@@ -3142,9 +3340,43 @@ async function handleOrgSwitch(selection, options) {
3142
3340
  `);
3143
3341
  }
3144
3342
  function registerOrgCommands(program) {
3145
- const org = program.command("org").description("List and switch organizations.");
3146
- org.command("list").description("List your organizations.").option("--json", "Emit JSON output").action(handleOrgList);
3147
- 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);
3343
+ const org = program.command("org").description("List and switch organizations.").addHelpText(
3344
+ "after",
3345
+ `
3346
+ Notes:
3347
+ Organizations are workspaces. Switching organizations mutates the saved host
3348
+ auth file so later CLI commands target the selected workspace.
3349
+
3350
+ Examples:
3351
+ deepline org list --json
3352
+ deepline org switch 2
3353
+ deepline org switch --org-id org_123 --json
3354
+ `
3355
+ );
3356
+ org.command("list").description("List your organizations.").addHelpText(
3357
+ "after",
3358
+ `
3359
+ Notes:
3360
+ Read-only. Marks the active organization when the server returns that metadata.
3361
+
3362
+ Examples:
3363
+ deepline org list
3364
+ deepline org list --json
3365
+ `
3366
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgList);
3367
+ org.command("switch [selection]").description("Switch to another organization and save the new API key in the host auth file.").addHelpText(
3368
+ "after",
3369
+ `
3370
+ Notes:
3371
+ Mutates the saved host auth file. Selection can be a list number, exact
3372
+ organization name, or organization id. Without a selection, prints choices.
3373
+
3374
+ Examples:
3375
+ deepline org switch
3376
+ deepline org switch 2
3377
+ deepline org switch --org-id org_123 --json
3378
+ `
3379
+ ).option("--org-id <id>", "Switch using an explicit organization id").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgSwitch);
3148
3380
  }
3149
3381
 
3150
3382
  // src/cli/commands/play.ts
@@ -6086,7 +6318,7 @@ function parsePlayRunOptions(args) {
6086
6318
  let input = null;
6087
6319
  let revisionId = null;
6088
6320
  let revisionSelector = null;
6089
- const watch = args.includes("--watch");
6321
+ const watch = args.includes("--watch") || args.includes("--wait");
6090
6322
  let jsonOutput = watch ? args.includes("--json") : argsWantJson(args);
6091
6323
  const emitLogs = !jsonOutput || args.includes("--logs");
6092
6324
  const force = args.includes("--force");
@@ -6136,15 +6368,13 @@ function parsePlayRunOptions(args) {
6136
6368
  if (arg === "--watch") {
6137
6369
  continue;
6138
6370
  }
6371
+ if (arg === "--wait") {
6372
+ continue;
6373
+ }
6139
6374
  if (arg === "--json") {
6140
6375
  jsonOutput = true;
6141
6376
  continue;
6142
6377
  }
6143
- if (arg === "--wait") {
6144
- throw new Error(
6145
- "--wait is removed for `plays run`; use `--watch` to stream completion output."
6146
- );
6147
- }
6148
6378
  if (arg === "--tail") {
6149
6379
  throw new Error(
6150
6380
  "--tail is removed for `plays run`; use `--watch` to stream completion output."
@@ -7259,12 +7489,15 @@ Concepts:
7259
7489
  Plays are durable cloud workflows.
7260
7490
  Stable ctx.tools.execute({ id, tool, input }) calls are replay-safe.
7261
7491
  ctx.map adds row keys and row progress.
7492
+ Named play runs use the live revision unless --latest or --revision-id is set.
7493
+ Running a local file does not make it live; use set-live/publish explicitly.
7262
7494
 
7263
7495
  Common commands:
7264
7496
  deepline plays search email --json
7265
7497
  deepline plays describe person-linkedin-to-email --json
7266
7498
  deepline plays check my.play.ts
7267
7499
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
7500
+ deepline plays set-live my.play.ts --json
7268
7501
  deepline plays get person-linkedin-to-email --json
7269
7502
  `
7270
7503
  );
@@ -7294,9 +7527,11 @@ Notes:
7294
7527
  Unknown --foo and --foo.bar flags are treated as play input args.
7295
7528
  File args accept local paths; the CLI stages files before submit.
7296
7529
  --watch prints logs, previews, stats, and next commands.
7530
+ --wait is accepted as a compatibility alias for --watch.
7297
7531
  The play page opens in your browser as soon as the run starts; use --no-open
7298
7532
  to only print the URL.
7299
7533
  --force supersedes active runs; it does not bypass completed reuse.
7534
+ This command starts cloud work and may spend Deepline credits through tool calls.
7300
7535
 
7301
7536
  Idempotent execution:
7302
7537
  Stable tool call ids are the reuse key:
@@ -7321,6 +7556,7 @@ Idempotent execution:
7321
7556
 
7322
7557
  Examples:
7323
7558
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
7559
+ deepline plays run my.play.ts --input @input.json --wait --json
7324
7560
  deepline plays run person-linkedin-to-email --input '{"linkedin_url":"..."}' --watch
7325
7561
  deepline plays run enrich.play.ts --csv leads.csv --watch --out leads-enriched.csv
7326
7562
  deepline plays run cto-search.play.ts --limit 5 --watch
@@ -7332,7 +7568,7 @@ Examples:
7332
7568
  ).option(
7333
7569
  "--out <path>",
7334
7570
  "Write the completed row output to CSV; requires --watch"
7335
- ).option("--watch", "Stream logs until completion").option(
7571
+ ).option("--watch", "Stream logs until completion").option("--wait", "Alias for --watch; stream logs until completion").option(
7336
7572
  "--logs",
7337
7573
  "When output is non-interactive, stream play logs to stderr while waiting"
7338
7574
  ).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 +7591,7 @@ Examples:
7355
7591
  ...options.latest ? ["--latest"] : [],
7356
7592
  ...options.revisionId ? ["--revision-id", options.revisionId] : [],
7357
7593
  ...options.out ? ["--out", options.out] : [],
7358
- ...options.watch ? ["--watch"] : [],
7594
+ ...options.watch || options.wait ? ["--watch"] : [],
7359
7595
  ...options.logs ? ["--logs"] : [],
7360
7596
  ...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
7361
7597
  ...options.force ? ["--force"] : [],
@@ -7386,12 +7622,36 @@ Examples:
7386
7622
  ...options.out ? ["--out", options.out] : []
7387
7623
  ]);
7388
7624
  });
7389
- play.command("list").description("List saved and prebuilt plays.").option("--json", "Emit JSON output").action(async (options) => {
7625
+ play.command("list").description("List saved and prebuilt plays.").addHelpText(
7626
+ "after",
7627
+ `
7628
+ Notes:
7629
+ Inventory command for saved org plays and prebuilt plays. Use search for
7630
+ ranked discovery by task or schema.
7631
+
7632
+ Examples:
7633
+ deepline plays list
7634
+ deepline plays list --json
7635
+ deepline plays search email --origin prebuilt --json
7636
+ `
7637
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
7390
7638
  process.exitCode = await handlePlayList([
7391
7639
  ...options.json ? ["--json"] : []
7392
7640
  ]);
7393
7641
  });
7394
- 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) => {
7642
+ play.command("search <query>").description("Search saved and prebuilt plays.").addHelpText(
7643
+ "after",
7644
+ `
7645
+ Notes:
7646
+ Ranked discovery for workflows. Use --origin prebuilt or --origin owned when
7647
+ you need to narrow results. Use describe on a result before running it.
7648
+
7649
+ Examples:
7650
+ deepline plays search email
7651
+ deepline plays search "linkedin to email" --origin prebuilt --compact --json
7652
+ deepline plays describe person-linkedin-to-email --json
7653
+ `
7654
+ ).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
7655
  process.exitCode = await handlePlaySearch([
7396
7656
  query,
7397
7657
  ...options.origin ? ["--origin", options.origin] : [],
@@ -7417,13 +7677,53 @@ Examples:
7417
7677
  ...options.json ? ["--json"] : []
7418
7678
  ]);
7419
7679
  });
7420
- play.command("versions").description("List revisions for a named play.").option("--name <name>", "Saved play name").option("--json", "Emit JSON output").action(async (options) => {
7680
+ play.command("versions").description("List revisions for a named play.").addHelpText(
7681
+ "after",
7682
+ `
7683
+ Notes:
7684
+ Shows saved revisions for an org-owned play, including which revision is live
7685
+ when that metadata is available. Named runs use the live revision by default.
7686
+
7687
+ Examples:
7688
+ deepline plays versions --name my-play
7689
+ deepline plays versions --name my-play --json
7690
+ deepline plays run my-play --revision-id <revision-id> --watch
7691
+ `
7692
+ ).option("--name <name>", "Saved play name").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
7421
7693
  process.exitCode = await handlePlayVersions([
7422
7694
  ...options.name ? ["--name", options.name] : [],
7423
7695
  ...options.json ? ["--json"] : []
7424
7696
  ]);
7425
7697
  });
7426
- 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) => {
7698
+ const addPublishHelp = (command) => command.addHelpText(
7699
+ "after",
7700
+ `
7701
+ Notes:
7702
+ Mutates cloud state. For a local file, this bundles, validates, saves a new
7703
+ revision, and promotes that revision live. For a saved play, --latest or
7704
+ --revision-id promotes an existing saved revision live.
7705
+ Running a local file with plays run does not publish it.
7706
+
7707
+ Examples:
7708
+ deepline plays set-live my.play.ts --json
7709
+ deepline plays set-live my-play --latest --json
7710
+ deepline plays set-live my-play --revision-id <revision-id> --json
7711
+ deepline plays publish my.play.ts --json
7712
+ `
7713
+ );
7714
+ addPublishHelp(
7715
+ play.command("publish <target>").description("Bundle, validate, save, and promote a play revision live.")
7716
+ ).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) => {
7717
+ process.exitCode = await handlePlayPublish([
7718
+ target,
7719
+ ...options.latest ? ["--latest"] : [],
7720
+ ...options.revisionId ? ["--revision-id", options.revisionId] : [],
7721
+ ...options.json ? ["--json"] : []
7722
+ ]);
7723
+ });
7724
+ addPublishHelp(
7725
+ play.command("set-live <target>").description("Promote a local file or saved revision as the live play revision.")
7726
+ ).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
7727
  process.exitCode = await handlePlayPublish([
7428
7728
  target,
7429
7729
  ...options.latest ? ["--latest"] : [],
@@ -7431,7 +7731,18 @@ Examples:
7431
7731
  ...options.json ? ["--json"] : []
7432
7732
  ]);
7433
7733
  });
7434
- 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) => {
7734
+ play.command("delete <target>").description("Delete an org-owned play and its saved revisions/runs.").addHelpText(
7735
+ "after",
7736
+ `
7737
+ Notes:
7738
+ Destructive mutation. Deletes an org-owned play plus saved revisions and run
7739
+ records. Prebuilt/read-only plays are refused. Use --yes for noninteractive runs.
7740
+
7741
+ Examples:
7742
+ deepline plays delete my-play
7743
+ deepline plays delete my-play --yes --json
7744
+ `
7745
+ ).option("-y, --yes", "Confirm deletion").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
7435
7746
  process.exitCode = await handlePlayDelete([
7436
7747
  target,
7437
7748
  ...options.yes ? ["--yes"] : [],
@@ -7441,6 +7752,12 @@ Examples:
7441
7752
  const runs = program.command("runs").description("Inspect, tail, stop, and export play runs.").addHelpText(
7442
7753
  "after",
7443
7754
  `
7755
+ Concepts:
7756
+ A run is one execution instance of a play. It has status, progress, logs,
7757
+ preview output, recovery metadata, and optional full row export.
7758
+ tail reads the live stream. logs fetches persisted logs after the fact.
7759
+ stop mutates cloud state by requesting cancellation.
7760
+
7444
7761
  Examples:
7445
7762
  deepline runs get play/my-play/run/20260501t000000-000 --json
7446
7763
  deepline runs tail play/my-play/run/20260501t000000-000
@@ -7450,14 +7767,36 @@ Examples:
7450
7767
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
7451
7768
  `
7452
7769
  );
7453
- 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) => {
7770
+ runs.command("get <runId>").description("Get status, progress, outputs, errors, and recovery metadata for a play run.").addHelpText(
7771
+ "after",
7772
+ `
7773
+ Notes:
7774
+ Full run status read. Use --full --json when debugging raw stream/status fields.
7775
+
7776
+ Examples:
7777
+ deepline runs get play/my-play/run/20260501t000000-000
7778
+ deepline runs get play/my-play/run/20260501t000000-000 --json
7779
+ deepline runs get play/my-play/run/20260501t000000-000 --full --json
7780
+ `
7781
+ ).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
7782
  process.exitCode = await handleRunGet([
7455
7783
  runId,
7456
7784
  ...options.json ? ["--json"] : [],
7457
7785
  ...options.full ? ["--full"] : []
7458
7786
  ]);
7459
7787
  });
7460
- 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) => {
7788
+ runs.command("list").description("List play runs.").addHelpText(
7789
+ "after",
7790
+ `
7791
+ Notes:
7792
+ Bounded inventory for a play's recent runs. Use --compact for agent loops.
7793
+ Common statuses include running, completed, failed, and stopped.
7794
+
7795
+ Examples:
7796
+ deepline runs list --play my-play
7797
+ deepline runs list --play my-play --status failed --compact --json
7798
+ `
7799
+ ).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
7800
  process.exitCode = await handleRunsList([
7462
7801
  "--play",
7463
7802
  options.play,
@@ -7466,14 +7805,37 @@ Examples:
7466
7805
  ...options.json ? ["--json"] : []
7467
7806
  ]);
7468
7807
  });
7469
- 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) => {
7808
+ runs.command("tail <runId>").description("Read the canonical live stream for a play run.").addHelpText(
7809
+ "after",
7810
+ `
7811
+ Notes:
7812
+ Streams live run events until the stream ends. Use get for current status and
7813
+ logs for persisted log history.
7814
+
7815
+ Examples:
7816
+ deepline runs tail play/my-play/run/20260501t000000-000
7817
+ deepline runs tail play/my-play/run/20260501t000000-000 --compact --json
7818
+ `
7819
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").option("--compact", "Drop verbose fields from JSON output").action(async (runId, options) => {
7470
7820
  process.exitCode = await handleRunTail([
7471
7821
  runId,
7472
7822
  ...options.json ? ["--json"] : [],
7473
7823
  ...options.compact ? ["--compact"] : []
7474
7824
  ]);
7475
7825
  });
7476
- 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) => {
7826
+ runs.command("logs <runId>").description("Fetch persisted logs for a play run.").addHelpText(
7827
+ "after",
7828
+ `
7829
+ Notes:
7830
+ Prints a bounded recent log preview by default. Use --out to write the full
7831
+ persisted log stream to a local file.
7832
+
7833
+ Examples:
7834
+ deepline runs logs play/my-play/run/20260501t000000-000
7835
+ deepline runs logs play/my-play/run/20260501t000000-000 --limit 500
7836
+ deepline runs logs play/my-play/run/20260501t000000-000 --out run.log --json
7837
+ `
7838
+ ).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
7839
  process.exitCode = await handleRunLogs([
7478
7840
  runId,
7479
7841
  ...options.limit ? ["--limit", options.limit] : [],
@@ -7481,14 +7843,36 @@ Examples:
7481
7843
  ...options.json ? ["--json"] : []
7482
7844
  ]);
7483
7845
  });
7484
- 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) => {
7846
+ runs.command("stop <runId>").description("Stop a play run.").addHelpText(
7847
+ "after",
7848
+ `
7849
+ Notes:
7850
+ Mutates cloud state by requesting cancellation for an active run. Already
7851
+ terminal runs are returned as no-ops by the server when applicable.
7852
+
7853
+ Examples:
7854
+ deepline runs stop play/my-play/run/20260501t000000-000 --reason "stale lock"
7855
+ deepline runs stop play/my-play/run/20260501t000000-000 --json
7856
+ `
7857
+ ).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
7858
  process.exitCode = await handleRunStop([
7486
7859
  runId,
7487
7860
  ...options.reason ? ["--reason", options.reason] : [],
7488
7861
  ...options.json ? ["--json"] : []
7489
7862
  ]);
7490
7863
  });
7491
- 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) => {
7864
+ runs.command("export <runId>").description("Export the completed row output for a play run to CSV.").addHelpText(
7865
+ "after",
7866
+ `
7867
+ Notes:
7868
+ Writes the completed row output to the requested local CSV path. Use runs get
7869
+ first when you need to confirm the run is complete or inspect preview output.
7870
+
7871
+ Examples:
7872
+ deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
7873
+ deepline runs export play/my-play/run/20260501t000000-000 --out output.csv --json
7874
+ `
7875
+ ).requiredOption("--out <path>", "Output CSV path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (runId, options) => {
7492
7876
  process.exitCode = await handleRunExport([
7493
7877
  runId,
7494
7878
  "--out",
@@ -7732,16 +8116,44 @@ Concepts:
7732
8116
 
7733
8117
  Common commands:
7734
8118
  deepline tools search email --json
7735
- deepline tools get hunter_email_verifier --json
8119
+ deepline tools describe hunter_email_verifier --json
7736
8120
  deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
8121
+
8122
+ Output:
8123
+ Search/list output is bounded. Use describe for a compact contract and get for
8124
+ the full machine-readable metadata available for the tool.
7737
8125
  `
7738
8126
  );
7739
- tools.command("list").description("List available tools.").option("--json", "Emit JSON output").action(async (options) => {
8127
+ tools.command("list").description("List available tools.").addHelpText(
8128
+ "after",
8129
+ `
8130
+ Notes:
8131
+ Inventory command for known tool ids. Use search for ranked discovery by
8132
+ intent, aliases, descriptions, and schema fields.
8133
+
8134
+ Examples:
8135
+ deepline tools list
8136
+ deepline tools list --json
8137
+ deepline tools search email --json
8138
+ `
8139
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
7740
8140
  process.exitCode = await listTools([
7741
8141
  ...options.json ? ["--json"] : []
7742
8142
  ]);
7743
8143
  });
7744
- 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) => {
8144
+ tools.command("search <query>").description("Search available tools.").addHelpText(
8145
+ "after",
8146
+ `
8147
+ Notes:
8148
+ Ranked discovery for atomic provider/API operations. Results include tool ids
8149
+ that can be passed to deepline tools describe or deepline tools call.
8150
+
8151
+ Examples:
8152
+ deepline tools search email
8153
+ deepline tools search "company enrichment" --categories enrichment --json
8154
+ deepline tools search verifier --search-mode v2 --json
8155
+ `
8156
+ ).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
8157
  process.exitCode = await searchTools(query, {
7746
8158
  json: options.json,
7747
8159
  categories: options.categories,
@@ -7750,15 +8162,18 @@ Common commands:
7750
8162
  includeSearchDebug: Boolean(options.includeSearchDebug)
7751
8163
  });
7752
8164
  });
7753
- tools.command("get <toolId>").alias("describe").description("Show metadata for a tool.").addHelpText(
8165
+ const addToolMetadataCommand = (command, preferredExample) => command.description("Show metadata for a tool.").addHelpText(
7754
8166
  "after",
7755
8167
  `
7756
8168
  Notes:
7757
- Shows the tool contract, input schema, output schema, costs, aliases, and metadata.
8169
+ Shows the tool contract, input schema, output schema, Deepline cost, aliases,
8170
+ and metadata. describe is the preferred discovery verb; get is kept as a
8171
+ compatibility command for the same metadata surface.
7758
8172
 
7759
8173
  Examples:
7760
- deepline tools get hunter_email_verifier
7761
- deepline tools get hunter_email_verifier --json | jq '.inputSchema'
8174
+ deepline tools ${preferredExample} hunter_email_verifier
8175
+ deepline tools ${preferredExample} hunter_email_verifier --json | jq '.inputSchema'
8176
+ deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
7762
8177
  `
7763
8178
  ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (toolId, options) => {
7764
8179
  process.exitCode = await getTool([
@@ -7766,12 +8181,16 @@ Examples:
7766
8181
  ...options.json ? ["--json"] : []
7767
8182
  ]);
7768
8183
  });
8184
+ addToolMetadataCommand(tools.command("describe <toolId>"), "describe");
8185
+ addToolMetadataCommand(tools.command("get <toolId>"), "get");
7769
8186
  tools.command("call <toolId>").alias("execute").alias("run").description("Execute a tool by id.").addHelpText(
7770
8187
  "after",
7771
8188
  `
7772
8189
  Notes:
7773
8190
  Use tools for one atomic provider/API operation. Use plays for composed workflows,
7774
8191
  waterfalls, row maps, checkpoints, and retries.
8192
+ Calling a provider-backed tool can spend Deepline credits. Use --json for the
8193
+ stable result payload and --full-output when debugging response metadata.
7775
8194
 
7776
8195
  Examples:
7777
8196
  deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
@@ -8457,6 +8876,9 @@ function shouldPrintStartupPhase() {
8457
8876
  return false;
8458
8877
  }
8459
8878
  const args = process.argv.slice(2);
8879
+ if (args.includes("-h") || args.includes("--help")) {
8880
+ return false;
8881
+ }
8460
8882
  const command = args[0];
8461
8883
  const subcommand = args[1];
8462
8884
  return (command === "play" || command === "plays") && subcommand === "run";
@@ -8490,9 +8912,23 @@ Common commands:
8490
8912
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}' --watch
8491
8913
  deepline tools call hunter_email_verifier --input '{"email":"a@b.com"}'
8492
8914
 
8915
+ Product model:
8916
+ Tools are atomic provider/API operations that may spend credits.
8917
+ Plays are durable workflows backed by source code or saved cloud revisions.
8918
+ Runs are execution instances with logs, status, outputs, and cancellation.
8919
+ Live plays are promoted revisions used by named play runs.
8920
+
8493
8921
  Output:
8494
8922
  Structured commands print human-readable output in a terminal and JSON when stdout is piped.
8495
8923
  Use --json to force JSON in an interactive terminal.
8924
+
8925
+ Safety:
8926
+ Commands that mutate state, open a browser, write files, stop work, or spend credits say so in their help.
8927
+ Use --no-open where available for CI and agent runs.
8928
+
8929
+ Exit codes:
8930
+ 0 success; 2 usage/local input error; 3 auth/permission error; 4 not found;
8931
+ 5 server/runtime/provider failure; 7 validation/check failed.
8496
8932
  `
8497
8933
  );
8498
8934
  program.hook("preAction", async (_thisCommand, actionCommand) => {
@@ -8527,7 +8963,17 @@ Output:
8527
8963
  registerCsvCommands(program);
8528
8964
  registerDbCommands(program);
8529
8965
  registerFeedbackCommands(program);
8530
- program.command("health").description("Check server health.").action(async () => {
8966
+ program.command("health").description("Check server health.").addHelpText(
8967
+ "after",
8968
+ `
8969
+ Notes:
8970
+ Read-only connectivity check for the configured Deepline host. Prints the raw
8971
+ server health payload as JSON.
8972
+
8973
+ Examples:
8974
+ deepline health
8975
+ `
8976
+ ).action(async () => {
8531
8977
  try {
8532
8978
  const client = new DeeplineClient();
8533
8979
  const data = await client.health();
@@ -8539,7 +8985,18 @@ Output:
8539
8985
  );
8540
8986
  }
8541
8987
  });
8542
- program.command("version").description("Show version.").action(() => {
8988
+ program.command("version").description("Show version.").addHelpText(
8989
+ "after",
8990
+ `
8991
+ Notes:
8992
+ Prints the SDK CLI package version. The top-level -v/--version flag returns
8993
+ the same version.
8994
+
8995
+ Examples:
8996
+ deepline version
8997
+ deepline --version
8998
+ `
8999
+ ).action(() => {
8543
9000
  process.stdout.write(`deepline ${SDK_VERSION}
8544
9001
  `);
8545
9002
  });