deepline 0.3.74 → 0.3.75

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 (34) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +279 -21
  2. package/dist/bundling-sources/sdk/src/config.ts +21 -3
  3. package/dist/bundling-sources/sdk/src/index.ts +1 -0
  4. package/dist/bundling-sources/sdk/src/play.ts +3 -6
  5. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  6. package/dist/bundling-sources/sdk/src/types.ts +3 -2
  7. package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +186 -0
  8. package/dist/bundling-sources/shared_libs/monitors/monitor-fleet-limits.ts +41 -0
  9. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +213 -55
  10. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +172 -299
  11. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +10 -0
  12. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +13 -32
  13. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +5 -1
  14. package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +7 -2
  15. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +11 -2
  16. package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +1 -1
  17. package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +16 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +1 -0
  19. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/testkit.ts +5 -4
  20. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +12 -2
  21. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +1 -1
  22. package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +74 -0
  23. package/dist/cli/index.js +918 -167
  24. package/dist/cli/index.mjs +918 -167
  25. package/dist/{compiler-manifest-CMNgA_JQ.d.mts → compiler-manifest-Dbov16F7.d.mts} +1 -1
  26. package/dist/{compiler-manifest-CMNgA_JQ.d.ts → compiler-manifest-Dbov16F7.d.ts} +1 -1
  27. package/dist/index.d.mts +176 -23
  28. package/dist/index.d.ts +176 -23
  29. package/dist/index.js +109 -12
  30. package/dist/index.mjs +109 -12
  31. package/dist/install-integrity.json +4 -2
  32. package/dist/plays/bundle-play-file.d.mts +2 -2
  33. package/dist/plays/bundle-play-file.d.ts +2 -2
  34. package/package.json +1 -1
@@ -890,6 +890,17 @@ function getResolvedProjectAuthSource(baseUrl, apiKey, startDir = process.cwd())
890
890
  return projectBaseUrl === normalizedBaseUrl && (env[API_KEY_ENV] ?? "").trim() === normalizedApiKey;
891
891
  }) ?? null;
892
892
  }
