deepline 0.1.40 → 0.1.42

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
@@ -216,8 +216,8 @@ function resolveConfig(options) {
216
216
  }
217
217
 
218
218
  // src/version.ts
219
- var SDK_VERSION = "0.1.40";
220
- var SDK_API_CONTRACT = "2026-05-cloud-play-search";
219
+ var SDK_VERSION = "0.1.42";
220
+ var SDK_API_CONTRACT = "2026-05-play-tool-result-errors";
221
221
 
222
222
  // ../shared_libs/play-runtime/coordinator-headers.ts
223
223
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
@@ -7483,6 +7483,126 @@ function shouldUseLocalOnlyPlayCheck() {
7483
7483
  const value = process.env.DEEPLINE_PLAY_CHECK_LOCAL_ONLY?.trim().toLowerCase();
7484
7484
  return value === "1" || value === "true" || value === "yes" || value === "on";
7485
7485
  }
7486
+ function isRecord3(value) {
7487
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
7488
+ }
7489
+ function stringValue(value) {
7490
+ return typeof value === "string" ? value.trim() : "";
7491
+ }
7492
+ function asArray(value) {
7493
+ return Array.isArray(value) ? value : [];
7494
+ }
7495
+ function extractionEntries(value) {
7496
+ if (Array.isArray(value)) return value.filter(isRecord3);
7497
+ if (!isRecord3(value)) return [];
7498
+ return Object.entries(value).map(
7499
+ ([name, entry]) => isRecord3(entry) ? { name, ...entry } : { name }
7500
+ );
7501
+ }
7502
+ function firstRawPath(entry) {
7503
+ const details = isRecord3(entry.details) ? entry.details : {};
7504
+ const paths = [
7505
+ ...asArray(details.rawToolOutputPaths),
7506
+ ...asArray(details.raw_tool_output_paths),
7507
+ ...asArray(details.candidatePaths),
7508
+ ...asArray(details.candidate_paths)
7509
+ ].map(stringValue).filter(Boolean);
7510
+ return paths[0];
7511
+ }
7512
+ function checkHintExpression(value) {
7513
+ return stringValue(value).replace(/^toolExecutionResult\./, "result.");
7514
+ }
7515
+ function checkHintRawPath(value) {
7516
+ return value?.replace(/^toolResponse\./, "result.toolResponse.");
7517
+ }
7518
+ function collectStaticPipelineToolIds(staticPipeline) {
7519
+ const seen = /* @__PURE__ */ new Set();
7520
+ const visitPipeline = (pipeline) => {
7521
+ if (!isRecord3(pipeline)) return;
7522
+ for (const step of [
7523
+ ...asArray(pipeline.stages),
7524
+ ...asArray(pipeline.substeps)
7525
+ ]) {
7526
+ if (!isRecord3(step)) continue;
7527
+ if (step.type === "tool") {
7528
+ const toolId = stringValue(step.toolId) || stringValue(step.tool);
7529
+ if (toolId) seen.add(toolId);
7530
+ }
7531
+ if (step.type === "play_call") {
7532
+ visitPipeline(step.pipeline);
7533
+ }
7534
+ }
7535
+ };
7536
+ visitPipeline(staticPipeline);
7537
+ return [...seen].sort();
7538
+ }
7539
+ function toolGetterHintFromMetadata(toolId, tool) {
7540
+ const usageGuidance = isRecord3(tool.usageGuidance) ? tool.usageGuidance : {};
7541
+ const resultGuidance = isRecord3(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord3(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
7542
+ const toolResponse = isRecord3(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord3(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
7543
+ const lists = extractionEntries(
7544
+ resultGuidance.extractedLists ?? resultGuidance.extracted_lists
7545
+ ).map((entry) => ({
7546
+ name: stringValue(entry.name),
7547
+ expression: checkHintExpression(entry.expression),
7548
+ raw: checkHintRawPath(firstRawPath(entry))
7549
+ })).filter((entry) => entry.name && entry.expression);
7550
+ const values = extractionEntries(
7551
+ resultGuidance.extractedValues ?? resultGuidance.extracted_values
7552
+ ).map((entry) => ({
7553
+ name: stringValue(entry.name),
7554
+ expression: checkHintExpression(entry.expression),
7555
+ raw: checkHintRawPath(firstRawPath(entry))
7556
+ })).filter((entry) => entry.name && entry.expression);
7557
+ return {
7558
+ toolId,
7559
+ lists,
7560
+ values,
7561
+ raw: checkHintExpression(toolResponse.raw) || "result.toolResponse.raw"
7562
+ };
7563
+ }
7564
+ async function buildToolGetterHints(client, staticPipeline) {
7565
+ const toolIds = collectStaticPipelineToolIds(staticPipeline);
7566
+ return Promise.all(
7567
+ toolIds.map(async (toolId) => {
7568
+ try {
7569
+ const tool = await client.getTool(toolId);
7570
+ return toolGetterHintFromMetadata(toolId, tool);
7571
+ } catch (error) {
7572
+ return {
7573
+ toolId,
7574
+ lists: [],
7575
+ values: [],
7576
+ raw: "result.toolResponse.raw",
7577
+ unavailable: error instanceof Error ? error.message : String(error)
7578
+ };
7579
+ }
7580
+ })
7581
+ );
7582
+ }
7583
+ function printToolGetterHints(hints) {
7584
+ if (!hints?.length) return;
7585
+ console.log(" Tool result getter hints:");
7586
+ for (const hint of hints) {
7587
+ console.log(` ${hint.toolId} output:`);
7588
+ if (hint.lists.length) {
7589
+ for (const entry of hint.lists) {
7590
+ const raw = entry.raw ? ` (raw: ${entry.raw})` : "";
7591
+ console.log(` - list ${entry.name}: ${entry.expression}${raw}`);
7592
+ }
7593
+ }
7594
+ if (hint.values.length) {
7595
+ const valueNames = hint.values.map((entry) => entry.name).join(", ");
7596
+ console.log(` - values: ${valueNames}`);
7597
+ for (const entry of hint.values) {
7598
+ const raw = entry.raw ? ` (raw: ${entry.raw})` : "";
7599
+ console.log(` ${entry.name}: ${entry.expression}${raw}`);
7600
+ }
7601
+ }
7602
+ if (hint.raw) console.log(` - raw: ${hint.raw}`);
7603
+ if (hint.unavailable) console.log(` - warning: ${hint.unavailable}`);
7604
+ }
7605
+ }
7486
7606
  async function handlePlayCheck(args) {
7487
7607
  const options = parsePlayCheckOptions(args);
7488
7608
  if (!isFileTarget(options.target)) {
@@ -7513,6 +7633,7 @@ async function handlePlayCheck(args) {
7513
7633
  valid: true,
7514
7634
  errors: [],
7515
7635
  staticPipeline: graph.root.compilerManifest?.staticPipeline ?? null,
7636
+ toolGetterHints: [],
7516
7637
  artifactHash: graph.root.artifact.artifactHash,
7517
7638
  graphHash: graph.root.artifact.graphHash
7518
7639
  };
@@ -7522,6 +7643,7 @@ async function handlePlayCheck(args) {
7522
7643
  } else {
7523
7644
  console.log(`\u2713 ${playName} passed local play check`);
7524
7645
  console.log(` artifact: ${result2.artifactHash.slice(0, 12)}`);
7646
+ printToolGetterHints(result2.toolGetterHints);
7525
7647
  }
7526
7648
  return 0;
7527
7649
  }
@@ -7532,21 +7654,27 @@ async function handlePlayCheck(args) {
7532
7654
  sourceFiles: graph.root.sourceFiles,
7533
7655
  artifact: graph.root.artifact
7534
7656
  });
7657
+ const enrichedResult = {
7658
+ ...result,
7659
+ toolGetterHints: result.toolGetterHints ?? await buildToolGetterHints(client, result.staticPipeline)
7660
+ };
7535
7661
  if (options.jsonOutput) {
7536
- process.stdout.write(`${JSON.stringify({ name: playName, ...result })}
7662
+ process.stdout.write(`${JSON.stringify({ name: playName, ...enrichedResult })}
7537
7663
  `);
7538
- } else if (result.valid) {
7664
+ } else if (enrichedResult.valid) {
7539
7665
  console.log(`\u2713 ${playName} passed cloud play check`);
7540
- if (result.artifactHash) {
7541
- console.log(` artifact: ${result.artifactHash.slice(0, 12)}`);
7666
+ if (enrichedResult.artifactHash) {
7667
+ console.log(` artifact: ${enrichedResult.artifactHash.slice(0, 12)}`);
7542
7668
  }
7669
+ printToolGetterHints(enrichedResult.toolGetterHints);
7543
7670
  } else {
7544
7671
  console.error(`\u2717 ${playName} failed cloud play check`);
7545
- for (const error of result.errors) {
7672
+ for (const error of enrichedResult.errors) {
7546
7673
  console.error(` ${error}`);
7547
7674
  }
7675
+ printToolGetterHints(enrichedResult.toolGetterHints);
7548
7676
  }
7549
- return result.valid ? 0 : 1;
7677
+ return enrichedResult.valid ? 0 : 1;
7550
7678
  }
7551
7679
  async function handleFileBackedRun(options) {
7552
7680
  if (options.target.kind !== "file") {
@@ -8649,7 +8777,7 @@ Pass-through input flags:
8649
8777
  ...options.logs ? ["--logs"] : [],
8650
8778
  ...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
8651
8779
  ...options.force ? ["--force"] : [],
8652
- ...options.open === false ? ["--no-open"] : [],
8780
+ ...options.noOpen || options.open === false ? ["--no-open"] : [],
8653
8781
  ...options.json ? ["--json"] : [],
8654
8782
  ...passthroughArgs
8655
8783
  ]);
@@ -9105,6 +9233,15 @@ function extractSummaryFields(payload) {
9105
9233
 
9106
9234
  // src/cli/commands/tools.ts
9107
9235
  function toListedTool(tool) {
9236
+ if (isPlayLikeTool(tool)) {
9237
+ const playReference = playReferenceForTool(tool);
9238
+ return {
9239
+ ...tool,
9240
+ id: tool.toolId,
9241
+ type: "play",
9242
+ executeCommand: `deepline plays run ${playReference} --input '{...}' --watch`
9243
+ };
9244
+ }
9108
9245
  return {
9109
9246
  ...tool,
9110
9247
  id: tool.toolId,
@@ -9143,11 +9280,12 @@ async function searchTools(queryInput, options = {}) {
9143
9280
  searchMode: options.searchMode,
9144
9281
  includeSearchDebug: options.includeSearchDebug
9145
9282
  });
9146
- const items = result.tools.map(toListedTool);
9283
+ const items = result.tools.filter((tool) => !isPlayLikeTool(tool)).map(toListedTool);
9147
9284
  const envelope = {
9148
9285
  ...result,
9149
9286
  tools: items,
9150
9287
  count: items.length,
9288
+ omitted_plays_hint: "Use `deepline plays search <query> --json` for prebuilt and org-owned plays.",
9151
9289
  render: {
9152
9290
  sections: [
9153
9291
  {
@@ -9160,6 +9298,10 @@ async function searchTools(queryInput, options = {}) {
9160
9298
  ...item.inputSchema ? [" inputSchema: yes"] : []
9161
9299
  ];
9162
9300
  })
9301
+ },
9302
+ {
9303
+ title: "plays",
9304
+ lines: ["For prebuilt or org-owned workflows, run: deepline plays search <query>"]
9163
9305
  }
9164
9306
  ]
9165
9307
  }
@@ -9178,13 +9320,36 @@ async function findPlayForToolId(client, toolId) {
9178
9320
  const plays = await client.searchPlays({ query: requested, compact: true });
9179
9321
  return plays.find((play) => playIdentifiers(play).includes(requested)) ?? null;
9180
9322
  }
9181
- function printPlayAliasToolError(toolId, play) {
9323
+ function playAliasToolErrorMessage(toolId, play) {
9182
9324
  const playName = play.reference ?? play.name;
9183
- console.error(
9184
- `${toolId} is a play, not a tool.
9325
+ return `${toolId} is a play, not a tool.
9185
9326
  Use: deepline plays run ${playName} --input '{...}' --watch
9186
- Inspect its schema with: deepline plays describe ${playName} --json`
9187
- );
9327
+ Inspect its schema with: deepline plays describe ${playName} --json`;
9328
+ }
9329
+ function printPlayAliasToolError(toolId, play) {
9330
+ console.error(playAliasToolErrorMessage(toolId, play));
9331
+ }
9332
+ function isPlayLikeTool(tool) {
9333
+ const record = tool;
9334
+ if (record.isPlay === true || record.is_play === true) return true;
9335
+ const playExpansion = recordField(record, "playExpansion", "play_expansion");
9336
+ if (Object.keys(playExpansion).length > 0) return true;
9337
+ const toolId = typeof record.toolId === "string" ? record.toolId : "";
9338
+ return toolId.endsWith("_waterfall");
9339
+ }
9340
+ function playReferenceForTool(tool) {
9341
+ const record = tool;
9342
+ const toolId = typeof record.toolId === "string" ? record.toolId : "play";
9343
+ return `prebuilt/${toolId.replace(/_/g, "-")}`;
9344
+ }
9345
+ function playLikeToolExecuteErrorMessage(toolId) {
9346
+ const playReference = `prebuilt/${toolId.replace(/_/g, "-")}`;
9347
+ return `${toolId} is a workflow/play entry, not an atomic provider tool.
9348
+ Use: deepline plays run ${playReference} --input '{...}' --watch
9349
+ Or search provider tools only with: deepline tools search "<query>" --json`;
9350
+ }
9351
+ function printPlayLikeToolExecuteError(toolId) {
9352
+ console.error(playLikeToolExecuteErrorMessage(toolId));
9188
9353
  }
9189
9354
  function registerToolsCommands(program) {
9190
9355
  const tools = program.command("tools").description("Search, describe, and execute atomic provider tools.").addHelpText(
@@ -9359,7 +9524,7 @@ function printToolDetails(tool, requestedToolId) {
9359
9524
  const operation = typeof tool.operation === "string" ? tool.operation : "";
9360
9525
  const displayBase = operation && operation.startsWith(`${tool.provider}_`) ? operation.slice(String(tool.provider).length + 1) : operation ? `${tool.provider} ${operation}`.trim() : toolId;
9361
9526
  const displayName = titleCase(displayBase || String(tool.displayName || toolId));
9362
- const cost = isRecord3(tool.cost) ? tool.cost : null;
9527
+ const cost = isRecord4(tool.cost) ? tool.cost : null;
9363
9528
  const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
9364
9529
  const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
9365
9530
  const deeplineUsdPerCredit = numberField(tool, "deeplineUsdPerCredit", "deepline_usd_per_credit");
@@ -9409,7 +9574,7 @@ function printToolDetails(tool, requestedToolId) {
9409
9574
  if (stepContributions.length) {
9410
9575
  console.log(" step contributions:");
9411
9576
  for (const item of stepContributions) {
9412
- if (!isRecord3(item)) continue;
9577
+ if (!isRecord4(item)) continue;
9413
9578
  const stepTool = typeof item.tool === "string" ? item.tool.trim() : "";
9414
9579
  const low = typeof item.lowCredits === "number" ? item.lowCredits : null;
9415
9580
  const high = typeof item.highCredits === "number" ? item.highCredits : null;
@@ -9449,7 +9614,7 @@ function printToolDetails(tool, requestedToolId) {
9449
9614
  }
9450
9615
  const toolExecutionResult = recordField(usageGuidance, "toolExecutionResult");
9451
9616
  const extractedValues = arrayField(toolExecutionResult, "extractedValues", "extracted_values");
9452
- const targets = extractedValues.map((entry) => isRecord3(entry) && typeof entry.name === "string" ? entry.name : "").filter(Boolean).sort();
9617
+ const targets = extractedValues.map((entry) => isRecord4(entry) && typeof entry.name === "string" ? entry.name : "").filter(Boolean).sort();
9453
9618
  if (targets.length) {
9454
9619
  console.log(` - Built-in extract targets: ${targets.join(", ")}`);
9455
9620
  }
@@ -9490,7 +9655,7 @@ function printExtractions(label, entries) {
9490
9655
  if (!entries.length) return;
9491
9656
  console.log(` ${label}:`);
9492
9657
  for (const entry of entries) {
9493
- if (!isRecord3(entry)) continue;
9658
+ if (!isRecord4(entry)) continue;
9494
9659
  const name = stringField(entry, "name");
9495
9660
  const expression = stringField(entry, "expression");
9496
9661
  const details = recordField(entry, "details");
@@ -9530,12 +9695,12 @@ function printToolCost(input) {
9530
9695
  return false;
9531
9696
  }
9532
9697
  function toolInputFieldsForDisplay(inputSchema) {
9533
- if (Array.isArray(inputSchema.fields)) return inputSchema.fields.filter(isRecord3);
9534
- const jsonSchema = isRecord3(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
9535
- const properties = isRecord3(jsonSchema.properties) ? jsonSchema.properties : {};
9698
+ if (Array.isArray(inputSchema.fields)) return inputSchema.fields.filter(isRecord4);
9699
+ const jsonSchema = isRecord4(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
9700
+ const properties = isRecord4(jsonSchema.properties) ? jsonSchema.properties : {};
9536
9701
  const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
9537
9702
  return Object.entries(properties).map(([name, value]) => {
9538
- const property = isRecord3(value) ? value : {};
9703
+ const property = isRecord4(value) ? value : {};
9539
9704
  return {
9540
9705
  name,
9541
9706
  type: typeof property.type === "string" ? property.type : "unknown",
@@ -9562,15 +9727,15 @@ function printJsonPreview(label, payload) {
9562
9727
  }
9563
9728
  function samplePayload(samples, key) {
9564
9729
  const entry = samples[key];
9565
- if (!isRecord3(entry)) return void 0;
9730
+ if (!isRecord4(entry)) return void 0;
9566
9731
  return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
9567
9732
  }
9568
9733
  function commandEnvelopeFromRawResponse(rawResponse) {
9569
- return isRecord3(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
9734
+ return isRecord4(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
9570
9735
  }
9571
9736
  function listExtractorPathsFromUsageGuidance(tool) {
9572
9737
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
9573
- const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord3(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
9738
+ const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord4(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
9574
9739
  return extractedLists.flatMap((entry) => {
9575
9740
  const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
9576
9741
  if (!Array.isArray(paths)) return [];
@@ -9597,7 +9762,7 @@ function formatDecimal(value) {
9597
9762
  function formatUsd(value) {
9598
9763
  return `$${formatDecimal(value)}`;
9599
9764
  }
9600
- function isRecord3(value) {
9765
+ function isRecord4(value) {
9601
9766
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
9602
9767
  }
9603
9768
  function stringField(source, ...keys) {
@@ -9624,7 +9789,7 @@ function arrayField(source, ...keys) {
9624
9789
  function recordField(source, ...keys) {
9625
9790
  for (const key of keys) {
9626
9791
  const value = source[key];
9627
- if (isRecord3(value)) return value;
9792
+ if (isRecord4(value)) return value;
9628
9793
  }
9629
9794
  return {};
9630
9795
  }
@@ -9722,8 +9887,11 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
9722
9887
  // .step('phone_waterfall', (row, rowCtx) => rowCtx.runPlay('contact_phone', 'contact-to-phone', { first_name: String(row.first_name ?? ''), last_name: String(row.last_name ?? ''), email: String(row.email ?? '') }, { description: 'Resolve phone.' }))
9723
9888
  // ctx.map is idempotent by map key + row key; reruns reuse completed rows.
9724
9889
  const enrichedData = await ctx
9725
- .map('enriched_data', rows, { key: ${rowKey} })
9726
- .run({ description: 'Enrich seeded rows.' });
9890
+ .map('enriched_data', rows)
9891
+ .run({
9892
+ key: ${rowKey},
9893
+ description: 'Enrich seeded rows.',
9894
+ });
9727
9895
 
9728
9896
  return {
9729
9897
  rows: enrichedData,
@@ -9753,7 +9921,7 @@ function buildToolExecuteBaseEnvelope(input) {
9753
9921
  kind: summaryEntries.length > 0 ? "object" : "raw",
9754
9922
  summary: input.summary
9755
9923
  };
9756
- const envelopeHasCanonicalOutput = isRecord3(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
9924
+ const envelopeHasCanonicalOutput = isRecord4(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
9757
9925
  const inspectCommand = `deepline tools execute ${input.toolId} --input ${shellQuote(JSON.stringify(input.params))} --json`;
9758
9926
  const actions = input.listConversion ? [
9759
9927
  {
@@ -9813,7 +9981,11 @@ async function executeTool(args) {
9813
9981
  } catch (error) {
9814
9982
  const play = await findPlayForToolId(client, parsed.toolId);
9815
9983
  if (play) {
9816
- printPlayAliasToolError(parsed.toolId, play);
9984
+ if (argsWantJson(args)) {
9985
+ printJsonError(new Error(playAliasToolErrorMessage(parsed.toolId, play)));
9986
+ } else {
9987
+ printPlayAliasToolError(parsed.toolId, play);
9988
+ }
9817
9989
  return 2;
9818
9990
  }
9819
9991
  if (error instanceof DeeplineError) {
@@ -9821,6 +9993,14 @@ async function executeTool(args) {
9821
9993
  }
9822
9994
  throw error;
9823
9995
  }
9996
+ if (isPlayLikeTool(metadata)) {
9997
+ if (argsWantJson(args)) {
9998
+ printJsonError(new Error(playLikeToolExecuteErrorMessage(parsed.toolId)));
9999
+ } else {
10000
+ printPlayLikeToolExecuteError(parsed.toolId);
10001
+ }
10002
+ return 2;
10003
+ }
9824
10004
  const rawResponse = await client.executeTool(parsed.toolId, parsed.params);
9825
10005
  const listConversion = tryConvertToList(rawResponse, {
9826
10006
  listExtractorPaths: listExtractorPathsFromUsageGuidance(metadata)
@@ -9843,7 +10023,7 @@ async function executeTool(args) {
9843
10023
  {
9844
10024
  ...baseEnvelope,
9845
10025
  local: {
9846
- ...isRecord3(baseEnvelope.local) ? baseEnvelope.local : {},
10026
+ ...isRecord4(baseEnvelope.local) ? baseEnvelope.local : {},
9847
10027
  payload_file: jsonPath
9848
10028
  }
9849
10029
  },
@@ -10441,9 +10621,15 @@ Notes:
10441
10621
 
10442
10622
  Examples:
10443
10623
  deepline version
10624
+ deepline version --json
10444
10625
  deepline --version
10445
10626
  `
10446
- ).action(() => {
10627
+ ).option("--json", "Emit JSON output").action((options) => {
10628
+ if (options.json) {
10629
+ process.stdout.write(`${JSON.stringify({ version: SDK_VERSION })}
10630
+ `);
10631
+ return;
10632
+ }
10447
10633
  process.stdout.write(`deepline ${SDK_VERSION}
10448
10634
  `);
10449
10635
  });