deepline 0.3.311 → 0.3.312

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 (113) hide show
  1. package/dist/bundling-sources/sdk/src/play.ts +7 -1
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +100 -25
  4. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +23 -1
  5. package/dist/bundling-sources/shared_libs/plays/core.ts +7 -1
  6. package/dist/bundling-sources/shared_libs/plays/settings-contract.ts +29 -3
  7. package/dist/cli/{auth-2A7OYHFJ.mjs → auth-ACDTPM3M.mjs} +4 -4
  8. package/dist/cli/auth-TFDGA24W.js +31 -0
  9. package/dist/cli/{billing-P7GIAP3U.mjs → billing-FVBBJ77L.mjs} +5 -5
  10. package/dist/cli/{billing-2PQ4VDRR.js → billing-YTJFHEGU.js} +71 -71
  11. package/dist/cli/{chunk-5IBHISKA.js → chunk-6KKETQSI.js} +6 -6
  12. package/dist/cli/{chunk-XDUQQTIS.js → chunk-6LLJWMYH.js} +6 -6
  13. package/dist/cli/{chunk-HOCPOTDX.mjs → chunk-6OGNRAS7.mjs} +2 -2
  14. package/dist/cli/chunk-76VKBPOC.mjs +406 -0
  15. package/dist/cli/{chunk-7TT4LZIR.js → chunk-7SW43OAX.js} +60 -60
  16. package/dist/cli/{chunk-SGTSJCOA.mjs → chunk-AA66YTS7.mjs} +1 -1
  17. package/dist/cli/{chunk-QO3GH6UP.js → chunk-BRJOVSTH.js} +2 -2
  18. package/dist/cli/{chunk-4WFNAWVO.mjs → chunk-EHVJ7XXD.mjs} +2 -2
  19. package/dist/cli/{chunk-G3QP2WYR.mjs → chunk-ENSDO4SG.mjs} +4 -4
  20. package/dist/cli/{chunk-VODJJUKE.js → chunk-FQVTHBEH.js} +15 -15
  21. package/dist/cli/{chunk-DUEHAEPM.mjs → chunk-GTEDCRKC.mjs} +1 -1
  22. package/dist/cli/{play-SOG5Q2GE.mjs → chunk-I25C4KL7.mjs} +166 -90
  23. package/dist/cli/{chunk-W7INSYJS.js → chunk-IALPYID6.js} +3 -3
  24. package/dist/cli/{chunk-ICZB4GTY.mjs → chunk-MK4K5MQU.mjs} +23 -3
  25. package/dist/cli/{chunk-WB6Z2Q44.mjs → chunk-N5V2SBB2.mjs} +19 -1
  26. package/dist/cli/{chunk-TBX7AA7Y.mjs → chunk-NJNYWVEF.mjs} +2 -2
  27. package/dist/cli/{chunk-QJA6SJHA.mjs → chunk-NMZPK7LM.mjs} +1 -1
  28. package/dist/cli/{chunk-5OVNL6LS.mjs → chunk-NWFE4PGX.mjs} +1 -1
  29. package/dist/cli/{chunk-ZDO3TO3M.js → chunk-OJ243ZA5.js} +19 -1
  30. package/dist/cli/{tools-G4HGCHNQ.mjs → chunk-OV6IFAXH.mjs} +180 -36
  31. package/dist/cli/{play-BCMGFYTF.js → chunk-QFSLMI42.js} +342 -266
  32. package/dist/cli/{chunk-LRI2FQF2.js → chunk-T4IJQKRE.js} +26 -26
  33. package/dist/cli/{chunk-RNJ74JDH.js → chunk-TID5XLTZ.js} +4 -4
  34. package/dist/cli/{chunk-QYL5ZV4U.js → chunk-ULI6UVV6.js} +6 -6
  35. package/dist/cli/{chunk-4NIQA6S7.mjs → chunk-US4S3E4Y.mjs} +1 -1
  36. package/dist/cli/{tools-WN7T25LW.js → chunk-V7N6BJQD.js} +231 -87
  37. package/dist/cli/{chunk-IB7OGQGH.js → chunk-VJDKV5RU.js} +29 -9
  38. package/dist/cli/{chunk-Q3LYQTSO.mjs → chunk-WPTUKXIF.mjs} +1 -1
  39. package/dist/cli/chunk-XNL3SEMC.js +406 -0
  40. package/dist/cli/{chunk-GCX3343L.js → chunk-YYU3PYVK.js} +48 -48
  41. package/dist/cli/{chunk-SPUTBCUR.mjs → chunk-ZH7KTVAB.mjs} +1 -1
  42. package/dist/cli/{chunk-FYPZ43Y4.js → chunk-ZQJDRSR5.js} +1 -1
  43. package/dist/cli/{client-PNLDT2M3.mjs → client-ENGOMTTU.mjs} +3 -3
  44. package/dist/cli/client-T6YGH6TT.js +20 -0
  45. package/dist/cli/{csv-L5DN7F45.js → csv-6WOJC6NZ.js} +12 -12
  46. package/dist/cli/{csv-KUAATBZQ.mjs → csv-ENKTPYAJ.mjs} +3 -3
  47. package/dist/cli/{db-6NIH4KTZ.js → db-BAEVP4QK.js} +20 -20
  48. package/dist/cli/{db-WZOD6NP5.mjs → db-DSCJZYJU.mjs} +4 -4
  49. package/dist/cli/describe-PAUHJF7H.mjs +236 -0
  50. package/dist/cli/describe-X2AFAC4B.js +236 -0
  51. package/dist/cli/{executions-TQ5WRHDS.js → executions-LXS6NLCV.js} +6 -6
  52. package/dist/cli/{executions-RDDXGT2Y.mjs → executions-R6JOR67D.mjs} +4 -4
  53. package/dist/cli/{feedback-ZB4WKBSS.mjs → feedback-CYRVNCGT.mjs} +3 -3
  54. package/dist/cli/{feedback-NYKLEQB6.js → feedback-HXP2D7K6.js} +6 -6
  55. package/dist/cli/git-JOE2RM3Q.js +23 -0
  56. package/dist/cli/{git-E6DKAX3X.mjs → git-XBYBZB4R.mjs} +4 -4
  57. package/dist/cli/index.js +82 -78
  58. package/dist/cli/index.mjs +45 -41
  59. package/dist/cli/{legacy-noops-26Y5NSU6.js → legacy-noops-AUNAFEZP.js} +7 -7
  60. package/dist/cli/{legacy-noops-25B7JCOZ.mjs → legacy-noops-OQP6VZKE.mjs} +4 -4
  61. package/dist/cli/{monitors-WRTHO7DT.mjs → monitors-L2HAAPAL.mjs} +7 -7
  62. package/dist/cli/{monitors-L3GFT4MG.js → monitors-QSIZG3CJ.js} +88 -88
  63. package/dist/cli/{org-BNCTGPWF.js → org-JUHQGBQE.js} +60 -60
  64. package/dist/cli/{org-ZTHOFVEO.mjs → org-UCSN5XRC.mjs} +4 -4
  65. package/dist/cli/play-2SNMTZGK.js +152 -0
  66. package/dist/cli/play-5AT2RB3M.mjs +152 -0
  67. package/dist/cli/{providers-MLOKTD6O.js → providers-CVG4L3VR.js} +7 -7
  68. package/dist/cli/{providers-SLAPPVMU.mjs → providers-GVPAPZ4L.mjs} +4 -4
  69. package/dist/cli/{quickstart-IWJLGET3.js → quickstart-7OIFIQG3.js} +5 -5
  70. package/dist/cli/{quickstart-LZRKZLNQ.mjs → quickstart-Y6ZU27LE.mjs} +3 -3
  71. package/dist/cli/{search-RCDGSNWW.mjs → search-4I2Y2NKK.mjs} +13 -5
  72. package/dist/cli/search-DS36UHOX.js +26 -0
  73. package/dist/cli/{secrets-GDPYV6OC.mjs → secrets-3Z4IUEBA.mjs} +4 -4
  74. package/dist/cli/{secrets-24KEMSCU.js → secrets-O2UFLU52.js} +13 -13
  75. package/dist/cli/{sessions-ST5XQQZN.mjs → sessions-OMAXRY5I.mjs} +4 -4
  76. package/dist/cli/{sessions-QOUUGVP3.js → sessions-T6MWWQRH.js} +5 -5
  77. package/dist/cli/{settings-V6Z775TO.mjs → settings-C47WXZY5.mjs} +7 -7
  78. package/dist/cli/{settings-4XWDMAA2.js → settings-R4LO5NMY.js} +74 -74
  79. package/dist/cli/{setup-W7SPZTUL.js → setup-FIUTV4DD.js} +41 -41
  80. package/dist/cli/{setup-QPZLP25U.mjs → setup-JPJVTIQ6.mjs} +6 -6
  81. package/dist/cli/{skills-QG22R2EI.mjs → skills-6WVTMKP5.mjs} +4 -4
  82. package/dist/cli/skills-GLPKPF7R.js +28 -0
  83. package/dist/cli/tools-L3YLQ7BR.js +38 -0
  84. package/dist/cli/tools-TKS77TNU.mjs +38 -0
  85. package/dist/cli/{update-5PSYBGVU.mjs → update-GD754XMA.mjs} +6 -6
  86. package/dist/cli/update-HXI35NME.js +28 -0
  87. package/dist/cli/{workflow-ZEQ46MGG.js → workflow-OCUQCNXA.js} +16 -16
  88. package/dist/cli/{workflow-EK7DV4AQ.mjs → workflow-YKQSPXQZ.mjs} +6 -6
  89. package/dist/{client-DpnkGBn-.d.mts → client-CtVdLZux.d.mts} +21 -4
  90. package/dist/{client-ypdBvf1o.d.ts → client-OBwghxPC.d.ts} +21 -4
  91. package/dist/{compiler-manifest-qtTNYvBl.d.ts → compiler-manifest-wOKNiXpa.d.mts} +21 -0
  92. package/dist/{compiler-manifest-qtTNYvBl.d.mts → compiler-manifest-wOKNiXpa.d.ts} +21 -0
  93. package/dist/index.d.mts +4 -4
  94. package/dist/index.d.ts +4 -4
  95. package/dist/index.js +13 -10
  96. package/dist/index.mjs +16 -13
  97. package/dist/install-integrity.json +84 -76
  98. package/dist/plays/bundle-play-file.d.mts +2 -2
  99. package/dist/plays/bundle-play-file.d.ts +2 -2
  100. package/dist/plays/bundle-play-file.mjs +2 -2
  101. package/dist/plays/run-request.d.mts +2 -2
  102. package/dist/plays/run-request.d.ts +2 -2
  103. package/dist/release.d.mts +1 -1
  104. package/dist/release.d.ts +1 -1
  105. package/dist/release.js +2 -2
  106. package/dist/release.mjs +1 -1
  107. package/package.json +1 -1
  108. package/dist/cli/auth-66JFXP6C.js +0 -31
  109. package/dist/cli/client-ADWRS22F.js +0 -20
  110. package/dist/cli/git-E56KOYJR.js +0 -23
  111. package/dist/cli/search-6FBDSA3K.js +0 -18
  112. package/dist/cli/skills-WKOQBJY7.js +0 -28
  113. package/dist/cli/update-WKVCWGYY.js +0 -28