893
+ function resolveBaseUrlOnly(options) {
894
+ const baseUrl = normalizeBaseUrl(
895
+ options?.baseUrl?.trim() || autoDetectBaseUrl()
896
+ );
897
+ if (!baseUrl) {
898
+ throw new ConfigError(
899
+ `Invalid ${HOST_URL_ENV}. Expected an http(s) URL such as https://code.deepline.com.`
900
+ );
901
+ }
902
+ return baseUrl;
903
+ }
893
904
  function resolveConfig(options) {
894
905
  const baseUrl = normalizeBaseUrl(
895
906
  options?.baseUrl?.trim() || autoDetectBaseUrl()
@@ -1199,7 +1210,7 @@ var SDK_RELEASE = {
1199
1210
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1200
1211
  // getters keep their established compatibility behavior.
1201
1212
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1202
- version: "0.3.74",
1213
+ version: "0.3.75",
1203
1214
  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.",
1204
1215
  packageCapabilities: {
1205
1216
  updatePreferences: 1
@@ -1621,7 +1632,7 @@ var RUNTIME_INCIDENT_DRILL_CATALOG = [
1621
1632
  valueMeaning: "occurrence"
1622
1633
  },
1623
1634
  expected: {
1624
- outcome: "The same logical run completes through receipt replay; recovery remains bounded if the provider outcome must be retried.",
1635
+ outcome: "The same logical run completes through terminal-cache replay; any provider retry is governed by its separate operation policy.",
1625
1636
  safetyFacts: ["same_logical_run", "bounded_provider_execution"]
1626
1637
  },
1627
1638
  verification: {
@@ -4476,6 +4487,10 @@ var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "ca
4476
4487
  var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
4477
4488
  var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
4478
4489
  var EXECUTE_RESPONSE_INTENT_HEADER = "x-deepline-execute-response-intent";
4490
+ var MONITOR_NON_RETRYABLE_MUTATION_OPTIONS = {
4491
+ maxRetries: 0,
4492
+ exactUrlOnly: true
4493
+ };
4479
4494
  var RAW_V2_EXECUTE_RESPONSE_CONTRACT = RAW_V2_TOOL_RESPONSE_CONTRACT;
4480
4495
  var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
4481
4496
  var REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
@@ -5034,11 +5049,15 @@ var DeeplineClient = class {
5034
5049
  update: (key, patch) => this.updateMonitor(key, patch),
5035
5050
  delete: (key, options2) => this.deleteMonitor(key, options2),
5036
5051
  reactivate: (key, options2) => this.reactivateMonitor(key, options2),
5052
+ audit: (options2) => this.auditMonitors(options2),
5053
+ repair: (options2) => this.repairMonitors(options2),
5054
+ health: (options2) => this.readMonitorsHealth(options2),
5037
5055
  fleets: {
5038
5056
  sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
5039
5057
  get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
5040
5058
  list: () => this.listMonitorFleets(),
5041
5059
  deactivate: (fleetId, options2) => this.deactivateMonitorFleet(fleetId, options2),
5060
+ reactivate: (fleetId, options2) => this.reactivateMonitorFleet(fleetId, options2),
5042
5061
  waitForConvergence: (fleetId, options2) => this.waitForMonitorFleetConvergence(fleetId, options2)
5043
5062
  }
5044
5063
  };
@@ -6624,13 +6643,23 @@ var DeeplineClient = class {
6624
6643
  if (options?.grep?.trim()) {
6625
6644
  params.set("grep", options.grep.trim());
6626
6645
  params.set("grep_mode", options.grepMode ?? "all");
6646
+ params.set("grep_paginated", "1");
6627
6647
  params.set("limit", "60");
6628
6648
  }
6629
- const suffix = params.toString() ? `?${params.toString()}` : "";
6630
- const response = await this.http.get(
6631
- `/api/v2/plays${suffix}`
6632
- );
6633
- return response.plays ?? [];
6649
+ const plays = [];
6650
+ let cursor = null;
6651
+ let hasMore = true;
6652
+ do {
6653
+ if (cursor) params.set("cursor", cursor);
6654
+ const suffix = params.toString() ? `?${params.toString()}` : "";
6655
+ const response = await this.http.get(
6656
+ `/api/v2/plays${suffix}`
6657
+ );
6658
+ plays.push(...response.plays ?? []);
6659
+ cursor = response.pagination?.cursor ?? response.cursor ?? null;
6660
+ hasMore = Boolean(response.pagination?.hasMore ?? response.hasMore);
6661
+ } while (Boolean(options?.grep?.trim()) && hasMore && cursor);
6662
+ return plays;
6634
6663
  }
6635
6664
  /** Set whether an org-owned Play sorts before unpinned Plays. */
6636
6665
  async setPlayPinned(playName, pinned) {
@@ -7207,6 +7236,44 @@ var DeeplineClient = class {
7207
7236
  ...typeof payload.reason === "string" && payload.reason.trim() ? { reason: payload.reason.trim() } : {}
7208
7237
  };
7209
7238
  }
7239
+ /**
7240
+ * One bounded audit pass. Prefer `client.monitors.audit(...)`.
7241
+ *
7242
+ * Never auto-retried: it is idempotent, but a retry that races the caller's
7243
+ * own next pass would spend a provider slot to learn nothing new.
7244
+ */
7245
+ async auditMonitors(options) {
7246
+ return this.http.request("/api/v2/monitors/audit", {
7247
+ method: "POST",
7248
+ body: {
7249
+ ...options?.fleetId ? { fleet_id: options.fleetId } : {},
7250
+ ...options?.cursor ? { cursor: options.cursor } : {}
7251
+ },
7252
+ maxRetries: 0
7253
+ });
7254
+ }
7255
+ /** One repair pass or plan. Prefer `client.monitors.repair(...)`. */
7256
+ async repairMonitors(options) {
7257
+ return this.http.request("/api/v2/monitors/repair", {
7258
+ method: "POST",
7259
+ body: {
7260
+ ...options?.fleetId ? { fleet_id: options.fleetId } : {},
7261
+ ...options?.dryRun === void 0 ? {} : { dry_run: options.dryRun }
7262
+ },
7263
+ maxRetries: 0
7264
+ });
7265
+ }
7266
+ /** Delivery and convergence health. Prefer `client.monitors.health(...)`. */
7267
+ async readMonitorsHealth(options) {
7268
+ const params = new URLSearchParams();
7269
+ if (options?.fleetId) params.set("fleet_id", options.fleetId);
7270
+ const query = params.toString();
7271
+ const suffix = query ? `?${query}` : "";
7272
+ return this.http.request(
7273
+ `/api/v2/monitors/health${suffix}`,
7274
+ { method: "GET" }
7275
+ );
7276
+ }
7210
7277
  /**
7211
7278
  * The deployable monitor tools catalog. Pass a tool id (positional or
7212
7279
  * `{ tool }`) to describe one tool's full payload/stream contract, or no tool
@@ -7284,7 +7351,6 @@ var DeeplineClient = class {
7284
7351
  if (options?.limit !== void 0)
7285
7352
  params.set("limit", String(options.limit));
7286
7353
  if (options?.cursor) params.set("cursor", options.cursor);
7287
- if (options?.compact) params.set("compact", "true");
7288
7354
  if (options?.includeConsumers) params.set("include_consumers", "true");
7289
7355
  const query = params.toString();
7290
7356
  const suffix = query ? `?${query}` : "";
@@ -7301,13 +7367,22 @@ var DeeplineClient = class {
7301
7367
  );
7302
7368
  }
7303
7369
  async testMonitorWebhook(key, payload, options) {
7370
+ if (options?.dispatch === true || options?.validationOnly === false) {
7371
+ throw new DeeplineError(
7372
+ "Monitor tests are validation-only and cannot dispatch events.",
7373
+ void 0,
7374
+ "MONITOR_TEST_DISPATCH_NOT_SUPPORTED"
7375
+ );
7376
+ }
7304
7377
  return this.http.request(
7305
7378
  `/api/v2/monitors/deployed/${encodeURIComponent(key)}/test`,
7306
7379
  {
7307
7380
  method: "POST",
7308
7381
  body: {
7309
7382
  payload,
7310
- ...options?.validationOnly ? { mode: "validation_only" } : options?.dispatch ? { mode: "dispatch" } : {}
7383
+ // Send the legacy safe mode as well as accepting it server-side: an
7384
+ // upgraded SDK must be safe when it reaches a still-running server.
7385
+ mode: "validation_only"
7311
7386
  }
7312
7387
  }
7313
7388
  );
@@ -7335,7 +7410,14 @@ var DeeplineClient = class {
7335
7410
  async updateMonitor(key, patch) {
7336
7411
  return this.http.request(
7337
7412
  `/api/v2/monitors/deployed/${encodeURIComponent(key)}`,
7338
- { method: "PATCH", body: patch }
7413
+ {
7414
+ method: "PATCH",
7415
+ body: patch,
7416
+ // A monitor write may have reached the control plane before a network
7417
+ // failure reaches the caller. Do not turn that unknown outcome into a
7418
+ // second mutation with a fresh snapshot.
7419
+ ...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
7420
+ }
7339
7421
  );
7340
7422
  }
7341
7423
  /** Delete a deployed monitor and its upstream provider resource. `dryRun` returns the delete plan. Prefer `client.monitors.delete(...)`. */
@@ -7352,7 +7434,12 @@ var DeeplineClient = class {
7352
7434
  const query = params.toString();
7353
7435
  return this.http.request(
7354
7436
  `/api/v2/monitors/deployed/${encodeURIComponent(key)}${query ? `?${query}` : ""}`,
7355
- { method: "DELETE" }
7437
+ options?.dryRun ? { method: "DELETE" } : {
7438
+ method: "DELETE",
7439
+ // Deletion is a provider lifecycle operation. A timeout is an
7440
+ // unknown outcome, not authority to begin another delete attempt.
7441
+ ...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
7442
+ }
7356
7443
  );
7357
7444
  }
7358
7445
  /**
@@ -7363,7 +7450,13 @@ var DeeplineClient = class {
7363
7450
  const query = options?.dryRun ? "?dry_run=true" : "";
7364
7451
  return this.http.request(
7365
7452
  `/api/v2/monitors/deployed/${encodeURIComponent(key)}/reactivate${query}`,
7366
- { method: "POST", body: {} }
7453
+ options?.dryRun ? { method: "POST", body: {} } : {
7454
+ method: "POST",
7455
+ body: {},
7456
+ // Reactivation can create an upstream resource, so it must not use
7457
+ // the generic transport's automatic replay policy.
7458
+ ...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
7459
+ }
7367
7460
  );
7368
7461
  }
7369
7462
  // ——————————————————————————————————————————————————————————
@@ -7440,6 +7533,21 @@ var DeeplineClient = class {
7440
7533
  }
7441
7534
  );
7442
7535
  }
7536
+ async reactivateMonitorFleet(fleetId, options) {
7537
+ return this.http.request(
7538
+ `${this.monitorFleetPath(fleetId)}/reactivate`,
7539
+ {
7540
+ method: "POST",
7541
+ body: {},
7542
+ headers: this.monitorFleetHeaders(
7543
+ "reactivate",
7544
+ options?.idempotencyKey
7545
+ ),
7546
+ maxRetries: 0,
7547
+ exactUrlOnly: true
7548
+ }
7549
+ );
7550
+ }
7443
7551
  /**
7444
7552
  * Poll one fleet until the server reports a terminal status.
7445
7553
  *
@@ -9034,6 +9142,12 @@ async function handleStatus(args) {
9034
9142
  ...payload.workspace.name ? [`Workspace: ${payload.workspace.name}`] : [],
9035
9143
  ...payload.workspace.slug ? [`Workspace slug: ${payload.workspace.slug}`] : [],
9036
9144
  ...payload.workspace.id != null ? [`Org ID: ${payload.workspace.id}`] : [],
9145
+ // Switching orgs lives under `deepline org`, but this is where
9146
+ // people look when they discover they are in the wrong
9147
+ // workspace. Without the pointer the reasonable next move is
9148
+ // `deepline auth register`, which re-approves the same account
9149
+ // and leaves the active org unchanged.
9150
+ "Switch workspace: deepline org list, then deepline org set <org-id>",
9037
9151
  ...payload.user.id != null ? [`User ID: ${payload.user.id}`] : [],
9038
9152
  ...payload.examples.length > 0 ? [
9039
9153
  "Examples:",
@@ -9065,8 +9179,16 @@ Notes:
9065
9179
  opening the approval page in Cowork. Use --wait no in CI or agent runs, then
9066
9180
  finish with deepline auth wait.
9067
9181
  Auth status shows the target host and active workspace without printing secrets.
9182
+ Registering again re-approves the same account; it does not change the active
9183
+ workspace. To switch, use deepline org list and deepline org set <org-id>.
9068
9184
  `
9069
9185
  );
9186
+ auth.command("workspaces").description("Deprecated. Use deepline org list to see workspaces.").action(() => {
9187
+ console.error(
9188
+ "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."
9189
+ );
9190
+ process.exitCode = 1;
9191
+ });
9070
9192
  auth.command("register").description(
9071
9193
  "Register this device and open the approval page in your browser."
9072
9194
  ).addHelpText(
@@ -9311,6 +9433,18 @@ function billingTopUpFailureFromError(error, input2) {
9311
9433
  }
9312
9434
  return null;
9313
9435
  }
9436
+ function normalizeUnixMilliseconds(value) {
9437
+ const timestamp = Math.floor(value);
9438
+ return Number.isFinite(timestamp) && timestamp >= 0 && Number.isFinite(new Date(timestamp).getTime()) ? timestamp : null;
9439
+ }
9440
+ function parseSince(raw) {
9441
+ if (!raw?.trim()) return null;
9442
+ const numeric = Number(raw);
9443
+ const normalizedNumeric = normalizeUnixMilliseconds(numeric);
9444
+ if (normalizedNumeric !== null) return normalizedNumeric;
9445
+ const parsed = Date.parse(raw);
9446
+ return normalizeUnixMilliseconds(parsed);
9447
+ }
9314
9448
  function humanize(value) {
9315
9449
  return String(value || "").split("_").filter(Boolean).map((token) => token[0]?.toUpperCase() + token.slice(1)).join(" ") || "Unknown";
9316
9450
  }
@@ -9596,6 +9730,18 @@ async function handleHistory(options) {
9596
9730
  );
9597
9731
  }
9598
9732
  async function handleLedgerExportAll(options) {
9733
+ const sinceAt = parseSince(options.since);
9734
+ if (options.since && sinceAt === null) {
9735
+ reportBillingFailure(
9736
+ {
9737
+ exitCode: 2,
9738
+ code: "INVALID_SINCE",
9739
+ message: "--since must be an ISO-8601 timestamp or Unix milliseconds."
9740
+ },
9741
+ options
9742
+ );
9743
+ return;
9744
+ }
9599
9745
  const { http } = getAuthedHttpClient();
9600
9746
  const outputPath = options.output ? resolve3(String(options.output)) : defaultLedgerExportPath();
9601
9747
  let summary = { row_count: 0, net_delta_credits: 0 };
@@ -9605,6 +9751,8 @@ async function handleLedgerExportAll(options) {
9605
9751
  const params = new URLSearchParams({ limit: "5000" });
9606
9752
  if (cursor !== null) params.set("cursor", cursor);
9607
9753
  if (options.runId) params.set("run_id", options.runId);
9754
+ if (options.operation) params.set("operation", options.operation);
9755
+ if (sinceAt !== null) params.set("since_at", String(sinceAt));
9608
9756
  const payload = await http.get(
9609
9757
  `/api/v2/billing/ledger?${params.toString()}`
9610
9758
  );
@@ -9633,13 +9781,15 @@ async function handleLedgerExportAll(options) {
9633
9781
  net_delta_credits: summary.net_delta_credits,
9634
9782
  scope: "workspace",
9635
9783
  ...options.runId ? { run_id: options.runId } : {},
9784
+ ...options.operation ? { operation: options.operation } : {},
9785
+ ...sinceAt !== null ? { since_at: sinceAt } : {},
9636
9786
  render: {
9637
9787
  sections: [
9638
9788
  {
9639
9789
  title: "billing ledger",
9640
9790
  lines: [
9641
9791
  `Billing ledger written to ${outputPath}`,
9642
- `${summary.row_count} row(s) exported for the active workspace${options.runId ? ` and run ${options.runId}` : ""}.`,
9792
+ `${summary.row_count} row(s) exported for the active workspace${options.runId ? ` and run ${options.runId}` : ""}${options.operation ? ` and operation ${options.operation}` : ""}${sinceAt !== null ? ` since ${new Date(sinceAt).toISOString()}` : ""}.`,
9643
9793
  `Net ledger delta: ${summary.net_delta_credits} Deepline Credits`
9644
9794
  ]
9645
9795
  }
@@ -10336,6 +10486,7 @@ Examples:
10336
10486
  deepline billing ledger export all
10337
10487
  deepline billing ledger export all --output ./ledger.csv
10338
10488
  deepline billing ledger export all --run-id play/demo/run/abc123
10489
+ deepline billing ledger export all --operation limadata_find_audience_identifiers --since 2026-09-01T00:00:00Z
10339
10490
  deepline billing ledger export all --json
10340
10491
  `
10341
10492
  ).addCommand(
@@ -10357,7 +10508,10 @@ Examples:
10357
10508
  deepline billing ledger export all
10358
10509
  deepline billing ledger export all --json
10359
10510
  `
10360
- ).option("--output <path>", "Write CSV to an explicit path").option("--run-id <run_id>", "Export ledger rows for one play run.").option(
10511
+ ).option("--output <path>", "Write CSV to an explicit path").option("--run-id <run_id>", "Export ledger rows for one play run.").option("--operation <id>", "Export rows for one tool operation.").option(
10512
+ "--since <timestamp>",
10513
+ "Only export rows since ISO-8601 time or Unix milliseconds."
10514
+ ).option(
10361
10515
  "--json",
10362
10516
  "Emit JSON output. Also automatic when stdout is piped"
10363
10517
  ).action(handleLedgerExportAll)
@@ -16696,7 +16850,7 @@ async function traceCliSpan(phase, fields, run) {
16696
16850
  var EXTRACTED_GETTER_ERROR_HINT = "Deepline hint: extractedValues/extractedLists .get() only works for declared Deepline getters listed by `deepline tools describe <tool> --json`. Use `toolExecutionResult.toolResponse.raw` for provider/tool-specific scalar fields, and `toolExecutionResult.extractedLists.<name>.get()` for declared row/list outputs.";
16697
16851
  var DATASET_API_HINT = "Deepline hint: PlayDataset is lazy, durable, and async-only. Use `.count()`, `.first()`, `.at(index)`, `.peek(n)`, `.materialize(limit)`, or async iteration; do not use `.length`, numeric indexing, spread, synchronous iteration, `.rows`, or `.toArray()`.";
16698
16852
  var ROW_PROPERTY_HINT = "Deepline hint: this row type only contains fields produced by the CSV/schema and previous map steps. Check source column casing and the exact output field names from earlier steps before scaling.";
16699
- var TOOLS_EXECUTE_SIGNATURE_HINT = "Deepline hint: ctx.tools.execute requires a request object: `ctx.tools.execute({ id, tool, input, description })`. The stable `id` is required for logs, metadata, and receipt attachment; provider-call reuse is based on play, tool, semantic input, auth scope, provider action version, and cache policy.";
16853
+ var TOOLS_EXECUTE_SIGNATURE_HINT = "Deepline hint: ctx.tools.execute requires a request object: `ctx.tools.execute({ id, tool, input, description })`. The stable `id` is required for logs, metadata, and result-cache identity; terminal cache reuse is based on play, tool, semantic input, auth scope, provider action version, and cache policy.";
16700
16854
  var RUN_PLAY_SIGNATURE_HINT = "Deepline hint: ctx.runPlay uses a stable key plus a composable child play reference. Direct-run-only or dataset-backed batch plays must be run directly, exported, then consumed by a separate play.";
16701
16855
  var MAP_BACKED_CHILD_HINT = "Deepline hint: dataset-backed child plays own durable table state and cannot be called from another play. Run that play directly, export its dataset, then pass the CSV to the next play.";
16702
16856
  function sourceLineForError(sourceCode, error) {
@@ -32538,7 +32692,7 @@ function renderDeployedListText(payload, requestedStatus) {
32538
32692
  return status && count !== void 0 ? [`${status}: ${count}`] : [];
32539
32693
  }).join(" ") : "";
32540
32694
  if (summary) lines.push(`All lifecycle states: ${summary}`);
32541
- if (payload.is_truncated === true) {
32695
+ if (payload.has_more === true || payload.is_truncated === true) {
32542
32696
  const nextCursor = asString(payload.next_cursor);
32543
32697
  lines.push(
32544
32698
  total !== void 0 ? `List truncated \u2014 showing ${monitors.length} of ${total}. Before concluding "no matching monitor exists," page the full registry:` : 'List truncated. Before concluding "no matching monitor exists," page the full registry:',
@@ -32552,11 +32706,15 @@ function renderDeployedListText(payload, requestedStatus) {
32552
32706
  `;
32553
32707
  }
32554
32708
  async function handleMonitorsList(options) {
32709
+ if (options.compact) {
32710
+ process.stderr.write(
32711
+ "`--compact` is deprecated and now does nothing; returning the complete monitor records.\n"
32712
+ );
32713
+ }
32555
32714
  const payload = await new DeeplineClient().monitors.list({
32556
32715
  ...options.status ? { status: options.status } : {},
32557
32716
  ...options.limit ? { limit: options.limit } : {},
32558
32717
  ...options.cursor ? { cursor: options.cursor } : {},
32559
- ...options.compact ? { compact: true } : {},
32560
32718
  ...options.includeConsumers ? { includeConsumers: true } : {}
32561
32719
  });
32562
32720
  printCommandEnvelope(payload, {
@@ -32667,6 +32825,10 @@ var MONITOR_FLEET_COMMANDS = [
32667
32825
  {
32668
32826
  name: "deactivate",
32669
32827
  summary: "Deactivate a fleet and the monitors it owns."
32828
+ },
32829
+ {
32830
+ name: "reactivate",
32831
+ summary: "Explicitly recreate a fleet after a credit-triggered suspension."
32670
32832
  }
32671
32833
  ];
32672
32834
  var MONITOR_FLEET_AGENT_NOTES = [
@@ -33169,6 +33331,72 @@ async function handleMonitorFleetsGet(fleetId, options) {
33169
33331
  { json: options.json, text }
33170
33332
  );
33171
33333
  }
33334
+ function fleetReactivateCommandLine(fleetId, options) {
33335
+ const parts = [
33336
+ "deepline",
33337
+ "monitors",
33338
+ "fleets",
33339
+ "reactivate",
33340
+ fleetShellArg(fleetId),
33341
+ "--yes"
33342
+ ];
33343
+ if (options.wait) parts.push("--wait");
33344
+ if (options.timeout)
33345
+ parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
33346
+ if (options.idempotencyKey)
33347
+ parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
33348
+ parts.push(...fleetJsonFlag(options));
33349
+ return parts.join(" ");
33350
+ }
33351
+ async function handleMonitorFleetsReactivate(fleetId, options, idempotencyKey) {
33352
+ if (!options.yes) {
33353
+ throw new MonitorsUsageError(
33354
+ `reactivate can recreate every suspended provider monitor and restart lifecycle billing. Confirm with --yes:
33355
+ ${fleetReactivateCommandLine(fleetId, options)}`
33356
+ );
33357
+ }
33358
+ const client2 = new DeeplineClient();
33359
+ const payload = await client2.monitors.fleets.reactivate(fleetId, {
33360
+ idempotencyKey
33361
+ });
33362
+ const accepted = { ...payload, idempotency_key: idempotencyKey };
33363
+ if (!options.wait) {
33364
+ printCommandEnvelope(accepted, {
33365
+ json: options.json,
33366
+ text: `Fleet ${fleetId} \u2014 ${asString(payload.status) ?? "billing_reactivating"}
33367
+ idempotency key ${idempotencyKey}
33368
+ `
33369
+ });
33370
+ return;
33371
+ }
33372
+ const timeoutMs = fleetTimeoutMs(options.timeout);
33373
+ const progress = fleetProgressReporter();
33374
+ let final;
33375
+ try {
33376
+ final = await client2.monitors.fleets.waitForConvergence(fleetId, {
33377
+ timeoutMs,
33378
+ pollIntervalMs: FLEET_POLL_INTERVAL_MS,
33379
+ onProgress: progress.report
33380
+ });
33381
+ } finally {
33382
+ progress.finish();
33383
+ }
33384
+ const envelope = { ...accepted, ...final };
33385
+ const text = renderFleetGet(final);
33386
+ if (fleetStatus(final) === "converged") {
33387
+ printCommandEnvelope(envelope, { json: options.json, text });
33388
+ return;
33389
+ }
33390
+ reportFleetState(
33391
+ envelope,
33392
+ new MonitorFleetStateError({
33393
+ code: "MONITOR_FLEET_WAIT_TIMEOUT",
33394
+ message: `Stopped waiting after ${timeoutMs}ms. Fleet ${fleetId} recovery is still in progress on the server.`,
33395
+ next: fleetServerNext(final) ?? `deepline monitors fleets get ${fleetShellArg(fleetId)} --json`
33396
+ }),
33397
+ { json: options.json, text }
33398
+ );
33399
+ }
33172
33400
  function fleetDeactivateCommandLine(fleetId, options) {
33173
33401
  const parts = [
33174
33402
  "deepline monitors fleets deactivate",
@@ -33466,18 +33694,11 @@ async function handleMonitorsGet(key, options) {
33466
33694
  }
33467
33695
  async function handleMonitorsTest(key, payload, options) {
33468
33696
  const explicitPayload = parseJsonObjectArg(payload, "<payload>");
33469
- const result = await new DeeplineClient().monitors.test(
33470
- key,
33471
- explicitPayload,
33472
- {
33473
- validationOnly: options.dispatch !== true,
33474
- dispatch: options.dispatch === true
33475
- }
33476
- );
33477
- const dispatch = options.dispatch === true;
33697
+ const result = await new DeeplineClient().monitors.test(key, explicitPayload);
33478
33698
  const text = `Monitor diagnostic for ${key}: ${result.accepted === true ? "accepted" : "rejected"}
33479
- ` + (dispatch ? " mode: dispatch (writes rows and may dispatch bound Plays)\n" : " mode: validation_only (no rows written, credits spent, or Plays dispatched)\n") + `${dispatch ? "persisted" : "would persist"} rows: ${asFiniteNumber(result.persisted_rows) ?? 0}
33480
- ${dispatch ? "dispatched" : "would dispatch"} bound Plays: ${asFiniteNumber(result.dispatched_bound_plays) ?? 0}
33699
+ mode: validation_only (no rows written, credits spent, or Plays dispatched)
33700
+ persisted rows: ${asFiniteNumber(result.persisted_rows) ?? 0}
33701
+ dispatched bound Plays: ${asFiniteNumber(result.dispatched_bound_plays) ?? 0}
33481
33702
  `;
33482
33703
  printCommandEnvelope(result, { json: options.json, text });
33483
33704
  }
@@ -33557,6 +33778,206 @@ async function handleMonitorsReactivate(key, options) {
33557
33778
  const payload = await client2.monitors.reactivate(key);
33558
33779
  printCommandEnvelope(payload, { json: options.json });
33559
33780
  }
33781
+ var MONITOR_VERB_POLL_INTERVAL_MS = 2e3;
33782
+ function monitorHealthLine(health) {
33783
+ return [
33784
+ `converged ${health.converged}/${health.scanned}`,
33785
+ `needs_repair ${health.needs_repair}`,
33786
+ `missing ${health.observed.missing}`,
33787
+ `unaudited ${health.observed.unknown + health.observed.unset}`,
33788
+ `silent ${health.silent}`
33789
+ ].join(" \xB7 ");
33790
+ }
33791
+ function monitorVerbProgressReporter() {
33792
+ const interactive = process.stderr.isTTY === true;
33793
+ let wrote = false;
33794
+ let lastPlainAt = 0;
33795
+ return {
33796
+ report: (health) => {
33797
+ const line = monitorHealthLine(health);
33798
+ if (interactive) {
33799
+ process.stderr.write(`\r\x1B[2K${line}`);
33800
+ wrote = true;
33801
+ return;
33802
+ }
33803
+ const now = Date.now();
33804
+ if (wrote && now - lastPlainAt < FLEET_PLAIN_PROGRESS_INTERVAL_MS) return;
33805
+ lastPlainAt = now;
33806
+ wrote = true;
33807
+ process.stderr.write(`${line}
33808
+ `);
33809
+ },
33810
+ finish: () => {
33811
+ if (interactive && wrote) process.stderr.write("\n");
33812
+ }
33813
+ };
33814
+ }
33815
+ async function watchMonitorHealth(input2) {
33816
+ const deadlineAt = Date.now() + input2.timeoutMs;
33817
+ const scope = input2.fleetId ? { fleetId: input2.fleetId } : {};
33818
+ let last = await input2.client.monitors.health(scope);
33819
+ input2.onProgress(last);
33820
+ while (Date.now() < deadlineAt) {
33821
+ if (last.needs_repair === 0 && last.observed.unknown === 0) return last;
33822
+ await new Promise(
33823
+ (resolve21) => setTimeout(resolve21, MONITOR_VERB_POLL_INTERVAL_MS)
33824
+ );
33825
+ last = await input2.client.monitors.health(scope);
33826
+ input2.onProgress(last);
33827
+ }
33828
+ return last;
33829
+ }
33830
+ function monitorHealthText(health) {
33831
+ const partial = health.truncated ? " (partial \u2014 scope larger than one read)" : "";
33832
+ const lines = [
33833
+ `scope: ${health.scope.fleet_id ?? "workspace"}${partial}`,
33834
+ monitorHealthLine(health)
33835
+ ];
33836
+ if (health.deactivation_reasons.length > 0) {
33837
+ lines.push("");
33838
+ lines.push("deactivated by Deepline:");
33839
+ for (const entry of health.deactivation_reasons) {
33840
+ const how = entry.resolution ? ` \u2014 ${entry.resolution}` : "";
33841
+ lines.push(` ${entry.reason} (${entry.count})${how}`);
33842
+ }
33843
+ }
33844
+ if (health.worst_offenders.length > 0) {
33845
+ lines.push("");
33846
+ lines.push(
33847
+ `silent longest (no delivery in ${health.silent_window_days}d):`
33848
+ );
33849
+ for (const entry of health.worst_offenders) {
33850
+ const when = entry.last_event_at === null ? "never" : new Date(entry.last_event_at).toISOString();
33851
+ lines.push(` ${entry.monitor_key} ${entry.tool} last event ${when}`);
33852
+ }
33853
+ }
33854
+ return `${lines.join("\n")}
33855
+ `;
33856
+ }
33857
+ async function handleMonitorsAudit(options) {
33858
+ const client2 = new DeeplineClient();
33859
+ const fleetId = options.fleet?.trim() || void 0;
33860
+ const scope = fleetId ? { fleetId } : {};
33861
+ let result = await client2.monitors.audit(scope);
33862
+ const passes = [result.audit];
33863
+ while (result.audit.cursor !== null) {
33864
+ result = await client2.monitors.audit({
33865
+ ...scope,
33866
+ cursor: result.audit.cursor
33867
+ });
33868
+ passes.push(result.audit);
33869
+ }
33870
+ const totals = passes.reduce(
33871
+ (sum, pass) => ({
33872
+ scanned: sum.scanned + pass.scanned,
33873
+ asked: sum.asked + pass.asked,
33874
+ stale: sum.stale + pass.stale,
33875
+ missing: sum.missing + pass.observed.missing
33876
+ }),
33877
+ { scanned: 0, asked: 0, stale: 0, missing: 0 }
33878
+ );
33879
+ let health = result.health;
33880
+ if (options.watch) {
33881
+ const progress = monitorVerbProgressReporter();
33882
+ try {
33883
+ health = await watchMonitorHealth({
33884
+ client: client2,
33885
+ ...scope,
33886
+ timeoutMs: fleetTimeoutMs(options.timeout),
33887
+ onProgress: progress.report
33888
+ });
33889
+ } finally {
33890
+ progress.finish();
33891
+ }
33892
+ }
33893
+ const unauditable = result.audit.unauditable_capabilities;
33894
+ const overtaken = totals.stale > 0 ? ` \xB7 ${totals.stale} observations overtaken by a concurrent settle` : "";
33895
+ const text = [
33896
+ `audited ${totals.scanned} monitors \xB7 asked the provider about ${totals.asked}`,
33897
+ `missing ${totals.missing}${overtaken}`,
33898
+ ...unauditable.length > 0 ? [`not auditable (no batch-read contract): ${unauditable.join(", ")}`] : [],
33899
+ "",
33900
+ monitorHealthText(health)
33901
+ ].join("\n");
33902
+ printCommandEnvelope(
33903
+ { ...result, audit: { ...result.audit, totals }, health },
33904
+ { json: options.json, text }
33905
+ );
33906
+ }
33907
+ async function handleMonitorsRepair(options) {
33908
+ const client2 = new DeeplineClient();
33909
+ const fleetId = options.fleet?.trim() || void 0;
33910
+ const scope = fleetId ? { fleetId } : {};
33911
+ const result = await client2.monitors.repair({
33912
+ ...scope,
33913
+ ...options.dryRun ? { dryRun: true } : {}
33914
+ });
33915
+ if (options.dryRun) {
33916
+ assertMonitorDryRunAcknowledged(
33917
+ result,
33918
+ { command: "monitors repair", mutation: "repair" }
33919
+ );
33920
+ }
33921
+ let health = result.health;
33922
+ if (options.watch && !options.dryRun) {
33923
+ const progress = monitorVerbProgressReporter();
33924
+ try {
33925
+ health = await watchMonitorHealth({
33926
+ client: client2,
33927
+ ...scope,
33928
+ timeoutMs: fleetTimeoutMs(options.timeout),
33929
+ onProgress: progress.report
33930
+ });
33931
+ } finally {
33932
+ progress.finish();
33933
+ }
33934
+ }
33935
+ const verb = options.dryRun ? "would queue" : "queued";
33936
+ const lines = [
33937
+ `${verb} ${result.repair.queued} of ${result.repair.scanned} monitors`
33938
+ ];
33939
+ for (const item of result.repair.plan.slice(0, REPAIR_PLAN_PREVIEW)) {
33940
+ const why = item.deactivation_reason ? ` \xB7 ${item.deactivation_reason}` : "";
33941
+ lines.push(
33942
+ ` ${item.action.padEnd(6)} ${item.monitor_key} desired ${item.desired} \xB7 observed ${item.observed}${why}`
33943
+ );
33944
+ }
33945
+ if (result.repair.plan.length > REPAIR_PLAN_PREVIEW) {
33946
+ lines.push(` \u2026 ${result.repair.plan.length - REPAIR_PLAN_PREVIEW} more`);
33947
+ }
33948
+ if (result.repair.unaudited.length > 0) {
33949
+ lines.push(
33950
+ `${result.repair.unaudited.length} monitors have never been observed \u2014 run 'deepline monitors audit' first.`
33951
+ );
33952
+ }
33953
+ if (result.repair.unowned.length > 0) {
33954
+ lines.push(
33955
+ `${result.repair.unowned.length} monitors disagree but no fleet owns them; repair those with 'deepline monitors deploy' or 'deepline monitors delete'.`
33956
+ );
33957
+ }
33958
+ if (result.repair.fenced.length > 0) {
33959
+ lines.push(
33960
+ `${result.repair.fenced.length} monitors have a provider operation in flight; Deepline is finishing those and repair left them alone.`
33961
+ );
33962
+ }
33963
+ lines.push("");
33964
+ lines.push(monitorHealthText(health));
33965
+ printCommandEnvelope(
33966
+ { ...result, health },
33967
+ { json: options.json, text: lines.join("\n") }
33968
+ );
33969
+ }
33970
+ var REPAIR_PLAN_PREVIEW = 20;
33971
+ async function handleMonitorsHealth(options) {
33972
+ const fleetId = options.fleet?.trim() || void 0;
33973
+ const health = await new DeeplineClient().monitors.health(
33974
+ fleetId ? { fleetId } : {}
33975
+ );
33976
+ printCommandEnvelope(health, {
33977
+ json: options.json,
33978
+ text: monitorHealthText(health)
33979
+ });
33980
+ }
33560
33981
  function registerMonitorsCommands(program) {
33561
33982
  const monitors = program.command("monitors").description("Discover, deploy, and manage Deepline monitors.").showSuggestionAfterError(true).addHelpText(
33562
33983
  "after",
@@ -33592,6 +34013,75 @@ Examples:
33592
34013
  deepline monitors reactivate my-monitor --dry-run
33593
34014
  `
33594
34015
  );
34016
+ withJsonOption(
34017
+ monitors.command("audit").description(
34018
+ "Re-read what the provider actually holds for your monitors."
34019
+ ).option("--fleet <fleet-id>", "Audit one fleet instead of every monitor").option("--watch", "Keep polling health until the scope settles").option(
34020
+ "--timeout <duration>",
34021
+ "How long --watch waits, e.g. 90s, 5m, 1h (default 10m)"
34022
+ ).addHelpText(
34023
+ "after",
34024
+ `
34025
+ Notes:
34026
+ Asks the provider, by resource id, what it still holds, and records the answer
34027
+ on each monitor. It changes nothing upstream: no creates, no deletes, no
34028
+ intent. Safe to run at any time, as often as you like \u2014 running it twice is
34029
+ running it once, twice.
34030
+
34031
+ A monitor the provider does not return is recorded "missing". Use
34032
+ 'deepline monitors repair' to act on that.
34033
+
34034
+ Examples:
34035
+ deepline monitors audit
34036
+ deepline monitors audit --fleet accounts-eu --json
34037
+ deepline monitors audit --fleet accounts-eu --watch --timeout 5m
34038
+ `
34039
+ )
34040
+ ).action(monitorsAction(handleMonitorsAudit));
34041
+ withJsonOption(
34042
+ monitors.command("repair").description(
34043
+ "Converge the monitors whose desired and observed states disagree."
34044
+ ).option("--fleet <fleet-id>", "Repair one fleet instead of every monitor").option("--dry-run", "Show what would be queued without queueing it").option("--watch", "Keep polling health until the scope settles").option(
34045
+ "--timeout <duration>",
34046
+ "How long --watch waits, e.g. 90s, 5m, 1h (default 10m)"
34047
+ ).addHelpText(
34048
+ "after",
34049
+ `
34050
+ Notes:
34051
+ Queues the monitors that disagree with the provider onto the same convergence
34052
+ loop a fleet sync uses; the provider work happens on Deepline's own schedule.
34053
+ Idempotent \u2014 the queue IS the disagreement, so a repeat run queues only what
34054
+ is still wrong.
34055
+
34056
+ Monitors nobody has observed are never repaired: run 'deepline monitors audit'
34057
+ first. Monitors no fleet owns are reported rather than queued; deploy or delete
34058
+ those directly.
34059
+
34060
+ Examples:
34061
+ deepline monitors repair --dry-run
34062
+ deepline monitors repair --fleet accounts-eu --watch
34063
+ `
34064
+ )
34065
+ ).action(monitorsAction(handleMonitorsRepair));
34066
+ withJsonOption(
34067
+ monitors.command("health").description("Delivery and convergence health for your monitors.").option(
34068
+ "--fleet <fleet-id>",
34069
+ "Report on one fleet instead of every monitor"
34070
+ ).addHelpText(
34071
+ "after",
34072
+ `
34073
+ Notes:
34074
+ Read-only. Reports how many monitors the provider holds as asked, how many
34075
+ disagree, how many Deepline deactivated and why, and how many are "silent" \u2014
34076
+ the provider holds them but nothing has been delivered recently. The worst
34077
+ offenders are listed longest-quiet first.
34078
+
34079
+ Examples:
34080
+ deepline monitors health
34081
+ deepline monitors health --fleet accounts-eu --json
34082
+ `
34083
+ )
34084
+ ).action(monitorsAction(handleMonitorsHealth));
33595
34085
  withJsonOption(
33596
34086
  monitors.command("status").description("Check whether you have access to Deepline monitors.").addHelpText(
33597
34087
  "after",
@@ -33644,10 +34134,10 @@ Examples:
33644
34134
  `
33645
34135
  Notes:
33646
34136
  Read-only. --status filters by monitor status: active (default), disabled, or
33647
- all. The output echoes the status filter that was applied. --compact returns
33648
- high-signal fields only. The response reports total (the true registry count,
33649
- not the page size), returned, is_truncated, and next_cursor. When is_truncated
33650
- is true, page with --cursor <next_cursor> until it is false \u2014 a "no matching
34137
+ all. The output echoes the status filter that was applied. The response reports
34138
+ total (the true registry count, not the page size), returned, has_more, and
34139
+ next_cursor. When has_more is true, page with --cursor <next_cursor> until it
34140
+ is false \u2014 a "no matching
33651
34141
  monitor" reuse conclusion off a truncated page deploys a duplicate paid feed.
33652
34142
  The default list stays cheap: it includes the current downstream Play binding
33653
34143
  metadata but does not resolve per-monitor delivery/run health. Pass
@@ -33658,7 +34148,6 @@ Examples:
33658
34148
  deepline monitors list
33659
34149
  deepline monitors list --status all --json
33660
34150
  deepline monitors list --status all --cursor <next_cursor> --json
33661
- deepline monitors list --compact --json
33662
34151
  deepline monitors list --include-consumers --limit 20 --json
33663
34152
  `
33664
34153
  ).option(
@@ -33667,7 +34156,10 @@ Examples:
33667
34156
  ).option("--limit <n>", "Limit the number of deployed monitors returned").option(
33668
34157
  "--cursor <cursor>",
33669
34158
  "Page past a truncated result using the next_cursor from a prior list response"
33670
- ).option("--compact", COMPACT_OPTION_DESCRIPTION).option(
34159
+ ).option(
34160
+ "--compact",
34161
+ "Deprecated no-op; complete records are always returned"
34162
+ ).option(
33671
34163
  "--include-consumers",
33672
34164
  "Include current SQL-listener consumer health (requires --limit 20 or fewer)"
33673
34165
  )
@@ -33690,10 +34182,7 @@ Examples:
33690
34182
  ).action(monitorsAction(handleMonitorsGet));
33691
34183
  withJsonOption(
33692
34184
  monitors.command("test <key> <payload>").description(
33693
- "Send an explicit payload through a monitor\u2019s webhook ingestion path."
33694
- ).option(
33695
- "--dispatch",
33696
- "Inject the test event through normal ingestion (writes rows and may dispatch bound Plays)"
34185
+ "Validate an explicit payload against a monitor\u2019s webhook contract."
33697
34186
  ).addHelpText(
33698
34187
  "after",
33699
34188
  `
@@ -33701,9 +34190,8 @@ Notes:
33701
34190
  <payload> must be an explicit JSON object. The command uses the deployed
33702
34191
  monitor\u2019s real binding and payload validation, but is a side-effect-free
33703
34192
  diagnostic: it does not persist rows, spend credits, dispatch Plays, or alter
33704
- monitor state. Pass --dispatch only when you deliberately need the historic
33705
- full-ingestion test event; it can write rows and trigger bound Plays. It does
33706
- not synthesize a provider event or accept an omitted payload.
34193
+ monitor state. It does not synthesize a provider event or accept an omitted
34194
+ payload.
33707
34195
 
33708
34196
  Examples:
33709
34197
  deepline monitors test rb2b-website-visitors '{"LinkedIn URL":"https://www.linkedin.com/in/example","Website":"https://example.com"}' --json
@@ -34020,6 +34508,40 @@ Examples:
34020
34508
  reportMonitorsFailure(error, { retryCommand });
34021
34509
  }
34022
34510
  });
34511
+ withJsonOption(
34512
+ fleets.command("reactivate <fleet-id>").description(
34513
+ "Explicitly recreate a fleet after a credit-triggered suspension."
34514
+ ).addHelpText(
34515
+ "after",
34516
+ `
34517
+ Notes:
34518
+ TAMRadar cannot reactivate a deleted radar. This command starts normal,
34519
+ fenced provider creates from the fleet's retained desired definitions and
34520
+ may restart lifecycle billing. A credit top-up alone never does this.
34521
+
34522
+ Example:
34523
+ deepline monitors fleets reactivate account-job-openings --yes --wait --json
34524
+ `
34525
+ ).option("--wait", "Poll until the fleet reports converged").option(
34526
+ "--timeout <duration>",
34527
+ "How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
34528
+ ).option("--yes", "Confirm recreating suspended provider monitors").option("--idempotency-key <key>", "Stable retry key")
34529
+ ).action(async (fleetId, options) => {
34530
+ let retryCommand = fleetReactivateCommandLine(fleetId, options);
34531
+ try {
34532
+ const idempotencyKey = fleetIdempotencyKey(
34533
+ "reactivate",
34534
+ options.idempotencyKey
34535
+ );
34536
+ retryCommand = fleetReactivateCommandLine(fleetId, {
34537
+ ...options,
34538
+ idempotencyKey
34539
+ });
34540
+ await handleMonitorFleetsReactivate(fleetId, options, idempotencyKey);
34541
+ } catch (error) {
34542
+ reportMonitorsFailure(error, { retryCommand });
34543
+ }
34544
+ });
34023
34545
  const deployed = withJsonOption(
34024
34546
  monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
34025
34547
  "--status <status>",
@@ -34027,7 +34549,10 @@ Examples:
34027
34549
  ).option("--limit <n>", "Limit the number of deployed monitors returned").option(
34028
34550
  "--cursor <cursor>",
34029
34551
  "Page past a truncated result using the next_cursor from a prior list response"
34030
- ).option("--compact", COMPACT_OPTION_DESCRIPTION).option(
34552
+ ).option(
34553
+ "--compact",
34554
+ "Deprecated no-op; complete records are always returned"
34555
+ ).option(
34031
34556
  "--include-consumers",
34032
34557
  "Include current SQL-listener consumer health (requires --limit 20 or fewer)"
34033
34558
  )
@@ -34355,11 +34880,13 @@ async function handleOrgStatus(options) {
34355
34880
  host_env_path: hostPath,
34356
34881
  folder_target: folderTargetPayload,
34357
34882
  project_pin: provenance.scope === "global" && provenance.project.state === "project" ? {
34358
- required: true,
34883
+ available: true,
34884
+ required: false,
34359
34885
  path: provenance.project.pinPath,
34360
- cloud_mutations_blocked: true,
34886
+ cloud_mutations_blocked: false,
34361
34887
  command: "deepline org set --auth-scope folder"
34362
34888
  } : {
34889
+ available: false,
34363
34890
  required: false,
34364
34891
  cloud_mutations_blocked: false
34365
34892
  },
@@ -34780,8 +35307,8 @@ Examples:
34780
35307
  Notes:
34781
35308
  Selection can be a list number, exact organization name, or organization id.
34782
35309
  Without a selection, prints choices. With --auth-scope folder while this
34783
- project is using global host auth, it pins the current target directly; this
34784
- is the fastest safe repair for a blocked cloud mutation.
35310
+ project is using global host auth, it pins the current target directly
35311
+ without an additional organization lookup.
34785
35312
 
34786
35313
  Mutates local auth state and asks Deepline for an org-scoped API key. It
34787
35314
  writes only the selected scope:
@@ -34798,7 +35325,9 @@ Notes:
34798
35325
 
34799
35326
  Prefer --auth-scope folder for a repository or customer workspace. Use
34800
35327
  --auth-scope global only for deliberate host-wide interactive defaults; it
34801
- is shared by every unpinned CLI on this machine. For automation, pass
35328
+ is shared by every unpinned CLI on this machine. Global auth remains
35329
+ supported in projects; use a folder pin when you want a project-specific
35330
+ default. For automation, pass
34802
35331
  DEEPLINE_API_KEY only to that invocation and confirm with org status --json.
34803
35332
 
34804
35333
  Use --json for stable fields including effective_auth_scope,
@@ -34841,6 +35370,318 @@ Examples:
34841
35370
  );
34842
35371
  }
34843
35372
 
35373
+ // src/cli/commands/git.ts
35374
+ function renderProject(project) {
35375
+ const root = project.rootDirectory ? ` (${project.rootDirectory})` : "";
35376
+ const flags = [
35377
+ project.disabled ? "unlinked" : "linked",
35378
+ `deploys ${project.productionBranch}`,
35379
+ project.checkOnPullRequest ? "PR checks on" : "PR checks off"
35380
+ ].join(", ");
35381
+ return `${project.id} ${project.repoFullName}${root} - ${flags}`;
35382
+ }
35383
+ function renderDeployment(deployment) {
35384
+ const ref = deployment.ref.replace("refs/heads/", "");
35385
+ const kind = deployment.isProduction ? "production" : deployment.trigger === "pull_request" ? `pr #${deployment.pullRequestNumber ?? "?"}` : deployment.trigger;
35386
+ const suffix = deployment.error ? ` - ${deployment.error.slice(0, 80)}` : "";
35387
+ return `${deployment.id} ${deployment.commitSha.slice(0, 10)} ${ref} (${kind}) - ${deployment.status}${suffix}`;
35388
+ }
35389
+ async function handleList(options) {
35390
+ const { http } = getAuthedHttpClient();
35391
+ const payload = await http.get(
35392
+ `/api/v2/play-projects${options.all ? "?includeDisabled=1" : ""}`
35393
+ );
35394
+ printCommandEnvelope(
35395
+ {
35396
+ projects: payload.projects,
35397
+ count: payload.projects.length,
35398
+ render: {
35399
+ sections: [
35400
+ {
35401
+ title: "linked repositories",
35402
+ lines: payload.projects.length ? payload.projects.map(renderProject) : [
35403
+ "No repositories are linked. Run `deepline git repos` to see what the GitHub installation can reach, then `deepline git link`."
35404
+ ]
35405
+ }
35406
+ ]
35407
+ }
35408
+ },
35409
+ { json: options.json }
35410
+ );
35411
+ }
35412
+ async function handleRepos(options) {
35413
+ const { http } = getAuthedHttpClient();
35414
+ const query = options.installation ? `?installationId=${encodeURIComponent(options.installation)}` : "";
35415
+ const payload = await http.get(`/api/v2/github/repos${query}`);
35416
+ printCommandEnvelope(
35417
+ {
35418
+ installation: payload.installation,
35419
+ repositories: payload.repositories,
35420
+ count: payload.repositories.length,
35421
+ render: {
35422
+ sections: [
35423
+ {
35424
+ title: `repos on installation @${payload.installation.accountLogin} (${payload.installation.repositorySelection})`,
35425
+ lines: payload.repositories.map(
35426
+ (repo) => `${repo.repoId} ${repo.fullName} (default: ${repo.defaultBranch}${repo.private ? ", private" : ""}${repo.fork ? ", fork" : ""})`
35427
+ )
35428
+ }
35429
+ ]
35430
+ }
35431
+ },
35432
+ { json: options.json }
35433
+ );
35434
+ }
35435
+ async function resolveRepoId(repo, installation) {
35436
+ if (/^\d+$/.test(repo)) return Number(repo);
35437
+ const { http } = getAuthedHttpClient();
35438
+ const query = installation ? `?installationId=${encodeURIComponent(installation)}` : "";
35439
+ const payload = await http.get(
35440
+ `/api/v2/github/repos${query}`
35441
+ );
35442
+ const match = payload.repositories.find(
35443
+ (entry) => entry.fullName.toLowerCase() === repo.toLowerCase()
35444
+ );
35445
+ if (!match) {
35446
+ throw new Error(
35447
+ `Repo "${repo}" is not accessible to the workspace's GitHub installation. Run \`deepline git repos\` to list what is.`
35448
+ );
35449
+ }
35450
+ return match.repoId;
35451
+ }
35452
+ async function handleLink(repo, options) {
35453
+ const repoId = await resolveRepoId(repo, options.installation);
35454
+ const { http } = getAuthedHttpClient();
35455
+ const payload = await http.post("/api/v2/play-projects", {
35456
+ repoId,
35457
+ ...options.installation !== void 0 ? { installationId: options.installation } : {},
35458
+ ...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
35459
+ ...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
35460
+ ...options.branch !== void 0 ? { productionBranch: options.branch } : {},
35461
+ ...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {}
35462
+ });
35463
+ printCommandEnvelope(
35464
+ {
35465
+ project: payload.project,
35466
+ render: {
35467
+ sections: [
35468
+ {
35469
+ title: "linked",
35470
+ lines: [
35471
+ renderProject(payload.project),
35472
+ ...(payload.warnings ?? []).map(
35473
+ (warning) => `WARNING: ${warning}`
35474
+ ),
35475
+ "Pushes to the production branch now register and promote changed plays.",
35476
+ "Anyone who can push to this repo can change what runs in this workspace."
35477
+ ]
35478
+ }
35479
+ ]
35480
+ }
35481
+ },
35482
+ { json: options.json }
35483
+ );
35484
+ }
35485
+ async function handleGet(id, options) {
35486
+ const { http } = getAuthedHttpClient();
35487
+ const payload = await http.get(
35488
+ `/api/v2/play-projects/${encodeURIComponent(id)}`
35489
+ );
35490
+ printCommandEnvelope(
35491
+ {
35492
+ project: payload.project,
35493
+ render: {
35494
+ sections: [
35495
+ {
35496
+ title: "linked repository",
35497
+ lines: [renderProject(payload.project)]
35498
+ }
35499
+ ]
35500
+ }
35501
+ },
35502
+ { json: options.json }
35503
+ );
35504
+ }
35505
+ async function handleSet(id, options) {
35506
+ const { http } = getAuthedHttpClient();
35507
+ const payload = await http.patch(
35508
+ `/api/v2/play-projects/${encodeURIComponent(id)}`,
35509
+ {
35510
+ ...options.branch !== void 0 ? { productionBranch: options.branch } : {},
35511
+ ...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
35512
+ ...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
35513
+ ...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {},
35514
+ ...options.disabled !== void 0 ? { disabled: options.disabled } : {}
35515
+ }
35516
+ );
35517
+ printCommandEnvelope(
35518
+ {
35519
+ project: payload.project,
35520
+ render: {
35521
+ sections: [
35522
+ { title: "updated", lines: [renderProject(payload.project)] }
35523
+ ]
35524
+ }
35525
+ },
35526
+ { json: options.json }
35527
+ );
35528
+ }
35529
+ async function handleUnlink(id, options) {
35530
+ const { http } = getAuthedHttpClient();
35531
+ await http.delete(`/api/v2/play-projects/${encodeURIComponent(id)}`);
35532
+ printCommandEnvelope(
35533
+ {
35534
+ ok: true,
35535
+ id,
35536
+ render: {
35537
+ sections: [
35538
+ {
35539
+ title: "unlinked",
35540
+ lines: [
35541
+ `Repository link ${id} removed. Deployments stop immediately and in-flight deploy credentials die; live plays keep running.`
35542
+ ]
35543
+ }
35544
+ ]
35545
+ }
35546
+ },
35547
+ { json: options.json }
35548
+ );
35549
+ }
35550
+ async function handleConnect(options) {
35551
+ const baseUrl = resolveBaseUrlOnly();
35552
+ const connectUrl = `${baseUrl.replace(/\/$/, "")}/api/v2/github/connect`;
35553
+ const opened = openInBrowser(connectUrl);
35554
+ printCommandEnvelope(
35555
+ {
35556
+ connectUrl,
35557
+ browser: opened,
35558
+ render: {
35559
+ sections: [
35560
+ {
35561
+ title: "connect GitHub",
35562
+ lines: [
35563
+ opened === "opened" ? `Opened ${connectUrl} in your browser.` : `Open ${connectUrl} in your browser.`,
35564
+ "Sign in as a workspace admin if prompted, approve the GitHub",
35565
+ "installation, then return here and run `deepline git repos`."
35566
+ ]
35567
+ }
35568
+ ]
35569
+ }
35570
+ },
35571
+ { json: options.json }
35572
+ );
35573
+ }
35574
+ async function handleDeploymentsList(options) {
35575
+ const { http } = getAuthedHttpClient();
35576
+ const query = new URLSearchParams();
35577
+ if (options.repo) query.set("projectId", options.repo);
35578
+ if (options.limit) query.set("limit", options.limit);
35579
+ const suffix = query.size > 0 ? `?${query.toString()}` : "";
35580
+ const payload = await http.get(
35581
+ `/api/v2/deployments${suffix}`
35582
+ );
35583
+ printCommandEnvelope(
35584
+ {
35585
+ deployments: payload.deployments,
35586
+ count: payload.deployments.length,
35587
+ render: {
35588
+ sections: [
35589
+ {
35590
+ title: "deployments",
35591
+ lines: payload.deployments.length ? payload.deployments.map(renderDeployment) : [
35592
+ "No deployments yet. Push to a linked repository to create one."
35593
+ ]
35594
+ }
35595
+ ]
35596
+ }
35597
+ },
35598
+ { json: options.json }
35599
+ );
35600
+ }
35601
+ async function handleDeploymentGet(id, options) {
35602
+ const { http } = getAuthedHttpClient();
35603
+ const payload = await http.get(`/api/v2/deployments/${encodeURIComponent(id)}`);
35604
+ const results = payload.deployment.results;
35605
+ const playLines = Array.isArray(results?.plays) ? results.plays.map(
35606
+ (play) => `${play.name ?? "?"} - ${play.status ?? "?"}${play.error ? `: ${play.error}` : ""}`
35607
+ ) : [];
35608
+ printCommandEnvelope(
35609
+ {
35610
+ deployment: payload.deployment,
35611
+ project: payload.project,
35612
+ render: {
35613
+ sections: [
35614
+ {
35615
+ title: `deployment ${payload.deployment.id}${payload.project ? ` (${payload.project.repoFullName})` : ""}`,
35616
+ lines: [renderDeployment(payload.deployment)]
35617
+ },
35618
+ ...playLines.length ? [{ title: "plays", lines: playLines }] : []
35619
+ ]
35620
+ }
35621
+ },
35622
+ { json: options.json }
35623
+ );
35624
+ }
35625
+ function registerGitCommands(program) {
35626
+ const git = program.command("git").alias("projects").description(
35627
+ "Git deploys: link repositories to this workspace and deploy plays on push."
35628
+ ).addHelpText(
35629
+ "after",
35630
+ `
35631
+ Examples:
35632
+ deepline git connect
35633
+ deepline git repos
35634
+ deepline git link acme/growth --branch main
35635
+ deepline git list
35636
+ deepline git set <id> --branch release
35637
+ deepline git unlink <id>
35638
+ deepline git deployments --repo <id>
35639
+ `
35640
+ );
35641
+ git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
35642
+ git.command("repos").description("List repos the workspace's GitHub installation can reach.").option(
35643
+ "--installation <id>",
35644
+ "GitHub installation id (required when several are connected)"
35645
+ ).option("--json", "Emit JSON output").action(
35646
+ async (options) => handleRepos(options)
35647
+ );
35648
+ git.command("list").description("List linked repositories.").option("--all", "Include unlinked repositories").option("--json", "Emit JSON output").action(
35649
+ async (options) => handleList(options)
35650
+ );
35651
+ git.command("link").description("Link a repository to this workspace for deploy-on-push.").argument("<repo>", "Repo full name (owner/name) or numeric repo id").option("--root-dir <path>", "Base path inside the repo for this link").option("--branch <name>", "Production branch (default: repo default)").option(
35652
+ "--manifest <file>",
35653
+ "Manifest file name under the base path (default: deepline.json)"
35654
+ ).option(
35655
+ "--installation <id>",
35656
+ "GitHub installation id (required when several are connected)"
35657
+ ).option("--no-pr-checks", "Skip Check Runs on pull requests").option("--json", "Emit JSON output").action(
35658
+ async (repo, options) => handleLink(repo, options)
35659
+ );
35660
+ git.command("get").description("Show one linked repository.").argument("<id>", "Repository link id").option("--json", "Emit JSON output").action(async (id, options) => handleGet(id, options));
35661
+ git.command("set").description("Update a linked repository.").argument("<id>", "Repository link id").option("--branch <name>", "Production branch").option("--root-dir <path>", "Base path inside the repo for this link").option(
35662
+ "--manifest <file>",
35663
+ "Manifest file name under the base path (default: deepline.json)"
35664
+ ).option("--pr-checks", "Enable Check Runs on pull requests").option("--no-pr-checks", "Disable Check Runs on pull requests").option("--disabled", "Pause deployments for this link").option("--enabled", "Resume deployments for this link").option("--json", "Emit JSON output").action(
35665
+ async (id, options) => handleSet(id, {
35666
+ ...options,
35667
+ disabled: options.enabled === true ? false : options.disabled === true ? true : void 0
35668
+ })
35669
+ );
35670
+ git.command("unlink").description("Unlink a repository (live plays keep running).").argument("<id>", "Repository link id").option("--json", "Emit JSON output").action(
35671
+ async (id, options) => handleUnlink(id, options)
35672
+ );
35673
+ git.command("deployments").description("Deployment history; pass an id for one deployment.").argument("[id]", "Deployment id (omit to list)").option("--repo <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
35674
+ async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
35675
+ );
35676
+ const deployments = program.command("deployments", { hidden: true });
35677
+ deployments.command("list").option("--project <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
35678
+ async (options) => handleDeploymentsList({ ...options, repo: options.project })
35679
+ );
35680
+ deployments.command("get").argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
35681
+ async (id, options) => handleDeploymentGet(id, options)
35682
+ );
35683
+ }
35684
+
34844
35685
  // src/cli/getting-started.ts
34845
35686
  var DEEPLINE_GTM_SKILL = "/deepline-gtm";
34846
35687
  var DEEPLINE_GTM_STARTER_PROMPTS = [
@@ -35081,7 +35922,7 @@ function preventShellHistoryLeak(forbidden) {
35081
35922
  );
35082
35923
  }
35083
35924
  }
35084
- async function handleList(options) {
35925
+ async function handleList2(options) {
35085
35926
  const client2 = new DeeplineClient();
35086
35927
  const secrets = await client2.listSecrets();
35087
35928
  printCommandEnvelope(
@@ -35124,7 +35965,7 @@ async function handleCheck(nameInput, options) {
35124
35965
  );
35125
35966
  if (!secret) process.exitCode = 4;
35126
35967
  }
35127
- async function handleSet(nameInput, forbidden, options) {
35968
+ async function handleSet2(nameInput, forbidden, options) {
35128
35969
  preventShellHistoryLeak(forbidden);
35129
35970
  const name = normalizeSecretName(nameInput);
35130
35971
  const scope = options.scope === "play" ? "play" : "org";
@@ -35183,14 +36024,14 @@ Examples:
35183
36024
  `
35184
36025
  );
35185
36026
  secrets.command("list").description("List secret metadata only.").option("--json", "Emit JSON output").action(async (options) => {
35186
- await handleList(options);
36027
+ await handleList2(options);
35187
36028
  });
35188
36029
  secrets.command("check").description("Check whether a secret exists and is active.").argument("<name>", "Secret name").option("--json", "Emit JSON output").action(async (name, options) => {
35189
36030
  await handleCheck(name, options);
35190
36031
  });
35191
36032
  secrets.command("set").description("Set or rotate a secret without exposing its value in argv.").argument("<name>", "Secret name").argument("[forbidden...]", "Do not pass secret values here").option("--json", "Emit JSON output").option("--scope <scope>", "Secret scope: org or play", "org").option("--play <name>", "Play name for play-scoped secrets").option("--value-stdin", "Read the value from piped stdin").option("--from-env <name>", "Read the value from an environment variable").option("--from-file <path>", "Read the value from a file").action(
35192
36033
  async (name, forbidden, options) => {
35193
- await handleSet(name, forbidden ?? [], options);
36034
+ await handleSet2(name, forbidden ?? [], options);
35194
36035
  }
35195
36036
  );
35196
36037
  }
@@ -36840,7 +37681,7 @@ function failSetupPhase(phases, phase, code) {
36840
37681
  }
36841
37682
  function rollbackCommand(scope, root) {
36842
37683
  const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify(join17(root, ".deepline", "runtime"))}` : "";
36843
- return `npm install -g${prefix} --no-audit --no-fund --include=optional --allow-scripts=esbuild deepline@${SDK_VERSION}`;
37684
+ return `npm install -g${prefix} --no-audit --no-fund --include=optional deepline@${SDK_VERSION}`;
36844
37685
  }
36845
37686
  function setupResumeCommand(baseUrl, scope) {
36846
37687
  const hostPrefix = baseUrl === "https://code.deepline.com" ? "" : `DEEPLINE_HOST_URL=${JSON.stringify(baseUrl)} `;
@@ -37409,9 +38250,7 @@ async function runSetupCommand(options) {
37409
38250
  title: "setup",
37410
38251
  lines: [
37411
38252
  workspaceName ? `Deepline is installed and connected to ${workspaceName}.` : "Deepline is installed and connected.",
37412
- ...workspaceName ? [
37413
- "To link a different workspace, run: deepline auth register"
37414
- ] : [],
38253
+ ...workspaceName ? ["To link a different workspace, run: deepline auth register"] : [],
37415
38254
  `Use ${DEEPLINE_GTM_SKILL} in your agent.`,
37416
38255
  ...DEEPLINE_GTM_STARTER_PROMPTS.map(
37417
38256
  (example, index) => `${index + 1}. ${example.title}: ${example.prompt}`
@@ -37778,12 +38617,6 @@ var NPM_SDK_INSTALL_COMMON_FLAGS = [
37778
38617
  "--no-fund",
37779
38618
  "--include=optional"
37780
38619
  ];
37781
- var NPM_SDK_GLOBAL_INSTALL_FLAGS = [
37782
- "--no-audit",
37783
- "--no-fund",
37784
- "--include=optional",
37785
- "--allow-scripts=esbuild"
37786
- ];
37787
38620
  var NPM_SDK_SIDECAR_PACKAGE_JSON = `${JSON.stringify(
37788
38621
  {
37789
38622
  private: true,
@@ -38018,9 +38851,9 @@ function resolveUpdatePlan(options = {}) {
38018
38851
  "-g",
38019
38852
  "--prefix",
38020
38853
  installPrefix,
38021
- ...NPM_SDK_GLOBAL_INSTALL_FLAGS,
38854
+ ...NPM_SDK_INSTALL_COMMON_FLAGS,
38022
38855
  packageSpec
38023
- ] : ["install", "-g", ...NPM_SDK_GLOBAL_INSTALL_FLAGS, packageSpec];
38856
+ ] : ["install", "-g", ...NPM_SDK_INSTALL_COMMON_FLAGS, packageSpec];
38024
38857
  const fallbackRegistryUrl = options.npmFallbackRegistryUrl !== void 0 ? options.npmFallbackRegistryUrl : publicNpmFallbackRegistryUrl(
38025
38858
  env.DEEPLINE_HOST_URL?.trim() || autoDetectBaseUrl()
38026
38859
  );
@@ -39772,6 +40605,17 @@ function numberValue(value) {
39772
40605
  return typeof value === "number" && Number.isFinite(value) ? value : null;
39773
40606
  }
39774
40607
 
40608
+ // src/cli/tool-connection-status.ts
40609
+ function toolConnectionStatusMessage(input2) {
40610
+ if (input2.credentialStatus === "requires_connection") {
40611
+ return "requires your credentials \u2014 not connected (connect to use)";
40612
+ }
40613
+ if (input2.connected === false && input2.credentialStatus === "managed") {
40614
+ return "temporarily unavailable";
40615
+ }
40616
+ return null;
40617
+ }
40618
+
39775
40619
  // src/cli/commands/tools.ts
39776
40620
  var TOOL_COMMAND_TEMPLATES = {
39777
40621
  describe: "deepline tools describe <toolId>",
@@ -39896,10 +40740,11 @@ function notConnectedSuffix(tool) {
39896
40740
  const record2 = tool;
39897
40741
  const status = stringField2(record2, "credentialStatus", "credential_status");
39898
40742
  const connected = record2.connected;
39899
- if (status === "requires_connection" || connected === false) {
39900
- return " - \u26A0 requires your credentials \u2014 not connected (connect to use)";
39901
- }
39902
- return "";
40743
+ const message = toolConnectionStatusMessage({
40744
+ connected: connected === false ? false : void 0,
40745
+ credentialStatus: status || void 0
40746
+ });
40747
+ return message ? ` - \u26A0 ${message}` : "";
39903
40748
  }
39904
40749
  function shortPricingHint(tool) {
39905
40750
  const pricing = recordField2(
@@ -42449,14 +43294,14 @@ async function handleTransform(id, options) {
42449
43294
  );
42450
43295
  return outcomes.every((o) => o.ok) ? 0 : 1;
42451
43296
  }
42452
- async function handleList2(options) {
43297
+ async function handleList3(options) {
42453
43298
  const limit = options.limit ? Number(options.limit) : void 0;
42454
43299
  const result = await client().listWorkflows({
42455
43300
  limit: Number.isFinite(limit) ? limit : void 0
42456
43301
  });
42457
43302
  emitPassThrough("list", result, options);
42458
43303
  }
42459
- async function handleGet(id, options) {
43304
+ async function handleGet2(id, options) {
42460
43305
  emitPassThrough("get", await client().getWorkflow(id), options);
42461
43306
  }
42462
43307
  async function handleDelete(id, options) {
@@ -42575,12 +43420,12 @@ Notes:
42575
43420
  });
42576
43421
  withJsonOption2(
42577
43422
  workflows.command("list").description("List workspace workflows.").option("--limit <n>", "Max workflows to return")
42578
- ).action(handleList2);
43423
+ ).action(handleList3);
42579
43424
  withJsonOption2(
42580
43425
  workflows.command("get <id>").description(
42581
43426
  "Fetch a workflow, including its published-revision config."
42582
43427
  )
42583
- ).action(handleGet);
43428
+ ).action(handleGet2);
42584
43429
  withJsonOption2(
42585
43430
  workflows.command("disable <id>").description("Turn a workflow off.")
42586
43431
  ).action(handleDisable);
@@ -42633,6 +43478,7 @@ function registerDeeplineCommandGroups(program) {
42633
43478
  registerBillingCommands(program);
42634
43479
  registerMonitorsCommands(program);
42635
43480
  registerOrgCommands(program);
43481
+ registerGitCommands(program);
42636
43482
  registerEnrichCommand(program);
42637
43483
  registerCsvCommands(program);
42638
43484
  registerDbCommands(program);
@@ -42846,97 +43692,6 @@ What changed in ${response.update_summary.version}: ${response.update_summary.su
42846
43692
 
42847
43693
  // src/cli/index.ts
42848
43694
  var PREFLIGHT_TIMEOUT_MS = 3e3;
42849
- var ProjectOrgPinRequiredError = class extends Error {
42850
- code = "PROJECT_ORG_NOT_PINNED";
42851
- exitCode = 3;
42852
- payload;
42853
- constructor(input2) {
42854
- super("Cloud work is blocked because this project uses global host auth.");
42855
- this.name = "ProjectOrgPinRequiredError";
42856
- this.payload = {
42857
- ok: false,
42858
- exitCode: this.exitCode,
42859
- code: this.code,
42860
- message: this.message,
42861
- command: input2.command,
42862
- auth: { scope: "global", source: "host", projectPinned: false },
42863
- project: { dir: input2.projectDir, pinPath: input2.pinPath },
42864
- next: "deepline org set --auth-scope folder"
42865
- };
42866
- }
42867
- };
42868
- function commandUsesOnlyReadOrLocalOperations(command) {
42869
- const [group, action] = command.split(" ");
42870
- if ([
42871
- "auth",
42872
- "org",
42873
- "health",
42874
- "preflight",
42875
- "version",
42876
- "update",
42877
- "skills",
42878
- "doctor",
42879
- "quickstart"
42880
- ].includes(group ?? "")) {
42881
- return true;
42882
- }
42883
- if (group === "plays") {
42884
- return [
42885
- "check",
42886
- "get",
42887
- "list",
42888
- "search",
42889
- "grep",
42890
- "describe",
42891
- "versions"
42892
- ].includes(action ?? "");
42893
- }
42894
- if (group === "runs") {
42895
- return ["get", "list", "tail", "logs", "export"].includes(action ?? "");
42896
- }
42897
- if (group === "tools") {
42898
- return ["list", "search", "get", "describe"].includes(action ?? "");
42899
- }
42900
- if (group === "providers") return ["list", "get"].includes(action ?? "");
42901
- if (group === "secrets") return ["list", "check"].includes(action ?? "");
42902
- if (group === "billing")
42903
- return ["balance", "usage", "history"].includes(action ?? "");
42904
- return false;
42905
- }
42906
- function assertProjectCloudWorkIsPinned(command) {
42907
- if (process.argv.includes("--dry-run") || commandUsesOnlyReadOrLocalOperations(command)) {
42908
- return;
42909
- }
42910
- const config = resolveConfig();
42911
- const provenance = resolveCliAuthProvenance(config);
42912
- if (provenance.scope !== "global" || provenance.project.state !== "project") {
42913
- return;
42914
- }
42915
- throw new ProjectOrgPinRequiredError({
42916
- command,
42917
- projectDir: provenance.project.dir,
42918
- pinPath: provenance.project.pinPath
42919
- });
42920
- }
42921
- function printProjectOrgPinRequiredError(error) {
42922
- if (shouldEmitJson(process.argv.includes("--json"))) {
42923
- printJson(error.payload);
42924
- return;
42925
- }
42926
- const project = error.payload.project;
42927
- process.stderr.write(
42928
- [
42929
- "\u2717 Cloud work is blocked in this project",
42930
- "",
42931
- " Auth: global host default",
42932
- " This project is not pinned. Global auth is shared by every unpinned CLI on this machine.",
42933
- "",
42934
- " Pin this folder to the current target:",
42935
- " deepline org set --auth-scope folder",
42936
- ` This writes: ${project.pinPath}`
42937
- ].join("\n") + "\n"
42938
- );
42939
- }
42940
43695
  function asCommanderError(error) {
42941
43696
  if (!(error instanceof Error) || !("code" in error)) {
42942
43697
  return null;
@@ -43247,7 +44002,6 @@ Exit codes:
43247
44002
  return;
43248
44003
  }
43249
44004
  const compatibilityCommand = compatibilityCommandPath(actionCommand) || actionCommand.name();
43250
- assertProjectCloudWorkIsPinned(compatibilityCommand);
43251
44005
  if (printStartupPhase) {
43252
44006
  progress?.phase("checking sdk compatibility");
43253
44007
  }
@@ -43424,10 +44178,7 @@ Examples:
43424
44178
  });
43425
44179
  progress?.fail();
43426
44180
  const wantsJson = process.argv.includes("--json");
43427
- if (error instanceof ProjectOrgPinRequiredError) {
43428
- printProjectOrgPinRequiredError(error);
43429
- process.exitCode = error.exitCode;
43430
- } else if (commanderError) {
44181
+ if (commanderError) {
43431
44182
  if (commanderError.code === "commander.unknownCommand") {
43432
44183
  }
43433
44184
  process.exitCode = commanderError.code === "commander.unknownCommand" && !wantsJson ? 2 : commanderError.exitCode ?? 1;