deepline 0.3.89 → 0.3.90

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 (211) hide show
  1. package/contracts/install-commands.json +29 -0
  2. package/dist/bundling-sources/sdk/src/client.ts +120 -37
  3. package/dist/bundling-sources/sdk/src/index.ts +4 -0
  4. package/dist/bundling-sources/sdk/src/pagination.ts +25 -0
  5. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
  6. package/dist/bundling-sources/sdk/src/release.ts +16 -9
  7. package/dist/bundling-sources/sdk/src/types.ts +23 -0
  8. package/dist/bundling-sources/shared_libs/monitors/analytics-public.ts +10 -0
  9. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +3 -0
  10. package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +4 -4
  11. package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +59 -0
  12. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +7 -9
  13. package/dist/bundling-sources/shared_libs/monitors/package.json +7 -0
  14. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +44 -2
  15. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +2 -2
  16. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +2 -2
  17. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +1 -1
  18. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +245 -0
  19. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-message.ts +38 -0
  20. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-ack-probe.ts +94 -0
  21. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-delivery.ts +60 -0
  22. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue.ts +60 -0
  23. package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +1 -1
  24. package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +2 -2
  25. package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +1 -1
  26. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +1 -1
  27. package/dist/bundling-sources/shared_libs/observability/build-context.ts +13 -0
  28. package/dist/bundling-sources/shared_libs/observability/log-metadata.ts +160 -0
  29. package/dist/bundling-sources/shared_libs/observability/request-context.ts +68 -0
  30. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +654 -0
  31. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +35 -0
  32. package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +5 -0
  33. package/dist/bundling-sources/shared_libs/play-data-plane/neon-constants.ts +9 -0
  34. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +272 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +45 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +66 -1
  37. package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +0 -1
  38. package/dist/bundling-sources/shared_libs/play-runtime/bounceban-batching.ts +137 -0
  39. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +779 -140
  40. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +46 -0
  41. package/dist/bundling-sources/shared_libs/play-runtime/daytona-payload-contract.ts +68 -0
  42. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +103 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +725 -0
  44. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +29 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +23 -0
  46. package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +442 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +3 -3
  48. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +18 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +9 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +1 -1
  51. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +1 -1
  52. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/contracts.ts +66 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/job.ts +145 -0
  54. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/ports.ts +21 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/postgres-store.ts +170 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +1322 -0
  57. package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +2 -2
  58. package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +1 -1
  59. package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +112 -0
  60. package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +8 -0
  61. package/dist/bundling-sources/shared_libs/play-runtime/perf-trace.ts +127 -0
  62. package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +5 -0
  63. package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +24 -1
  64. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +56 -0
  65. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +13 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/job.ts +41 -0
  67. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/ports.ts +17 -0
  68. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +54 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/contracts.ts +114 -0
  70. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/engine-suspension.ts +108 -0
  71. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/index.ts +36 -0
  72. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/job.ts +97 -0
  73. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/ports.ts +104 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/postgres-fence-adapter.ts +263 -0
  75. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/worker-terminal-projection.ts +64 -0
  76. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/contracts.ts +29 -0
  77. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +56 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/index.ts +15 -0
  79. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/job.ts +65 -0
  80. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/ports.ts +17 -0
  81. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +42 -0
  82. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/index.ts +17 -0
  83. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +142 -0
  84. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/ports.ts +42 -0
  85. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/postgres-adapter.ts +102 -0
  86. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/contracts.ts +60 -0
  87. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/index.ts +16 -0
  88. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +78 -0
  89. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +54 -0
  90. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/postgres-adapter.ts +71 -0
  91. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +4 -0
  92. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
  93. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +5 -8
  94. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +3 -5
  95. package/dist/bundling-sources/shared_libs/play-runtime/run-identity.ts +168 -0
  96. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +72 -9
  97. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +6 -12
  98. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +19 -0
  99. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +0 -1
  100. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +14 -44
  101. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +57 -205
  102. package/dist/bundling-sources/shared_libs/play-runtime/runtime-authority.ts +201 -0
  103. package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
  104. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +67 -0
  105. package/dist/bundling-sources/shared_libs/play-runtime/runtime-release-environment.ts +2 -0
  106. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sandbox-contract.ts +68 -0
  107. package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +14 -2
  108. package/dist/bundling-sources/shared_libs/play-runtime/runtime-telemetry.ts +108 -0
  109. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +4 -0
  110. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +3 -0
  111. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +7 -0
  112. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +88 -0
  113. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +124 -0
  114. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-run-task.ts +68 -0
  115. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +193 -0
  116. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-lifecycle.ts +269 -0
  117. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-suffix.ts +73 -0
  118. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +6642 -0
  119. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +897 -0
  120. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-metrics.ts +120 -0
  121. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +76 -0
  122. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +476 -0
  123. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-heavy-request-admission.ts +47 -0
  124. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-progress-registry.ts +147 -0
  125. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/index.ts +27 -0
  126. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/lazy.ts +50 -0
  127. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/play-run-recovery.ts +98 -0
  128. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-budget-state.ts +260 -0
  129. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +1416 -0
  130. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +1255 -0
  131. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +942 -0
  132. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +14636 -0
  133. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +888 -0
  134. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +355 -0
  135. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-terminal-transition.ts +46 -0
  136. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runner-push.ts +60 -0
  137. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +33 -0
  138. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-gateway-health.ts +64 -0
  139. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +835 -0
  140. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +1218 -0
  141. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-operation.ts +207 -0
  142. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-scheduler-schema.ts +10 -0
  143. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-capacity.ts +123 -0
  144. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-launch-read-observability.ts +78 -0
  145. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +169 -0
  146. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/terminal-contract.ts +20 -0
  147. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-queue-metrics.ts +34 -0
  148. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-resource-metrics.ts +249 -0
  149. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +7 -0
  150. package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +296 -0
  151. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +3 -3
  152. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +20 -1
  153. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +60 -15
  154. package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +20 -0
  155. package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +12 -0
  156. package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +14 -1
  157. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +165 -0
  158. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +15 -23
  159. package/dist/bundling-sources/shared_libs/play-runtime/workflow-executor-auth.ts +169 -0
  160. package/dist/bundling-sources/shared_libs/play-runtime/zerobounce-batching.ts +122 -0
  161. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +2 -0
  162. package/dist/bundling-sources/shared_libs/plays/contracts.ts +2 -0
  163. package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +1 -1
  164. package/dist/bundling-sources/shared_libs/plays/docflow.ts +1 -1
  165. package/dist/bundling-sources/shared_libs/plays/play-grep-search.ts +39 -0
  166. package/dist/bundling-sources/shared_libs/plays/share/copy.ts +271 -0
  167. package/dist/bundling-sources/shared_libs/plays/share/metrics.ts +140 -0
  168. package/dist/bundling-sources/shared_libs/plays/share/public-read-model.ts +86 -0
  169. package/dist/bundling-sources/shared_libs/plays/share/seo-quality.ts +181 -0
  170. package/dist/bundling-sources/shared_libs/plays/share/static-pipeline-summary.ts +658 -0
  171. package/dist/bundling-sources/shared_libs/plays/share/types.ts +197 -0
  172. package/dist/bundling-sources/shared_libs/plays/slack-hitl-timeout-error.ts +37 -0
  173. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +6 -1
  174. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
  175. package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +7 -1
  176. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +3 -2
  177. package/dist/bundling-sources/shared_libs/product-notifications/overflow.ts +18 -0
  178. package/dist/bundling-sources/shared_libs/product-notifications/rolling-limit.ts +24 -0
  179. package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +624 -0
  180. package/dist/bundling-sources/shared_libs/product-notifications/slack-payload.ts +140 -0
  181. package/dist/bundling-sources/shared_libs/product-notifications/slack-transport.ts +75 -0
  182. package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
  183. package/dist/bundling-sources/shared_libs/security/email-blacklist.ts +42 -0
  184. package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +10 -3
  185. package/dist/bundling-sources/shared_libs/security/slack-sanitize.ts +133 -0
  186. package/dist/cli/getting-started.d.mts +52 -0
  187. package/dist/cli/getting-started.d.ts +52 -0
  188. package/dist/cli/getting-started.js +65 -0
  189. package/dist/cli/getting-started.mjs +36 -0
  190. package/dist/cli/index.d.mts +9 -0
  191. package/dist/cli/index.d.ts +9 -0
  192. package/dist/cli/index.js +545 -264
  193. package/dist/cli/index.mjs +543 -271
  194. package/dist/{compiler-manifest-DsLbQaew.d.mts → compiler-manifest-BaJfE-5H.d.mts} +5 -3
  195. package/dist/{compiler-manifest-DsLbQaew.d.ts → compiler-manifest-BaJfE-5H.d.ts} +5 -3
  196. package/dist/index.d.mts +81 -148
  197. package/dist/index.d.ts +81 -148
  198. package/dist/index.js +83 -26
  199. package/dist/index.mjs +83 -26
  200. package/dist/install-integrity.json +130 -2
  201. package/dist/monitor-fleet-contract.d.mts +138 -0
  202. package/dist/monitor-fleet-contract.d.ts +138 -0
  203. package/dist/monitor-fleet-contract.js +404 -0
  204. package/dist/monitor-fleet-contract.mjs +367 -0
  205. package/dist/plays/bundle-play-file.d.mts +2 -2
  206. package/dist/plays/bundle-play-file.d.ts +2 -2
  207. package/dist/release.d.mts +255 -0
  208. package/dist/release.d.ts +255 -0
  209. package/dist/release.js +215 -0
  210. package/dist/release.mjs +188 -0
  211. package/package.json +21 -4
@@ -163,6 +163,26 @@ import { join as join24 } from "path";
163
163
  import { tmpdir as tmpdir6 } from "os";
164
164
  import { Command as Command5 } from "commander";
165
165
 
166
+ // src/pagination.ts
167
+ async function* iterateCursorPages(fetchPage) {
168
+ let cursor = null;
169
+ const seen = /* @__PURE__ */ new Set();
170
+ for (; ; ) {
171
+ const page = await fetchPage(cursor);
172
+ if (page.hasMore) {
173
+ if (!page.cursor || seen.has(page.cursor)) {
174
+ throw new Error(
175
+ "Pagination reported more results without an advancing cursor"
176
+ );
177
+ }
178
+ seen.add(page.cursor);
179
+ }
180
+ yield page.items;
181
+ if (!page.hasMore) return;
182
+ cursor = page.cursor;
183
+ }
184
+ }
185
+
166
186
  // src/config.ts
