deepline 0.3.357 → 0.3.359

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 (103) hide show
  1. package/dist/bundling-sources/sdk/src/release.ts +7 -1
  2. package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +14 -1
  3. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +52 -19
  4. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +35 -18
  5. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +202 -44
  6. package/dist/cli/auth-CN5UHM3M.js +33 -0
  7. package/dist/cli/{auth-5Y2YV5LY.mjs → auth-ZOW4L37H.mjs} +6 -4
  8. package/dist/cli/{billing-UOFR7KDB.mjs → billing-JPMZX77W.mjs} +5 -5
  9. package/dist/cli/{billing-Y6IKDJ6H.js → billing-YZJ5Q4ZC.js} +74 -74
  10. package/dist/cli/{chunk-LJTZVC2T.mjs → chunk-36TKIMVG.mjs} +2 -2
  11. package/dist/cli/{chunk-SXXUOZRS.js → chunk-3EF4OMSE.js} +6 -1
  12. package/dist/cli/{chunk-2NZUC5OS.mjs → chunk-4DCOBHTZ.mjs} +4 -4
  13. package/dist/cli/{chunk-4YXJTQ5X.js → chunk-5ZKZWXVN.js} +5 -5
  14. package/dist/cli/{chunk-NZ6BT4NL.mjs → chunk-72362UER.mjs} +7 -7
  15. package/dist/cli/{chunk-5UNTNKNX.js → chunk-ARNODHMC.js} +6 -6
  16. package/dist/cli/{chunk-N47R7S3E.mjs → chunk-BJYW3XTM.mjs} +6 -1
  17. package/dist/cli/{chunk-SMLKQAEB.mjs → chunk-DZ34Z4DO.mjs} +3 -3
  18. package/dist/cli/{chunk-SCY4UCEZ.js → chunk-EMMXSY6F.js} +75 -50
  19. package/dist/cli/{chunk-VG5WMYSF.mjs → chunk-FCZIE4UQ.mjs} +3 -3
  20. package/dist/cli/{chunk-EWTVIN3O.js → chunk-I7XYIKAK.js} +47 -47
  21. package/dist/cli/{chunk-VXH4225Y.mjs → chunk-JHX6XSLT.mjs} +27 -2
  22. package/dist/cli/{chunk-ZYPSNUDU.js → chunk-LDGO56ZU.js} +231 -231
  23. package/dist/cli/{chunk-WQSV34KV.js → chunk-LXKJTNB3.js} +11 -11
  24. package/dist/cli/{chunk-O7IM72KW.mjs → chunk-M2DOAC65.mjs} +15 -15
  25. package/dist/cli/{chunk-R5P3KFF5.js → chunk-P4CCF5ZV.js} +8 -8
  26. package/dist/cli/{chunk-CPQIVH6G.js → chunk-QDLSDKEK.js} +8 -8
  27. package/dist/cli/chunk-QFBHEQCQ.mjs +1421 -0
  28. package/dist/cli/chunk-QILHWZFP.js +1421 -0
  29. package/dist/cli/{chunk-C2EHMMME.js → chunk-SVAI3Z3Q.js} +64 -60
  30. package/dist/cli/{chunk-2AROJ4EZ.mjs → chunk-U2G2WO43.mjs} +2 -2
  31. package/dist/cli/{chunk-6P235JSN.js → chunk-UC6KM43R.js} +15 -15
  32. package/dist/cli/{chunk-XYD76KJB.mjs → chunk-UKXON54N.mjs} +8 -8
  33. package/dist/cli/{chunk-NEMHJYA4.js → chunk-VGXKDHTJ.js} +2 -2
  34. package/dist/cli/{chunk-J4A4MRBK.js → chunk-WLDT7GTI.js} +26 -26
  35. package/dist/cli/{chunk-IWBFG4XI.mjs → chunk-WNBXT425.mjs} +1 -1
  36. package/dist/cli/{chunk-PJYCAGKK.mjs → chunk-WR7H6MZ6.mjs} +1 -1
  37. package/dist/cli/{chunk-QYCAH7SM.mjs → chunk-ZY6QZZ5K.mjs} +6 -2
  38. package/dist/cli/{client-23QTYYIR.mjs → client-32IMOGBO.mjs} +4 -4
  39. package/dist/cli/client-TNHDPNDK.js +20 -0
  40. package/dist/cli/command-docs.d.mts +50 -0
  41. package/dist/cli/command-docs.d.ts +50 -0
  42. package/dist/cli/command-docs.js +13 -0
  43. package/dist/cli/command-docs.mjs +13 -0
  44. package/dist/cli/{csv-VKEF5C65.mjs → csv-4QWZUAJP.mjs} +3 -3
  45. package/dist/cli/{csv-SQIEBX66.js → csv-BCPDP5UL.js} +12 -12
  46. package/dist/cli/{db-Z33ZRE3N.js → db-OF2SH2BI.js} +30 -30
  47. package/dist/cli/{db-KX7FDHL4.mjs → db-T4CMZPJQ.mjs} +5 -5
  48. package/dist/cli/{describe-K2SJ22B3.mjs → describe-5WQ55FIR.mjs} +16 -16
  49. package/dist/cli/{describe-5ZQ6KIJH.js → describe-LIHZ4U6X.js} +21 -21
  50. package/dist/cli/{executions-KCZZY6SS.js → executions-JSXFOVBH.js} +7 -7
  51. package/dist/cli/{executions-452G2REF.mjs → executions-R7WAC2JA.mjs} +5 -5
  52. package/dist/cli/{feedback-55HU4EQY.mjs → feedback-2V5PBCPX.mjs} +3 -3
  53. package/dist/cli/{feedback-BM7ZNH7Y.js → feedback-Y42C4WP2.js} +7 -7
  54. package/dist/cli/git-D5SJIU36.js +23 -0
  55. package/dist/cli/{git-CAPESVAJ.mjs → git-Y6VXODAK.mjs} +4 -4
  56. package/dist/cli/index.js +183 -83
  57. package/dist/cli/index.mjs +145 -45
  58. package/dist/cli/{legacy-noops-PV5AWTIZ.js → legacy-noops-KDRTNUUC.js} +7 -7
  59. package/dist/cli/{legacy-noops-3B3MG33Y.mjs → legacy-noops-YEEZNYIS.mjs} +4 -4
  60. package/dist/cli/{monitors-43R6CUFK.mjs → monitors-7GHIY5BR.mjs} +5 -5
  61. package/dist/cli/{monitors-DVFEJHQT.js → monitors-RVXH73TC.js} +86 -86
  62. package/dist/cli/{org-BGCB45VI.js → org-OMUUGH6W.js} +61 -61
  63. package/dist/cli/{org-X5WSLJRD.mjs → org-ZGU7BBDD.mjs} +5 -5
  64. package/dist/cli/{play-OFO6XZ5L.mjs → play-PB6LSSNG.mjs} +11 -11
  65. package/dist/cli/play-XKIDMLH7.js +153 -0
  66. package/dist/cli/{providers-L2MPYA3E.mjs → providers-GFR4DPBC.mjs} +5 -5
  67. package/dist/cli/{providers-RJYHQC4J.js → providers-J3OTP5VK.js} +8 -8
  68. package/dist/cli/{quickstart-E6OWYYMT.js → quickstart-ALUTGFAA.js} +7 -7
  69. package/dist/cli/{quickstart-NHFMGZ3B.mjs → quickstart-MXH3LZQ5.mjs} +5 -5
  70. package/dist/cli/{search-IPTZAOUE.mjs → search-OVRR4XOJ.mjs} +6 -6
  71. package/dist/cli/search-X3IZW2TP.js +26 -0
  72. package/dist/cli/{secrets-6LD4CA2X.js → secrets-KT4OFUKB.js} +14 -14
  73. package/dist/cli/{secrets-TCOPPNXR.mjs → secrets-VXXVGDET.mjs} +5 -5
  74. package/dist/cli/{sessions-QV4LUKEP.js → sessions-GXDEX5EM.js} +5 -5
  75. package/dist/cli/{sessions-D4JETMAW.mjs → sessions-JP4XKXEJ.mjs} +4 -4
  76. package/dist/cli/{settings-JOYKXSY7.js → settings-BJT3RAJD.js} +75 -75
  77. package/dist/cli/{settings-IVJPCORG.mjs → settings-MMC5Q5FJ.mjs} +8 -8
  78. package/dist/cli/{setup-WCKQK7FE.mjs → setup-6LWUQ34C.mjs} +8 -8
  79. package/dist/cli/{setup-MIJZTYMH.js → setup-RP4VN7WE.js} +43 -43
  80. package/dist/cli/skills-3S5UET5W.js +28 -0
  81. package/dist/cli/{skills-GYWMUDDF.mjs → skills-VRVG63GO.mjs} +4 -4
  82. package/dist/cli/{tools-ILYNEPGQ.mjs → tools-M4VNLWYB.mjs} +8 -8
  83. package/dist/cli/tools-MTRW5VF6.js +40 -0
  84. package/dist/cli/update-5PPNAWY7.js +28 -0
  85. package/dist/cli/{update-P3VIHMC6.mjs → update-HXQVI37L.mjs} +6 -6
  86. package/dist/cli/{workflow-YWKK3A4X.js → workflow-JTA3DWCM.js} +19 -19
  87. package/dist/cli/{workflow-A6ID4C6N.mjs → workflow-PE2IONVL.mjs} +9 -9
  88. package/dist/index.js +13 -13
  89. package/dist/index.mjs +12 -12
  90. package/dist/install-integrity.json +80 -74
  91. package/dist/release.d.mts +5 -1
  92. package/dist/release.d.ts +5 -1
  93. package/dist/release.js +2 -2
  94. package/dist/release.mjs +1 -1
  95. package/package.json +6 -1
  96. package/dist/cli/auth-AABYKR2S.js +0 -31
  97. package/dist/cli/client-3DYV3HZ4.js +0 -20
  98. package/dist/cli/git-VESXOJ4M.js +0 -23
  99. package/dist/cli/play-ZO4HDGMC.js +0 -153
  100. package/dist/cli/search-2FJA6OH4.js +0 -26
  101. package/dist/cli/skills-JL4J5CII.js +0 -28
  102. package/dist/cli/tools-ZOKG4AX4.js +0 -40
  103. package/dist/cli/update-WUMDEAEE.js +0 -28
