deepline 0.1.36 → 0.1.38

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.36";
220
- var SDK_API_CONTRACT = "2026-05-v2-tool-response";
219
+ var SDK_VERSION = "0.1.38";
220
+ var SDK_API_CONTRACT = "2026-05-v2-tool-response-play-guardrails";
221
221
 
222
222
  // ../shared_libs/play-runtime/coordinator-headers.ts
223
223
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
@@ -7491,6 +7491,126 @@ function shouldUseLocalOnlyPlayCheck() {
7491
7491
  const value = process.env.DEEPLINE_PLAY_CHECK_LOCAL_ONLY?.trim().toLowerCase();
7492
7492
  return value === "1" || value === "true" || value === "yes" || value === "on";
7493
7493
  }
7494
+ function isRecord3(value) {
7495
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
7496
+ }
7497
+ function stringValue(value) {
7498
+ return typeof value === "string" ? value.trim() : "";
7499
+ }
7500
+ function asArray(value) {
7501
+ return Array.isArray(value) ? value : [];
7502
+ }
7503
+ function extractionEntries(value) {
7504
+ if (Array.isArray(value)) return value.filter(isRecord3);
7505
+ if (!isRecord3(value)) return [];
7506
+ return Object.entries(value).map(
7507
+ ([name, entry]) => isRecord3(entry) ? { name, ...entry } : { name }
7508
+ );
7509
+ }
7510
+ function firstRawPath(entry) {
7511
+ const details = isRecord3(entry.details) ? entry.details : {};
7512
+ const paths = [
7513
+ ...asArray(details.rawToolOutputPaths),
7514
+ ...asArray(details.raw_tool_output_paths),
7515
+ ...asArray(details.candidatePaths),
7516
+ ...asArray(details.candidate_paths)
7517
+ ].map(stringValue).filter(Boolean);
7518
+ return paths[0];
7519
+ }
7520
+ function checkHintExpression(value) {
7521
+ return stringValue(value).replace(/^toolExecutionResult\./, "result.");
7522
+ }
7523
+ function checkHintRawPath(value) {
7524
+ return value?.replace(/^toolResponse\./, "result.toolResponse.");
7525
+ }
7526
+ function collectStaticPipelineToolIds(staticPipeline) {
7527
+ const seen = /* @__PURE__ */ new Set();
7528
+ const visitPipeline = (pipeline) => {
7529
+ if (!isRecord3(pipeline)) return;
7530
+ for (const step of [
7531
+ ...asArray(pipeline.stages),
7532
+ ...asArray(pipeline.substeps)
7533
+ ]) {
7534
+ if (!isRecord3(step)) continue;
7535
+ if (step.type === "tool") {
7536
+ const toolId = stringValue(step.toolId) || stringValue(step.tool);
7537
+ if (toolId) seen.add(toolId);
7538
+ }
7539
+ if (step.type === "play_call") {
7540
+ visitPipeline(step.pipeline);
7541
+ }
7542
+ }
7543
+ };
7544
+ visitPipeline(staticPipeline);
7545
+ return [...seen].sort();
7546
+ }
7547
+ function toolGetterHintFromMetadata(toolId, tool) {
7548
+ const usageGuidance = isRecord3(tool.usageGuidance) ? tool.usageGuidance : {};
7549
+ const resultGuidance = isRecord3(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord3(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
7550
+ const toolResponse = isRecord3(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord3(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
7551
+ const lists = extractionEntries(
7552
+ resultGuidance.extractedLists ?? resultGuidance.extracted_lists
7553
+ ).map((entry) => ({
7554
+ name: stringValue(entry.name),
7555
+ expression: checkHintExpression(entry.expression),
7556
+ raw: checkHintRawPath(firstRawPath(entry))
7557
+ })).filter((entry) => entry.name && entry.expression);
7558
+ const values = extractionEntries(
7559
+ resultGuidance.extractedValues ?? resultGuidance.extracted_values
7560
+ ).map((entry) => ({
7561
+ name: stringValue(entry.name),
7562
+ expression: checkHintExpression(entry.expression),
7563
+ raw: checkHintRawPath(firstRawPath(entry))
7564
+ })).filter((entry) => entry.name && entry.expression);
7565
+ return {
7566
+ toolId,
7567
+ lists,
7568
+ values,
7569
+ raw: checkHintExpression(toolResponse.raw) || "result.toolResponse.raw"
7570
+ };
7571
+ }
7572
+ async function buildToolGetterHints(client, staticPipeline) {
7573
+ const toolIds = collectStaticPipelineToolIds(staticPipeline);
7574
+ return Promise.all(
7575
+ toolIds.map(async (toolId) => {
7576
+ try {
7577
+ const tool = await client.getTool(toolId);
7578
+ return toolGetterHintFromMetadata(toolId, tool);
7579
+ } catch (error) {
7580
+ return {
7581
+ toolId,
7582
+ lists: [],
7583
+ values: [],
7584
+ raw: "result.toolResponse.raw",
7585
+ unavailable: error instanceof Error ? error.message : String(error)
7586
+ };
7587
+ }
7588
+ })
7589
+ );
7590
+ }
7591
+ function printToolGetterHints(hints) {
7592
+ if (!hints?.length) return;
7593
+ console.log(" Tool result getter hints:");
7594
+ for (const hint of hints) {
7595
+ console.log(` ${hint.toolId} output:`);
7596
+ if (hint.lists.length) {
7597
+ for (const entry of hint.lists) {
7598
+ const raw = entry.raw ? ` (raw: ${entry.raw})` : "";
7599
+ console.log(` - list ${entry.name}: ${entry.expression}${raw}`);
7600
+ }
7601
+ }
7602
+ if (hint.values.length) {
7603
+ const valueNames = hint.values.map((entry) => entry.name).join(", ");
7604
+ console.log(` - values: ${valueNames}`);
7605
+ for (const entry of hint.values) {
7606
+ const raw = entry.raw ? ` (raw: ${entry.raw})` : "";
7607
+ console.log(` ${entry.name}: ${entry.expression}${raw}`);
7608
+ }
7609
+ }
7610
+ if (hint.raw) console.log(` - raw: ${hint.raw}`);
7611
+ if (hint.unavailable) console.log(` - warning: ${hint.unavailable}`);
7612
+ }
7613
+ }
7494
7614
  async function handlePlayCheck(args) {
7495
7615
  const options = parsePlayCheckOptions(args);
7496
7616
  if (!isFileTarget(options.target)) {
@@ -7521,6 +7641,7 @@ async function handlePlayCheck(args) {
7521
7641
  valid: true,
7522
7642
  errors: [],
7523
7643
  staticPipeline: graph.root.compilerManifest?.staticPipeline ?? null,
7644
+ toolGetterHints: [],
7524
7645
  artifactHash: graph.root.artifact.artifactHash,
7525
7646
  graphHash: graph.root.artifact.graphHash
7526
7647
  };
@@ -7530,6 +7651,7 @@ async function handlePlayCheck(args) {
7530
7651
  } else {
7531
7652
  console.log(`\u2713 ${playName} passed local play check`);
7532
7653
  console.log(` artifact: ${result2.artifactHash.slice(0, 12)}`);
7654
+ printToolGetterHints(result2.toolGetterHints);
7533
7655
  }
7534
7656
  return 0;
7535
7657
  }
@@ -7540,21 +7662,27 @@ async function handlePlayCheck(args) {
7540
7662
  sourceFiles: graph.root.sourceFiles,
7541
7663
  artifact: graph.root.artifact
7542
7664
  });
7665
+ const enrichedResult = {
7666
+ ...result,
7667
+ toolGetterHints: result.toolGetterHints ?? await buildToolGetterHints(client, result.staticPipeline)
7668
+ };
7543
7669
  if (options.jsonOutput) {
7544
- process.stdout.write(`${JSON.stringify({ name: playName, ...result })}
7670
+ process.stdout.write(`${JSON.stringify({ name: playName, ...enrichedResult })}
7545
7671
  `);
7546
- } else if (result.valid) {
7672
+ } else if (enrichedResult.valid) {
7547
7673
  console.log(`\u2713 ${playName} passed cloud play check`);
7548
- if (result.artifactHash) {
7549
- console.log(` artifact: ${result.artifactHash.slice(0, 12)}`);
7674
+ if (enrichedResult.artifactHash) {
7675
+ console.log(` artifact: ${enrichedResult.artifactHash.slice(0, 12)}`);
7550
7676
  }
7677
+ printToolGetterHints(enrichedResult.toolGetterHints);
7551
7678
  } else {
7552
7679
  console.error(`\u2717 ${playName} failed cloud play check`);
7553
- for (const error of result.errors) {
7680
+ for (const error of enrichedResult.errors) {
7554
7681
  console.error(` ${error}`);
7555
7682
  }
7683
+ printToolGetterHints(enrichedResult.toolGetterHints);
7556
7684
  }
7557
- return result.valid ? 0 : 1;
7685
+ return enrichedResult.valid ? 0 : 1;
7558
7686
  }
7559
7687
  async function handleFileBackedRun(options) {
7560
7688
  if (options.target.kind !== "file") {
@@ -8657,7 +8785,7 @@ Pass-through input flags:
8657
8785
  ...options.logs ? ["--logs"] : [],
8658
8786
  ...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
8659
8787
  ...options.force ? ["--force"] : [],
8660
- ...options.open === false ? ["--no-open"] : [],
8788
+ ...options.noOpen || options.open === false ? ["--no-open"] : [],
8661
8789
  ...options.json ? ["--json"] : [],
8662
8790
  ...passthroughArgs
8663
8791
  ]);
@@ -9113,6 +9241,15 @@ function extractSummaryFields(payload) {
9113
9241
 
9114
9242
  // src/cli/commands/tools.ts
9115
9243
  function toListedTool(tool) {
9244
+ if (isPlayLikeTool(tool)) {
9245
+ const playReference = playReferenceForTool(tool);
9246
+ return {
9247
+ ...tool,
9248
+ id: tool.toolId,
9249
+ type: "play",
9250
+ executeCommand: `deepline plays run ${playReference} --input '{...}' --watch`
9251
+ };
9252
+ }
9116
9253
  return {
9117
9254
  ...tool,
9118
9255
  id: tool.toolId,
@@ -9151,11 +9288,12 @@ async function searchTools(queryInput, options = {}) {
9151
9288
  searchMode: options.searchMode,
9152
9289
  includeSearchDebug: options.includeSearchDebug
9153
9290
  });
9154
- const items = result.tools.map(toListedTool);
9291
+ const items = result.tools.filter((tool) => !isPlayLikeTool(tool)).map(toListedTool);
9155
9292
  const envelope = {
9156
9293
  ...result,
9157
9294
  tools: items,
9158
9295
  count: items.length,
9296
+ omitted_plays_hint: "Use `deepline plays search <query> --json` for prebuilt and org-owned plays.",
9159
9297
  render: {
9160
9298
  sections: [
9161
9299
  {
@@ -9168,6 +9306,10 @@ async function searchTools(queryInput, options = {}) {
9168
9306
  ...item.inputSchema ? [" inputSchema: yes"] : []
9169
9307
  ];
9170
9308
  })
9309
+ },
9310
+ {
9311
+ title: "plays",
9312
+ lines: ["For prebuilt or org-owned workflows, run: deepline plays search <query>"]
9171
9313
  }
9172
9314
  ]
9173
9315
  }
@@ -9186,13 +9328,36 @@ async function findPlayForToolId(client, toolId) {
9186
9328
  const plays = await client.searchPlays({ query: requested, compact: true });
9187
9329
  return plays.find((play) => playIdentifiers(play).includes(requested)) ?? null;
9188
9330
  }
9189
- function printPlayAliasToolError(toolId, play) {
9331
+ function playAliasToolErrorMessage(toolId, play) {
9190
9332
  const playName = play.reference ?? play.name;
9191
- console.error(
9192
- `${toolId} is a play, not a tool.
9333
+ return `${toolId} is a play, not a tool.
9193
9334
  Use: deepline plays run ${playName} --input '{...}' --watch
9194
- Inspect its schema with: deepline plays describe ${playName} --json`
9195
- );
9335
+ Inspect its schema with: deepline plays describe ${playName} --json`;
9336
+ }
9337
+ function printPlayAliasToolError(toolId, play) {
9338
+ console.error(playAliasToolErrorMessage(toolId, play));
9339
+ }
9340
+ function isPlayLikeTool(tool) {
9341
+ const record = tool;
9342
+ if (record.isPlay === true || record.is_play === true) return true;
9343
+ const playExpansion = recordField(record, "playExpansion", "play_expansion");
9344
+ if (Object.keys(playExpansion).length > 0) return true;
9345
+ const toolId = typeof record.toolId === "string" ? record.toolId : "";
9346
+ return toolId.endsWith("_waterfall");
9347
+ }
9348
+ function playReferenceForTool(tool) {
9349
+ const record = tool;
9350
+ const toolId = typeof record.toolId === "string" ? record.toolId : "play";
9351
+ return `prebuilt/${toolId.replace(/_/g, "-")}`;
9352
+ }
9353
+ function playLikeToolExecuteErrorMessage(toolId) {
9354
+ const playReference = `prebuilt/${toolId.replace(/_/g, "-")}`;
9355
+ return `${toolId} is a workflow/play entry, not an atomic provider tool.
9356
+ Use: deepline plays run ${playReference} --input '{...}' --watch
9357
+ Or search provider tools only with: deepline tools search "<query>" --json`;
9358
+ }
9359
+ function printPlayLikeToolExecuteError(toolId) {
9360
+ console.error(playLikeToolExecuteErrorMessage(toolId));
9196
9361
  }
9197
9362
  function registerToolsCommands(program) {
9198
9363
  const tools = program.command("tools").description("Search, describe, and execute atomic provider tools.").addHelpText(
@@ -9367,7 +9532,7 @@ function printToolDetails(tool, requestedToolId) {
9367
9532
  const operation = typeof tool.operation === "string" ? tool.operation : "";
9368
9533
  const displayBase = operation && operation.startsWith(`${tool.provider}_`) ? operation.slice(String(tool.provider).length + 1) : operation ? `${tool.provider} ${operation}`.trim() : toolId;
9369
9534
  const displayName = titleCase(displayBase || String(tool.displayName || toolId));
9370
- const cost = isRecord3(tool.cost) ? tool.cost : null;
9535
+ const cost = isRecord4(tool.cost) ? tool.cost : null;
9371
9536
  const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
9372
9537
  const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
9373
9538
  const deeplineUsdPerCredit = numberField(tool, "deeplineUsdPerCredit", "deepline_usd_per_credit");
@@ -9417,7 +9582,7 @@ function printToolDetails(tool, requestedToolId) {
9417
9582
  if (stepContributions.length) {
9418
9583
  console.log(" step contributions:");
9419
9584
  for (const item of stepContributions) {
9420
- if (!isRecord3(item)) continue;
9585
+ if (!isRecord4(item)) continue;
9421
9586
  const stepTool = typeof item.tool === "string" ? item.tool.trim() : "";
9422
9587
  const low = typeof item.lowCredits === "number" ? item.lowCredits : null;
9423
9588
  const high = typeof item.highCredits === "number" ? item.highCredits : null;
@@ -9457,7 +9622,7 @@ function printToolDetails(tool, requestedToolId) {
9457
9622
  }
9458
9623
  const toolExecutionResult = recordField(usageGuidance, "toolExecutionResult");
9459
9624
  const extractedValues = arrayField(toolExecutionResult, "extractedValues", "extracted_values");
9460
- const targets = extractedValues.map((entry) => isRecord3(entry) && typeof entry.name === "string" ? entry.name : "").filter(Boolean).sort();
9625
+ const targets = extractedValues.map((entry) => isRecord4(entry) && typeof entry.name === "string" ? entry.name : "").filter(Boolean).sort();
9461
9626
  if (targets.length) {
9462
9627
  console.log(` - Built-in extract targets: ${targets.join(", ")}`);
9463
9628
  }
@@ -9498,7 +9663,7 @@ function printExtractions(label, entries) {
9498
9663
  if (!entries.length) return;
9499
9664
  console.log(` ${label}:`);
9500
9665
  for (const entry of entries) {
9501
- if (!isRecord3(entry)) continue;
9666
+ if (!isRecord4(entry)) continue;
9502
9667
  const name = stringField(entry, "name");
9503
9668
  const expression = stringField(entry, "expression");
9504
9669
  const details = recordField(entry, "details");
@@ -9538,12 +9703,12 @@ function printToolCost(input) {
9538
9703
  return false;
9539
9704
  }
9540
9705
  function toolInputFieldsForDisplay(inputSchema) {
9541
- if (Array.isArray(inputSchema.fields)) return inputSchema.fields.filter(isRecord3);
9542
- const jsonSchema = isRecord3(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
9543
- const properties = isRecord3(jsonSchema.properties) ? jsonSchema.properties : {};
9706
+ if (Array.isArray(inputSchema.fields)) return inputSchema.fields.filter(isRecord4);
9707
+ const jsonSchema = isRecord4(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
9708
+ const properties = isRecord4(jsonSchema.properties) ? jsonSchema.properties : {};
9544
9709
  const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
9545
9710
  return Object.entries(properties).map(([name, value]) => {
9546
- const property = isRecord3(value) ? value : {};
9711
+ const property = isRecord4(value) ? value : {};
9547
9712
  return {
9548
9713
  name,
9549
9714
  type: typeof property.type === "string" ? property.type : "unknown",
@@ -9570,15 +9735,15 @@ function printJsonPreview(label, payload) {
9570
9735
  }
9571
9736
  function samplePayload(samples, key) {
9572
9737
  const entry = samples[key];
9573
- if (!isRecord3(entry)) return void 0;
9738
+ if (!isRecord4(entry)) return void 0;
9574
9739
  return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
9575
9740
  }
9576
9741
  function commandEnvelopeFromRawResponse(rawResponse) {
9577
- return isRecord3(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
9742
+ return isRecord4(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
9578
9743
  }
9579
9744
  function listExtractorPathsFromUsageGuidance(tool) {
9580
9745
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
9581
- const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord3(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
9746
+ const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord4(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
9582
9747
  return extractedLists.flatMap((entry) => {
9583
9748
  const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
9584
9749
  if (!Array.isArray(paths)) return [];
@@ -9605,7 +9770,7 @@ function formatDecimal(value) {
9605
9770
  function formatUsd(value) {
9606
9771
  return `$${formatDecimal(value)}`;
9607
9772
  }
9608
- function isRecord3(value) {
9773
+ function isRecord4(value) {
9609
9774
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
9610
9775
  }
9611
9776
  function stringField(source, ...keys) {
@@ -9632,7 +9797,7 @@ function arrayField(source, ...keys) {
9632
9797
  function recordField(source, ...keys) {
9633
9798
  for (const key of keys) {
9634
9799
  const value = source[key];
9635
- if (isRecord3(value)) return value;
9800
+ if (isRecord4(value)) return value;
9636
9801
  }
9637
9802
  return {};
9638
9803
  }
@@ -9730,8 +9895,11 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
9730
9895
  // .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.' }))
9731
9896
  // ctx.map is idempotent by map key + row key; reruns reuse completed rows.
9732
9897
  const enrichedData = await ctx
9733
- .map('enriched_data', rows, { key: ${rowKey} })
9734
- .run({ description: 'Enrich seeded rows.' });
9898
+ .map('enriched_data', rows)
9899
+ .run({
9900
+ key: ${rowKey},
9901
+ description: 'Enrich seeded rows.',
9902
+ });
9735
9903
 
9736
9904
  return {
9737
9905
  rows: enrichedData,
@@ -9761,7 +9929,7 @@ function buildToolExecuteBaseEnvelope(input) {
9761
9929
  kind: summaryEntries.length > 0 ? "object" : "raw",
9762
9930
  summary: input.summary
9763
9931
  };
9764
- const envelopeHasCanonicalOutput = isRecord3(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
9932
+ const envelopeHasCanonicalOutput = isRecord4(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
9765
9933
  const inspectCommand = `deepline tools execute ${input.toolId} --input ${shellQuote(JSON.stringify(input.params))} --json`;
9766
9934
  const actions = input.listConversion ? [
9767
9935
  {
@@ -9821,7 +9989,11 @@ async function executeTool(args) {
9821
9989
  } catch (error) {
9822
9990
  const play = await findPlayForToolId(client, parsed.toolId);
9823
9991
  if (play) {
9824
- printPlayAliasToolError(parsed.toolId, play);
9992
+ if (argsWantJson(args)) {
9993
+ printJsonError(new Error(playAliasToolErrorMessage(parsed.toolId, play)));
9994
+ } else {
9995
+ printPlayAliasToolError(parsed.toolId, play);
9996
+ }
9825
9997
  return 2;
9826
9998
  }
9827
9999
  if (error instanceof DeeplineError) {
@@ -9829,6 +10001,14 @@ async function executeTool(args) {
9829
10001
  }
9830
10002
  throw error;
9831
10003
  }
10004
+ if (isPlayLikeTool(metadata)) {
10005
+ if (argsWantJson(args)) {
10006
+ printJsonError(new Error(playLikeToolExecuteErrorMessage(parsed.toolId)));
10007
+ } else {
10008
+ printPlayLikeToolExecuteError(parsed.toolId);
10009
+ }
10010
+ return 2;
10011
+ }
9832
10012
  const rawResponse = await client.executeTool(parsed.toolId, parsed.params);
9833
10013
  const listConversion = tryConvertToList(rawResponse, {
9834
10014
  listExtractorPaths: listExtractorPathsFromUsageGuidance(metadata)
@@ -9851,7 +10031,7 @@ async function executeTool(args) {
9851
10031
  {
9852
10032
  ...baseEnvelope,
9853
10033
  local: {
9854
- ...isRecord3(baseEnvelope.local) ? baseEnvelope.local : {},
10034
+ ...isRecord4(baseEnvelope.local) ? baseEnvelope.local : {},
9855
10035
  payload_file: jsonPath
9856
10036
  }
9857
10037
  },
@@ -10449,9 +10629,15 @@ Notes:
10449
10629
 
10450
10630
  Examples:
10451
10631
  deepline version
10632
+ deepline version --json
10452
10633
  deepline --version
10453
10634
  `
10454
- ).action(() => {
10635
+ ).option("--json", "Emit JSON output").action((options) => {
10636
+ if (options.json) {
10637
+ process.stdout.write(`${JSON.stringify({ version: SDK_VERSION })}
10638
+ `);
10639
+ return;
10640
+ }
10455
10641
  process.stdout.write(`deepline ${SDK_VERSION}
10456
10642
  `);
10457
10643
  });