167
187
  import {
168
188
  existsSync,
@@ -1250,20 +1270,27 @@ var SDK_RELEASE = {
1250
1270
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1251
1271
  // getters keep their established compatibility behavior.
1252
1272
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1253
- version: "0.3.89",
1254
- updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
1273
+ // 0.3.90 is the first deliberately versioned SDK release for API v3. Play
1274
+ // grep hard-cuts to the single Convex full-text index; it does not retain a
1275
+ // registry/scanner reader for any SDK/API major.
1276
+ version: "0.3.90",
1277
+ updateSummary: "Play grep now uses one source-only Convex full-text index. It no longer scans the registry, pages through the complete indexed match set, and rejects retired grep modes. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
1255
1278
  packageCapabilities: {
1256
1279
  updatePreferences: 1
1257
1280
  },
1258
1281
  contracts: {
1259
1282
  api: {
1260
1283
  name: "sdk-http-api",
1261
- // API v2 is append-only. A breaking public request/response change needs
1262
- // v3 and an explicit v2 support-window decision, never a patch release.
1263
- currentMajor: 2,
1264
- supportedMajors: [2],
1265
- // Accepted only to bridge SDKs released before X-Deepline-API-Major.
1284
+ // API v3 hard-cuts Play grep to the canonical Convex index. API v2 stays
1285
+ // admitted for the explicit SDK support window, but it selects neither a
1286
+ // registry scanner nor another grep reader: every accepted grep request
1287
+ // uses the same indexed query and retired flags fail at the API boundary.
1288
+ currentMajor: 3,
1289
+ supportedMajors: [3, 2],
1290
+ // The first wire id is emitted by the current SDK. Remaining ids are
1291
+ // accepted only while the API v2 support window is open.
1266
1292
  legacyWireIds: [
1293
+ "2026-09-play-grep-convex-index-hard-cutover",
1267
1294
  "2026-07-admin-cli-local-cutover",
1268
1295
  "2026-07-native-monitor-launch-hard-cutover"
1269
1296
  ]
@@ -2512,6 +2539,10 @@ function normalizeProductNotificationEmail(value) {
2512
2539
  const email = typeof value === "string" ? value.trim().toLowerCase() : "";
2513
2540
  return email && email.length <= 320 && PRODUCT_NOTIFICATION_EMAIL_PATTERN.test(email) ? email : null;
2514
2541
  }
2542
+ var DEFAULT_PRODUCT_NOTIFICATION_DELIVERY_TIMING = {
2543
+ mode: "rolling_limit",
2544
+ windowMs: 36e5
2545
+ };
2515
2546
 
2516
2547
  // src/stream-reconnect.ts
2517
2548
  var STREAM_RECONNECT_BASE_DELAY_MS = 500;
@@ -5105,6 +5136,7 @@ var DeeplineClient = class {
5105
5136
  this.runs = {
5106
5137
  get: (runId, options2) => this.getRunStatus(runId, options2),
5107
5138
  list: (options2) => this.listRuns(options2),
5139
+ listPage: (options2) => this.listRunsPage(options2),
5108
5140
  tail: (runId, options2) => this.tailRun(runId, options2),
5109
5141
  logs: (runId, options2) => this.getRunLogs(runId, options2),
5110
5142
  input: (runId) => this.getRunInput(runId),
@@ -6318,6 +6350,10 @@ var DeeplineClient = class {
6318
6350
  * ```
6319
6351
  */
6320
6352
  async listRuns(options) {
6353
+ return (await this.listRunsPage(options)).runs;
6354
+ }
6355
+ /** Read one run page without discarding server pagination metadata. */
6356
+ async listRunsPage(options) {
6321
6357
  const playName = options.play?.trim();
6322
6358
  const params = new URLSearchParams();
6323
6359
  if (playName) {
@@ -6348,7 +6384,7 @@ var DeeplineClient = class {
6348
6384
  const response = await this.http.get(
6349
6385
  `/api/v2/runs?${params.toString()}`
6350
6386
  );
6351
- return response.runs ?? [];
6387
+ return { ...response, runs: response.runs ?? [] };
6352
6388
  }
6353
6389
  /**
6354
6390
  * Observe one run's live events. Uses the Convex Run Snapshot subscription
@@ -6743,13 +6779,33 @@ var DeeplineClient = class {
6743
6779
  );
6744
6780
  }
6745
6781
  /**
6746
- * List callable plays visible to the workspace.
6782
+ * List one page of callable plays; grep retains exhaustive matching results.
6783
+ * Use listPlaysPage to retain pagination metadata.
6747
6784
  *
6748
6785
  * Pass `origin: "prebuilt"` for Deepline-managed prebuilts or
6749
6786
  * `origin: "owned"` for org-owned plays.
6750
6787
  */
6751
6788
  async listPlays(options) {
6789
+ if (!options?.grep?.trim()) {
6790
+ return (await this.requestPlaysPage(options, false)).plays;
6791
+ }
6792
+ const plays = [];
6793
+ for await (const items of iterateCursorPages(async (cursor) => {
6794
+ const page = await this.listPlaysPage({ ...options, cursor });
6795
+ return { items: page.plays, cursor: page.cursor, hasMore: page.hasMore };
6796
+ })) {
6797
+ plays.push(...items);
6798
+ }
6799
+ return plays;
6800
+ }
6801
+ /** Read one bounded inventory page; cursor continues the same filters. */
6802
+ async listPlaysPage(options) {
6803
+ return this.requestPlaysPage(options);
6804
+ }
6805
+ async requestPlaysPage(options, paginateInventory = true) {
6752
6806
  const params = new URLSearchParams();
6807
+ if (paginateInventory && !options?.grep?.trim())
6808
+ params.set("inventory_paginated", "1");
6753
6809
  if (options?.origin) params.set("origin", options.origin);
6754
6810
  if (options?.categories) {
6755
6811
  params.set(
@@ -6761,26 +6817,27 @@ var DeeplineClient = class {
6761
6817
  params.set("include_tool_categories", "1");
6762
6818
  }
6763
6819
  if (options?.includeArchived) params.set("include_archived", "1");
6820
+ if (options?.includeCostEstimates) {
6821
+ params.set("include_cost_estimates", "1");
6822
+ }
6764
6823
  if (options?.grep?.trim()) {
6765
6824
  params.set("grep", options.grep.trim());
6766
- params.set("grep_mode", options.grepMode ?? "all");
6767
- params.set("grep_paginated", "1");
6768
6825
  params.set("limit", "60");
6769
6826
  }
6770
- const plays = [];
6771
- let cursor = null;
6772
- let hasMore = true;
6773
- do {
6774
- if (cursor) params.set("cursor", cursor);
6775
- const suffix = params.toString() ? `?${params.toString()}` : "";
6776
- const response = await this.http.get(
6777
- `/api/v2/plays${suffix}`
6778
- );
6779
- plays.push(...response.plays ?? []);
6780
- cursor = response.pagination?.cursor ?? response.cursor ?? null;
6781
- hasMore = Boolean(response.pagination?.hasMore ?? response.hasMore);
6782
- } while (Boolean(options?.grep?.trim()) && hasMore && cursor);
6783
- return plays;
6827
+ if (options?.limit !== void 0) {
6828
+ if (!Number.isSafeInteger(options.limit) || options.limit < 1) {
6829
+ throw new Error("Play page limit must be a positive integer");
6830
+ }
6831
+ params.set("limit", String(options.limit));
6832
+ }
6833
+ if (options?.cursor) params.set("cursor", options.cursor);
6834
+ const suffix = params.size ? `?${params.toString()}` : "";
6835
+ const response = await this.http.get(`/api/v2/plays${suffix}`);
6836
+ return {
6837
+ plays: response.plays ?? [],
6838
+ cursor: response.pagination?.cursor ?? response.cursor ?? null,
6839
+ hasMore: Boolean(response.pagination?.hasMore ?? response.hasMore)
6840
+ };
6784
6841
  }
6785
6842
  /** Set whether an org-owned Play sorts before unpinned Plays. */
6786
6843
  async setPlayPinned(playName, pinned) {
@@ -6914,7 +6971,7 @@ var DeeplineClient = class {
6914
6971
  groupKey,
6915
6972
  name,
6916
6973
  enabled: true,
6917
- deliveryTiming: { mode: "immediate" },
6974
+ deliveryTiming: DEFAULT_PRODUCT_NOTIFICATION_DELIVERY_TIMING,
6918
6975
  source: "workspace",
6919
6976
  configMode: "custom",
6920
6977
  version: 0
@@ -8142,13 +8199,6 @@ function getAuthedHttpClient() {
8142
8199
  const config = resolveConfig();
8143
8200
  return { config, http: new HttpClient(config) };
8144
8201
  }
8145
- async function writeOutputFile(filename, content) {
8146
- const outputDir = resolve2(process.cwd(), "deepline", "data");
8147
- await mkdir(outputDir, { recursive: true });
8148
- const fullPath = join4(outputDir, filename);
8149
- await writeFile(fullPath, content, "utf-8");
8150
- return fullPath;
8151
- }
8152
8202
  function stableOsUserId() {
8153
8203
  try {
8154
8204
  const info = userInfo();
@@ -8791,13 +8841,6 @@ function createTimestampedName(prefix, extension) {
8791
8841
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8792
8842
  return `${prefix}-${timestamp}.${extension}`;
8793
8843
  }
8794
- async function writeCsvRowsFile(prefix, rows) {
8795
- const path = await writeOutputFile(
8796
- createTimestampedName(prefix, "csv"),
8797
- csvStringFromRows(rows)
8798
- );
8799
- return path;
8800
- }
8801
8844
  function clip(value, maxLength) {
8802
8845
  return value.length > maxLength ? `${value.slice(0, maxLength - 1)}\u2026` : value;
8803
8846
  }
@@ -9582,7 +9625,7 @@ Notes:
9582
9625
  workspace. To switch, use deepline org list and deepline org set <org-id>.
9583
9626
  `
9584
9627
  );
9585
- auth.command("workspaces").description("Deprecated. Use deepline org list to see workspaces.").action(() => {
9628
+ auth.command("workspaces", { hidden: true }).description("Deprecated. Use deepline org list to see workspaces.").action(() => {
9586
9629
  console.error(
9587
9630
  "Workspaces live under `deepline org`.\n List: deepline org list\n Switch: deepline org set <org-id>\n`deepline auth register` re-approves this device; it does not change the active workspace."
9588
9631
  );
@@ -9679,7 +9722,6 @@ var SUBSCRIPTION_STATUS_NEXT_COMMAND = "deepline billing subscription status --j
9679
9722
  var SUBSCRIPTION_CANCEL_PATH = "/api/v2/billing/subscription/cancel";
9680
9723
  var BILLING_TOP_UP_PATH = "/api/v2/billing/top-up";
9681
9724
  var DEFAULT_BALANCE_RECOVERY_CREDITS = 100;
9682
- var BILLING_HISTORY_EXPORT_LIMIT = 5e3;
9683
9725
  function billingFailureFromError(error, options) {
9684
9726
  if (error instanceof AuthError) {
9685
9727
  return {
@@ -9970,6 +10012,9 @@ async function handleBalance(options) {
9970
10012
  );
9971
10013
  return;
9972
10014
  }
10015
+ function quoteShellArgument(value) {
10016
+ return `'${value.replace(/'/g, `'\\''`)}'`;
10017
+ }
9973
10018
  async function handleUsage(options) {
9974
10019
  const { http } = getAuthedHttpClient();
9975
10020
  const params = new URLSearchParams();
@@ -9986,6 +10031,7 @@ async function handleUsage(options) {
9986
10031
  const recent = payload.recent ?? {};
9987
10032
  const last30Usage = usage.last_30_days_usage_credits ?? usage.month_spent_credits;
9988
10033
  const temporaryHolds = Number(usage.temporary_hold_credits ?? 0);
10034
+ const nextPage = typeof recent.next_cursor === "string" && recent.next_cursor.length > 0 ? `deepline billing usage --cursor ${quoteShellArgument(recent.next_cursor)}${options.limit ? ` --limit ${options.limit}` : ""}${options.runId ? ` --run-id ${quoteShellArgument(options.runId)}` : ""} --json` : null;
9989
10035
  const lines = [
9990
10036
  `Balance: ${payload.balance ?? "(unknown)"}`,
9991
10037
  `Last 30 days usage: ${last30Usage ?? "(unknown)"}`,
@@ -9997,13 +10043,20 @@ async function handleUsage(options) {
9997
10043
  ...recentUsageLines(
9998
10044
  Array.isArray(recent.entries) ? recent.entries : []
9999
10045
  ),
10000
- ...typeof recent.next_cursor === "string" && recent.next_cursor.length > 0 ? [
10001
- `Next page: deepline billing usage --cursor ${recent.next_cursor}${options.limit ? ` --limit ${options.limit}` : ""}${options.runId ? ` --run-id ${options.runId}` : ""}`
10046
+ ...recent.has_more === true || recent.incomplete === true ? ["List truncated \u2014 more recent calls match this query."] : [],
10047
+ ...nextPage ? [`Next page: ${nextPage}`] : [],
10048
+ ...!nextPage && (recent.has_more === true || recent.incomplete === true) ? [
10049
+ "No continuation is available for this view. Use deepline billing ledger export all --json for the full ledger."
10002
10050
  ] : []
10003
10051
  ];
10004
10052
  printCommandEnvelope(
10005
10053
  {
10006
10054
  ...payload,
10055
+ recent: {
10056
+ ...recent,
10057
+ is_truncated: recent.has_more === true || recent.incomplete === true
10058
+ },
10059
+ next: { page: nextPage },
10007
10060
  render: { sections: [{ title: "billing usage", lines }] }
10008
10061
  },
10009
10062
  { json: options.json }
@@ -10067,6 +10120,39 @@ async function handleLimitOff(options) {
10067
10120
  { json: options.json }
10068
10121
  );
10069
10122
  }
10123
+ async function exportLedger(http, outputPath, options) {
10124
+ let summary = { row_count: 0, net_delta_credits: 0 };
10125
+ let initialized = false;
10126
+ for await (const entries of iterateCursorPages(async (cursor) => {
10127
+ const params = new URLSearchParams({ limit: "5000" });
10128
+ if (cursor) params.set("cursor", cursor);
10129
+ if (options.sinceAt !== null)
10130
+ params.set("since_at", String(options.sinceAt));
10131
+ if (options.runId) params.set("run_id", options.runId);
10132
+ if (options.operation) params.set("operation", options.operation);
10133
+ const payload = await http.get(
10134
+ `/api/v2/billing/ledger?${params.toString()}`
10135
+ );
10136
+ if (!Array.isArray(payload.entries) || typeof payload.has_more !== "boolean") {
10137
+ throw new Error("Billing ledger response is missing entries");
10138
+ }
10139
+ return {
10140
+ items: payload.entries,
10141
+ hasMore: payload.has_more === true,
10142
+ cursor: typeof payload.next_cursor === "string" ? payload.next_cursor : null
10143
+ };
10144
+ })) {
10145
+ if (!initialized) {
10146
+ await mkdir2(dirname6(outputPath), { recursive: true });
10147
+ await writeFile2(outputPath, ledgerRowsToCsv([], true), "utf-8");
10148
+ initialized = true;
10149
+ }
10150
+ const rows = entries.map(ledgerApiEntryToRow);
10151
+ await appendFile(outputPath, ledgerRowsToCsv(rows, false), "utf-8");
10152
+ summary = summarizeLedgerRows(summary, rows);
10153
+ }
10154
+ return summary;
10155
+ }
10070
10156
  async function handleHistory(options) {
10071
10157
  const { http } = getAuthedHttpClient();
10072
10158
  const windows = {
@@ -10076,41 +10162,20 @@ async function handleHistory(options) {
10076
10162
  "1y": 31536e3
10077
10163
  };
10078
10164
  const sinceAt = Math.max(0, Math.floor(Date.now() / 1e3) - windows[options.time]) * 1e3;
10079
- const entries = [];
10080
- let cursor = null;
10081
- while (entries.length < BILLING_HISTORY_EXPORT_LIMIT) {
10082
- const params = new URLSearchParams({
10083
- since_at: String(sinceAt),
10084
- limit: String(BILLING_HISTORY_EXPORT_LIMIT - entries.length)
10085
- });
10086
- if (cursor !== null) params.set("cursor", cursor);
10087
- const payload = await http.get(
10088
- `/api/v2/billing/ledger?${params.toString()}`
10089
- );
10090
- if (Array.isArray(payload.entries)) {
10091
- entries.push(
10092
- ...payload.entries.slice(
10093
- 0,
10094
- BILLING_HISTORY_EXPORT_LIMIT - entries.length
10095
- )
10096
- );
10097
- }
10098
- const nextCursor = typeof payload.next_cursor === "string" && payload.next_cursor.length > 0 ? payload.next_cursor : null;
10099
- if (payload.has_more !== true || nextCursor === null) break;
10100
- if (nextCursor === cursor) {
10101
- throw new Error("Billing history pagination cursor did not advance");
10102
- }
10103
- cursor = nextCursor;
10104
- }
10105
- const rows = entries.map(ledgerApiEntryToRow);
10106
- const outputPath = await writeCsvRowsFile(
10107
- `billing-history-${options.time}`,
10108
- rows
10165
+ const outputPath = resolve3(
10166
+ process.cwd(),
10167
+ "deepline",
10168
+ "data",
10169
+ createTimestampedName(`billing-history-${options.time}`, "csv")
10109
10170
  );
10171
+ const summary = await exportLedger(http, outputPath, { sinceAt });
10110
10172
  printCommandEnvelope(
10111
10173
  {
10112
10174
  output_path: outputPath,
10113
- row_count: rows.length,
10175
+ row_count: summary.row_count,
10176
+ has_more: false,
10177
+ is_truncated: false,
10178
+ next_cursor: null,
10114
10179
  time_window: options.time,
10115
10180
  render: {
10116
10181
  sections: [
@@ -10118,7 +10183,7 @@ async function handleHistory(options) {
10118
10183
  title: "billing history",
10119
10184
  lines: [
10120
10185
  `Billing history written to ${outputPath}`,
10121
- `${rows.length} row(s) exported.`
10186
+ `${summary.row_count} row(s) exported.`
10122
10187
  ]
10123
10188
  }
10124
10189
  ]
@@ -10143,40 +10208,18 @@ async function handleLedgerExportAll(options) {
10143
10208
  }
10144
10209
  const { http } = getAuthedHttpClient();
10145
10210
  const outputPath = options.output ? resolve3(String(options.output)) : defaultLedgerExportPath();
10146
- let summary = { row_count: 0, net_delta_credits: 0 };
10147
- let cursor = null;
10148
- let initializedOutput = false;
10149
- for (; ; ) {
10150
- const params = new URLSearchParams({ limit: "5000" });
10151
- if (cursor !== null) params.set("cursor", cursor);
10152
- if (options.runId) params.set("run_id", options.runId);
10153
- if (options.operation) params.set("operation", options.operation);
10154
- if (sinceAt !== null) params.set("since_at", String(sinceAt));
10155
- const payload = await http.get(
10156
- `/api/v2/billing/ledger?${params.toString()}`
10157
- );
10158
- const entries = Array.isArray(payload.entries) ? payload.entries : [];
10159
- const rows = entries.map(ledgerApiEntryToRow);
10160
- if (!initializedOutput) {
10161
- await mkdir2(dirname6(outputPath), { recursive: true });
10162
- await writeFile2(outputPath, ledgerRowsToCsv([], true), "utf-8");
10163
- initializedOutput = true;
10164
- }
10165
- if (rows.length > 0) {
10166
- await appendFile(outputPath, ledgerRowsToCsv(rows, false), "utf-8");
10167
- summary = summarizeLedgerRows(summary, rows);
10168
- }
10169
- const nextCursor = typeof payload.next_cursor === "string" && payload.next_cursor.length > 0 ? payload.next_cursor : null;
10170
- if (payload.has_more !== true || nextCursor === null) {
10171
- break;
10172
- }
10173
- if (nextCursor === cursor) break;
10174
- cursor = nextCursor;
10175
- }
10211
+ const summary = await exportLedger(http, outputPath, {
10212
+ sinceAt,
10213
+ runId: options.runId,
10214
+ operation: options.operation
10215
+ });
10176
10216
  printCommandEnvelope(
10177
10217
  {
10178
10218
  output_path: outputPath,
10179
10219
  row_count: summary.row_count,
10220
+ has_more: false,
10221
+ is_truncated: false,
10222
+ next_cursor: null,
10180
10223
  net_delta_credits: summary.net_delta_credits,
10181
10224
  scope: "workspace",
10182
10225
  ...options.runId ? { run_id: options.runId } : {},
@@ -10921,7 +10964,9 @@ Examples:
10921
10964
  `
10922
10965
  Notes:
10923
10966
  Read-only server query that writes a local CSV file. With --json, stdout is a
10924
- summary containing the output path and row count.
10967
+ summary containing the output path, row count, and completeness metadata.
10968
+ Exports the complete window using bounded pages. For an exact start timestamp:
10969
+ deepline billing ledger export all --since <ISO-8601> --json
10925
10970
 
10926
10971
  Examples:
10927
10972
  deepline billing history --time 1m
@@ -10989,7 +11034,10 @@ Examples:
10989
11034
  "Disable automatic recharge without clearing saved amounts."
10990
11035
  ).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeOff)
10991
11036
  );
10992
- billing.command("change-plan").description("Start or change the target billing plan.").argument("<plan_sku>", "payg-v1, builder-v1, growth-v1, growth-canary-v1, or team-v1").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
11037
+ billing.command("change-plan").description("Start or change the target billing plan.").argument(
11038
+ "<plan_sku>",
11039
+ "payg-v1, builder-v1, growth-v1, growth-canary-v1, or team-v1"
11040
+ ).option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
10993
11041
  billing.command("cancel-plan").description("Cancel a target subscription at period end, or undo it.").option("--undo", "Undo a pending period-end cancellation").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlanCancellation);
10994
11042
  billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
10995
11043
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
@@ -19839,6 +19887,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
19839
19887
  runId: workflowId,
19840
19888
  playName: input2.playName,
19841
19889
  dashboardUrl,
19890
+ inputFieldCount: Object.keys(input2.request.input ?? {}).length,
19842
19891
  jsonOutput: false,
19843
19892
  progress: input2.progress
19844
19893
  });
@@ -23482,12 +23531,13 @@ async function handleRunsList(args) {
23482
23531
  return 1;
23483
23532
  }
23484
23533
  const client2 = new DeeplineClient();
23485
- const runs = (await client2.runs.list({
23534
+ const page = await client2.runs.listPage({
23486
23535
  ...playName ? { play: playName } : {},
23487
23536
  ...statusFilter ? { status: statusFilter } : {},
23488
23537
  ...limit !== void 0 ? { limit } : {},
23489
23538
  ...offset !== void 0 ? { offset } : {}
23490
- })).map((run) => ({
23539
+ });
23540
+ const runs = page.runs.map((run) => ({
23491
23541
  runId: run.workflowId,
23492
23542
  // `workflowId` is the legacy SDK name for the same public Deepline run
23493
23543
  // identity. Keep it during the compatibility window, but never label the
@@ -23525,11 +23575,24 @@ async function handleRunsList(args) {
23525
23575
  if (run.rootRunId) lines2.push(` root: ${run.rootRunId}`);
23526
23576
  return lines2.join("\n");
23527
23577
  });
23578
+ const nextOffset = (page.offset ?? offset ?? 0) + runs.length;
23579
+ const nextPage = page.hasMore && playName ? `deepline runs list --play ${shellQuote2(playName)}${statusFilter ? ` --status ${shellQuote2(statusFilter)}` : ""} --limit ${page.limit ?? limit ?? 20} --offset ${nextOffset} --json` : null;
23580
+ if (page.hasMore) {
23581
+ lines.push("List truncated \u2014 more runs match this filter.");
23582
+ lines.push(
23583
+ nextPage ? `Next page: ${nextPage}` : "Narrow with --play <play-name> to page through runs."
23584
+ );
23585
+ }
23528
23586
  printCommandEnvelope(
23529
23587
  {
23530
23588
  runs,
23531
23589
  count: runs.length,
23590
+ ...page.total !== void 0 ? { total: page.total } : {},
23591
+ offset: page.offset ?? offset ?? 0,
23592
+ limit: page.limit ?? limit ?? (playName ? 20 : 100),
23593
+ ...page.hasMore !== void 0 ? { has_more: page.hasMore, is_truncated: page.hasMore } : {},
23532
23594
  next: {
23595
+ page: nextPage,
23533
23596
  get: runs[0]?.runId ? `deepline runs get ${runs[0].runId} --json` : null
23534
23597
  },
23535
23598
  render: { sections: [{ title: "runs", lines }] }
@@ -24177,23 +24240,47 @@ async function handlePlayVersions(args) {
24177
24240
  }
24178
24241
  return 0;
24179
24242
  }
24243
+ function formatPlayCostEstimate(estimate) {
24244
+ if (!estimate || estimate.status === "unavailable") {
24245
+ return `unavailable${estimate ? `: ${estimate.message}` : ""}`;
24246
+ }
24247
+ const formatCredits = (value) => value.toLocaleString("en-US", {
24248
+ maximumFractionDigits: value < 1 ? 4 : 2
24249
+ });
24250
+ const credits = estimate.lowCredits === estimate.highCredits ? `${estimate.source === "observed" ? "~" : ""}${formatCredits(estimate.lowCredits)}` : `${formatCredits(estimate.lowCredits)}\u2013${formatCredits(estimate.highCredits)}`;
24251
+ const unit = estimate.unit === "row" ? "output row" : "run";
24252
+ const source = estimate.source === "observed" ? `observed from ${estimate.sampleRunCount} ${estimate.sampleRunCount === 1 ? "run" : "runs"}` : "static estimate";
24253
+ return `${credits} Deepline credits per ${unit} (${source})`;
24254
+ }
24180
24255
  async function handlePlayList(args) {
24181
24256
  const jsonOutput = argsWantJson(args);
24257
+ const showCost = args.includes("--show-cost");
24182
24258
  const client2 = new DeeplineClient();
24183
24259
  const categoriesIndex = args.indexOf("--categories");
24184
24260
  const categories = categoriesIndex >= 0 ? args[categoriesIndex + 1]?.trim() : void 0;
24185
- const plays = await client2.listPlays({
24261
+ const limitIndex = args.indexOf("--limit");
24262
+ const cursorIndex = args.indexOf("--cursor");
24263
+ const limit = limitIndex >= 0 ? Number(args[limitIndex + 1]) : void 0;
24264
+ const cursor = cursorIndex >= 0 ? args[cursorIndex + 1] : void 0;
24265
+ if (limitIndex >= 0 && (!Number.isSafeInteger(limit) || limit < 1) || cursorIndex >= 0 && !cursor?.trim()) {
24266
+ console.error("Pass a positive --limit and a non-empty --cursor.");
24267
+ return 2;
24268
+ }
24269
+ const page = await client2.listPlaysPage({
24186
24270
  categories,
24187
- includeToolCategories: true
24188
- });
24189
- if (jsonOutput) {
24190
- process.stdout.write(`${JSON.stringify(plays)}
24191
- `);
24192
- return 0;
24271
+ includeToolCategories: true,
24272
+ ...showCost ? { includeCostEstimates: true } : {},
24273
+ limit,
24274
+ cursor
24275
+ });
24276
+ const plays = page.plays;
24277
+ const nextPage = page.hasMore && page.cursor ? `deepline plays list${categories ? ` --categories ${shellQuote2(categories)}` : ""}${limit ? ` --limit ${limit}` : ""}${showCost ? " --show-cost" : ""} --cursor ${shellQuote2(page.cursor)} --json` : null;
24278
+ if (page.hasMore && !nextPage) {
24279
+ throw new Error(
24280
+ "Play list reported more results without a continuation cursor"
24281
+ );
24193
24282
  }
24194
- process.stdout.write(`${plays.length} plays available:
24195
-
24196
- `);
24283
+ const lines = [`${plays.length} plays in this page:`];
24197
24284
  for (const play of plays) {
24198
24285
  const flags = [
24199
24286
  play.pinned ? "pinned" : null,
@@ -24203,32 +24290,48 @@ async function handlePlayList(args) {
24203
24290
  play.isDraftDirty ? "draft-dirty" : null
24204
24291
  ].filter(Boolean).join(", ");
24205
24292
  const reference = formatPlayListReference(play);
24206
- process.stdout.write(` ${reference}${flags ? ` [${flags}]` : ""}
24207
- `);
24293
+ lines.push(` ${reference}${flags ? ` [${flags}]` : ""}`);
24208
24294
  if (play.inputSchema || play.hasInputSchema) {
24209
- process.stdout.write(" inputSchema: yes\n");
24295
+ lines.push(" inputSchema: yes");
24210
24296
  }
24211
24297
  if (play.triggerStatus?.cron) {
24212
- process.stdout.write(
24213
- ` scheduled execution: ${cronExecutionLabel(play.triggerStatus.cron)}
24214
- `
24298
+ lines.push(
24299
+ ` scheduled execution: ${cronExecutionLabel(play.triggerStatus.cron)}`
24215
24300
  );
24216
24301
  if (play.triggerStatus.blockedReason) {
24217
- process.stdout.write(
24218
- ` schedule issue: ${play.triggerStatus.blockedReason}
24219
- `
24220
- );
24302
+ lines.push(` schedule issue: ${play.triggerStatus.blockedReason}`);
24221
24303
  }
24222
24304
  } else {
24223
- process.stdout.write(" scheduled execution: not configured\n");
24305
+ lines.push(" scheduled execution: not configured");
24224
24306
  }
24225
24307
  if (play.triggerStatus?.webhook) {
24226
- process.stdout.write(` webhook: ${play.triggerStatus.webhook}
24227
- `);
24308
+ lines.push(` webhook: ${play.triggerStatus.webhook}`);
24228
24309
  }
24229
- process.stdout.write(` run: deepline plays run ${reference} --watch
24230
- `);
24310
+ if (showCost) {
24311
+ lines.push(
24312
+ ` cost estimate: ${formatPlayCostEstimate(play.costEstimate)}`
24313
+ );
24314
+ }
24315
+ lines.push(` run: deepline plays run ${reference} --watch`);
24231
24316
  }
24317
+ if (page.hasMore) {
24318
+ lines.push("List truncated \u2014 more plays are available.");
24319
+ lines.push(`Next page: ${nextPage}`);
24320
+ }
24321
+ printCommandEnvelope(
24322
+ {
24323
+ plays,
24324
+ count: plays.length,
24325
+ has_more: page.hasMore,
24326
+ is_truncated: page.hasMore,
24327
+ next_cursor: page.cursor,
24328
+ next: { page: nextPage },
24329
+ render: {
24330
+ sections: [{ title: "plays", lines }]
24331
+ }
24332
+ },
24333
+ { json: jsonOutput }
24334
+ );
24232
24335
  return 0;
24233
24336
  }
24234
24337
  async function handlePlayPin(args, pinned) {
@@ -24492,76 +24595,23 @@ async function handlePlaySearch(args) {
24492
24595
  }
24493
24596
  return 0;
24494
24597
  }
24495
- function normalizePlayGrepText(value) {
24496
- if (value === null || value === void 0) return "";
24497
- if (typeof value === "string") return value.toLowerCase();
24498
- if (typeof value === "number" || typeof value === "boolean") {
24499
- return String(value).toLowerCase();
24500
- }
24501
- if (Array.isArray(value)) return value.map(normalizePlayGrepText).join(" ");
24502
- if (typeof value === "object") {
24503
- return Object.values(value).map(normalizePlayGrepText).join(" ");
24504
- }
24505
- return "";
24506
- }
24507
- function parsePlayGrepTerms(query, mode) {
24508
- const trimmed = query.trim().toLowerCase();
24509
- if (!trimmed) return [];
24510
- if (mode === "phrase") return [trimmed];
24511
- const matches = trimmed.match(/"([^"]+)"|'([^']+)'|\S+/g) ?? [];
24512
- return matches.map((term) => term.replace(/^["']|["']$/g, "").trim()).filter(Boolean);
24513
- }
24514
- function matchesPlayGrepQuery(value, query, mode) {
24515
- const terms = parsePlayGrepTerms(query, mode);
24516
- if (terms.length === 0) return true;
24517
- const haystack = normalizePlayGrepText(value);
24518
- if (mode === "any") return terms.some((term) => haystack.includes(term));
24519
- return terms.every((term) => haystack.includes(term));
24520
- }
24521
24598
  async function handlePlayGrep(args) {
24522
24599
  const query = args[0]?.trim();
24523
24600
  if (!query) {
24524
- console.error(
24525
- "Usage: deepline plays grep <query> [--mode all|any|phrase] [--compact] [--json]"
24526
- );
24601
+ console.error("Usage: deepline plays grep <query> [--compact] [--json]");
24527
24602
  return 1;
24528
24603
  }
24529
- let mode = "all";
24530
- for (let index = 1; index < args.length; index += 1) {
24531
- const arg = args[index];
24532
- if (arg === "--mode" && args[index + 1]) {
24533
- const rawMode = args[++index].trim().toLowerCase();
24534
- mode = rawMode === "any" || rawMode === "phrase" ? rawMode : "all";
24535
- }
24536
- }
24537
24604
  const compact = args.includes("--compact");
24538
24605
  const client2 = new DeeplineClient();
24539
- const plays = (await client2.listPlays({
24540
- grep: query,
24541
- grepMode: mode
24542
- })).filter(
24543
- (play) => matchesPlayGrepQuery(
24544
- {
24545
- name: play.name,
24546
- reference: play.reference,
24547
- displayName: play.displayName,
24548
- origin: play.origin,
24549
- ownerType: play.ownerType,
24550
- aliases: play.aliases,
24551
- toolCategories: play.toolCategories,
24552
- inputSchema: play.inputSchema,
24553
- outputSchema: play.outputSchema
24554
- },
24555
- query,
24556
- mode
24557
- )
24558
- ).map((play) => summarizePlayListItemForCli(play, { compact }));
24606
+ const plays = (await client2.listPlays({ grep: query })).map(
24607
+ (play) => summarizePlayListItemForCli(play, { compact })
24608
+ );
24559
24609
  if (argsWantJson(args)) {
24560
24610
  printCompactJson({
24561
24611
  plays,
24562
24612
  count: plays.length,
24563
24613
  query,
24564
- grep: { mode, terms: parsePlayGrepTerms(query, mode) }
24614
+ grep: { engine: "convex_full_text" }
24565
24615
  });
24566
24616
  return 0;
24567
24617
  }
@@ -25269,7 +25319,7 @@ Pass-through input flags:
25269
25319
  if (effectiveTarget && passthroughArgs[0] === effectiveTarget) {
25270
25320
  passthroughArgs.shift();
25271
25321
  }
25272
- process.exitCode = await handlePlayRun([
25322
+ const exitCode = await handlePlayRun([
25273
25323
  ...effectiveTarget ? [effectiveTarget] : [],
25274
25324
  ...options.file ? ["--file", options.file] : [],
25275
25325
  ...options.name ? ["--name", options.name] : [],
@@ -25299,6 +25349,11 @@ Pass-through input flags:
25299
25349
  ...options.full ? ["--full"] : [],
25300
25350
  ...passthroughArgs
25301
25351
  ]);
25352
+ recordCliTrace({
25353
+ phase: "cli.play_command_exit",
25354
+ exitCode
25355
+ });
25356
+ process.exitCode = exitCode;
25302
25357
  });
25303
25358
  registerPlayBootstrapCommand(play);
25304
25359
  play.command("get <target>").description(
@@ -25340,17 +25395,22 @@ Examples:
25340
25395
  `
25341
25396
  Notes:
25342
25397
  Inventory command for saved org plays and prebuilt plays. Use search for
25343
- ranked discovery by task or schema.
25398
+ ranked discovery by task or schema. Returns one bounded page with has_more,
25399
+ is_truncated, next_cursor, and a next-page command. Use --limit to choose
25400
+ the page size and --cursor to continue with the same filters.
25344
25401
 
25345
25402
  Examples:
25346
25403
  deepline plays list
25347
25404
  deepline plays search email --json
25348
25405
  `
25349
- ).option("--json", "Emit JSON output. Also automatic when stdout is piped").option(
25406
+ ).option("--limit <count>", "Page size").option("--cursor <cursor>", "Continue a previous page").option("--show-cost", "Include the per-row or per-run cost estimate").option("--json", "Emit JSON output. Also automatic when stdout is piped").option(
25350
25407
  "--categories <categories>",
25351
25408
  "Filter by comma-separated canonical tool categories"
25352
25409
  ).action(async (options) => {
25353
25410
  process.exitCode = await handlePlayList([
25411
+ ...options.limit ? ["--limit", options.limit] : [],
25412
+ ...options.cursor ? ["--cursor", options.cursor] : [],
25413
+ ...options.showCost ? ["--show-cost"] : [],
25354
25414
  ...options.categories ? ["--categories", options.categories] : [],
25355
25415
  ...options.json ? ["--json"] : []
25356
25416
  ]);
@@ -25389,8 +25449,8 @@ Notes:
25389
25449
  because they are trusted, robust plays with maintained contracts. Use describe
25390
25450
  on a result before running it.
25391
25451
  Add --all only when you are specifically looking for a play you created.
25392
- The grep alias is the same ranked retrieval surface with a more literal name
25393
- for agents that are filtering the play registry.
25452
+ Use plays grep to search active org-owned Plays through Convex's indexed
25453
+ authored corpus. It does not search prebuilt or archived Plays.
25394
25454
 
25395
25455
  Examples:
25396
25456
  deepline plays search email
@@ -25408,25 +25468,24 @@ Examples:
25408
25468
  ]);
25409
25469
  });
25410
25470
  addPlaySearchCommand(play.command("search <query>"));
25411
- play.command("grep <query>").description("Literal grep over play names, schemas, and descriptions.").addHelpText(
25471
+ play.command("grep <query>").description(
25472
+ "Search active org-owned Plays through Convex full-text search."
25473
+ ).addHelpText(
25412
25474
  "after",
25413
25475
  `
25414
25476
  Notes:
25415
- Literal registry filtering. Terms are matched case-insensitively against play
25416
- names, references, display names, ownership, and schemas. Use
25417
- --mode phrase for exact phrase matching, --mode any for OR, and the default
25418
- --mode all for AND.
25477
+ Queries use Convex token semantics over the indexed authored Play corpus.
25478
+ Prebuilt and archived Plays are not part of this index.
25419
25479
 
25420
25480
  Examples:
25421
25481
  deepline plays grep email --json
25422
- deepline plays grep "company contact" --mode all --json
25482
+ deepline plays grep "company contact" --compact --json
25423
25483
  deepline plays describe prebuilt/company-to-contact --json
25424
25484
  `
25425
- ).option("--compact", "Emit compact schemas").option("--mode <mode>", "Grep matching mode: all, any, or phrase").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
25485
+ ).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
25426
25486
  process.exitCode = await handlePlayGrep([
25427
25487
  query,
25428
25488
  ...options.compact ? ["--compact"] : [],
25429
- ...options.mode ? ["--mode", options.mode] : [],
25430
25489
  ...options.json ? ["--json"] : []
25431
25490
  ]);
25432
25491
  });
@@ -31024,7 +31083,7 @@ async function compileConfig(input2) {
31024
31083
  })).config;
31025
31084
  }
31026
31085
  function registerEnrichCommand(program) {
31027
- program.command("enrich").allowUnknownOption(true).description("Run v1-style CSV enrichment through the V2 play runner.").configureHelp({
31086
+ program.command("enrich", { hidden: true }).allowUnknownOption(true).description("Run v1-style CSV enrichment through the V2 play runner.").configureHelp({
31028
31087
  optionTerm(option) {
31029
31088
  return option.long === "--timeout" ? "--timeout SECONDS" : option.flags;
31030
31089
  }
@@ -32087,7 +32146,7 @@ function loadViewerAssets() {
32087
32146
  "viewer"
32088
32147
  )
32089
32148
  ] : [],
32090
- join12(process.cwd(), "src", "lib", "cli", "viewer")
32149
+ join12(process.cwd(), "apps", "deepline-api", "src", "lib", "cli", "viewer")
32091
32150
  ];
32092
32151
  for (const root of candidateRoots2) {
32093
32152
  try {
@@ -32304,7 +32363,7 @@ function addDeprecatedSubcommand(parent, family, subcommand, description) {
32304
32363
  });
32305
32364
  }
32306
32365
  function registerDeprecatedCommands(program) {
32307
- const session = program.command("session").description("Deprecated legacy session command namespace.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
32366
+ const session = program.command("session", { hidden: true }).description("Deprecated legacy session command namespace.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
32308
32367
  "after",
32309
32368
  `
32310
32369
  Notes:
@@ -32336,7 +32395,7 @@ Examples:
32336
32395
  `Deprecated legacy "deepline session ${subcommand}" command.`
32337
32396
  );
32338
32397
  }
32339
- const backend = program.command("backend").description("Deprecated legacy local backend command namespace.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
32398
+ const backend = program.command("backend", { hidden: true }).description("Deprecated legacy local backend command namespace.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
32340
32399
  "after",
32341
32400
  `
32342
32401
  Notes:
@@ -34347,11 +34406,13 @@ function monitorHealthLine(health) {
34347
34406
  if (health.refresh?.state === "running") {
34348
34407
  return `refreshing whole scope \xB7 scanned ${health.scanned} so far`;
34349
34408
  }
34409
+ const alignmentRequired = health.alignment_required ?? 0;
34350
34410
  return [
34351
34411
  `converged ${health.converged}/${health.scanned}`,
34352
34412
  `needs_repair ${health.needs_repair}`,
34353
34413
  `missing ${health.observed.missing}`,
34354
34414
  `unaudited ${health.observed.unknown + health.observed.unset}`,
34415
+ ...alignmentRequired > 0 ? [`needs_alignment ${alignmentRequired}`] : [],
34355
34416
  `silent ${health.silent}`
34356
34417
  ].join(" \xB7 ");
34357
34418
  }
@@ -34385,7 +34446,9 @@ async function watchMonitorHealth(input2) {
34385
34446
  let last = await input2.client.monitors.health(scope);
34386
34447
  input2.onProgress(last);
34387
34448
  while (Date.now() < deadlineAt) {
34388
- if (last.refresh?.state !== "running" && last.needs_repair === 0 && last.observed.unknown === 0) {
34449
+ const unresolved = last.observed.unknown + last.observed.unset;
34450
+ const alignmentRequired = last.alignment_required ?? 0;
34451
+ if (last.refresh?.state !== "running" && !last.truncated && last.needs_repair === 0 && (unresolved === 0 || alignmentRequired === unresolved)) {
34389
34452
  return last;
34390
34453
  }
34391
34454
  await new Promise(
@@ -34398,6 +34461,7 @@ async function watchMonitorHealth(input2) {
34398
34461
  }
34399
34462
  function monitorHealthText(health) {
34400
34463
  const partial = health.refresh?.state === "running" ? " (refreshing \u2014 counts below are not final)" : health.truncated ? " (partial \u2014 scope larger than one read)" : "";
34464
+ const unauditedMonitors = health.unaudited_monitors ?? [];
34401
34465
  const lines = [
34402
34466
  `scope: ${health.scope.fleet_id ?? "workspace"}${partial}`,
34403
34467
  monitorHealthLine(health)
@@ -34420,6 +34484,29 @@ function monitorHealthText(health) {
34420
34484
  lines.push(` ${entry.reason} (${entry.count})${how}`);
34421
34485
  }
34422
34486
  }
34487
+ if (unauditedMonitors.length > 0) {
34488
+ const reason = {
34489
+ not_yet_audited: "has not been observed yet",
34490
+ missing_provider_resource_id: "has no stored upstream resource id",
34491
+ provider_observation_unknown: "the provider observation is still unknown"
34492
+ };
34493
+ lines.push("");
34494
+ lines.push("unresolved monitor observations:");
34495
+ for (const entry of unauditedMonitors) {
34496
+ lines.push(
34497
+ ` ${entry.monitor_key} ${entry.tool} \u2014 ${reason[entry.reason]}`
34498
+ );
34499
+ }
34500
+ }
34501
+ if ((health.alignment_required ?? 0) > 0) {
34502
+ lines.push("");
34503
+ lines.push(
34504
+ `${health.alignment_required} monitor(s) need provider identity alignment; normal repair intentionally will not guess or create a paid replacement.`
34505
+ );
34506
+ lines.push(
34507
+ `Run the exact inventory audit, then review one safe adoption candidate: deepline-admin monitors reconcile ${health.scope.org_id} --monitor <monitor-key> --environment production --json`
34508
+ );
34509
+ }
34423
34510
  if (health.worst_offenders.length > 0) {
34424
34511
  lines.push("");
34425
34512
  lines.push(
@@ -34644,9 +34731,8 @@ Exit codes:
34644
34731
 
34645
34732
  Examples:
34646
34733
  deepline monitors status --json
34647
- deepline monitors available --json # compact list by default
34648
- deepline monitors available --full --json # complete catalog
34649
- deepline monitors available deepline_native.company_radar --json
34734
+ deepline tools list --categories monitors --json
34735
+ deepline tools get deepline_native.company_radar --json
34650
34736
  deepline monitors check '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
34651
34737
  deepline monitors deploy --dry-run --file monitor.json
34652
34738
  deepline monitors deploy --file monitor.json
@@ -34816,7 +34902,7 @@ Examples:
34816
34902
  )
34817
34903
  ).action(monitorsAction(handleMonitorsStatus));
34818
34904
  withJsonOption(
34819
- monitors.command("available [tool-id]").alias("tools").description(
34905
+ monitors.command("available [tool-id]", { hidden: true }).alias("tools").description(
34820
34906
  "List the monitor types you can deploy, or describe one by tool id."
34821
34907
  ).addHelpText(
34822
34908
  "after",
@@ -34933,7 +35019,7 @@ Notes:
34933
35019
  Play delivery. The JSON response reports this validation scope explicitly.
34934
35020
  Provider-specific grammar, precedence, enum applicability, examples, and
34935
35021
  update semantics are returned by the live monitor contract. Inspect it with
34936
- \`deepline monitors available deepline_native.company_radar --json\`.
35022
+ \`deepline tools get deepline_native.company_radar --json\`.
34937
35023
  For a bounded urgent Deepline Native preview, use
34938
35024
  controls.execution_type="priority". Deepline injects the upstream marker;
34939
35025
  do not author custom_fields yourself. Priority is capped at ten upstream or
@@ -34971,6 +35057,10 @@ Notes:
34971
35057
  no separate repair command or retry queue: rerun the same deploy/update.
34972
35058
  Scheduled reconciliation can also finish that exact saved cleanup; it never
34973
35059
  creates another monitor.
35060
+ For TamRadar, deliberately changing payload.updates_since is an explicit
35061
+ historical replay request, including when redeploying a disabled monitor.
35062
+ Deepline preserves that selected boundary; filter-only deploys and ordinary
35063
+ reactivation start from a fresh future-only source boundary instead.
34974
35064
  For a bounded urgent Deepline Native preview, set
34975
35065
  controls.execution_type="priority". Deepline injects the provider custom
34976
35066
  field and enforces a ten-slot per-org cap; do not use it for regular or bulk
@@ -35000,6 +35090,11 @@ positionally, via --file <path>, or from stdin with --file -.
35000
35090
  When <patch> includes payload, its top-level fields are merged with the stored
35001
35091
  payload before validation. This lets you change one filter without resending
35002
35092
  domain or radar_type; nested values and arrays replace atomically.
35093
+ For TamRadar, changing payload.updates_since is an explicit historical replay
35094
+ request. Deepline passes that requested boundary upstream, but previously
35095
+ delivered canonical findings are deduplicated before dispatch and billing; only
35096
+ previously unseen historical findings are chargeable. Filter-only updates,
35097
+ repair, and reactivation instead use a fresh future-only source boundary.
35003
35098
  Use {"controls":{"execution_type":"priority"}} only for a bounded urgent
35004
35099
  Deepline Native preview. The ten-radar priority cap applies on update too.
35005
35100
  Use {"controls":{"execution_type":null}} to release priority without
@@ -35086,7 +35181,7 @@ ${MONITOR_FLEET_HELP_EPILOG}`
35086
35181
  Creates a ready-to-review JSON definition. Fleets always sync ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.cadence} and retain
35087
35182
  a missing member for ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.removalGrace} before it is ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.onRemoved}d; those
35088
35183
  policies are not authored in the file. ${MONITOR_FLEET_DOCUMENTATION.stickyMembership} The payload remains the actual monitor payload for the chosen tool, so use
35089
- \`deepline monitors available\` to discover a tool first.
35184
+ \`deepline tools list --categories monitors\` to discover a tool first.
35090
35185
 
35091
35186
  Example:
35092
35187
  deepline monitors fleets init account-job-openings \\
@@ -36079,7 +36174,7 @@ Examples:
36079
36174
  )
36080
36175
  ).action(handleOrgSwitch);
36081
36176
  addOrgSetOptions(
36082
- org.command("switch [selection]").description(
36177
+ org.command("switch [selection]", { hidden: true }).description(
36083
36178
  "Deprecated alias for org set. Set the organization for the selected auth scope."
36084
36179
  ).addHelpText(
36085
36180
  "after",
@@ -36106,6 +36201,9 @@ Examples:
36106
36201
 
36107
36202
  // src/cli/commands/git.ts
36108
36203
  var GIT_DEPLOY_FEATURE = "github-deploy";
36204
+ function shellQuote3(value) {
36205
+ return `'${value.replace(/'/g, `'\\''`)}'`;
36206
+ }
36109
36207
  function renderProject(project) {
36110
36208
  const root = project.rootDirectory ? ` (${project.rootDirectory})` : "";
36111
36209
  const flags = [
@@ -36144,6 +36242,98 @@ async function handleList(options) {
36144
36242
  { json: options.json }
36145
36243
  );
36146
36244
  }
36245
+ function describeInstallationStatus(installation) {
36246
+ switch (installation.status) {
36247
+ case "active":
36248
+ return [
36249
+ `Connected to ${installation.accountLogin} (installation ${installation.installationId}).`
36250
+ ];
36251
+ case "uninstalled":
36252
+ return [
36253
+ `The Deepline GitHub App was uninstalled from ${installation.accountLogin}${installation.uninstalledAt ? ` at ${new Date(installation.uninstalledAt).toISOString()}` : ""}.`,
36254
+ "Deploys are paused for every linked repository. Run `deepline git connect`, then `deepline git link <owner/repo>` again for each repository; links from the old installation cannot be resumed."
36255
+ ];
36256
+ case "suspended":
36257
+ return [
36258
+ `GitHub suspended the Deepline App on ${installation.accountLogin}${installation.suspendedAt ? ` at ${new Date(installation.suspendedAt).toISOString()}` : ""}.`,
36259
+ "Pushes are not delivered while it is suspended; unsuspend it in GitHub settings."
36260
+ ];
36261
+ }
36262
+ }
36263
+ async function handleStatus2(options) {
36264
+ const { http } = getAuthedHttpClient();
36265
+ const payload = await http.get("/api/v2/github/installation");
36266
+ const installation = payload.installation;
36267
+ const others = (payload.installations ?? []).filter(
36268
+ (row) => row.installationId !== installation?.installationId
36269
+ );
36270
+ const lines = installation ? describeInstallationStatus(installation) : [
36271
+ "No GitHub installation is connected to this workspace. Run `deepline git connect`."
36272
+ ];
36273
+ for (const other of others) {
36274
+ lines.push(
36275
+ `Also: ${other.accountLogin} (installation ${other.installationId}) is ${other.status}.`
36276
+ );
36277
+ }
36278
+ const byId = new Map(
36279
+ (payload.installations ?? []).map((row) => [row.installationId, row])
36280
+ );
36281
+ const { projects } = await http.get(
36282
+ "/api/v2/play-projects?includeDisabled=1"
36283
+ );
36284
+ const affected_links = projects.map((project) => {
36285
+ const own = byId.get(project.installationId);
36286
+ const verdict = !own ? "unknown" : own.status === "active" ? null : own.status;
36287
+ return verdict ? {
36288
+ id: project.id,
36289
+ repoId: project.repoId,
36290
+ repoFullName: project.repoFullName,
36291
+ rootDirectory: project.rootDirectory,
36292
+ productionBranch: project.productionBranch,
36293
+ manifestPath: project.manifestPath,
36294
+ checkOnPullRequest: project.checkOnPullRequest,
36295
+ disabled: project.disabled,
36296
+ installationId: project.installationId,
36297
+ installationStatus: verdict
36298
+ } : null;
36299
+ }).filter((row) => row !== null);
36300
+ const activeInstallations = (payload.installations ?? []).filter(
36301
+ (row) => row.status === "active"
36302
+ );
36303
+ const relinkCommand = (link2) => [
36304
+ // The numeric repo id, not the name: a repository renamed while the
36305
+ // App was gone keeps a stale name here, and `git link` accepts the id.
36306
+ `deepline git link ${link2.repoId}`,
36307
+ // Stored values are admin-controlled text and this line is
36308
+ // copy-pasted into a shell by whoever reads it, so every
36309
+ // interpolated value below is quoted.
36310
+ `--branch ${shellQuote3(link2.productionBranch)}`,
36311
+ link2.rootDirectory ? `--root-dir ${shellQuote3(link2.rootDirectory)}` : "",
36312
+ link2.manifestPath && link2.manifestPath !== "deepline.json" ? `--manifest ${shellQuote3(link2.manifestPath)}` : "",
36313
+ link2.checkOnPullRequest ? "" : "--no-pr-checks",
36314
+ // With several active installations no id is guessed: the reader picks.
36315
+ activeInstallations.length > 1 ? "--installation <id>" : ""
36316
+ ].filter(Boolean).join(" ");
36317
+ for (const link2 of affected_links) {
36318
+ const label = `${link2.repoFullName}${link2.rootDirectory ? ` (${link2.rootDirectory})` : ""}`;
36319
+ lines.push(
36320
+ link2.installationStatus !== "suspended" ? `Link again: ${label} \u2014 its installation ${link2.installationId} is ${link2.installationStatus}; run \`${relinkCommand(link2)}\`${activeInstallations.length > 1 ? ` with <id> being the installation that reaches this repo: ${activeInstallations.map((row) => `${row.installationId} (${row.accountLogin})`).join(", ")}` : ""}.` : (
36321
+ // A link disabled during the suspension stays disabled; only an
36322
+ // enabled one picks up again on its own when GitHub unsuspends.
36323
+ link2.disabled ? `Paused and disabled: ${label} \u2014 its installation is suspended, and the link stays disabled after GitHub unsuspends it until you run \`deepline git set ${link2.id} --enabled\`.` : `Paused: ${label} \u2014 its installation is suspended; pushes resume when GitHub unsuspends it.`
36324
+ )
36325
+ );
36326
+ }
36327
+ printCommandEnvelope(
36328
+ {
36329
+ installation,
36330
+ installations: payload.installations ?? [],
36331
+ affected_links,
36332
+ render: { sections: [{ title: "github installation", lines }] }
36333
+ },
36334
+ { json: options.json }
36335
+ );
36336
+ }
36147
36337
  async function handleRepos(options) {
36148
36338
  const { http } = getAuthedHttpClient();
36149
36339
  const query = options.installation ? `?installationId=${encodeURIComponent(options.installation)}` : "";
@@ -36374,6 +36564,9 @@ Examples:
36374
36564
  `
36375
36565
  );
36376
36566
  git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
36567
+ git.command("status").description(
36568
+ "Show the workspace's GitHub installation and whether it is still usable."
36569
+ ).option("--json", "Emit JSON output").action(async (options) => handleStatus2(options));
36377
36570
  git.command("repos").description("List repos the workspace's GitHub installation can reach.").option(
36378
36571
  "--installation <id>",
36379
36572
  "GitHub installation id (required when several are connected)"
@@ -36484,7 +36677,7 @@ async function handleQuickstart(options) {
36484
36677
  return 0;
36485
36678
  }
36486
36679
  function registerQuickstartCommands(program) {
36487
- program.command("quickstart").description(
36680
+ program.command("quickstart", { hidden: true }).description(
36488
36681
  "Deprecated compatibility command. Use /deepline-gtm in your agent."
36489
36682
  ).addHelpText(
36490
36683
  "after",
@@ -36931,7 +37124,7 @@ import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as r
36931
37124
  import { homedir as homedir8 } from "os";
36932
37125
  import { dirname as dirname15, join as join16 } from "path";
36933
37126
 
36934
- // ../../shared_libs/cli/install-commands.json
37127
+ // contracts/install-commands.json
36935
37128
  var install_commands_default = {
36936
37129
  skills: {
36937
37130
  index_path: "/.well-known/skills/index.json",
@@ -37039,10 +37232,15 @@ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
37039
37232
 
37040
37233
  // src/cli/skills-sync.ts
37041
37234
  import { spawn as spawn2, spawnSync } from "child_process";
37235
+ import { randomUUID as randomUUID7 } from "crypto";
37042
37236
  import {
37043
37237
  existsSync as existsSync13,
37044
37238
  mkdirSync as mkdirSync10,
37239
+ readdirSync as readdirSync4,
37045
37240
  readFileSync as readFileSync14,
37241
+ renameSync,
37242
+ rmdirSync,
37243
+ statSync as statSync5,
37046
37244
  unlinkSync as unlinkSync2,
37047
37245
  writeFileSync as writeFileSync14
37048
37246
  } from "fs";
@@ -37401,6 +37599,7 @@ async function maybeReportSdkCliFailure(input2) {
37401
37599
 
37402
37600
  // src/cli/skills-sync.ts
37403
37601
  var CHECK_TIMEOUT_MS2 = 3e3;
37602
+ var SKILLS_SYNC_CLAIM_MAX_AGE_MS = 60 * 60 * 1e3;
37404
37603
  function shouldSkipSkillsSync() {
37405
37604
  if (detectAgentRuntime() === "claude_cowork") {
37406
37605
  return true;
@@ -37417,6 +37616,60 @@ function failedSkillsSyncPath(baseUrl, agents) {
37417
37616
  `skills-sync-failed-${agents.join("-")}-version`
37418
37617
  );
37419
37618
  }
37619
+ function inProgressSkillsSyncPath(baseUrl, agents) {
37620
+ return join15(
37621
+ sdkCliStateDirPath(baseUrl),
37622
+ `skills-sync-in-progress-${agents.join("-")}`
37623
+ );
37624
+ }
37625
+ function removeSkillsSyncClaim(path, token) {
37626
+ try {
37627
+ unlinkSync2(join15(path, token));
37628
+ rmdirSync(path);
37629
+ } catch {
37630
+ }
37631
+ }
37632
+ function claimSkillsSync(baseUrl, agents) {
37633
+ const path = inProgressSkillsSyncPath(baseUrl, agents);
37634
+ try {
37635
+ mkdirSync10(dirname14(path), { recursive: true });
37636
+ } catch {
37637
+ return { status: "unavailable" };
37638
+ }
37639
+ const token = randomUUID7();
37640
+ for (let attempt = 0; attempt < 2; attempt += 1) {
37641
+ const pendingPath = `${path}-pending-${token}`;
37642
+ try {
37643
+ mkdirSync10(pendingPath);
37644
+ writeFileSync14(join15(pendingPath, token), "", { flag: "wx" });
37645
+ renameSync(pendingPath, path);
37646
+ return { status: "claimed", token };
37647
+ } catch {
37648
+ removeSkillsSyncClaim(pendingPath, token);
37649
+ if (!existsSync13(path)) continue;
37650
+ }
37651
+ if (attempt > 0) return { status: "held" };
37652
+ try {
37653
+ if (Date.now() - statSync5(path).mtimeMs <= SKILLS_SYNC_CLAIM_MAX_AGE_MS) {
37654
+ return { status: "held" };
37655
+ }
37656
+ const owners = readdirSync4(path);
37657
+ if (owners.length === 0) {
37658
+ rmdirSync(path);
37659
+ continue;
37660
+ }
37661
+ if (owners.length !== 1) return { status: "held" };
37662
+ renameSync(path, `${path}-stale-${owners[0]}`);
37663
+ } catch {
37664
+ return { status: "held" };
37665
+ }
37666
+ }
37667
+ return { status: "held" };
37668
+ }
37669
+ function clearSkillsSyncClaim(baseUrl, agents, token) {
37670
+ const path = inProgressSkillsSyncPath(baseUrl, agents);
37671
+ removeSkillsSyncClaim(path, token);
37672
+ }
37420
37673
  function hasMarkedSkillsSyncVersion(path, version) {
37421
37674
  return Boolean(version) && readMarkedSkillsSyncVersion(path) === version;
37422
37675
  }
@@ -37552,7 +37805,7 @@ function hasCommand(command) {
37552
37805
  });
37553
37806
  return result.status === 0;
37554
37807
  }
37555
- function shellQuote3(arg) {
37808
+ function shellQuote4(arg) {
37556
37809
  return `'${arg.replace(/'/g, `'\\''`)}'`;
37557
37810
  }
37558
37811
  function temporarySkillsSyncSkipCommand() {
@@ -37571,7 +37824,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
37571
37824
  commands.push({
37572
37825
  command: "bunx",
37573
37826
  args: bunxArgs,
37574
- manualCommand: `bunx ${bunxArgs.map(shellQuote3).join(" ")}`
37827
+ manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
37575
37828
  });
37576
37829
  }
37577
37830
  if (hasCommand("npx")) {
@@ -37579,7 +37832,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
37579
37832
  commands.push({
37580
37833
  command: "npx",
37581
37834
  args: npxArgs,
37582
- manualCommand: `npx ${npxArgs.map(shellQuote3).join(" ")}`
37835
+ manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
37583
37836
  });
37584
37837
  }
37585
37838
  return commands;
@@ -37746,30 +37999,43 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
37746
37999
  writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
37747
38000
  return;
37748
38001
  }
37749
- writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
37750
- const installResult = await runSkillsInstall(installs, agents);
37751
- if (!installResult.installed) {
37752
- const markerWritten = markFailedSkillsSync(
37753
- baseUrl,
37754
- update.remoteVersion,
37755
- agents
38002
+ const claim = claimSkillsSync(baseUrl, agents);
38003
+ if (claim.status === "held") return;
38004
+ try {
38005
+ if (hasFailedSkillsSync(baseUrl, update.remoteVersion, agents) || readSdkSkillsLocalVersion(baseUrl) === update.remoteVersion) {
38006
+ return;
38007
+ }
38008
+ writeSdkSkillsStatusLine(
38009
+ "Deepline skills changed; syncing agent skills..."
37756
38010
  );
37757
- void maybeReportAutomaticSkillsSyncFailure({
37758
- baseUrl,
37759
- remoteSkillsVersion: update.remoteVersion,
37760
- agents,
37761
- skillsPackage: SKILLS_NPX_PACKAGE,
37762
- targetSkillCount: skillNames.length,
37763
- markerWritten,
37764
- attempts: installResult.attempts
37765
- });
37766
- return;
38011
+ const installResult = await runSkillsInstall(installs, agents);
38012
+ if (!installResult.installed) {
38013
+ const markerWritten = markFailedSkillsSync(
38014
+ baseUrl,
38015
+ update.remoteVersion,
38016
+ agents
38017
+ );
38018
+ void maybeReportAutomaticSkillsSyncFailure({
38019
+ baseUrl,
38020
+ remoteSkillsVersion: update.remoteVersion,
38021
+ agents,
38022
+ skillsPackage: SKILLS_NPX_PACKAGE,
38023
+ targetSkillCount: skillNames.length,
38024
+ markerWritten,
38025
+ attempts: installResult.attempts
38026
+ });
38027
+ return;
38028
+ }
38029
+ runLegacySkillsCleanup(agents);
38030
+ writeSdkSkillsLocalVersion(baseUrl, update.remoteVersion, agents);
38031
+ clearUnavailableSkillsNotice(baseUrl);
38032
+ clearFailedSkillsSync(baseUrl, agents);
38033
+ writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
38034
+ } finally {
38035
+ if (claim.status === "claimed") {
38036
+ clearSkillsSyncClaim(baseUrl, agents, claim.token);
38037
+ }
37767
38038
  }
37768
- runLegacySkillsCleanup(agents);
37769
- writeSdkSkillsLocalVersion(baseUrl, update.remoteVersion, agents);
37770
- clearUnavailableSkillsNotice(baseUrl);
37771
- clearFailedSkillsSync(baseUrl, agents);
37772
- writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
37773
38039
  }
37774
38040
 
37775
38041
  // src/cli/commands/skills.ts
@@ -39086,7 +39352,7 @@ import {
39086
39352
  existsSync as existsSync16,
39087
39353
  mkdirSync as mkdirSync13,
39088
39354
  readFileSync as readFileSync17,
39089
- renameSync,
39355
+ renameSync as renameSync2,
39090
39356
  rmSync as rmSync5,
39091
39357
  writeFileSync as writeFileSync17
39092
39358
  } from "fs";
@@ -39155,7 +39421,7 @@ function writeCliUpdatePreferences(preferences, homeDir2 = homedir10()) {
39155
39421
  encoding: "utf8",
39156
39422
  mode: 384
39157
39423
  });
39158
- renameSync(tempPath, path);
39424
+ renameSync2(tempPath, path);
39159
39425
  } finally {
39160
39426
  rmSync5(tempPath, { force: true });
39161
39427
  }
@@ -39212,7 +39478,7 @@ import {
39212
39478
  mkdirSync as mkdirSync14,
39213
39479
  realpathSync as realpathSync5,
39214
39480
  readFileSync as readFileSync19,
39215
- renameSync as renameSync2,
39481
+ renameSync as renameSync3,
39216
39482
  rmSync as rmSync6,
39217
39483
  unlinkSync as unlinkSync3,
39218
39484
  writeFileSync as writeFileSync18
@@ -39229,7 +39495,7 @@ import {
39229
39495
 
39230
39496
  // src/cli/install-integrity.ts
39231
39497
  import { createRequire } from "module";
39232
- import { existsSync as existsSync17, readFileSync as readFileSync18, statSync as statSync5 } from "fs";
39498
+ import { existsSync as existsSync17, readFileSync as readFileSync18, statSync as statSync6 } from "fs";
39233
39499
  import { isAbsolute as isAbsolute6, join as join19, relative as relative6, resolve as resolve17 } from "path";
39234
39500
  var SDK_SIDECAR_CRITICAL_PACKAGE_FILES = [
39235
39501
  "dist/cli/index.mjs",
@@ -39269,7 +39535,7 @@ function parseJson(path) {
39269
39535
  }
39270
39536
  function isFile(path) {
39271
39537
  try {
39272
- return statSync5(path).isFile();
39538
+ return statSync6(path).isFile();
39273
39539
  } catch {
39274
39540
  return false;
39275
39541
  }
@@ -39416,14 +39682,14 @@ function posixShellQuote(value) {
39416
39682
  function windowsCmdQuote(value) {
39417
39683
  return `"${value.replace(/"/g, '""')}"`;
39418
39684
  }
39419
- function shellQuote4(value) {
39685
+ function shellQuote5(value) {
39420
39686
  if (process.platform === "win32") {
39421
39687
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
39422
39688
  }
39423
39689
  return posixShellQuote(value);
39424
39690
  }
39425
39691
  function buildSourceUpdateCommand(sourceRoot) {
39426
- const quotedRoot = shellQuote4(sourceRoot);
39692
+ const quotedRoot = shellQuote5(sourceRoot);
39427
39693
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
39428
39694
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
39429
39695
  }
@@ -39435,7 +39701,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
39435
39701
  "fs.mkdirSync(dir,{recursive:true});",
39436
39702
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
39437
39703
  ].join("");
39438
- return `${shellQuote4(nodeBin)} -e ${shellQuote4(script)} ${shellQuote4(versionDir)}`;
39704
+ return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
39439
39705
  }
39440
39706
  function sidecarStateDir(input2) {
39441
39707
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -39498,7 +39764,7 @@ function resolvePythonSidecarUpdatePlan(options) {
39498
39764
  const npmCommand = "npm";
39499
39765
  const registryUrl = sidecarRegistryUrl(hostUrl);
39500
39766
  const versionDir = join20(stateDir, "versions", "<version>");
39501
- const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote4(versionDir)} --registry ${shellQuote4(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote4).join(" ")} ${shellQuote4(packageSpec)}`;
39767
+ const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} --registry ${shellQuote5(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
39502
39768
  return {
39503
39769
  kind: "python-sidecar",
39504
39770
  stateDir,
@@ -39645,7 +39911,7 @@ function resolveUpdatePlan(options = {}) {
39645
39911
  args,
39646
39912
  ...installPrefix ? { installPrefix } : {},
39647
39913
  ...fallbackRegistryUrl ? { fallbackRegistryUrl } : {},
39648
- manualCommand: `${command} ${args.map(shellQuote4).join(" ")}`
39914
+ manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
39649
39915
  };
39650
39916
  }
39651
39917
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -39913,23 +40179,23 @@ function writeSidecarLauncher(input2) {
39913
40179
  input2.path,
39914
40180
  [
39915
40181
  "#!/usr/bin/env sh",
39916
- `export DEEPLINE_HOST_URL=${shellQuote4(input2.hostUrl)}`,
39917
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote4(input2.scope)}`,
39918
- `if ${criticalPaths.map((path) => `[ ! -f ${shellQuote4(path)} ]`).join(" || ")}; then`,
40182
+ `export DEEPLINE_HOST_URL=${shellQuote5(input2.hostUrl)}`,
40183
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote5(input2.scope)}`,
40184
+ `if ${criticalPaths.map((path) => `[ ! -f ${shellQuote5(path)} ]`).join(" || ")}; then`,
39919
40185
  ' if [ -n "${DEEPLINE_REAL_BINARY:-}" ] && [ -x "$DEEPLINE_REAL_BINARY" ]; then',
39920
40186
  ' exec "$DEEPLINE_REAL_BINARY" --version=v2 "$@"',
39921
40187
  " fi",
39922
40188
  ' printf "%s\\n" "Deepline SDK CLI install is incomplete. Run \\`deepline update\\` to repair it." >&2',
39923
40189
  " exit 1",
39924
40190
  "fi",
39925
- `if ! ${shellQuote4(input2.nodeBin)} -e ${shellQuote4(esbuildProbe)} ${shellQuote4(versionDir)} >/dev/null 2>&1; then`,
40191
+ `if ! ${shellQuote5(input2.nodeBin)} -e ${shellQuote5(esbuildProbe)} ${shellQuote5(versionDir)} >/dev/null 2>&1; then`,
39926
40192
  ' if [ -n "${DEEPLINE_REAL_BINARY:-}" ] && [ -x "$DEEPLINE_REAL_BINARY" ]; then',
39927
40193
  ' exec "$DEEPLINE_REAL_BINARY" --version=v2 "$@"',
39928
40194
  " fi",
39929
40195
  ' printf "%s\\n" "Deepline SDK CLI install is incomplete. Run \\`deepline update\\` to repair it." >&2',
39930
40196
  " exit 1",
39931
40197
  "fi",
39932
- `exec ${shellQuote4(input2.nodeBin)} ${shellQuote4(input2.entryPath)} "$@"`,
40198
+ `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
39933
40199
  ""
39934
40200
  ].join("\n"),
39935
40201
  { encoding: "utf8", mode: 493 }
@@ -39997,7 +40263,7 @@ async function runPythonSidecarUpdatePlan(plan) {
39997
40263
  `.backup-${installedVersion}-${process.pid}-${Date.now()}`
39998
40264
  );
39999
40265
  try {
40000
- renameSync2(finalDir, backupDir);
40266
+ renameSync3(finalDir, backupDir);
40001
40267
  } catch (error) {
40002
40268
  const concurrentlyPublishedFailure = sidecarInstallFailure(finalDir);
40003
40269
  if (!concurrentlyPublishedFailure) {
@@ -40016,7 +40282,7 @@ async function runPythonSidecarUpdatePlan(plan) {
40016
40282
  }
40017
40283
  if (shouldPublishTemp) {
40018
40284
  try {
40019
- renameSync2(tempDir, finalDir);
40285
+ renameSync3(tempDir, finalDir);
40020
40286
  } catch (error) {
40021
40287
  rmSync6(tempDir, { recursive: true, force: true });
40022
40288
  const concurrentlyPublishedFailure = sidecarInstallFailure(finalDir);
@@ -40027,7 +40293,7 @@ async function runPythonSidecarUpdatePlan(plan) {
40027
40293
  let restoreFailure = "";
40028
40294
  if (backupDir && existsSync18(backupDir) && !existsSync18(finalDir)) {
40029
40295
  try {
40030
- renameSync2(backupDir, finalDir);
40296
+ renameSync3(backupDir, finalDir);
40031
40297
  backupDir = null;
40032
40298
  } catch (restoreError) {
40033
40299
  restoreFailure = `; failed to restore previous install: ${restoreError.message}`;
@@ -40047,7 +40313,7 @@ async function runPythonSidecarUpdatePlan(plan) {
40047
40313
  if (backupDir && existsSync18(backupDir)) {
40048
40314
  rmSync6(finalDir, { recursive: true, force: true });
40049
40315
  try {
40050
- renameSync2(backupDir, finalDir);
40316
+ renameSync3(backupDir, finalDir);
40051
40317
  backupDir = null;
40052
40318
  } catch {
40053
40319
  }
@@ -43199,9 +43465,9 @@ function apifySyncRecoveryNext(rawResponse) {
43199
43465
  const getDatasetItemsTool = stringField2(getDatasetItems, "tool");
43200
43466
  const getDatasetItemsPayload = recordField2(getDatasetItems, "payload");
43201
43467
  return {
43202
- getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote5(JSON.stringify(getActorRunPayload))} --json`,
43468
+ getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote6(JSON.stringify(getActorRunPayload))} --json`,
43203
43469
  ...getDatasetItemsTool && Object.keys(getDatasetItemsPayload).length > 0 ? {
43204
- getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote5(JSON.stringify(getDatasetItemsPayload))} --json`
43470
+ getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote6(JSON.stringify(getDatasetItemsPayload))} --json`
43205
43471
  } : {}
43206
43472
  };
43207
43473
  }
@@ -43374,7 +43640,7 @@ function parseExecuteOptions(args) {
43374
43640
  function safeFileStem(value) {
43375
43641
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
43376
43642
  }
43377
- function shellQuote5(value) {
43643
+ function shellQuote6(value) {
43378
43644
  return `'${value.replace(/'/g, `'\\''`)}'`;
43379
43645
  }
43380
43646
  function powerShellQuote(value) {
@@ -43444,7 +43710,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
43444
43710
  path: scriptPath,
43445
43711
  sourceCode: script,
43446
43712
  projectDir,
43447
- macCopyCommand: `mkdir -p ${shellQuote5(projectDir)} && cp ${shellQuote5(scriptPath)} ${shellQuote5(`${projectDir}/${fileName}`)}`,
43713
+ macCopyCommand: `mkdir -p ${shellQuote6(projectDir)} && cp ${shellQuote6(scriptPath)} ${shellQuote6(`${projectDir}/${fileName}`)}`,
43448
43714
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
43449
43715
  };
43450
43716
  }
@@ -43471,7 +43737,7 @@ function buildToolExecuteBaseEnvelope(input2) {
43471
43737
  envelope,
43472
43738
  "output"
43473
43739
  );
43474
- const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote5(JSON.stringify(input2.params))} --json`;
43740
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote6(JSON.stringify(input2.params))} --json`;
43475
43741
  const actions = input2.listConversion ? [
43476
43742
  {
43477
43743
  label: "next",
@@ -44291,7 +44557,7 @@ async function handleTail(id, runId, options) {
44291
44557
  }
44292
44558
  }
44293
44559
  function registerWorkflowCommands(program) {
44294
- const workflows = program.command("workflows").description(
44560
+ const workflows = program.command("workflows", { hidden: true }).description(
44295
44561
  "Legacy cloud workflows (now becoming plays). Commands still work; use `workflows transform` to migrate one to a play. " + TRIGGER_REDIRECT
44296
44562
  ).addHelpText(
44297
44563
  "after",
@@ -45111,4 +45377,10 @@ Examples:
45111
45377
  }
45112
45378
  process.exitCode = process.exitCode ?? 0;
45113
45379
  }
45114
- main();
45380
+ var DEV_CLI_AWAIT_MAIN = Symbol.for("@deepline/sdk/dev-cli-await-main");
45381
+ if (globalThis[DEV_CLI_AWAIT_MAIN] !== true) {
45382
+ void main();
45383
+ }
45384
+ export {
45385
+ main
45386
+ };