@@ -0,0 +1,1421 @@
1
+ // src/cli/command-docs.ts
2
+ var CONVENTIONS = `
3
+ Conventions (apply to every command):
4
+ Output mode: structured commands print JSON automatically when stdout is not
5
+ a terminal, which is the case inside agent tool shells. --json forces it in
6
+ a terminal. search is the exception: readable unless --json.
7
+ Streams: stdout carries only the command result. Progress, update notices,
8
+ skills-sync notes, and warnings go to stderr.
9
+ Piping JSON: 2>&1 puts stderr text in front of the JSON, so the parse fails
10
+ and the real error is hidden; | head and | tail cut the document. Parse
11
+ stdout alone (--json | python3 ..., or --json > out.json).
12
+ JSON envelope: most payloads include render.sections[].lines (the human
13
+ summary as text), next.* (exact follow-up commands; run commands name
14
+ them actions.*Cmd), and command_context.
15
+ Read render.sections when you want the short human view of a JSON result.
16
+ File inputs: every --input, --payload, and --sql flag accepts inline text or
17
+ @path to read the value from a local file, for example --input @input.json.
18
+ Ids: play references look like prebuilt/person-to-phone-batch or
19
+ <workspace-slug>/my-play; run ids look like
20
+ play/<play-ref>/run/<timestamp>-<suffix> and are printed by plays run.
21
+ Large results: prefer the narrower command over post-processing a big
22
+ payload: runs export for rows, billing usage --run-id for cost,
23
+ --compact where offered, and runs get without --full.
24
+ Exit codes: 0 success; 2 usage or local input error; 3 auth or permission;
25
+ 4 not found; 5 server, runtime, or provider failure; 7 validation or
26
+ check failed.
27
+ Help detail: the first --help for a command prints its full explanation,
28
+ with field-level output references and edge cases; later ones print the
29
+ core section. --help --verbose prints the full explanation again;
30
+ --help --quiet prints commander help only.
31
+ `;
32
+ var COMMAND_DOCS = {
33
+ "": {
34
+ core: `
35
+ Make sure to run --help before running a command, you'll often find its
36
+ behavior has some differences from your expectations!
37
+
38
+ What Deepline is for:
39
+ Deepline runs GTM data work: find companies and people, resolve emails and
40
+ phones, research accounts, and keep durable, resumable runs of that work.
41
+ Three nouns cover almost everything:
42
+ tools one provider or API operation (search, enrich, verify). Atomic,
43
+ priced per call. Discover with search, inspect with tools
44
+ describe, call with tools execute.
45
+ plays a durable workflow, usually a prebuilt waterfall over a CSV. Discover
46
+ with search, read the contract with plays describe, start with
47
+ plays run.
48
+ runs one execution of a play: status, rows, logs, cost, and export.
49
+ Inspect with runs get, download rows with runs export.
50
+
51
+ The agent path for a typical task:
52
+ deepline --help prints the CLI version and the auth state on its first two
53
+ lines, checked live. Do not run version or auth status as well.
54
+ 1. deepline preflight only when you need the credit balance
55
+ 2. deepline search "<input you have -> result you need>"
56
+ one search over prebuilt plays, tools, your
57
+ workspace's plays, and monitor types
58
+ 3. deepline plays describe <ref> read required input, CSV columns, output
59
+ 4. deepline plays run <ref> --input '{"csv":"file.csv"}' waits, prints run id
60
+ 5. deepline runs export <run-id> --out result.csv rows as CSV
61
+ 6. deepline billing usage --run-id <run-id> what it cost
62
+ Use tools execute only when no play covers the job or for one-off lookups.
63
+ ${CONVENTIONS}`,
64
+ verbose: `
65
+ Working rules:
66
+ Search with the task as one sentence, not keywords: search "50 seed-stage
67
+ company domains -> each company's lead investors".
68
+ Results are ranked for what you have and what you need, and each one
69
+ names its kind: prebuilt play, tool, custom play, or monitor type.
70
+ A CSV goes through the batch form of a prebuilt play, never one
71
+ single-record run per row: plays run prebuilt/<play>-batch --input
72
+ '{"csv":"leads.csv"}', then runs export <run-id> --out <path>. Work
73
+ emails: person-to-email-batch takes the whole file in one run. Each row
74
+ tries its LinkedIn profile first and falls through to name and company
75
+ domain, so do not split the file or run a second pass. Phones: a known
76
+ person -> person-to-phone-batch.
77
+ The balance is a ceiling, not a budget to use up. Before each paid call,
78
+ estimate its cost: the price from tools describe <tool> --pricing-only or
79
+ plays list --show-cost, times the results or rows you will request. Take
80
+ the cheapest route that can answer and test it with the smallest limit.
81
+ If one tool call would cost more than about 5 credits, lower its limit or
82
+ find a cheaper route first. Never top up, buy credits, or change billing
83
+ unless the user asks. When the balance runs out, stop spending, deliver
84
+ the rows you have, and name the rows left unresolved.
85
+ Pilot before scale: run the play on a small slice, read its actual cost
86
+ with billing usage --run-id <run-id>, then run the full file under the
87
+ same play. A stated-scope input of about 25 rows or fewer is its own
88
+ pilot: run it once.
89
+
90
+ Choosing between tools and plays:
91
+ A play is the right choice when the job has rows (a CSV) or needs more than
92
+ one provider in sequence: waterfalls stop at the first verified hit, reuse
93
+ completed rows on rerun, and persist results in the customer database. A
94
+ tool is right for one lookup, a search that returns candidates, or when
95
+ search returns no play that fits. Tools have no retry, no row memory,
96
+ and no export; you get one JSON response.
97
+
98
+ Reading results without parsing:
99
+ Every structured payload carries render.sections, a list of titled line
100
+ groups that is exactly what a terminal user would see. When a result is
101
+ large, read render.sections first, then the specific field you need.
102
+
103
+ Auth in non-interactive shells:
104
+ When the Auth line of deepline --help says not connected, stop and report
105
+ it; auth register needs a browser approval and auth register --wait blocks
106
+ until it happens, so an unattended agent must not call it.
107
+
108
+ Skills:
109
+ The bare skills command reinstalls the Deepline skill files on disk. To see
110
+ which skills are installed without changing anything, run
111
+ skills --dry-run --json and read the plan.
112
+ `
113
+ },
114
+ preflight: {
115
+ core: `
116
+ Purpose:
117
+ One read-only call that reports server health, whether this shell is
118
+ authenticated, and the workspace's Deepline credit balance.
119
+ When:
120
+ Once at the start of a task, before the first paid call. Its balance is the
121
+ balance for the whole task; do not repeat preflight, auth status, or billing
122
+ balance later unless a command fails with an auth or balance error.
123
+ Input:
124
+ No arguments. --json forces JSON in a terminal (automatic when piped).
125
+ Output (JSON):
126
+ status ("ok" or "error"), cli_version, host, health.status, auth.connected
127
+ (boolean),
128
+ auth.org_name, billing.balance (number of Deepline credits),
129
+ billing.balance_display, billing.balance_status, and render.sections with
130
+ the four-line human summary.
131
+ Cost:
132
+ Free. Makes no provider calls.
133
+ Avoid:
134
+ Do not treat auth.connected false as something to fix with auth register in
135
+ an unattended shell; report it instead.
136
+ `,
137
+ verbose: `
138
+ Output fields:
139
+ health.status "ok" when the API answered; anything else means the host
140
+ is unreachable or degraded and paid work should not start.
141
+ health.version API version string, currently "v2".
142
+ auth.status "claimed" for a working key; auth.connected mirrors it as
143
+ a boolean and is the field to branch on.
144
+ auth.org_id/org_name the workspace every following command will bill.
145
+ auth.rate_limit_tier informational.
146
+ billing.balance Deepline credits available now. Compare it with a play's
147
+ cost estimate (plays list --show-cost) times the row
148
+ count before running a large file.
149
+ billing.rough_usd_balance the same balance in approximate USD.
150
+ billing.balance_status "active" normally; other values mean the workspace
151
+ cannot spend and runs will fail with a balance error.
152
+ Related:
153
+ health (server only), auth status (identity only), billing balance (credits
154
+ only). preflight is the union and is the one to prefer.
155
+ `
156
+ },
157
+ health: {
158
+ core: `
159
+ Purpose:
160
+ Read-only connectivity check that prints the server's raw health payload.
161
+ When:
162
+ Only when preflight reports a health problem and you want the raw payload,
163
+ or with --play-runner to prove the whole play execution plane works.
164
+ Input:
165
+ No arguments. --play-runner runs a tiny no-provider play end to end.
166
+ Output (JSON):
167
+ The server health object (status, version). With --play-runner, a run
168
+ summary for the smoke play.
169
+ Cost:
170
+ Free. --play-runner uses no providers.
171
+ Avoid:
172
+ Do not use health to check auth or balance; preflight covers all three.
173
+ `
174
+ },
175
+ "auth status": {
176
+ core: `
177
+ Purpose:
178
+ Report which Deepline host, workspace, and user this shell is authenticated
179
+ as, without changing anything.
180
+ When:
181
+ When you need the workspace name or id, or to confirm auth after a 3 exit
182
+ code. For the routine start-of-task check, prefer preflight.
183
+ Input:
184
+ No arguments. --auth-scope folder|global reads one auth store only.
185
+ --reveal persists the API key into the local auth file; do not use it.
186
+ Output (JSON):
187
+ host, hostStatus, status ("claimed" when authenticated), connected
188
+ (boolean), workspace {id, name, slug}, user {id}, render.sections.
189
+ Cost:
190
+ Free.
191
+ Avoid:
192
+ connected false in an unattended shell is a stop-and-report condition, not
193
+ a prompt to run auth register.
194
+ `
195
+ },
196
+ "auth register": {
197
+ core: `
198
+ Purpose:
199
+ Start a device-style login: it prints an approval URL, and once a person
200
+ approves it in a browser the shell receives a workspace API key.
201
+ When:
202
+ Only in an interactive session where a person can open the URL. Never in an
203
+ unattended agent shell: the command has nothing to do until a human acts.
204
+ Input:
205
+ No arguments. It opens the approval page and waits for approval; keep that
206
+ default. In Cowork it prints the link and returns, and auth wait finishes
207
+ the login.
208
+ Output:
209
+ The approval URL and, after approval, the connected workspace.
210
+ Cost:
211
+ Free.
212
+ Avoid:
213
+ If auth status says connected false and you cannot open a browser, report
214
+ that Deepline is not connected and stop.
215
+ `
216
+ },
217
+ "auth wait": {
218
+ core: `
219
+ Purpose:
220
+ Poll a pending auth register approval until it completes or times out.
221
+ When:
222
+ After auth register returned before approval, as it does in Cowork, and a
223
+ person is approving it in a browser.
224
+ Input:
225
+ No arguments beyond the pending registration it finds locally.
226
+ Output:
227
+ The connected workspace once approved; a timeout error otherwise.
228
+ Cost:
229
+ Free.
230
+ `
231
+ },
232
+ "billing balance": {
233
+ core: `
234
+ Purpose:
235
+ Read the workspace's current Deepline credit balance.
236
+ When:
237
+ After a run reports a balance or insufficient-credits error, or when you
238
+ need only the balance and preflight was not run. preflight already
239
+ includes this number; do not call both at the start of a task.
240
+ Input:
241
+ No arguments. Prints one line, "Balance: N credits". --verbose adds
242
+ reservations and usage awaiting settlement; --json returns the full record.
243
+ Output (JSON):
244
+ balance (Deepline credits), balance_display, rough_usd_balance,
245
+ balance_status, and render.sections. The balance includes other activity
246
+ in the workspace, so a before and after difference does not isolate one
247
+ command; use billing usage for that.
248
+ Cost:
249
+ Free.
250
+ `
251
+ },
252
+ "billing usage": {
253
+ core: `
254
+ Purpose:
255
+ Read what the workspace, or one run, has spent in Deepline credits.
256
+ When:
257
+ After a run finishes, to report its actual cost: billing usage --run-id
258
+ <run-id>. This is the canonical per-run cost read; runs get does not
259
+ include cost unless you pass --full.
260
+ Input:
261
+ --run-id <run-id> scopes the spend to one play run. --limit and --cursor
262
+ page the recent-call list. --json forces JSON.
263
+ Output (JSON):
264
+ balance, usage.last_30_days_usage_credits, usage.month_spent_credits, and
265
+ with --run-id: run.spent_credits, run.rough_usd_spent, run.event_count.
266
+ render.sections includes a "Run spend: N Deepline Credits" line.
267
+ Cost:
268
+ Free.
269
+ Avoid:
270
+ Do not grep a runs get payload for cost; use this command.
271
+ `,
272
+ verbose: `
273
+ Output fields:
274
+ balance, balance_display, rough_usd_balance the same balance preflight shows.
275
+ plan.usd_per_credit conversion used for rough USD.
276
+ usage.month_spent_credits spend in the current period.
277
+ usage.last_30_days_usage_credits trailing-30-day spend.
278
+ usage.temporary_hold_credits credits held by active runs.
279
+ run (only with --run-id) {run_id, spent_credits,
280
+ rough_usd_spent, event_count};
281
+ null when the run has no
282
+ billing events yet.
283
+ quota.* monthly cap, when enabled.
284
+ recent activity one line per billed call in
285
+ render.sections, newest first.
286
+ Cases:
287
+ A run that is still active shows a partial spend; read it again after the
288
+ run reaches completed or failed.
289
+ A failed run with row failures still shows spend for the rows that ran.
290
+ `
291
+ },
292
+ search: {
293
+ core: `
294
+ Purpose:
295
+ One ranked search across everything Deepline can run: provider tools,
296
+ prebuilt plays, plays this workspace created, and monitor types. Each
297
+ result names its kind.
298
+ When:
299
+ First, for any task where you do not already know the exact play or tool.
300
+ Search once with the task; there is no separate search for plays and for
301
+ tools.
302
+ Input:
303
+ One argument: the task as a sentence, written as the input you have ->
304
+ the result you need, for example "50 company domains -> each one's lead
305
+ investors". Do not send keywords; the sentence is what ranks the results.
306
+ --type narrows to tools, prebuilts, custom, plays (prebuilts
307
+ and custom), or monitors, and --exclude leaves kinds out; both take a
308
+ comma-separated list. --categories <a,b> and --search_terms <a,b> filter
309
+ tools and work without a task. --limit (1-50) and --offset page.
310
+ Output:
311
+ A readable ranked list by default, also when piped; read that form. With
312
+ --json: results[] where each item has id, kind (tool, prebuilt_play,
313
+ custom_play, monitor_type), displayName, and description. A tool adds
314
+ provider, categories, inputFields, pricing, connected, and executeCommand;
315
+ a play adds reference, inputFields, describeCommand, and runCommand. Also
316
+ kinds, count, total, next_offset when there is another page, and
317
+ render.sections.
318
+ Cost:
319
+ Free.
320
+ Next:
321
+ describe <id> reads any result, whatever its kind. Then plays run for a
322
+ play, tools execute for a tool. When a play and a tool both fit a job with
323
+ rows, take the play.
324
+ Avoid:
325
+ Do not hardcode a provider list; search returns what this workspace can
326
+ call now. Do not run anything from search output alone; describe it first.
327
+ tools search and plays search are deprecated aliases of this command.
328
+ `
329
+ },
330
+ describe: {
331
+ core: `
332
+ Purpose:
333
+ The contract for anything search returns: a tool, a play, or a monitor
334
+ type. What it is, cost, inputs, outputs, and an example of running it from
335
+ the CLI and from inside a play.
336
+ When:
337
+ After search and before the first run of something you have not used. You
338
+ do not say which kind the id is.
339
+ Input:
340
+ The id or reference from search. --verbose fills in every input and reads
341
+ every output in the examples; --cli-example and --play-example print one
342
+ example; --schema-only prints only the schema; --full-schema unfolds a
343
+ schema over 100 lines; --out <path> saves the output; --json prints JSON.
344
+ A play your workspace created is shown instead of a Deepline tool or
345
+ prebuilt play of the same name; --prebuilt shows the Deepline one.
346
+ Output:
347
+ Readable text by default, also when piped; read that form. With --json:
348
+ kind, id, displayName, description, cost, inputs[], outputs[], and
349
+ runExamples {cli, play}, plus the fields tools describe or plays describe
350
+ returns for that kind.
351
+ Cost:
352
+ Free.
353
+ Avoid:
354
+ tools describe and plays describe are this command limited to one kind and
355
+ keep their own flags (--pricing-only, --examples-only, --getters-only).
356
+ `
357
+ },
358
+ tools: {
359
+ core: `
360
+ Purpose:
361
+ The atomic provider layer: one operation per call (search people, enrich a
362
+ company, verify an email), priced per call in Deepline credits.
363
+ When:
364
+ For one-off lookups, candidate searches, or when search finds no play
365
+ for the job. For CSV-shaped work use a play instead: plays retry,
366
+ reuse completed rows, and export.
367
+ The sequence:
368
+ search <words> ranked tools and plays for an intent
369
+ tools describe <id> required input fields, pricing, output shape
370
+ tools execute <id> --input '{...}' run it
371
+ Cost:
372
+ search, describe, list, and grep are free. execute can spend credits; the
373
+ price is in tools describe <id> --pricing-only.
374
+ `
375
+ },
376
+ "tools grep": {
377
+ core: `
378
+ Purpose:
379
+ Literal, case-insensitive filtering of the tool registry by id, provider,
380
+ description, categories, or input field names.
381
+ When:
382
+ When you know a provider or field name and want every matching tool rather
383
+ than a ranked guess. Use search for intent queries.
384
+ Input:
385
+ A query; --mode all (default, AND), any (OR), or phrase; --categories.
386
+ Output (JSON):
387
+ tools[] with id, provider, displayName, description, categories, and
388
+ executeCommand.
389
+ Cost:
390
+ Free.
391
+ `
392
+ },
393
+ "tools list": {
394
+ core: `
395
+ Purpose:
396
+ Browse tool categories, or list every tool in one category exhaustively.
397
+ When:
398
+ To see what kinds of tools exist (bare tools list) or to enumerate one
399
+ category without ranking (tools list email_finder).
400
+ Input:
401
+ Optional positional category. --json forces JSON.
402
+ Output (JSON):
403
+ Bare: one entry per category with its tool count. With a category: one row
404
+ per tool with required inputs and a pricing hint. Never truncated.
405
+ Cost:
406
+ Free.
407
+ `
408
+ },
409
+ "tools describe": {
410
+ core: `
411
+ Purpose:
412
+ The contract for one tool: what it does, required inputs, pricing, and
413
+ output shape. Read it before the first execute of a tool you have not used.
414
+ When:
415
+ Always before paying for an unfamiliar tool; the input schema is the only
416
+ reliable source of field names.
417
+ Input:
418
+ The tool id. Prints readable text by default, also when piped; read that
419
+ form and pass --json only for a program. --pricing-only, --schema-only,
420
+ --examples-only, --getters-only print one section. --out <path> saves the
421
+ output to a file. get is an alias of describe, and deepline describe <id>
422
+ is the same read for a tool, a play, or a monitor type.
423
+ Output (JSON):
424
+ kind, id, cost {displayText, unit, billingMode}, inputs[] {name, type,
425
+ required, example}, outputs[] {name, type, read}, runExamples {cli, play},
426
+ toolId, provider, displayName, bestFor, description, categories,
427
+ inputSchema.fields[] {name, required, type, description},
428
+ inputSchema.jsonSchema, outputSchema, pricing {displayText, unit,
429
+ creditsPerUnit, usdPerUnit}, billingSource, connected, credentialStatus,
430
+ guidance (usage notes for the provider and the tool), examples[] (an
431
+ illustrative input and response, not an observed one), usageGuidance,
432
+ extractors (list paths for row-shaped output).
433
+ Cost:
434
+ Free.
435
+ Avoid:
436
+ Do not guess field names from the tool id; read inputSchema.fields.
437
+ The declared output shape and getters are the contract, and a tool can
438
+ return something else at runtime: a declared getter that is missing, or a
439
+ full list where one value is declared. Run one row and read what it
440
+ returned before building a play column on a getter.
441
+ A field with no declared getter is read from toolResponse.rawV2, with the
442
+ provider's nesting kept: .data and .data.data are different. A shape you
443
+ did not expect is a contract mismatch to fix, not a provider miss or an
444
+ invalid result.
445
+ `,
446
+ verbose: `
447
+ Output fields:
448
+ inputSchema.fields[] the flat list to build --input from. required true
449
+ fields must be present; type is string, integer,
450
+ boolean, object, or array.
451
+ inputSchema.jsonSchema the full JSON Schema when a field is an object, for
452
+ example provider filter objects.
453
+ pricing.displayText human price, for example "0.15 Deepline credits /
454
+ $0.015 per result".
455
+ pricing.unit what one price unit is: result, call, row, credit.
456
+ connected false means the provider needs a connected account or
457
+ key in this workspace; execute will fail with 3.
458
+ credentialStatus detail for connected false.
459
+ extractors / targetGetters JSON paths the CLI uses to turn the raw provider
460
+ response into rows; the same paths appear in tools
461
+ execute output as output_preview.listSourcePath.
462
+ usageGuidance provider-specific notes worth reading once.
463
+ Related:
464
+ tools execute <id> --input @file.json uses the same schema; runtime output
465
+ help for authoring a play appears under runtimeOutputHelp.
466
+ `
467
+ },
468
+ "tools execute": {
469
+ core: `
470
+ Purpose:
471
+ Run one provider tool with a JSON input and print its result.
472
+ When:
473
+ One-off lookups, searches that return candidates, or when no play covers the
474
+ job. Use a play for a CSV of rows.
475
+ Input:
476
+ Positional tool id, then the parameters in exactly one of these forms:
477
+ --input '{"email":"a@b.com"}' inline JSON object
478
+ --input @input.json read the JSON object from a file
479
+ -p email=a@b.com one key=value per -p, repeatable
480
+ --payload is an alias of --input. There is no --payload-file flag; use
481
+ @path. --out <file.csv> writes row-shaped output to a CSV file.
482
+ Output (JSON):
483
+ job_id, status ("completed" or a failure status), toolResponse.rawV2 (the
484
+ complete provider result), output_preview {kind, rowCount, columns, preview,
485
+ listSourcePath}, summary, next, render.sections. Errors return a non-zero
486
+ exit code and an error object, not a completed status.
487
+ Cost:
488
+ Spends Deepline credits per call at the price in tools describe. A search
489
+ with limit N is one call; it is not billed per result.
490
+ Avoid:
491
+ Do not wrap the result in shell parsing to find rows; output_preview
492
+ already lists the row path and the first rows, and --out writes the CSV.
493
+ Do not add 2>&1 when you parse --json: stderr text breaks the parse. A
494
+ failed call prints its error as JSON on stdout.
495
+ `,
496
+ verbose: `
497
+ Input rules:
498
+ The object must match inputSchema.fields from tools describe. Extra keys
499
+ are rejected by most providers. Nested filter objects (for example
500
+ crustdata_v3_* filters) must be passed as JSON, so use --input, not -p.
501
+ An @path value is read relative to the current directory.
502
+ Output fields:
503
+ toolResponse.rawV2 the complete provider response with its nesting
504
+ kept; toolResponse.raw is the older field beside it.
505
+ output_preview.kind "list" when the CLI found a row array; "value"
506
+ otherwise.
507
+ output_preview.listSourcePath the JSON path of that array inside
508
+ toolResponse, for example toolResponse.raw.companies.
509
+ output_preview.preview a bounded sample of rows; the full array is at the
510
+ listSourcePath, and --out writes all of it as CSV.
511
+ next.inspect the same command with --json, for debugging.
512
+ Cases:
513
+ Insufficient credits fail before the provider is called, with an
514
+ insufficient-credits error; check the preflight balance first.
515
+ A provider that needs a connected account fails with an auth or permission
516
+ error; tools describe shows connected false beforehand.
517
+ Free tools (run_javascript, free_* ids) never charge.
518
+ Related:
519
+ To run the same operation over many rows, put the rows in a CSV and use a
520
+ prebuilt play (search), or write one (plays --help).
521
+ `
522
+ },
523
+ plays: {
524
+ core: `
525
+ Purpose:
526
+ Durable workflows. Prebuilt plays are Deepline-maintained waterfalls such as
527
+ name-and-domain-to-email, person-linkedin-to-email, person-to-phone, and
528
+ company search, each with a single-row and a -batch (CSV) variant. A play
529
+ you write is one TypeScript file.
530
+ When:
531
+ Any job with rows, or any job that chains providers. A play reuses finished
532
+ rows on rerun, so a failed run can be resumed instead of repaid.
533
+ The sequence:
534
+ search "<input you have -> result you need>" find the play
535
+ plays describe <ref> required input, CSV columns, output fields
536
+ plays list --show-cost per-row or per-run credit estimate
537
+ plays run <ref> --input '{"csv":"file.csv"}' start and wait
538
+ runs export <run-id> --out out.csv rows
539
+ Writing a play:
540
+ Start from code that already works, not a blank file.
541
+ plays get prebuilt/<name> --source --out my.play.ts
542
+ copy the closest prebuilt and edit the copy
543
+ plays check my.play.ts validate after every edit; free
544
+ plays run my.play.ts --input '{...}' run the local file
545
+ plays publish my.play.ts make it live for plays run <name> and triggers
546
+ The file is: export default definePlay('name', async (ctx, input) => {...}).
547
+ --help --verbose lists the authoring rules.
548
+ Auditing plays:
549
+ plays list --json every saved play
550
+ plays versions --name <play> its revisions, and which one is live
551
+ plays get <play> --source --out <dir> a revision's source (--live,
552
+ --working, or --revision <n>)
553
+ plays check <file> deprecated or invalid usage, one hint per
554
+ issue; read-only and free
555
+ plays triggers every cron and webhook trigger
556
+ Cost:
557
+ search, describe, list, check, and get are free; run spends credits.
558
+ `,
559
+ verbose: `
560
+ Authoring rules:
561
+ Reach the outside world only through ctx: ctx.csv, ctx.dataset,
562
+ ctx.tools.execute, ctx.runPlay, ctx.step, ctx.fetch, ctx.secrets,
563
+ ctx.customerDb, and ctx.log. No fs, raw fetch, or shell commands, also not
564
+ inside ctx.step. Local nondeterministic work such as Date.now or
565
+ Math.random goes inside ctx.step.
566
+ A run can be interrupted and replayed from the top; every finished step
567
+ and tool call then returns its saved result. So the play name, each
568
+ ctx.dataset key, ctx.step id, ctx.fetch key, and ctx.tools.execute id is
569
+ a fixed string literal, and renaming one pays for that work again.
570
+ Rows: ctx.dataset('key', rows).withColumn('name', (row, rowCtx) => ...)
571
+ .run({ key: 'domain' }). Use a business identifier as the row key. Put
572
+ one paid call in a column, and shaping, status, and miss_reason in
573
+ separate plain columns after it. Return the dataset for anything that
574
+ should export as CSV.
575
+ Dataset handles are async: await rows.count(), rows.first(),
576
+ rows.peek(n), rows.materialize(n), or for await. Array methods on a
577
+ handle fail plays check.
578
+ Tool calls: rowCtx.tools.execute({ id, tool, input, description }). Read
579
+ results through the getters tools describe lists:
580
+ result.extractedValues.<name>.get() and
581
+ result.extractedLists.<name>.get(). A field with no getter is under
582
+ result.toolResponse.rawV2 with the provider's nesting kept.
583
+ staleAfterSeconds on the call sets how fresh a saved result must be.
584
+ Reuse before rebuilding: ctx.runPlay('prebuilt/<name>', input) runs a
585
+ prebuilt as one stage. Independent calls run together with Promise.all;
586
+ a call that needs another's result waits for it.
587
+ Failures: catch only ProviderTransientError, and only when another
588
+ provider can answer the same question. Keep the last provider outside
589
+ the catch so an exhausted waterfall fails loudly. Never branch on an
590
+ error message.
591
+ External APIs: ctx.fetch with a fixed key, and credentials through
592
+ ctx.secrets.bearer(...) or ctx.secrets.header(...), stored with deepline
593
+ secrets set. res.json is a property, not a method; check res.ok. A play
594
+ cannot loop ctx.fetch over pages: fan out over rows with ctx.dataset, or
595
+ call one endpoint that returns the whole result.
596
+ Triggers: a cron trigger receives {} unless its binding declares an input
597
+ object, written inline and pinned with the published revision.
598
+ Runtime: The default Play runtime is 30 minutes. For a bounded long batch
599
+ set the play option runtime: { timeout: '90m', size: 'standard' }, up to
600
+ 4h. That is not the CLI wait timeout.
601
+ Recurring sourcing: .run({ key: 'domain', mode: 'net_new' }) returns only
602
+ rows the table has not seen before.
603
+ Results: project each answer into flat columns (the value, its source,
604
+ whether it was validated, the outcome, the reason) and keep evidence
605
+ under _dl_meta, including result._metadata.execution.receiptKey. Unknown
606
+ stays null, not false.
607
+ Diagram: a /** @mermaid <name> */ block above the play draws it in the
608
+ dashboard, with // @mermaid-node <id> out:"<identifier>" above the
609
+ statement each box stands for. plays check validates it.
610
+ `
611
+ },
612
+ "plays grep": {
613
+ core: `
614
+ Purpose:
615
+ Full-text search over plays this workspace authored (not prebuilt ones).
616
+ When:
617
+ Finding a saved play by a phrase in its source or description.
618
+ Input:
619
+ A query. --json forces JSON.
620
+ Output (JSON):
621
+ Matching owned plays with the matched fields and terms.
622
+ Cost:
623
+ Free.
624
+ `
625
+ },
626
+ "plays list": {
627
+ core: `
628
+ Purpose:
629
+ Inventory of saved and prebuilt plays, one bounded page at a time. It is
630
+ the command that carries cost estimates.
631
+ When:
632
+ To price a play before running it: plays list --show-cost, then read the
633
+ cost estimate line for the play, or costEstimate in JSON.
634
+ Input:
635
+ --show-cost adds estimates. --limit and --cursor page. --categories
636
+ filters by tool category. --json forces JSON.
637
+ Output (JSON):
638
+ plays[] with playKey, reference, displayName, description, origin,
639
+ runCount, lastRun, and with --show-cost costEstimate {status, unit ("row"
640
+ or "run"), lowCredits, highCredits, source, sampleRunCount} or
641
+ {status: "unavailable", reason, message}; count, has_more, next_cursor,
642
+ next (the next-page command), render.sections with a "cost estimate:"
643
+ line per play.
644
+ Cost:
645
+ Free.
646
+ Avoid:
647
+ plays describe does not include a cost estimate; this command does.
648
+ `,
649
+ verbose: `
650
+ Pricing a run:
651
+ Multiply lowCredits..highCredits by the row count when unit is "row", or
652
+ use it directly when unit is "run". Compare with billing.balance from
653
+ preflight. When the estimate is unavailable, run a two-row slice first and
654
+ read its actual spend with billing usage --run-id <run-id>.
655
+ Output fields:
656
+ costEstimate.source "observed" (from past runs; shown with ~) or
657
+ "static" (from the play's declared tools).
658
+ costEstimate.sampleRunCount how many runs the observation is based on.
659
+ has_more / next_cursor the page is bounded; pass --cursor to continue.
660
+ is_truncated true when the page was cut for size.
661
+ `
662
+ },
663
+ "plays describe": {
664
+ core: `
665
+ Purpose:
666
+ The contract for one play: required input, CSV column expectations, output
667
+ fields, and the exact run command.
668
+ When:
669
+ Always before the first run of a play. It is free and it is the only
670
+ reliable source of the input field and column names.
671
+ Input:
672
+ The play reference from search (prebuilt/... or <workspace>/...).
673
+ --compact shortens schemas. --json forces JSON.
674
+ Output (JSON):
675
+ name, reference, displayName, description, inputSchema (JSON Schema plus
676
+ fields[] {name, required, type}), outputSchema, csvInput {inputField,
677
+ rowInputSchema.required[], defaultColumns, columnFlags}, rowOutputSchema,
678
+ runCommand, examples, triggerStatus, latestRunId.
679
+ No cost estimate; use plays list --show-cost for that.
680
+ Cost:
681
+ Free.
682
+ Avoid:
683
+ Do not pass --show-cost here; it is not an option of this command.
684
+ `,
685
+ verbose: `
686
+ CSV plays:
687
+ csvInput.inputField is the input key that takes the CSV path (usually
688
+ "csv"), so the run input is {"csv":"path.csv"}. rowInputSchema.required
689
+ lists the per-row fields the play needs (for example first_name,
690
+ last_name, domain). defaultColumns maps each field to the header name the
691
+ play looks for (FIRST_NAME, LAST_NAME, COMPANY_DOMAIN). When your file uses
692
+ other headers, either rename them or pass the columnFlags, for example
693
+ --columns.domain website. The run fails at validation, before any credit
694
+ is spent, when a required column is missing.
695
+ Output fields:
696
+ inputSchema.fields[] flat list for a single-row play; build --input
697
+ from it.
698
+ outputSchema.properties the per-row result fields, for example email,
699
+ email_source, email_validated, waterfall_attempts.
700
+ runCommand copy it and replace the placeholder input.
701
+ latestRunId the most recent run in this workspace, if any;
702
+ useful to reuse a finished result instead of
703
+ rerunning.
704
+ triggerStatus cron or webhook triggers configured for the play.
705
+ Related:
706
+ plays get <ref> returns full metadata, revisions, and source; describe is
707
+ the compact read meant for running.
708
+ `
709
+ },
710
+ "plays get": {
711
+ core: `
712
+ Purpose:
713
+ Full metadata for a play: revisions, source, triggers, and latest runs.
714
+ When:
715
+ Only when describe is not enough: reading the source (--source --out
716
+ file.play.ts), checking revisions, or auditing a saved play.
717
+ Input:
718
+ The play reference. --source prints or writes the source; --working,
719
+ --live, --revision <n> pick which source.
720
+ Output (JSON):
721
+ The play record with revision and trigger metadata; with --source, the
722
+ TypeScript source.
723
+ Cost:
724
+ Free.
725
+ `
726
+ },
727
+ "plays check": {
728
+ core: `
729
+ Purpose:
730
+ Validate a play contract without starting a run: a local .play.ts file is
731
+ bundled and checked, a named or prebuilt play is confirmed discoverable.
732
+ When:
733
+ Before running a local play file, and after editing one. Free, so run it
734
+ every time.
735
+ Input:
736
+ A local path ending in .play.ts, or a play reference. --json forces JSON.
737
+ Output (JSON):
738
+ valid (boolean), target, name, reference, inputSchema, outputSchema,
739
+ runtimeLimit, note, and for local files any errors or warnings with the
740
+ repair steps.
741
+ Cost:
742
+ Free.
743
+ Avoid:
744
+ valid true does not mean the input you plan to pass is valid; describe
745
+ shows the required fields.
746
+ `
747
+ },
748
+ "plays run": {
749
+ core: `
750
+ Purpose:
751
+ Start one run of a play, wait for it, and print the result package with
752
+ the run id.
753
+ When:
754
+ After describe. A CSV goes through the play's batch form
755
+ (prebuilt/<name>-batch) in one run; the single-record form is for one
756
+ person or company. Pilot a slice first when the estimate times the row
757
+ count is a large share of the balance; an input of about 25 rows or fewer
758
+ is its own pilot.
759
+ Input:
760
+ Positional: a play reference (prebuilt/... or <workspace>/...) or a local
761
+ .play.ts path. A path runs that file as written and never publishes it; a
762
+ name runs the live version, which only plays set-live changes. Then the
763
+ play input in exactly one of these forms:
764
+ --input '{"csv":"leads.csv"}' inline JSON object (CSV plays take the path)
765
+ --input @input.json read the object from a file
766
+ --key value any unknown flag becomes input.key
767
+ --columns.<field> <header> maps a CSV header to a required field.
768
+ --no-wait returns the run id immediately instead of waiting.
769
+ --run-id-file <path> writes the run id as soon as the server accepts it.
770
+ Output (JSON, printed when the run ends):
771
+ run {id, playName, status ("completed", "failed", "stopped")},
772
+ dashboardUrl, steps[] with per-step progress, rowOutcomes, warnings,
773
+ datasets[] {datasetId, name, storage {schema, table}}, and actions holding
774
+ exact follow-up commands: getRunCmd, getFullRunCmd, getBillingCmd,
775
+ getLogsCmd, exportDatasetCmds[], queryTableSqlCmds[]. Rows are not in this
776
+ payload. Progress lines are printed while it waits; the JSON is the last
777
+ thing printed.
778
+ Cost:
779
+ Spends Deepline credits through the play's tool calls. Validation errors
780
+ (missing column, bad input) fail before any spend.
781
+ Avoid:
782
+ Do not run the single-record play once per row of a file; each run pays
783
+ its own start-up and balance admission, and the batch form keeps a
784
+ row-level failure inside one completed run.
785
+ Do not poll runs get while plays run is still waiting; it already waits.
786
+ Do not rerun a failed run from scratch; the same command reuses completed
787
+ rows.
788
+ `,
789
+ verbose: `
790
+ Waiting and timeouts:
791
+ The command watches the run until it ends. Prefixed activity lines report
792
+ queueing and per-step progress; if the tool shell has an execution
793
+ timeout shorter than the run, start with --no-wait or --run-id-file and
794
+ poll with runs get <run-id> until run.status is terminal.
795
+ Input rules:
796
+ A CSV path is relative to the current directory; the CLI uploads the file
797
+ before submitting, so the run does not depend on the file afterwards.
798
+ Header matching is case-insensitive against csvInput.defaultColumns from
799
+ describe; other headers need --columns.<field> <header>.
800
+ --limit 5 and similar pass-through flags become input.limit = 5.
801
+ Output fields:
802
+ run.status the run's terminal state. "failed" with row-level
803
+ failures still keeps the succeeded rows; read
804
+ rowOutcomes and warnings.
805
+ steps[].progress {total, executed, reused, failed, completedRows}
806
+ per dataset step. reused counts rows recovered from
807
+ an earlier run.
808
+ datasets[].storage {schema, table}: where the rows live in the
809
+ customer database. Row counts and fill statistics
810
+ are in runs get, not here.
811
+ actions.exportDatasetCmds[] the exact runs export line for each dataset.
812
+ actions.getBillingCmd the exact cost read for this run.
813
+ error present on failure; insufficient-credits errors
814
+ name the missing amount.
815
+ Reruns and idempotency:
816
+ Running the same play with the same input reuses completed provider calls
817
+ and rows, so rerunning after a partial failure only pays for the missing
818
+ work. --force starts a fresh run graph; --force-tool-refresh repeats
819
+ billed provider calls and is almost never what you want.
820
+ Related:
821
+ runs get <run-id> for status later; runs export for rows; runs logs for
822
+ persisted logs; billing usage --run-id for cost.
823
+ `
824
+ },
825
+ "plays set-live": {
826
+ core: `
827
+ Purpose:
828
+ Make one version of a play live, so plays run <name>, triggers, and
829
+ ctx.runPlay callers use it. A local .play.ts file is bundled, validated,
830
+ saved as a revision, and promoted in one step; a saved play promotes one
831
+ of its existing revisions.
832
+ When:
833
+ After iterating on a local file with plays run ./file.play.ts, once its
834
+ result is right. Running a local file never publishes it.
835
+ Input:
836
+ A local path ending in .play.ts, or a saved play name with --latest or
837
+ --revision-id <id>. --dry-run bundles and prints the planned artifact
838
+ without publishing. --expected-artifact <hash> refuses to publish when the
839
+ file no longer produces the artifact hash plays check printed.
840
+ Output (JSON):
841
+ success, name, liveVersion, revisionId, artifactHash, previousLiveVersion,
842
+ previousArtifactHash, and the trigger metadata and bindings now live.
843
+ Cost:
844
+ Free. It changes cloud state: every caller of the play name gets the new
845
+ version at once.
846
+ Avoid:
847
+ Do not publish to test a change; run the file by path instead.
848
+ A cron or webhook trigger cannot report its own failure. After publishing
849
+ a triggered play, check that a failure notifies someone: notifications
850
+ --help.
851
+ `
852
+ },
853
+ "plays publish": {
854
+ core: `
855
+ Purpose:
856
+ Publish a local .play.ts file or promote a saved revision, so plays run
857
+ <name>, triggers, and ctx.runPlay callers use it. The same operation as
858
+ plays set-live.
859
+ When:
860
+ Once a play run by file path gives the right result. Running a local file
861
+ never publishes it.
862
+ Input:
863
+ A local path ending in .play.ts, or a saved play name with --latest or
864
+ --revision-id <id>. --dry-run bundles and prints the planned artifact
865
+ without publishing. --expected-artifact <hash> refuses to publish when the
866
+ file no longer produces the artifact hash plays check printed.
867
+ Output (JSON):
868
+ success, name, liveVersion, revisionId, artifactHash, and the trigger
869
+ metadata and bindings now live.
870
+ Cost:
871
+ Free. It changes cloud state: every caller of the play name gets the new
872
+ version at once.
873
+ Avoid:
874
+ A cron or webhook trigger cannot report its own failure. After publishing
875
+ a triggered play, check that a failure notifies someone: notifications
876
+ --help.
877
+ `
878
+ },
879
+ runs: {
880
+ core: `
881
+ Purpose:
882
+ Everything about executions of plays: current status, row outcomes, logs,
883
+ cost, export, and cancellation.
884
+ Which command:
885
+ runs get <run-id> status, step progress, dataset handles, next steps
886
+ runs export <run-id> --out f.csv the result rows as CSV
887
+ billing usage --run-id <run-id> what the run cost
888
+ runs list --play <ref> recent runs of a play with status and credits
889
+ runs logs <run-id> persisted logs; --failed for the failure window
890
+ runs watch <run-id> follow an active run until it ends
891
+ runs stop <run-id> cancel; runs stop-all cancels every active run
892
+ Ids:
893
+ play/<play-ref>/run/<timestamp>-<suffix>, printed by plays run as runId.
894
+ Cost:
895
+ All of these are free; a run's spend was charged while it ran.
896
+ `
897
+ },
898
+ "runs get": {
899
+ core: `
900
+ Purpose:
901
+ Current status and structure of one run: state, per-step progress, row
902
+ counts, dataset handles, and exact follow-up commands.
903
+ When:
904
+ To check a run started with --no-wait, to find the dataset table name for
905
+ db query, or to see row-level failure counts. Not for cost and not for
906
+ rows.
907
+ Input:
908
+ The run id. --full resolves a full-only result and adds diagnostics with
909
+ billing and timeline (large). --log-failed attaches the failure log window.
910
+ --input prints the original input (may contain customer data). --json
911
+ forces JSON; --json run.status,datasets.name selects fields.
912
+ Output (JSON):
913
+ kind "run_overview", run {id, playName, status, startedAt, finishedAt,
914
+ durationMs}, steps[] {id, kind, status, label, progress {total, executed,
915
+ reused, failed, completedRows}}, failures.steps[], errorDetails,
916
+ rowOutcomes, warnings[], datasets[] {datasetId, name, rowCount, summary,
917
+ storage {schema, table}, preview {returnedRows, totalRows, partial, rows}},
918
+ result or resultState, and actions holding exact follow-up commands
919
+ (getFullRunCmd, getBillingCmd, getLogsCmd, exportDatasetCmds[],
920
+ queryTableSqlCmds[]). A batch run's payload is tens of kilobytes; read
921
+ run.status and datasets[] and take rows and cost from the narrower
922
+ commands.
923
+ Cost:
924
+ Free.
925
+ Avoid:
926
+ Cost is not in this payload without --full; use billing usage --run-id.
927
+ datasets[].preview.rows is a sample, not the rows; use runs export or db
928
+ query.
929
+ `,
930
+ verbose: `
931
+ Output fields:
932
+ run.status queued, running, completed, failed, or stopped. Only
933
+ the last three are terminal.
934
+ run.activity the current step while running, null when finished.
935
+ steps[].label the step's state in one line, as the dashboard shows
936
+ it.
937
+ datasets[].summary.reportedPopulation {totalRows, persistedRows,
938
+ succeededRows, failedRows}. failedRows > 0 means some
939
+ rows have no result; export them and read the
940
+ failure columns before reporting.
941
+ datasets[].summary.columnStats per-column fill and unique counts; a quick
942
+ fill-rate read without exporting.
943
+ datasets[].storage {schema, table}: the customer-database table holding
944
+ the rows; actions.queryTableSqlCmds[] has a ready db
945
+ query for it.
946
+ datasets[].preview {returnedRows, totalRows, partial, rows}: a sample
947
+ for a first look, never an export count.
948
+ resultState "available_in_full" means the result was left out;
949
+ --full resolves it.
950
+ rowOutcomes terminal row accounting: successes, failures and
951
+ superseded rows are disjoint, and a superseded row
952
+ belongs to a newer write's latest view. Absent while
953
+ the run is active. A completed status alone does not
954
+ mean every input row produced a successful row.
955
+ actions.*Cmd exact commands: exportDatasetCmds[], getBillingCmd,
956
+ queryTableSqlCmds[], getLogsCmd, and stopRunCmd while
957
+ the run is active.
958
+ With --full:
959
+ diagnostics holds the raw status: billing, timeline, errors, child runs.
960
+ --json diagnostics needs --full. Use --full only when a program will read
961
+ it; it is several times larger than the default overview.
962
+ Debugging a run:
963
+ When a run failed or looks stuck, read runs get <run-id> for its state and
964
+ last event, then runs logs <run-id> --failed for the failure window, then
965
+ runs watch <run-id> to follow it if it is still active. A run can go quiet
966
+ for minutes while it waits on a slow provider (Apify actors, large company
967
+ searches), an intentional ctx.sleep, or a rate-limit backoff; that is
968
+ healthy. Stop it only after about ten minutes without progress on a fast
969
+ tool.
970
+ `
971
+ },
972
+ "runs export": {
973
+ core: `
974
+ Purpose:
975
+ Write a run's result rows to a local CSV file.
976
+ When:
977
+ After a run completes, as the way to get rows. It is also the file to
978
+ show a user.
979
+ Input:
980
+ The run id and --out <path> (required). --format json writes an array of
981
+ rows instead of CSV. --dataset <path> selects a handle when the run
982
+ returned more than one (default: the returned dataset, usually
983
+ result.rows). --metadata-out <path.json> writes the export metadata. --json
984
+ prints the receipt as JSON; it does not change the file format.
985
+ Output (JSON):
986
+ csv_path or json_path (absolute), source, rowCount, columns[] (the CSV
987
+ header), datasets, and actions with follow-up commands. The file includes
988
+ the input columns
989
+ plus the play's output fields (for example email, email_source,
990
+ email_validated, waterfall_attempts) and per-provider attempt columns.
991
+ Cost:
992
+ Free.
993
+ Avoid:
994
+ Do not reconstruct rows from runs get; export is complete and cheap.
995
+ `,
996
+ verbose: `
997
+ Cases:
998
+ Right after a run finishes, export can report that the backing dataset was
999
+ not ready to export yet and print the command to retry. Run that command
1000
+ again, or read the rows with db query meanwhile; never rerun the play, the
1001
+ rows are already paid for.
1002
+ A run with failed rows exports them too; the output fields for those rows
1003
+ are blank and the attempt columns explain why. Report them as unresolved
1004
+ rather than dropping them.
1005
+ A run that returned no dataset (a single-value play) has nothing to export;
1006
+ the result is in runs get under outputs or result.
1007
+ --dataset accepts a dataset path such as result.rows; runs get
1008
+ actions.exportDatasetCmds[] has the exact line for each dataset.
1009
+ Output fields:
1010
+ columns[] the exact header order written; use it to pick columns to
1011
+ show.
1012
+ rowCount rows written, including failed rows.
1013
+ local.csv_path same as csv_path; present for tooling.
1014
+ `
1015
+ },
1016
+ "runs list": {
1017
+ core: `
1018
+ Purpose:
1019
+ Recent runs of a play, or all runs in a status, with per-run credits.
1020
+ When:
1021
+ To find a previous run id, to check whether a play already ran on the same
1022
+ input, or to read per-run spend across several runs.
1023
+ Input:
1024
+ --play <ref> and/or --status <queued|running|completed|failed|stopped>
1025
+ (at least one). --limit, --offset (with --play), --compact, --json.
1026
+ Output (JSON):
1027
+ runs[] {id, status, playName, createdAtIso, startedAtIso, finishedAtIso,
1028
+ billingTotalCredits}, count, total, has_more, next, render.sections (one
1029
+ line per run: id, status, start time, credits).
1030
+ Cost:
1031
+ Free.
1032
+ Avoid:
1033
+ runs[].id is the public run id that runs get, watch, export and stop
1034
+ accept. runId and workflowId are older names for it; temporalRunId is a
1035
+ backend identifier and not a run id. Use the id plays run returned for
1036
+ your own run: the latest entry here may belong to another invocation that
1037
+ started at the same time.
1038
+ `
1039
+ },
1040
+ "runs logs": {
1041
+ core: `
1042
+ Purpose:
1043
+ The stored text logs of one run, or a search of recent events across the
1044
+ workspace's runs. Nothing runs again.
1045
+ When:
1046
+ When a run failed and the runs get error is not enough: runs logs
1047
+ <run-id> --failed shows the failure window; --out <path> saves the whole
1048
+ log. Without a run id it searches events: which runs or steps failed
1049
+ (--kind run.failed, --kind step.failed), with --payloads for the details.
1050
+ To read what a tool call in a run returned: runs logs <run-id> --kind
1051
+ receipt.completed --payloads --json, then one exact result by its eventId
1052
+ with --where.
1053
+ Input:
1054
+ A run id alone reads text logs; no run id, or any search flag, searches
1055
+ events. The flags, event kinds, and --where filter examples are listed
1056
+ above.
1057
+ Output:
1058
+ Log lines (human) or a JSON envelope; with --out, the file path. Follow
1059
+ next.logs for the next page of events, and pass nextCursor to --cursor for
1060
+ older text logs.
1061
+ Cost:
1062
+ Free.
1063
+ Avoid:
1064
+ --out, --failed and --log-level apply to text logs and cannot be combined
1065
+ with an event search. --where is not SQL: it takes equality tests joined
1066
+ with &&.
1067
+ `
1068
+ },
1069
+ "runs receipt": {
1070
+ core: `
1071
+ Purpose:
1072
+ Read the tool responses a run retained, by receipt key. Nothing runs again
1073
+ and nothing is billed.
1074
+ When:
1075
+ A row of a run's output records a receipt key and you need what that tool
1076
+ call returned. Without a key, find the call first with runs logs <run-id>
1077
+ --kind receipt.completed --payloads --json.
1078
+ Input:
1079
+ The run id, then --key <key> (repeatable) or --keys <file> with one key
1080
+ per line (--keys - reads stdin). --out <file> writes the JSON to a new
1081
+ file and does not overwrite. The key is the row's
1082
+ _metadata.execution.receiptKey, not a call-site id or a job id; read the
1083
+ row's actual schema before extracting keys.
1084
+ Output (JSON):
1085
+ One outcome per key, in the order asked, duplicates kept. A successful
1086
+ entry holds result.toolResponse; an error stays with its key.
1087
+ Cost:
1088
+ Free.
1089
+ Avoid:
1090
+ Exit 4 means a key was not found; exit 5 means a result is incomplete or
1091
+ unavailable, with the successful entries still returned. Reads need the
1092
+ workspace the run belongs to.
1093
+ `
1094
+ },
1095
+ "runs watch": {
1096
+ core: `
1097
+ Purpose:
1098
+ Follow an active run until it ends, polling its status every two seconds.
1099
+ When:
1100
+ Only for a run started with --no-wait that you want to watch. plays run
1101
+ already waits, and runs get answers "is it done". runs tail is an alias.
1102
+ Input:
1103
+ The run id. --compact shows step transitions only; --json prints one
1104
+ terminal package at the end; --jsonl prints events as JSON Lines.
1105
+ Output:
1106
+ Progress lines as the run changes, then the same package shape as runs get
1107
+ --json.
1108
+ Cost:
1109
+ Free.
1110
+ `
1111
+ },
1112
+ "runs stop": {
1113
+ core: `
1114
+ Purpose:
1115
+ Request cancellation of one active run.
1116
+ When:
1117
+ A run is stuck, was started by mistake, or was superseded. Runs of the same
1118
+ play do not cancel each other: an older run keeps working and keeps
1119
+ spending until it ends or is stopped. runs list --play <name> --status
1120
+ running lists them. Completed work is kept and reused by a later run of the
1121
+ same play and input.
1122
+ Input:
1123
+ The run id and --reason "<text>". --json forces JSON.
1124
+ Output (JSON):
1125
+ The run's new status; cancellation is asynchronous, so poll runs get.
1126
+ Cost:
1127
+ Free, but rows already processed were charged.
1128
+ `
1129
+ },
1130
+ "runs stop-all": {
1131
+ core: `
1132
+ Purpose:
1133
+ Request cancellation of every active run in the workspace.
1134
+ When:
1135
+ Unjamming a workspace. Do not use it to stop one run; use runs stop.
1136
+ Input:
1137
+ --reason "<text>". --dry-run lists what would be stopped. --json.
1138
+ Output (JSON):
1139
+ The runs that were asked to stop.
1140
+ Cost:
1141
+ Free.
1142
+ `
1143
+ },
1144
+ "runs rerun": {
1145
+ core: `
1146
+ Purpose:
1147
+ Start a new run of the same play with the same input as an earlier run,
1148
+ reusing its completed rows.
1149
+ When:
1150
+ After fixing the cause of a partial failure. When a failed run is
1151
+ resumable, runs get also prints the exact command under actions.rerunCmd.
1152
+ Input:
1153
+ The run id. --json.
1154
+ Output (JSON):
1155
+ The new run's package, as plays run prints.
1156
+ Cost:
1157
+ Spends credits only for rows that were not completed before.
1158
+ `
1159
+ },
1160
+ notifications: {
1161
+ core: `
1162
+ Purpose:
1163
+ Named notifications. Each one sends the play events you choose to a
1164
+ connected target, such as a Slack channel or an email address.
1165
+ When:
1166
+ After publishing a play that runs on a cron or webhook trigger. A trigger
1167
+ cannot report its own failure, so check that a failed run reaches someone.
1168
+ Input:
1169
+ notifications list what exists; read it before editing a rule
1170
+ notifications events the play events a notification can receive;
1171
+ do not guess event ids
1172
+ notifications slack channels --search <words>
1173
+ find a channel in the connected Slack
1174
+ notifications add <name> --to slack:#channel --for play.cron.failed
1175
+ notifications test <name> send a test message
1176
+ Output:
1177
+ The named notifications with their targets and events; add and test
1178
+ confirm what changed or was sent.
1179
+ Cost:
1180
+ Free.
1181
+ Avoid:
1182
+ Reading the configuration needs no approval. Adding a rule or sending a
1183
+ test changes something outside the run, so get the user's go-ahead first.
1184
+ Slack itself is connected in Dashboard -> Integrations, not here.
1185
+ Delivery retries are handled internally and are not configurable.
1186
+ `
1187
+ },
1188
+ "csv show": {
1189
+ core: `
1190
+ Purpose:
1191
+ Inspect a local CSV before running a play over it: headers, fill rates,
1192
+ sample values, or a row range.
1193
+ When:
1194
+ Before plays run, to confirm the file has the columns describe requires
1195
+ and to count rows for pricing. Free and local.
1196
+ Input:
1197
+ <path> (required). --summary prints stats instead of rows. --rows
1198
+ start:end (inclusive, default 0:19), --columns a,b, --format json|csv|table.
1199
+ Output (JSON):
1200
+ With --summary: total_rows and rows, one per column: {column, present,
1201
+ missing, present_percent, unique, top_values, other_count}. Without it:
1202
+ the rows in the requested range.
1203
+ Cost:
1204
+ Free. No network.
1205
+ Avoid:
1206
+ Do not use head or wc to inspect a CSV that a play will consume; --summary
1207
+ gives the row count and column names in one call.
1208
+ `
1209
+ },
1210
+ "db query": {
1211
+ core: `
1212
+ Purpose:
1213
+ Run SQL against the workspace's customer database, where play runs persist
1214
+ their result rows.
1215
+ When:
1216
+ To read result rows in place (filter, join, count) instead of exporting,
1217
+ or to write to your own storage.* tables.
1218
+ Input:
1219
+ --sql "<statement>" or --sql @file.sql (required). --max-rows <n>,
1220
+ --format table|json|csv|markdown, --out <path> for csv or markdown, --json.
1221
+ Table names come from runs get: datasets[].storage {schema, table}, for
1222
+ example "storage"."prebuilt_person_to_phone_batch_phone_rows"; quote both
1223
+ parts. actions.queryTableSqlCmds[] has a ready query for each dataset.
1224
+ Output (JSON):
1225
+ command ("SELECT" and so on), rows[] (one object per row), columns[]
1226
+ {name}, row_count, row_count_returned, truncated (true when --max-rows or
1227
+ the server bound cut the result), next.
1228
+ Cost:
1229
+ Free.
1230
+ Avoid:
1231
+ Do not guess table names; a run's dataset table is named in runs get
1232
+ under datasets[].storage.
1233
+ `
1234
+ },
1235
+ "sessions send": {
1236
+ core: `
1237
+ Purpose:
1238
+ Upload an agent session transcript, or a file, to Deepline so the team can
1239
+ see how a task went.
1240
+ When:
1241
+ Only after the user agrees. Ask once, at the end of the task and in its own
1242
+ message. After a user-requested feedback report, offer it alongside. When
1243
+ the upload succeeds, tell the user: "Session sent to Deepline. Rating:
1244
+ <rating>".
1245
+ Input:
1246
+ --current-session (the calling agent's session, else the newest one started
1247
+ in this directory), or --session-id <uuid> (repeatable, each with an
1248
+ optional --label), or --file <path> for a raw file. --agent
1249
+ auto|claude|codex limits where transcripts are looked for.
1250
+ --rating good|poor|neutral, judged by outcome and not tone: good when the
1251
+ user's goal was met without product problems; poor when it was missed, or
1252
+ a product failure, bug, or avoidable friction (including a substantial
1253
+ workaround) got in the way; neutral when partly met or unclear. A session
1254
+ that produced a feedback report is usually poor or neutral. --json.
1255
+ Output (JSON):
1256
+ A confirmation envelope with uploaded and session_ids; the text form names
1257
+ the session that was uploaded.
1258
+ Cost:
1259
+ Free.
1260
+ Avoid:
1261
+ The command is sessions, plural; the singular session form is the old one.
1262
+ In a Cowork sandbox the transcripts are mounted under
1263
+ ~/mnt/.claude/projects: when no session files are found and that directory
1264
+ exists, link it to ~/.claude/projects and retry, or pass the newest
1265
+ transcript there with --file.
1266
+ `
1267
+ },
1268
+ "feedback send": {
1269
+ core: `
1270
+ Purpose:
1271
+ Send a bug report or product feedback to the Deepline team. The calling
1272
+ agent's session id is attached, so a report can be matched to a transcript.
1273
+ When:
1274
+ The user asks to report something: confirm the text with them first, pass
1275
+ --requested, and offer to share the session with sessions send.
1276
+ Unasked, when you see friction Deepline could act on, unless the user
1277
+ restricts external reporting: a play far slower than its input size,
1278
+ earlier comparable runs, or visible progress would suggest, or one that
1279
+ looks stuck; or an ordinary result that took avoidable discovery,
1280
+ conversion, id extraction, retries, exports, or a manual workaround. Send
1281
+ one concise report per issue, without --requested and without a
1282
+ transcript, then keep working on the task. Provider work that is
1283
+ legitimately long is not friction.
1284
+ Input:
1285
+ Positional text or --file <path> (- for stdin). --command "<the command
1286
+ that reproduced it>" and --payload <json or text> attach a repro.
1287
+ --error-outcome terminal when an error stopped the task, continued when
1288
+ work went on, including through a workaround; omit it when no error
1289
+ occurred. --requested only when the user asked for the report. --json.
1290
+ Put the evidence in the text. A slow run: the goal, the play and run id,
1291
+ input size, observed duration, status changes or polling count, and what
1292
+ you expected. Extra steps: the goal, the command path you took, the
1293
+ detours, and the direct path you expected.
1294
+ Output (JSON):
1295
+ A confirmation envelope for the report.
1296
+ Cost:
1297
+ Free. A report does not authorize a paid reproduction or a session upload.
1298
+ `
1299
+ },
1300
+ skills: {
1301
+ core: `
1302
+ Purpose:
1303
+ Reinstall the Deepline agent skill files (deepline-gtm and its siblings)
1304
+ from the current release. It writes to disk.
1305
+ When:
1306
+ Only when asked to install or update skills. To see what is installed
1307
+ without changing anything, use --dry-run --json and read the plan.
1308
+ Input:
1309
+ --scope global|local, --agent <target>, --dry-run, --json.
1310
+ Output (JSON):
1311
+ The install plan (dry run) or the result envelope listing written and
1312
+ removed skill directories.
1313
+ Cost:
1314
+ Free.
1315
+ Avoid:
1316
+ The bare command replaces skill files; in a sandbox or a task that said
1317
+ not to change skills, use --dry-run.
1318
+ `
1319
+ },
1320
+ update: {
1321
+ core: `
1322
+ Purpose:
1323
+ Update the Deepline CLI to the latest release.
1324
+ When:
1325
+ When a command reports the CLI is too old for a feature. Ordinary commands
1326
+ auto-update in the background unless DEEPLINE_SKIP_SELF_UPDATE=1 is set or
1327
+ settings autoupdate off was run.
1328
+ Input:
1329
+ No arguments. --json.
1330
+ Output:
1331
+ The installed and new versions.
1332
+ Cost:
1333
+ Free.
1334
+ `
1335
+ },
1336
+ doctor: {
1337
+ core: `
1338
+ Purpose:
1339
+ Read-only diagnosis of the local install: CLI version, skills, auth,
1340
+ workspace, and API connectivity, with suggested repairs.
1341
+ When:
1342
+ When something local is wrong (skills missing, auth file odd). For the
1343
+ routine start-of-task check use preflight; doctor is stricter and exits 7
1344
+ when any check fails, which is common in sandboxes with no skills on disk.
1345
+ Input:
1346
+ --scope global|local. --json.
1347
+ Output (JSON):
1348
+ Check results with status and repair hints. Exit 7 means at least one
1349
+ check failed; the JSON says which.
1350
+ Cost:
1351
+ Free.
1352
+ `
1353
+ },
1354
+ setup: {
1355
+ core: `
1356
+ Purpose:
1357
+ Interactive first-run setup: authenticate, install skills, and print
1358
+ starter prompts.
1359
+ When:
1360
+ A person setting up a new machine. Not for unattended shells; it needs a
1361
+ browser for auth.
1362
+ Input:
1363
+ Flags for scope and agent target; see the options above.
1364
+ Output:
1365
+ Progress and the starter prompts.
1366
+ Cost:
1367
+ Free.
1368
+ `
1369
+ },
1370
+ version: {
1371
+ core: `
1372
+ Purpose:
1373
+ Print the installed CLI version.
1374
+ Output (JSON with --json):
1375
+ {version}.
1376
+ `
1377
+ }
1378
+ };
1379
+ function commandDocKey(command) {
1380
+ const parts = [];
1381
+ let current = command;
1382
+ while (current && current.parent) {
1383
+ parts.unshift(current.name());
1384
+ current = current.parent;
1385
+ }
1386
+ return parts.join(" ");
1387
+ }
1388
+ function helpDetailFromArgv(argv) {
1389
+ if (argv.includes("--quiet")) return "quiet";
1390
+ if (argv.includes("--verbose")) return "verbose";
1391
+ return "core";
1392
+ }
1393
+ function renderCommandExplanation(key, detail, options = {}) {
1394
+ if (detail === "quiet") return "";
1395
+ const doc = COMMAND_DOCS[key];
1396
+ if (!doc) return "";
1397
+ const prefix = key ? `deepline ${key}` : "deepline";
1398
+ const sections = [doc.core.trim()];
1399
+ if (detail === "verbose" && doc.verbose) {
1400
+ sections.push(doc.verbose.trim());
1401
+ }
1402
+ const body = `
1403
+ Explanation:
1404
+ ${indent(sections.join("\n\n"))}
1405
+ `;
1406
+ if (options.pointer === false) return body;
1407
+ const pointer = options.firstRead && doc.verbose ? `Help detail: this first read printed the full explanation; later ${prefix} --help calls in this session print the core section, --help --verbose prints the full explanation again, and --help --quiet omits it.` : detail === "verbose" || !doc.verbose ? `Help detail: ${prefix} --help --quiet omits this explanation.` : `Help detail: ${prefix} --help --verbose adds output field references and edge cases; --help --quiet omits this explanation.`;
1408
+ return `${body}
1409
+ ${pointer}
1410
+ `;
1411
+ }
1412
+ function indent(text) {
1413
+ return text.split("\n").map((line) => line.length > 0 ? ` ${line}` : line).join("\n");
1414
+ }
1415
+
1416
+ export {
1417
+ COMMAND_DOCS,
1418
+ commandDocKey,
1419
+ helpDetailFromArgv,
1420
+ renderCommandExplanation
1421
+ };