deepline 0.3.395 → 0.3.397

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.
Files changed (126) hide show
  1. package/dist/bundling-sources/sdk/src/plays/play-description.ts +1 -1
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +1 -1
  4. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +2 -2
  5. package/dist/cli/{auth-NMQXZRS7.mjs → auth-AZJFXGKP.mjs} +5 -4
  6. package/dist/cli/auth-CZJQU7B5.js +40 -0
  7. package/dist/cli/{billing-Z4JTGUU3.js → billing-MQV5AGDJ.js} +77 -76
  8. package/dist/cli/{billing-5MVXZRS6.mjs → billing-MZAAUHGH.mjs} +6 -5
  9. package/dist/cli/{chunk-6D7A2FSL.mjs → chunk-2LDADJNO.mjs} +7 -107
  10. package/dist/cli/{chunk-UKU6JM3S.js → chunk-3VP34TAU.js} +8 -8
  11. package/dist/cli/{chunk-7XAM7KDW.mjs → chunk-4D745XZO.mjs} +21 -108
  12. package/dist/cli/chunk-7DRPTGCK.js +930 -0
  13. package/dist/cli/{chunk-ZMVJSS6N.js → chunk-BQR6UN3C.js} +62 -78
  14. package/dist/cli/{chunk-HRWUQJ4K.js → chunk-DQ65ZVHN.js} +6 -6
  15. package/dist/cli/{chunk-5VCZ3WRH.mjs → chunk-EIMG75BT.mjs} +1 -0
  16. package/dist/cli/{chunk-EFLQHJZ6.mjs → chunk-F3BUFYKE.mjs} +182 -1031
  17. package/dist/cli/chunk-FIVKWNMT.mjs +210 -0
  18. package/dist/cli/{describe-DBRY5BNK.mjs → chunk-HFYQBC2D.mjs} +51 -171
  19. package/dist/cli/chunk-HGFFYVXN.js +210 -0
  20. package/dist/cli/{chunk-VB6KECLU.mjs → chunk-IHG7UAHD.mjs} +63 -79
  21. package/dist/cli/{chunk-TO2MWPGR.js → chunk-IZ74ABSX.js} +1 -1
  22. package/dist/cli/{chunk-G4IWGRMK.mjs → chunk-J7ABTQQ7.mjs} +5 -3
  23. package/dist/cli/{chunk-LZLBR2SF.js → chunk-K33MXVXQ.js} +323 -1172
  24. package/dist/cli/{chunk-DRM3CMHL.js → chunk-KXMNM4AQ.js} +2 -1
  25. package/dist/cli/chunk-LJ5747UC.mjs +107 -0
  26. package/dist/cli/{chunk-BON3DRC6.mjs → chunk-MRXMMERY.mjs} +1 -1
  27. package/dist/cli/{chunk-7MVWUXOD.mjs → chunk-MV7QRALK.mjs} +3 -3
  28. package/dist/cli/{chunk-WCCKMLHL.mjs → chunk-MYPH2LUU.mjs} +2 -2
  29. package/dist/cli/{chunk-RDXFGPJU.js → chunk-NA4T3B62.js} +64 -272
  30. package/dist/cli/{chunk-BLYL3KOC.mjs → chunk-NOX2TCBP.mjs} +1 -1
  31. package/dist/cli/chunk-OSDXE27V.mjs +88 -0
  32. package/dist/cli/{chunk-R4XZO6Z5.js → chunk-PSGEDGLT.js} +28 -115
  33. package/dist/cli/chunk-Q2E4E4FJ.js +112 -0
  34. package/dist/cli/chunk-RFG3MRAC.js +286 -0
  35. package/dist/cli/{chunk-47M6HPGP.mjs → chunk-RNSWDKBM.mjs} +1 -1
  36. package/dist/cli/{chunk-56IFFVIB.js → chunk-RYW4HPSM.js} +21 -121
  37. package/dist/cli/{chunk-K5T3EN6D.js → chunk-SO7RUVTY.js} +26 -26
  38. package/dist/cli/{chunk-KZZC33PY.mjs → chunk-TXZVVBQZ.mjs} +63 -271
  39. package/dist/cli/{chunk-36ML3YKA.js → chunk-UVXBVUZQ.js} +15 -13
  40. package/dist/cli/{chunk-PZ5BZ76S.js → chunk-VTF4RRWJ.js} +50 -50
  41. package/dist/cli/{chunk-3TRY7KAC.mjs → chunk-W3HMGKMI.mjs} +2 -2
  42. package/dist/cli/{chunk-ZWH2TFA7.mjs → chunk-WM2QEHZL.mjs} +2 -2
  43. package/dist/cli/chunk-YHPYUZZX.mjs +112 -0
  44. package/dist/cli/chunk-YHZUZO3U.mjs +930 -0
  45. package/dist/cli/{chunk-UCXK2DS4.js → chunk-YLRME7MK.js} +15 -15
  46. package/dist/cli/{chunk-MYIBHORT.js → chunk-YSVORIEW.js} +2 -2
  47. package/dist/cli/{chunk-OCSG6X67.mjs → chunk-YUDKBQUD.mjs} +4 -4
  48. package/dist/cli/chunk-ZAAKSJAS.js +88 -0
  49. package/dist/cli/{chunk-VYLJJQ7Y.js → chunk-ZHUMDMOS.js} +65 -65
  50. package/dist/cli/chunk-ZM2YPJQJ.js +107 -0
  51. package/dist/cli/{csv-HTS5ZYQ4.js → csv-AQBQ5O3I.js} +13 -12
  52. package/dist/cli/{csv-SVOD5UBH.mjs → csv-MB7PJMYQ.mjs} +4 -3
  53. package/dist/cli/{db-7AP4P52N.js → db-JPUYC5RB.js} +31 -30
  54. package/dist/cli/{db-7QLNI3Q4.mjs → db-L5IEI2AU.mjs} +6 -5
  55. package/dist/cli/describe-6WT74AOR.js +164 -0
  56. package/dist/cli/describe-S6BFANVI.mjs +164 -0
  57. package/dist/cli/describe-core.d.mts +100 -0
  58. package/dist/cli/describe-core.d.ts +100 -0
  59. package/dist/cli/describe-core.js +18 -0
  60. package/dist/cli/describe-core.mjs +18 -0
  61. package/dist/cli/{executions-GRQXTB2P.js → executions-6TMQTFP4.js} +8 -7
  62. package/dist/cli/{executions-QNZTPNG4.mjs → executions-L7I2ZW4Z.mjs} +6 -5
  63. package/dist/cli/{feedback-JMCSR624.mjs → feedback-DSJ63HK6.mjs} +4 -3
  64. package/dist/cli/{feedback-ZOLA2KY7.js → feedback-XF7CQGMD.js} +8 -7
  65. package/dist/cli/{git-LJGL2IHS.mjs → git-C3ENM67D.mjs} +5 -4
  66. package/dist/cli/git-HYDZK2QR.js +24 -0
  67. package/dist/cli/index.js +96 -94
  68. package/dist/cli/index.mjs +41 -39
  69. package/dist/cli/{legacy-noops-YSCIR2SD.js → legacy-noops-B2NHWIVD.js} +8 -7
  70. package/dist/cli/{legacy-noops-F23PKVBN.mjs → legacy-noops-VFG2K6HK.mjs} +5 -4
  71. package/dist/cli/{monitors-WMZ6HJZX.js → monitors-ORFWOVZB.js} +87 -86
  72. package/dist/cli/{monitors-S4LOEL7W.mjs → monitors-TCEDBDGY.mjs} +6 -5
  73. package/dist/cli/{org-U3WA2NQM.mjs → org-45KREIKZ.mjs} +6 -5
  74. package/dist/cli/{org-PFHM5ZLY.js → org-T74CJESN.js} +66 -65
  75. package/dist/cli/{chunk-XMAPE2KH.mjs → play-MU7MYBIM.mjs} +78 -131
  76. package/dist/cli/{chunk-4KLCLLTO.js → play-XHK2LPON.js} +273 -326
  77. package/dist/cli/{providers-XYMHLKCA.js → providers-4MGQKYFD.js} +9 -8
  78. package/dist/cli/{providers-QBBRFBOH.mjs → providers-VYCXIJT5.mjs} +6 -5
  79. package/dist/cli/{quickstart-IYGD6ZY3.js → quickstart-47G3VEOT.js} +6 -5
  80. package/dist/cli/{quickstart-5JTDGISY.mjs → quickstart-H724EFM2.mjs} +4 -3
  81. package/dist/cli/search-3356ENLD.js +30 -0
  82. package/dist/cli/{search-X6W6GRHS.mjs → search-VQHXEFQ4.mjs} +8 -6
  83. package/dist/cli/{secrets-UHG6OQFD.js → secrets-ALLKCU35.js} +15 -14
  84. package/dist/cli/{secrets-N55B67H6.mjs → secrets-CPBNGA44.mjs} +6 -5
  85. package/dist/cli/{sessions-JTRSTDSS.mjs → sessions-7RSQB7IX.mjs} +5 -4
  86. package/dist/cli/sessions-FKGAY7WQ.js +16 -0
  87. package/dist/cli/{settings-Q24HRAQI.mjs → settings-UYSGV4IC.mjs} +9 -8
  88. package/dist/cli/{settings-ATX4U5AS.js → settings-Y5BI42P7.js} +76 -75
  89. package/dist/cli/{setup-77ZWLVHT.mjs → setup-L3ZBBTS4.mjs} +7 -6
  90. package/dist/cli/{setup-EJCNOUCE.js → setup-VXQPEU3E.js} +42 -41
  91. package/dist/cli/skills-DUZQTDTE.js +29 -0
  92. package/dist/cli/{skills-XIS5AWQI.mjs → skills-QHVDLSFE.mjs} +5 -4
  93. package/dist/cli/{tools-WCKLYEGQ.mjs → tools-LSCEK4K2.mjs} +16 -19
  94. package/dist/cli/tools-YWU5QOQ5.js +39 -0
  95. package/dist/cli/update-5LYQAI55.js +29 -0
  96. package/dist/cli/{update-UT5WANMV.mjs → update-CU22OTBM.mjs} +7 -6
  97. package/dist/cli/{workflow-226QYUN2.js → workflow-ERFLTRNX.js} +17 -16
  98. package/dist/cli/{workflow-ZMX3L4ML.mjs → workflow-KQARK5BZ.mjs} +7 -6
  99. package/dist/{client-hdFtwhTm.d.mts → client-D0j-_aaa.d.mts} +2 -1
  100. package/dist/{client-CivP-PAI.d.ts → client-DflfVyj6.d.ts} +2 -1
  101. package/dist/index.d.mts +2 -2
  102. package/dist/index.d.ts +2 -2
  103. package/dist/index.js +15 -11
  104. package/dist/index.mjs +19 -15
  105. package/dist/install-integrity.json +94 -80
  106. package/dist/plays/play-description.d.mts +1 -1
  107. package/dist/plays/play-description.d.ts +1 -1
  108. package/dist/plays/play-description.js +4 -2
  109. package/dist/plays/play-description.mjs +3 -1
  110. package/dist/plays/run-request.d.mts +1 -1
  111. package/dist/plays/run-request.d.ts +1 -1
  112. package/dist/release.d.mts +1 -1
  113. package/dist/release.d.ts +1 -1
  114. package/dist/release.js +2 -2
  115. package/dist/release.mjs +1 -1
  116. package/package.json +6 -1
  117. package/dist/cli/auth-UYCOBAL5.js +0 -39
  118. package/dist/cli/describe-YKOE54ZO.js +0 -406
  119. package/dist/cli/git-EJQLRK27.js +0 -23
  120. package/dist/cli/play-AGSECQFN.mjs +0 -159
  121. package/dist/cli/play-BR2LWGXK.js +0 -159
  122. package/dist/cli/search-ZVSYH5GY.js +0 -28
  123. package/dist/cli/sessions-57L5MGHN.js +0 -15
  124. package/dist/cli/skills-SPXUBLII.js +0 -28
  125. package/dist/cli/tools-DBHUUZJX.js +0 -42
  126. package/dist/cli/update-VSNFXRHJ.js +0 -28