@@ -0,0 +1,406 @@
1
+ // src/cli/described.ts
2
+ var SHAPE = "{}";
3
+ var SCHEMA_LINE_LIMIT = 100;
4
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ var NAMED_EXAMPLES = {
8
+ email: "ada@example.com",
9
+ domain: "example.com",
10
+ website: "example.com",
11
+ linkedin_url: "https://www.linkedin.com/in/ada-lovelace",
12
+ first_name: "Ada",
13
+ last_name: "Lovelace",
14
+ full_name: "Ada Lovelace"
15
+ };
16
+ function schemaType(schema) {
17
+ const brackets = (type) => type.includes(" | ") ? `(${type})` : type;
18
+ if (Array.isArray(schema.enum) && schema.enum.length) {
19
+ return {
20
+ type: schema.enum.map((value) => JSON.stringify(value)).join(" | ")
21
+ };
22
+ }
23
+ const alternatives = [schema.anyOf, schema.oneOf].find(Array.isArray);
24
+ if (alternatives) {
25
+ const parts = alternatives.map(
26
+ (option) => schemaType(isRecord(option) ? option : {})
27
+ );
28
+ const shaped = parts.find((part) => part.fields);
29
+ return {
30
+ type: parts.map(
31
+ (part) => part === shaped ? part.type : part.type.replace(SHAPE, "object")
32
+ ).join(" | "),
33
+ ...shaped ? { fields: shaped.fields } : {}
34
+ };
35
+ }
36
+ const types = [schema.type].flat().filter((type) => typeof type === "string");
37
+ const nullable = types.includes("null") ? " | null" : "";
38
+ const fields = fieldsOf(schema);
39
+ if (fields.length && !types.includes("array")) {
40
+ return { type: `${SHAPE}${nullable}`, fields };
41
+ }
42
+ if (types.includes("array")) {
43
+ const item = schemaType(isRecord(schema.items) ? schema.items : {});
44
+ return {
45
+ type: `${brackets(item.type)}[]${nullable}`,
46
+ ...item.fields ? { fields: item.fields } : {}
47
+ };
48
+ }
49
+ return {
50
+ type: types.filter((type) => type !== "null").join(" | ") + nullable || "unknown"
51
+ };
52
+ }
53
+ function schemaField(name, node, required) {
54
+ const schema = isRecord(node) ? node : {};
55
+ const { type, fields } = schemaType(schema);
56
+ const example = [
57
+ schema.example,
58
+ schema.default,
59
+ Array.isArray(schema.enum) ? schema.enum[0] : void 0,
60
+ type === "string" ? NAMED_EXAMPLES[name.toLowerCase()] : void 0
61
+ ].find((value) => value !== void 0);
62
+ return {
63
+ name,
64
+ type,
65
+ required,
66
+ ...example !== void 0 ? { example } : {},
67
+ ...typeof schema.description === "string" && schema.description ? { description: schema.description } : {},
68
+ ...fields ? { fields } : {}
69
+ };
70
+ }
71
+ function withoutRefs(node, root, depth = 0) {
72
+ if (Array.isArray(node)) {
73
+ return node.map((item) => withoutRefs(item, root, depth));
74
+ }
75
+ if (!isRecord(node)) return node;
76
+ const { $ref: ref, ...rest } = node;
77
+ if (typeof ref === "string") {
78
+ const definitions = isRecord(root) ? [root.$defs, root.definitions].filter(isRecord) : [];
79
+ const target = ref.startsWith("#/") ? ref.slice(2).split("/").reduce(
80
+ (at, key) => isRecord(at) ? at[key] : void 0,
81
+ root
82
+ ) : definitions.flatMap((group) => Object.values(group)).find((definition) => isRecord(definition) && definition.$id === ref);
83
+ return isRecord(target) && depth < 12 ? withoutRefs({ ...target, ...rest }, root, depth + 1) : rest;
84
+ }
85
+ return Object.fromEntries(
86
+ Object.entries(rest).map(([key, value]) => [
87
+ key,
88
+ key === "$defs" || key === "definitions" ? value : withoutRefs(value, root, depth)
89
+ ])
90
+ );
91
+ }
92
+ function schemaFields(schema) {
93
+ return fieldsOf(withoutRefs(schema, schema));
94
+ }
95
+ function fieldsOf(schema) {
96
+ if (!isRecord(schema)) return [];
97
+ const required = new Set(
98
+ Array.isArray(schema.required) ? schema.required.map(String) : []
99
+ );
100
+ const properties = isRecord(schema.properties) ? schema.properties : {};
101
+ const entries = Object.keys(properties).length ? Object.entries(properties) : (Array.isArray(schema.fields) ? schema.fields : []).map((field) => [
102
+ isRecord(field) ? field.name : "",
103
+ field
104
+ ]);
105
+ return entries.flatMap(
106
+ ([name, node]) => typeof name === "string" && name ? [
107
+ schemaField(
108
+ name,
109
+ node,
110
+ isRecord(node) && node.required === true || required.has(name)
111
+ )
112
+ ] : []
113
+ );
114
+ }
115
+ function rateLimitSummary(limits) {
116
+ const windows = {
117
+ 1e3: "second",
118
+ 6e4: "minute",
119
+ 36e5: "hour",
120
+ 864e5: "day"
121
+ };
122
+ const parts = (Array.isArray(limits) ? limits : []).flatMap((limit) => {
123
+ if (!isRecord(limit)) return [];
124
+ const { requestsPerWindow: requests, windowMs } = limit;
125
+ if (typeof requests !== "number" || typeof windowMs !== "number") return [];
126
+ return [
127
+ `${requests} requests/${windows[windowMs] ?? `${windowMs / 1e3}s`}`
128
+ ];
129
+ });
130
+ return parts.length ? parts.join(", ") : void 0;
131
+ }
132
+ function exampleValue(field) {
133
+ if (field.example !== void 0) return field.example;
134
+ const type = field.type.toLowerCase();
135
+ if (type.includes("[]")) return [];
136
+ if (type.startsWith(SHAPE) || type.startsWith("object")) return {};
137
+ if (type.startsWith("integer") || type.startsWith("number")) return 1;
138
+ if (type.startsWith("boolean")) return true;
139
+ return "...";
140
+ }
141
+ function shapeKey(fields) {
142
+ return JSON.stringify(
143
+ fields.map((field) => [
144
+ field.name,
145
+ field.required,
146
+ field.type,
147
+ field.fields ? shapeKey(field.fields) : null
148
+ ])
149
+ );
150
+ }
151
+ function pascalCase(text) {
152
+ return text.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean).map((word) => word[0].toUpperCase() + word.slice(1)).join("");
153
+ }
154
+ function namedShapes(roots) {
155
+ const seen = /* @__PURE__ */ new Map();
156
+ const visit = (field) => {
157
+ if (!field.fields) return;
158
+ const key = shapeKey(field.fields);
159
+ const entry = seen.get(key) ?? {
160
+ fields: field.fields,
161
+ count: 0,
162
+ descriptions: /* @__PURE__ */ new Set(),
163
+ under: field.name
164
+ };
165
+ entry.count += 1;
166
+ entry.descriptions.add(field.description ?? "");
167
+ seen.set(key, entry);
168
+ field.fields.forEach(visit);
169
+ };
170
+ roots.forEach(visit);
171
+ const taken = /* @__PURE__ */ new Set();
172
+ const named = /* @__PURE__ */ new Map();
173
+ for (const [key, entry] of seen) {
174
+ if (entry.count < 2) continue;
175
+ const [description] = entry.descriptions.size === 1 ? [...entry.descriptions] : [""];
176
+ const title = (description ?? "").split(/[.:]/)[0].trim();
177
+ const base = pascalCase(
178
+ title && title.split(/\s+/).length <= 3 ? title : entry.fields.length <= 3 ? entry.fields.map((field) => field.name).join(" ") : entry.under
179
+ ) || "Shape";
180
+ let name = base;
181
+ for (let n = 2; taken.has(name); n += 1) name = `${base}${n}`;
182
+ taken.add(name);
183
+ named.set(key, {
184
+ name,
185
+ fields: entry.fields,
186
+ ...description ? { description } : {}
187
+ });
188
+ }
189
+ return named;
190
+ }
191
+ function schemaBlocks(described, maxDepth, everyField = false) {
192
+ const sections = [
193
+ ["Inputs:", described.inputs],
194
+ ["CSV columns read from each row:", described.rowInputs ?? []],
195
+ ["Outputs:", described.outputs],
196
+ ["Columns added to each row:", described.rowOutputs ?? []],
197
+ [
198
+ "Raw response, as declared (read it from result.toolResponse.rawV2; check one real response for its nesting):",
199
+ everyField ? described.rawResponse ?? [] : []
200
+ ]
201
+ ];
202
+ const shapes = namedShapes(sections.flatMap(([, fields]) => fields));
203
+ const used = [];
204
+ const comment = (notes) => {
205
+ const shown = notes.filter(Boolean);
206
+ return shown.length ? ` // ${shown.join(" - ")}` : "";
207
+ };
208
+ const fieldLines = (field, indent, depth) => {
209
+ const example = field.example === void 0 ? void 0 : JSON.stringify(field.example);
210
+ const start = `${indent}${JSON.stringify(field.name)}${field.required ? "" : "?"}: `;
211
+ if (!field.fields) {
212
+ return [`${start}${field.type},${comment([example, field.description])}`];
213
+ }
214
+ const [before, after] = field.type.split(SHAPE);
215
+ const shape = shapes.get(shapeKey(field.fields));
216
+ if (shape) {
217
+ if (!used.includes(shape)) used.push(shape);
218
+ const own = field.description === shape.description ? void 0 : field.description;
219
+ return [`${start}${before}${shape.name}${after},${comment([own])}`];
220
+ }
221
+ if (depth >= maxDepth || field.summarized && !everyField) {
222
+ const names = field.fields.map((child) => child.name).join(", ");
223
+ return [
224
+ `${start}${before}{ ${names} }${after},${comment([field.description])}`
225
+ ];
226
+ }
227
+ return [
228
+ `${start}${before}{${comment([field.description])}`,
229
+ ...field.fields.flatMap(
230
+ (child) => fieldLines(child, `${indent} `, depth + 1)
231
+ ),
232
+ `${indent}}${after},`
233
+ ];
234
+ };
235
+ const block = (title, fields) => fields.length ? [
236
+ "",
237
+ title,
238
+ "{",
239
+ ...fields.flatMap((field) => fieldLines(field, " ", 1)),
240
+ "}"
241
+ ] : [];
242
+ const lines = sections.flatMap(([title, fields]) => block(title, fields));
243
+ const types = [];
244
+ for (let index = 0; index < used.length; index += 1) {
245
+ const shape = used[index];
246
+ types.push(
247
+ ` ${shape.name} = {${comment([shape.description])}`,
248
+ ...shape.fields.flatMap((field) => fieldLines(field, " ", 1)),
249
+ " }"
250
+ );
251
+ }
252
+ return [...lines, ...types.length ? ["", "Types:", ...types] : []];
253
+ }
254
+ function schemaLines(described, options) {
255
+ if (options.full) return schemaBlocks(described, Infinity, true);
256
+ const raw = described.rawResponse?.length ? [
257
+ "",
258
+ `Other response fields (${described.rawResponse.map((field) => field.name).join(", ")}) are in result.toolResponse.rawV2. --full-schema lists them.`
259
+ ] : [];
260
+ const full = schemaBlocks(described, Infinity);
261
+ if (full.length <= SCHEMA_LINE_LIMIT) return [...full, ...raw];
262
+ const folded = [3, 2].map((depth) => ({ depth, lines: schemaBlocks(described, depth) })).find(({ lines }) => lines.length <= SCHEMA_LINE_LIMIT) ?? {
263
+ depth: 1,
264
+ lines: schemaBlocks(described, 1)
265
+ };
266
+ return [
267
+ ...folded.lines,
268
+ ...raw,
269
+ "",
270
+ `This schema is long (${full.length} lines), so deeper objects show only their field names. --full-schema prints every field.`
271
+ ];
272
+ }
273
+ function safeIdentifier(name) {
274
+ return name.replace(/[^a-zA-Z0-9_$]+/g, "_").replace(/^[^a-zA-Z_$]+/, "") || "value";
275
+ }
276
+ function examples(described, options) {
277
+ const { runner } = described;
278
+ const required = described.inputs.filter((field) => field.required);
279
+ const shown = options.verbose ? described.inputs : required.length ? required : described.inputs.slice(0, 1);
280
+ const input = JSON.stringify(
281
+ Object.fromEntries(shown.map((field) => [field.name, exampleValue(field)]))
282
+ );
283
+ const read = options.verbose ? described.outputs : described.outputs.slice(0, 1);
284
+ const reads = (expression) => read.flatMap((field) => {
285
+ const source = expression(field);
286
+ return source ? [`const ${safeIdentifier(field.name)} = ${source};`] : [];
287
+ });
288
+ if (runner.via === "monitor") return { cli: runner.deploy, play: null };
289
+ if (runner.via === "tool") {
290
+ return {
291
+ cli: `deepline tools execute ${runner.toolId} --input '${input}'`,
292
+ play: [
293
+ "const result = await ctx.tools.execute({",
294
+ ` id: '${safeIdentifier(runner.toolId)}',`,
295
+ ` tool: '${runner.toolId}',`,
296
+ ` input: ${input},`,
297
+ "});",
298
+ ...reads((field) => field.read)
299
+ ].join("\n")
300
+ };
301
+ }
302
+ return {
303
+ cli: runner.cli ?? `deepline plays run ${runner.reference} --input '${input}'`,
304
+ play: [
305
+ `const output = await ctx.runPlay('${safeIdentifier(runner.reference.replace(/^.*\//, ""))}', '${runner.reference}', ${input});`,
306
+ ...reads((field) => `output.${field.name}`)
307
+ ].join("\n")
308
+ };
309
+ }
310
+ var EXPLANATIONS = {
311
+ tool: {
312
+ cli: "--input takes a JSON object or @file.json. The result prints when the call finishes; add --json for the full result payload.",
313
+ play: "id names the step and must stay stable. Read a declared output with its getter; every other provider field is in result.toolResponse.rawV2."
314
+ },
315
+ play: {
316
+ cli: "--input takes a JSON object or @file.json. The run waits and prints its output; add --json for the full result, or read it later with deepline runs get <run-id> --json.",
317
+ play: "The first argument is a stable key for the child run. The call waits and returns the output object."
318
+ },
319
+ monitor: {
320
+ cli: "A monitor type is deployed, not executed. Its inputs are the filters in the payload, and its events stream into your warehouse.",
321
+ play: ""
322
+ }
323
+ };
324
+ function describedLines(described, view) {
325
+ const { cli, play } = examples(described, view);
326
+ const explanation = EXPLANATIONS[described.runner.via];
327
+ const indented = (text) => text.split("\n").map((line) => ` ${line}`);
328
+ const section = (lines) => lines.length ? ["", ...lines] : [];
329
+ return [
330
+ `${described.id} [${described.kind.replace("_", " ")}]`,
331
+ ...described.displayName ? [described.displayName] : [],
332
+ ...described.description ? [described.description] : [],
333
+ ...described.cost ? [`Cost: ${described.cost}`] : [],
334
+ ...described.guidance.map((line) => `Guidance: ${line}`),
335
+ ...described.rateLimit ? [`Rate limit: ${described.rateLimit}`] : [],
336
+ ...schemaLines(described, { full: view.fullSchema }),
337
+ ...section(
338
+ view.cli ? [
339
+ "Run from the CLI:",
340
+ ...indented(cli),
341
+ ...view.explain ? indented(explanation.cli) : []
342
+ ] : []
343
+ ),
344
+ ...section(
345
+ view.play && play ? [
346
+ "Run in a play:",
347
+ ...indented(play),
348
+ ...view.explain ? indented(explanation.play) : []
349
+ ] : []
350
+ ),
351
+ ...section(described.source ? [`Source: ${described.source}`] : []),
352
+ "",
353
+ "For more detail or examples, see deepline describe --help."
354
+ ];
355
+ }
356
+ function topLevelField({ fields: _fields, ...field }) {
357
+ return { ...field, type: field.type.replace(SHAPE, "object") };
358
+ }
359
+
360
+ // src/cli/describe-options.ts
361
+ function addDescribeOptions(command, options = {}) {
362
+ command.option(
363
+ "--prebuilt",
364
+ "Show the Deepline tool or play, not a play your workspace created under the same name"
365
+ ).option("--tool", "Same as --prebuilt").option(
366
+ "--verbose",
367
+ "Examples fill in every input and read every output, not only required ones"
368
+ ).option(
369
+ "--cli-example",
370
+ "Show only the CLI example, and explain how it takes inputs and returns outputs"
371
+ ).option(
372
+ "--play-example",
373
+ "Show only the in-play example, and explain how it takes inputs and returns outputs"
374
+ ).option("--no-example", "Hide the run examples").option(
375
+ "--full-schema",
376
+ `Print every field: a long schema unfolded (over ${SCHEMA_LINE_LIMIT} lines), list rows, and a tool's raw response`
377
+ ).option(
378
+ "-o, --out <path>",
379
+ "Save the output to this file instead of printing it"
380
+ );
381
+ if (options.schemaOnly !== false) {
382
+ command.option(
383
+ "--schema-only",
384
+ "Print only the schema, with every field, and nothing else"
385
+ );
386
+ }
387
+ if (options.json !== false) {
388
+ command.option(
389
+ "--json",
390
+ "Print JSON instead of text; with --schema-only, only the input and output JSON Schemas"
391
+ );
392
+ }
393
+ return command;
394
+ }
395
+
396
+ export {
397
+ SCHEMA_LINE_LIMIT,
398
+ schemaField,
399
+ schemaFields,
400
+ rateLimitSummary,
401
+ schemaLines,
402
+ examples,
403
+ describedLines,
404
+ topLevelField,
405
+ addDescribeOptions
406
+ };