@@ -0,0 +1,210 @@
1
+ // src/tool-output.ts
2
+ import {
3
+ closeSync,
4
+ mkdirSync,
5
+ openSync,
6
+ writeFileSync,
7
+ writeSync
8
+ } from "fs";
9
+ import { homedir } from "os";
10
+ import { dirname, join } from "path";
11
+ function isPlainObject(value) {
12
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
13
+ }
14
+ function getByDottedPath(root, dottedPath) {
15
+ let current = root;
16
+ for (const segment of String(dottedPath || "").split(".").filter(Boolean)) {
17
+ if (!isPlainObject(current) || !(segment in current)) {
18
+ return null;
19
+ }
20
+ current = current[segment];
21
+ }
22
+ return current;
23
+ }
24
+ function normalizeRows(value) {
25
+ if (!Array.isArray(value)) return null;
26
+ return value.map((entry) => {
27
+ if (isPlainObject(entry)) return entry;
28
+ return { value: entry };
29
+ });
30
+ }
31
+ function columnsForRows(rows) {
32
+ const seen = /* @__PURE__ */ new Set();
33
+ const columns = [];
34
+ for (const row of rows) {
35
+ for (const key of Object.keys(row)) {
36
+ if (!seen.has(key)) {
37
+ seen.add(key);
38
+ columns.push(key);
39
+ }
40
+ }
41
+ }
42
+ return columns;
43
+ }
44
+ function candidateRoots(payload) {
45
+ const roots = [
46
+ { path: null, value: payload }
47
+ ];
48
+ if (isPlainObject(payload) && isPlainObject(payload.toolResponse)) {
49
+ roots.push({ path: "toolResponse", value: payload.toolResponse });
50
+ if (Object.prototype.hasOwnProperty.call(payload.toolResponse, "raw")) {
51
+ roots.push({
52
+ path: "toolResponse.raw",
53
+ value: payload.toolResponse.raw
54
+ });
55
+ }
56
+ }
57
+ if (isPlainObject(payload) && isPlainObject(payload.output)) {
58
+ roots.push({ path: "output", value: payload.output });
59
+ if (Object.prototype.hasOwnProperty.call(payload.output, "body")) {
60
+ roots.push({ path: "output.body", value: payload.output.body });
61
+ }
62
+ }
63
+ if (isPlainObject(payload) && isPlainObject(payload.result)) {
64
+ roots.push({ path: "result", value: payload.result });
65
+ if (isPlainObject(payload.result.data)) {
66
+ roots.push({ path: "result.data", value: payload.result.data });
67
+ }
68
+ }
69
+ return roots;
70
+ }
71
+ function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
72
+ if (depth > 5) return null;
73
+ const directRows = normalizeRows(value);
74
+ const hasObjectRow = directRows?.some(
75
+ (row) => Object.keys(row).some((key) => key !== "value")
76
+ ) ?? false;
77
+ let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
78
+ if (!isPlainObject(value)) {
79
+ return best;
80
+ }
81
+ for (const [key, child] of Object.entries(value)) {
82
+ const childPath = pathPrefix ? `${pathPrefix}.${key}` : key;
83
+ const candidate = findBestArrayCandidate(child, childPath, depth + 1);
84
+ if (!candidate) continue;
85
+ if (!best || candidate.rows.length > best.rows.length) {
86
+ best = candidate;
87
+ }
88
+ }
89
+ return best;
90
+ }
91
+ function tryConvertToList(payload, options) {
92
+ const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter(
93
+ (entry) => typeof entry === "string" && entry.trim().length > 0
94
+ ) : [];
95
+ if (listExtractorPaths.length > 0) {
96
+ let emptyMatch = null;
97
+ for (const root of candidateRoots(payload)) {
98
+ for (const extractorPath of listExtractorPaths) {
99
+ const resolved = getByDottedPath(root.value, extractorPath);
100
+ const rows = normalizeRows(resolved);
101
+ if (!rows) {
102
+ continue;
103
+ }
104
+ const sourcePath = root.path ? `${root.path}.${extractorPath}` : extractorPath;
105
+ if (rows.length > 0) {
106
+ return { rows, strategy: "configured_paths", sourcePath };
107
+ }
108
+ emptyMatch ??= { rows, strategy: "configured_paths", sourcePath };
109
+ }
110
+ }
111
+ if (emptyMatch) {
112
+ return emptyMatch;
113
+ }
114
+ }
115
+ const roots = candidateRoots(payload);
116
+ const v2Raw = roots.find((root) => root.path === "toolResponse.raw");
117
+ for (const root of v2Raw ? [v2Raw] : roots) {
118
+ const candidate = findBestArrayCandidate(root.value, root.path ?? "");
119
+ if (!candidate || candidate.rows.length === 0) continue;
120
+ return {
121
+ rows: candidate.rows,
122
+ strategy: "auto_detected",
123
+ sourcePath: candidate.path || root.path
124
+ };
125
+ }
126
+ return null;
127
+ }
128
+ function projectRowOutput(conversion) {
129
+ return {
130
+ rows: conversion.rows,
131
+ rowCount: conversion.rows.length,
132
+ columns: columnsForRows(conversion.rows),
133
+ previewRows: conversion.rows.slice(0, 5),
134
+ strategy: conversion.strategy,
135
+ sourcePath: conversion.sourcePath
136
+ };
137
+ }
138
+ function ensureOutputDir() {
139
+ const outputDir = join(homedir(), ".local", "share", "deepline", "data");
140
+ mkdirSync(outputDir, { recursive: true });
141
+ return outputDir;
142
+ }
143
+ function writeJsonOutputFile(payload, stem) {
144
+ const outputDir = ensureOutputDir();
145
+ const outputPath = join(outputDir, `${stem}_${Date.now()}.json`);
146
+ writeFileSync(outputPath, JSON.stringify(payload, null, 2), "utf-8");
147
+ return outputPath;
148
+ }
149
+ function writeCsvOutputFile(rows, stem, options) {
150
+ const outputPath = options?.outPath ? options.outPath : join(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
151
+ mkdirSync(dirname(outputPath), { recursive: true });
152
+ const columns = columnsForRows(rows);
153
+ const escapeCell = (value) => {
154
+ const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
155
+ if (/[",\n]/.test(normalized)) {
156
+ return `"${normalized.replace(/"/g, '""')}"`;
157
+ }
158
+ return normalized;
159
+ };
160
+ const fd = openSync(outputPath, "w");
161
+ try {
162
+ writeSync(fd, `${columns.map(escapeCell).join(",")}
163
+ `);
164
+ for (const row of rows) {
165
+ writeSync(
166
+ fd,
167
+ `${columns.map((column) => escapeCell(row[column])).join(",")}
168
+ `
169
+ );
170
+ }
171
+ } finally {
172
+ closeSync(fd);
173
+ }
174
+ const previewRows = rows.slice(0, 5);
175
+ const previewColumns = columns.slice(0, 5);
176
+ const preview = [
177
+ previewColumns.join(","),
178
+ ...previewRows.map(
179
+ (row) => previewColumns.map((column) => escapeCell(row[column])).join(",")
180
+ )
181
+ ].join("\n");
182
+ return {
183
+ path: outputPath,
184
+ rowCount: rows.length,
185
+ columns,
186
+ preview
187
+ };
188
+ }
189
+ function extractSummaryFields(payload) {
190
+ const candidates = candidateRoots(payload);
191
+ for (const candidate of candidates) {
192
+ if (!isPlainObject(candidate.value)) continue;
193
+ const summaryEntries = Object.entries(candidate.value).filter(
194
+ ([, value]) => {
195
+ return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
196
+ }
197
+ );
198
+ if (summaryEntries.length === 0) continue;
199
+ return Object.fromEntries(summaryEntries);
200
+ }
201
+ return {};
202
+ }
203
+
204
+ export {
205
+ tryConvertToList,
206
+ projectRowOutput,
207
+ writeJsonOutputFile,
208
+ writeCsvOutputFile,
209
+ extractSummaryFields
210
+ };
@@ -1,57 +1,22 @@
1
- import {
2
- buildPlayDashboardUrl,
3
- describedPlay
4
- } from "./chunk-XMAPE2KH.mjs";
5
- import "./chunk-3TRY7KAC.mjs";
6
1
  import {
7
2
  describedTool,
8
3
  formatModelDescription,
9
4
  publicToolSchemas,
10
5
  toolMetadataJsonForDescribe
11
- } from "./chunk-EFLQHJZ6.mjs";
6
+ } from "./chunk-YHZUZO3U.mjs";
12
7
  import {
13
- SCHEMA_LINE_LIMIT,
14
- addDescribeOptions,
8
+ buildPlayDashboardUrl,
15
9
  byokLines,
16
10
  describedJson,
17
11
  describedLines,
12
+ describedPlay,
18
13
  examples,
19
14
  schemaLines,
20
15
  topLevelField
21
- } from "./chunk-VB6KECLU.mjs";
22
- import "./chunk-OVDNJAJN.mjs";
23
- import "./chunk-3HWALOL2.mjs";
24
- import "./chunk-H7HIDGZ7.mjs";
25
- import "./chunk-HQXL5526.mjs";
26
- import "./chunk-7XAM7KDW.mjs";
27
- import "./chunk-ERFN2QY4.mjs";
28
- import "./chunk-KZZC33PY.mjs";
29
- import "./chunk-3HU47EGZ.mjs";
30
- import {
31
- DeeplineClient
32
- } from "./chunk-G4IWGRMK.mjs";
33
- import "./chunk-6IKARAYD.mjs";
34
- import "./chunk-JI2B4RZP.mjs";
35
- import "./chunk-5VCZ3WRH.mjs";
36
- import "./chunk-UBKA33KY.mjs";
37
- import "./chunk-UFS752TU.mjs";
38
- import "./chunk-GAMFK2ZP.mjs";
39
- import "./chunk-WXLOW623.mjs";
40
- import {
41
- printCommandEnvelope
42
- } from "./chunk-47M6HPGP.mjs";
43
- import "./chunk-6D7A2FSL.mjs";
44
- import "./chunk-DLIRSHV6.mjs";
16
+ } from "./chunk-IHG7UAHD.mjs";
45
17
  import {
46
18
  DeeplineError
47
19
  } from "./chunk-NXGCO4JB.mjs";
48
- import "./chunk-BON3DRC6.mjs";
49
- import "./chunk-WZYKRD7T.mjs";
50
- import "./chunk-KRD6H754.mjs";
51
-
52
- // src/cli/commands/describe.ts
53
- import { writeFileSync } from "fs";
54
- import { resolve } from "path";
55
20
 
56
21
  // src/cli/tool-features.ts
57
22
  var VIEWS = {
@@ -116,7 +81,7 @@ async function describeFeature(tool, feature, value, dependencies) {
116
81
  return VIEWS[feature.view](value ?? feature.defaultValue, tool, dependencies);
117
82
  }
118
83
 
119
- // src/cli/commands/describe.ts
84
+ // src/cli/describe-core.ts
120
85
  var FILTER_OF = {
121
86
  tool: "tools",
122
87
  monitor_type: "monitors",
@@ -133,12 +98,20 @@ async function found(lookup) {
133
98
  throw error;
134
99
  }
135
100
  }
136
- async function describeAnything(name, options, onMissing) {
101
+ function describeLookupsFor(client) {
102
+ return {
103
+ play: (reference) => found(client.describePlay(reference)),
104
+ tool: (name) => found(client.getTool(name)),
105
+ describeModel: (model) => client.describeModel(model),
106
+ baseUrl: client.baseUrl
107
+ };
108
+ }
109
+ async function describeName(name, options, lookups) {
137
110
  const maintainedOnly = options.prebuilt === true || options.tool === true;
138
111
  const wants = (filter) => (!options.kinds || options.kinds.includes(filter)) && !(maintainedOnly && filter === "custom");
139
- const client = new DeeplineClient();
140
112
  const play = async (reference) => {
141
- const record2 = await client.describePlay(reference);
113
+ const record2 = await lookups.play(reference);
114
+ if (!record2) return null;
142
115
  return {
143
116
  described: describedPlay(record2),
144
117
  record: { ...record2 },
@@ -149,7 +122,8 @@ async function describeAnything(name, options, onMissing) {
149
122
  };
150
123
  };
151
124
  const tool = async () => {
152
- const record2 = options.fetchedTool ?? await client.getTool(name);
125
+ const record2 = await lookups.tool(name);
126
+ if (!record2) return null;
153
127
  const { byok } = record2;
154
128
  const features = toolFeatures(record2);
155
129
  return {
@@ -160,12 +134,16 @@ async function describeAnything(name, options, onMissing) {
160
134
  ...byok?.required === true ? { byok } : {},
161
135
  ...features.length ? { features: features.map(({ view: _view, ...feature }) => feature) } : {}
162
136
  },
163
- record: toolMetadataJsonForDescribe(record2, name),
137
+ record: toolMetadataJsonForDescribe(
138
+ record2,
139
+ name,
140
+ lookups.seedStarterScript
141
+ ),
164
142
  schemas: publicToolSchemas(record2),
165
143
  feature: (featureName, value) => {
166
144
  const feature = features.find(({ name: name2 }) => name2 === featureName);
167
145
  return feature ? describeFeature(record2, feature, value, {
168
- describeModel: (model) => client.describeModel(model)
146
+ describeModel: (model) => lookups.describeModel(model)
169
147
  }) : null;
170
148
  }
171
149
  };
@@ -177,19 +155,13 @@ async function describeAnything(name, options, onMissing) {
177
155
  ];
178
156
  const matches = await Promise.all(
179
157
  sources.filter((source) => source.kinds.some(wants)).map(async ({ kinds, find }) => {
180
- const match = await found(find());
158
+ const match = await find();
181
159
  const filter = match && FILTER_OF[match.described.kind];
182
160
  return filter && kinds.includes(filter) && wants(filter) ? match : null;
183
161
  })
184
162
  );
185
163
  const [chosen, shadowed] = matches.filter((match) => match !== null);
186
- if (!chosen) {
187
- if (onMissing) return onMissing();
188
- console.error(
189
- `Nothing named "${name}". Search for it: deepline search ${JSON.stringify(name.replace(/[-_./]+/g, " "))}`
190
- );
191
- return 2;
192
- }
164
+ if (!chosen) return { status: "missing" };
193
165
  const { described, record } = chosen;
194
166
  const shadows = described.kind === "custom_play" && shadowed ? {
195
167
  kind: shadowed.described.kind,
@@ -197,49 +169,49 @@ async function describeAnything(name, options, onMissing) {
197
169
  } : null;
198
170
  const note = shadows ? `Showing your workspace play "${name}". It has the same name as a Deepline ${shadows.kind.replace("_", " ")}; see that one with: ${shadows.describeCommand}` : null;
199
171
  const verbose = options.verbose === true;
200
- const json = options.json === true;
201
172
  const isPlay = described.kind === "prebuilt_play" || described.kind === "custom_play";
202
- const dashboardUrl = isPlay ? buildPlayDashboardUrl(client.baseUrl, described.id) : null;
173
+ const dashboardUrl = isPlay ? buildPlayDashboardUrl(lookups.baseUrl, described.id) : null;
203
174
  if (options.webUrl) {
204
175
  if (!dashboardUrl) {
205
- console.error(
206
- `${described.id} is a ${described.kind.replace("_", " ")}, not a play; only plays have a play page.`
207
- );
208
- return 1;
176
+ return {
177
+ status: "refused",
178
+ message: `${described.id} is a ${described.kind.replace("_", " ")}, not a play; only plays have a play page.`,
179
+ exitCode: 1
180
+ };
209
181
  }
210
- printCommandEnvelope(
211
- { dashboardUrl },
212
- { json, text: `${dashboardUrl}
213
- ` }
214
- );
215
- return 0;
182
+ return {
183
+ status: "described",
184
+ envelope: { dashboardUrl },
185
+ lines: [dashboardUrl]
186
+ };
216
187
  }
217
188
  if (options.feature !== void 0) {
218
189
  const { name: featureName, value } = parseFeatureRequest(options.feature);
219
190
  const pending = chosen.feature?.(featureName, value) ?? null;
220
191
  const features = described.features ?? [];
221
192
  if (!pending) {
222
- console.error(
223
- features.length ? `${described.id} has no feature "${featureName}". Its features: ${features.map(({ name: name2 }) => name2).join(", ")}.` : `${described.id} has no features to describe.`
224
- );
225
- return 2;
193
+ return {
194
+ status: "refused",
195
+ message: features.length ? `${described.id} has no feature "${featureName}". Its features: ${features.map(({ name: name2 }) => name2).join(", ")}.` : `${described.id} has no features to describe.`,
196
+ exitCode: 2
197
+ };
226
198
  }
227
199
  const shownValue = value ?? features.find(({ name: name2 }) => name2 === featureName)?.defaultValue;
228
200
  const { details, lines } = await pending;
229
- return deliver(
230
- {
201
+ return {
202
+ status: "described",
203
+ envelope: {
231
204
  kind: described.kind,
232
205
  id: described.id,
233
206
  feature: featureName,
234
207
  ...shownValue ? { value: shownValue } : {},
235
208
  details
236
209
  },
237
- [
210
+ lines: [
238
211
  `${described.id} --feature ${featureName}${shownValue ? `=${shownValue}` : ""}`,
239
212
  ...lines
240
- ],
241
- { json, out: options.out }
242
- );
213
+ ]
214
+ };
243
215
  }
244
216
  const fields = (options.fields ?? "").split(",").map((name2) => name2.trim()).filter(Boolean);
245
217
  const named = options.cliExample === true || options.playExample === true;
@@ -305,102 +277,10 @@ async function describeAnything(name, options, onMissing) {
305
277
  ...dashboardUrl ? { dashboardUrl } : {},
306
278
  ...shadows ? { shadows, note } : {}
307
279
  };
308
- return deliver(envelope, view.lines, { json, out: options.out });
309
- }
310
- function deliver(envelope, lines, { json, out }) {
311
- const text = `${lines.join("\n")}
312
- `;
313
- if (out) {
314
- const path = resolve(out);
315
- const content = json ? `${JSON.stringify(envelope, null, 2)}
316
- ` : text;
317
- writeFileSync(path, content);
318
- const bytes = Buffer.byteLength(content);
319
- printCommandEnvelope(
320
- { path, bytes },
321
- { json, text: `Wrote ${path} (${bytes} bytes)
322
- ` }
323
- );
324
- return 0;
325
- }
326
- printCommandEnvelope(envelope, { json, text });
327
- return 0;
280
+ return { status: "described", envelope, lines: view.lines };
328
281
  }
329
- function registerDescribeCommand(program) {
330
- addDescribeOptions(program.command("describe <name>")).option("--web-url", "Print only a play's play page URL").description(
331
- "Describe anything search returns: a tool, monitor type, or play."
332
- ).addHelpText(
333
- "after",
334
- `
335
- What you can describe:
336
- Any id deepline search returns: a tool id, a monitor type id, or a play name
337
- or reference. You do not say which kind it is; tool ids, monitor type ids
338
- and prebuilt play names never overlap.
339
-
340
- When a name is taken twice:
341
- A play your workspace created is shown instead of a Deepline tool, monitor
342
- type or prebuilt play with the same name, and the output says so.
343
- Pass --prebuilt (or --tool) to see the Deepline one.
344
-
345
- What it prints:
346
- The same sections for every kind: what it is, cost, inputs, outputs, then
347
- an example of running it from the CLI and from inside a play.
348
282
 
349
- Examples in the output:
350
- (default) required inputs filled in, first output read
351
- --verbose every input filled in, every output read; also shows
352
- secondary fields
353
- --cli-example only the CLI example, with how inputs and outputs work
354
- --play-example only the in-play example, with how inputs and outputs work
355
- --no-example no examples
356
-
357
- Features:
358
- A tool lists its features: parts with their own description, such as the
359
- model an AI tool runs. --feature <name> describes one at its default value,
360
- --feature <name>=<value> at another, e.g. --feature model=openai/gpt-5.6-luna.
361
-
362
- Schema size and format:
363
- Secondary fields (diagnostics, attempt logs, echoes of input) are left out
364
- by default; the output names them, and --verbose shows them.
365
- --fields email,miss_reason shows only the fields you name, plus every
366
- required input, and names the rest. Use it when you know what you need.
367
- A schema over ${SCHEMA_LINE_LIMIT} lines is folded: deeper objects show only their field
368
- names. A shape used more than once is printed once under Types.
369
- --full-schema the normal output, with the schema not folded
370
- --schema-only only the schema, not folded, and nothing else
371
- --json the same facts as JSON: fields keyed by name, with what
372
- each means and, for a tool, where it is in the result;
373
- secondary fields are named in "hidden"
374
- --json --full-schema the whole catalog record, as tools describe and
375
- plays describe print it
376
- --schema-only --json
377
- only the input and output JSON Schemas; use this for a
378
- program, or for a schema too large to read
379
- --out <path> save any of the above to a file instead of printing it
380
-
381
- Play page:
382
- For a play, the output ends with its play page URL (JSON: dashboardUrl).
383
- --web-url print only that URL; with --json, {"dashboardUrl": ...}.
384
- Fails for a tool or monitor type, which have no play page.
385
-
386
- Older commands:
387
- deepline tools describe and deepline plays describe are this command limited
388
- to one kind. Their own flags still work: --pricing-only, --examples-only,
389
- --model and --estimate-payload on tools; --json <fields> on plays.
390
-
391
- Examples:
392
- deepline describe hunter_email_verifier
393
- deepline describe person-linkedin-to-email
394
- deepline describe my-play --prebuilt
395
- deepline describe ai_ark_people_search --full-schema
396
- deepline describe prebuilt/person-to-email-batch --web-url
397
- deepline describe ai_ark_people_search --schema-only --out schema.json
398
- `
399
- ).action(async (name, options) => {
400
- process.exitCode = await describeAnything(name, options);
401
- });
402
- }
403
283
  export {
404
- describeAnything,
405
- registerDescribeCommand
284
+ describeLookupsFor,
285
+ describeName
406
286
  };