deepline 0.3.97 → 0.3.99

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 (36) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +152 -5
  2. package/dist/bundling-sources/sdk/src/index.ts +17 -4
  3. package/dist/bundling-sources/sdk/src/monitor-fleets.ts +1 -0
  4. package/dist/bundling-sources/sdk/src/monitor-input-contract.ts +1 -0
  5. package/dist/bundling-sources/sdk/src/monitors.ts +8 -25
  6. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  7. package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +1 -0
  8. package/dist/bundling-sources/shared_libs/integration-contracts/monitor-fleet-contract.ts +218 -16
  9. package/dist/bundling-sources/shared_libs/integration-contracts/monitor-input-contract.ts +455 -0
  10. package/dist/bundling-sources/shared_libs/monitors/fleets/plan.ts +6 -1
  11. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +2 -1
  12. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -0
  13. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +1 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +19 -3
  15. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +5 -1
  16. package/dist/cli/index.js +1030 -295
  17. package/dist/cli/index.mjs +1038 -303
  18. package/dist/index.d.mts +48 -25
  19. package/dist/index.d.ts +48 -25
  20. package/dist/index.js +606 -42
  21. package/dist/index.mjs +602 -42
  22. package/dist/install-integrity.json +6 -0
  23. package/dist/monitor-fleet-contract.d.mts +44 -8
  24. package/dist/monitor-fleet-contract.d.ts +44 -8
  25. package/dist/monitor-fleet-contract.js +354 -27
  26. package/dist/monitor-fleet-contract.mjs +343 -27
  27. package/dist/monitor-input-contract.d.mts +33 -0
  28. package/dist/monitor-input-contract.d.ts +33 -0
  29. package/dist/monitor-input-contract.js +392 -0
  30. package/dist/monitor-input-contract.mjs +353 -0
  31. package/dist/plays/bundle-play-file.mjs +1 -1
  32. package/dist/release.d.mts +1 -1
  33. package/dist/release.d.ts +1 -1
  34. package/dist/release.js +1 -1
  35. package/dist/release.mjs +1 -1
  36. package/package.json +7 -1
@@ -1271,7 +1271,7 @@ var SDK_RELEASE = {
1271
1271
  // getters keep their established compatibility behavior.
1272
1272
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1273
1273
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1274
- version: "0.3.97",
1274
+ version: "0.3.99",
1275
1275
  updateSummary: "Play grep now returns concise results with the matched fields and terms. 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.",
1276
1276
  packageCapabilities: {
1277
1277
  updatePreferences: 1
@@ -3343,9 +3343,9 @@ function nonEmptyString(value) {
3343
3343
  }
3344
3344
  function normalizeDatasetBornFrom(value) {
3345
3345
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
3346
- const record2 = value;
3347
- const table = nonEmptyString(record2.table);
3348
- const rowCountIn = finiteNonNegativeInteger2(record2.rowCountIn);
3346
+ const record3 = value;
3347
+ const table = nonEmptyString(record3.table);
3348
+ const rowCountIn = finiteNonNegativeInteger2(record3.rowCountIn);
3349
3349
  if (!table || rowCountIn === null) return null;
3350
3350
  return { table, rowCountIn };
3351
3351
  }
@@ -4534,21 +4534,21 @@ function normalizePlayRuntimeNamespace(value) {
4534
4534
  }
4535
4535
  function normalizePlayRuntimeSelection(value) {
4536
4536
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
4537
- const record2 = value;
4538
- if (Object.keys(record2).some(
4537
+ const record3 = value;
4538
+ if (Object.keys(record3).some(
4539
4539
  (key) => key !== "environment" && key !== "namespace" && key !== "backend"
4540
- ) || record2.environment !== "preview") {
4540
+ ) || record3.environment !== "preview") {
4541
4541
  return null;
4542
4542
  }
4543
- const namespace = normalizePlayRuntimeNamespace(record2.namespace);
4543
+ const namespace = normalizePlayRuntimeNamespace(record3.namespace);
4544
4544
  if (!namespace) return null;
4545
- if (record2.backend === void 0) {
4545
+ if (record3.backend === void 0) {
4546
4546
  return { environment: "preview", namespace };
4547
4547
  }
4548
- if (record2.backend !== PLAY_RUNTIME_BACKENDS.daytona && record2.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4548
+ if (record3.backend !== PLAY_RUNTIME_BACKENDS.daytona && record3.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4549
4549
  return null;
4550
4550
  }
4551
- return { environment: "preview", namespace, backend: record2.backend };
4551
+ return { environment: "preview", namespace, backend: record3.backend };
4552
4552
  }
4553
4553
  function normalizePlayRuntimeEnvironment(value) {
4554
4554
  return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
@@ -5193,10 +5193,18 @@ var DeeplineClient = class {
5193
5193
  repair: (options2) => this.repairMonitors(options2),
5194
5194
  health: (options2) => this.readMonitorsHealth(options2),
5195
5195
  batch: {
5196
+ deploy: (definitions, options2) => this.deployMonitorBatch(definitions, options2),
5196
5197
  submit: (options2) => this.submitMonitorBatch(options2),
5197
5198
  get: (operationId, options2) => this.getMonitorBatch(operationId, options2)
5198
5199
  },
5200
+ jobs: {
5201
+ get: (jobId) => this.getMonitorJob(jobId),
5202
+ logs: (jobId, options2) => this.getMonitorJobLogs(jobId, options2),
5203
+ cancel: (jobId) => this.cancelMonitorJob(jobId),
5204
+ wait: (jobId, options2) => this.waitForMonitorJob(jobId, options2)
5205
+ },
5199
5206
  fleets: {
5207
+ deploy: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
5200
5208
  sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
5201
5209
  get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
5202
5210
  list: () => this.listMonitorFleets(),
@@ -7540,7 +7548,8 @@ var DeeplineClient = class {
7540
7548
  enabled: true,
7541
7549
  threshold_credits: options.thresholdCredits,
7542
7550
  refill_to_credits: options.refillToCredits,
7543
- ...options.purchaseLimitCents !== void 0 ? { purchase_limit_cents: options.purchaseLimitCents } : {}
7551
+ ...options.purchaseLimitCents !== void 0 ? { purchase_limit_cents: options.purchaseLimitCents } : {},
7552
+ ...options.purchaseLimitCredits !== void 0 ? { purchase_limit_credits: options.purchaseLimitCredits } : {}
7544
7553
  } : { enabled: false },
7545
7554
  { "Idempotency-Key": idempotencyKey }
7546
7555
  );
@@ -7948,6 +7957,68 @@ var DeeplineClient = class {
7948
7957
  );
7949
7958
  }
7950
7959
  // ——————————————————————————————————————————————————————————
7960
+ // Monitor Jobs, Batches, and Fleets
7961
+ // ——————————————————————————————————————————————————————————
7962
+ monitorJobIdempotencyKey(operation) {
7963
+ const uuid = globalThis.crypto?.randomUUID?.();
7964
+ return `monitor-job-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
7965
+ }
7966
+ monitorJobHeaders(operation, idempotencyKey) {
7967
+ return {
7968
+ "Idempotency-Key": idempotencyKey?.trim() || this.monitorJobIdempotencyKey(operation)
7969
+ };
7970
+ }
7971
+ async deployMonitorBatch(definitions, options) {
7972
+ return this.http.request(
7973
+ "/api/v2/monitors/batch/deploy",
7974
+ {
7975
+ method: "POST",
7976
+ body: { version: 1, kind: "batch", monitors: definitions },
7977
+ headers: this.monitorJobHeaders(
7978
+ "batch-deploy",
7979
+ options?.idempotencyKey
7980
+ ),
7981
+ maxRetries: 0,
7982
+ exactUrlOnly: true
7983
+ }
7984
+ );
7985
+ }
7986
+ async getMonitorJob(jobId) {
7987
+ return this.http.request(
7988
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}`,
7989
+ { method: "GET" }
7990
+ );
7991
+ }
7992
+ async getMonitorJobLogs(jobId, options) {
7993
+ const query = options?.limit === void 0 ? "" : `?limit=${encodeURIComponent(String(options.limit))}`;
7994
+ return this.http.request(
7995
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/logs${query}`,
7996
+ { method: "GET" }
7997
+ );
7998
+ }
7999
+ async cancelMonitorJob(jobId) {
8000
+ return this.http.request(
8001
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/cancel`,
8002
+ { method: "POST", body: {}, maxRetries: 0, exactUrlOnly: true }
8003
+ );
8004
+ }
8005
+ async waitForMonitorJob(jobId, options) {
8006
+ const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
8007
+ const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
8008
+ const terminal = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
8009
+ const startedAt = Date.now();
8010
+ let latest = await this.getMonitorJob(jobId);
8011
+ while (true) {
8012
+ options?.onProgress?.(latest);
8013
+ const job = latest.job;
8014
+ const state = typeof job?.state === "string" ? job.state : void 0;
8015
+ if (state && terminal.has(state)) return latest;
8016
+ if (Date.now() - startedAt >= timeoutMs) return latest;
8017
+ await sleep2(pollIntervalMs);
8018
+ latest = await this.getMonitorJob(jobId);
8019
+ }
8020
+ }
8021
+ // ——————————————————————————————————————————————————————————
7951
8022
  // Monitor Fleets
7952
8023
  // ——————————————————————————————————————————————————————————
7953
8024
  monitorFleetIdempotencyKey(operation) {
@@ -8731,30 +8802,30 @@ function flattenObjectColumns(row, options = {}) {
8731
8802
  continue;
8732
8803
  }
8733
8804
  if (value && typeof value === "object" && !Array.isArray(value)) {
8734
- const record2 = value;
8805
+ const record3 = value;
8735
8806
  if (options.objectColumns === "json") {
8736
- flattened[key] = csvSafeJsonString(record2);
8807
+ flattened[key] = csvSafeJsonString(record3);
8737
8808
  continue;
8738
8809
  }
8739
- const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record2, "matched_result") || Object.prototype.hasOwnProperty.call(record2, "matchedResult");
8810
+ const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record3, "matched_result") || Object.prototype.hasOwnProperty.call(record3, "matchedResult");
8740
8811
  if (hasMatchedEnvelope) {
8741
- flattened[key] = csvSafeJsonString(record2);
8812
+ flattened[key] = csvSafeJsonString(record3);
8742
8813
  continue;
8743
8814
  }
8744
8815
  if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
8745
8816
  flattened[key] = rawValue;
8746
8817
  continue;
8747
8818
  } else {
8748
- const failureMessage = failureMessageFromRecord(record2);
8819
+ const failureMessage = failureMessageFromRecord(record3);
8749
8820
  if (failureMessage) {
8750
8821
  flattened[key] = failureMessage;
8751
8822
  continue;
8752
- } else if (Object.prototype.hasOwnProperty.call(record2, "result")) {
8753
- flattened[key] = csvSafeJsonString(record2);
8823
+ } else if (Object.prototype.hasOwnProperty.call(record3, "result")) {
8824
+ flattened[key] = csvSafeJsonString(record3);
8754
8825
  continue;
8755
8826
  }
8756
8827
  }
8757
- for (const [nestedKey, nestedValue] of Object.entries(record2)) {
8828
+ for (const [nestedKey, nestedValue] of Object.entries(record3)) {
8758
8829
  flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
8759
8830
  }
8760
8831
  continue;
@@ -9760,7 +9831,7 @@ Examples:
9760
9831
  }
9761
9832
 
9762
9833
  // src/cli/commands/billing.ts
9763
- import { Command } from "commander";
9834
+ import { Command, Option } from "commander";
9764
9835
  import { randomUUID } from "crypto";
9765
9836
  import { appendFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
9766
9837
  import { dirname as dirname6, resolve as resolve3 } from "path";
@@ -10703,8 +10774,8 @@ async function handleAutoRechargeStatus(options) {
10703
10774
  `State: ${state}`,
10704
10775
  ...payload.threshold_credits !== null ? [`Threshold: ${payload.threshold_credits} credits`] : [],
10705
10776
  ...payload.refill_to_credits !== null ? [`Refill balance to: ${payload.refill_to_credits} credits`] : [],
10706
- ...payload.purchase_limit_cents !== void 0 ? [
10707
- payload.purchase_limit_cents === null ? "Automatic purchase cap: none" : `Automatic purchase cap: $${(payload.purchase_limit_cents / 100).toFixed(2)} per rolling 30 days`
10777
+ ...payload.purchase_limit_credits != null ? [
10778
+ `Automatic credit purchase cap: ${payload.purchase_limit_credits} credits per rolling 30 days`
10708
10779
  ] : []
10709
10780
  ];
10710
10781
  printCommandEnvelope(
@@ -10720,6 +10791,18 @@ async function handleAutoRechargeSet(options) {
10720
10791
  const thresholdCredits = parseTopUpCredits(options.thresholdCredits);
10721
10792
  const refillToCredits = parseTopUpCredits(options.refillToCredits);
10722
10793
  const rollingLimitCents = options.purchaseLimitCents === void 0 ? void 0 : options.purchaseLimitCents === "none" ? null : Number(options.purchaseLimitCents);
10794
+ const rollingLimitCredits = options.purchaseLimitCredits === void 0 ? void 0 : options.purchaseLimitCredits === "none" ? null : Number(options.purchaseLimitCredits);
10795
+ if (rollingLimitCredits != null && (!Number.isSafeInteger(rollingLimitCredits) || rollingLimitCredits < 0)) {
10796
+ reportBillingFailure(
10797
+ {
10798
+ exitCode: 2,
10799
+ code: "INVALID_AUTO_RECHARGE_CONFIGURATION",
10800
+ message: "--purchase-limit-credits must be a nonnegative whole number of credits or none."
10801
+ },
10802
+ options
10803
+ );
10804
+ return;
10805
+ }
10723
10806
  if (rollingLimitCents !== void 0 && rollingLimitCents !== null && (!Number.isSafeInteger(rollingLimitCents) || rollingLimitCents <= 0)) {
10724
10807
  reportBillingFailure(
10725
10808
  {
@@ -10756,7 +10839,8 @@ async function handleAutoRechargeSet(options) {
10756
10839
  enabled: true,
10757
10840
  threshold_credits: thresholdCredits,
10758
10841
  refill_to_credits: refillToCredits,
10759
- ...rollingLimitCents !== void 0 ? { purchase_limit_cents: rollingLimitCents } : {}
10842
+ ...rollingLimitCents !== void 0 ? { purchase_limit_cents: rollingLimitCents } : {},
10843
+ ...rollingLimitCredits !== void 0 ? { purchase_limit_credits: rollingLimitCredits } : {}
10760
10844
  }
10761
10845
  }
10762
10846
  },
@@ -10769,6 +10853,7 @@ async function handleAutoRechargeSet(options) {
10769
10853
  thresholdCredits,
10770
10854
  refillToCredits,
10771
10855
  ...rollingLimitCents !== void 0 ? { purchaseLimitCents: rollingLimitCents } : {},
10856
+ ...rollingLimitCredits !== void 0 ? { purchaseLimitCredits: rollingLimitCredits } : {},
10772
10857
  idempotencyKey
10773
10858
  });
10774
10859
  printCommandEnvelope(
@@ -11156,9 +11241,14 @@ Examples:
11156
11241
  ).requiredOption(
11157
11242
  "--refill-to-credits <credits>",
11158
11243
  "Recharge the balance to this amount"
11244
+ ).addOption(
11245
+ new Option(
11246
+ "--purchase-limit-cents <cents>",
11247
+ "Deprecated: converted to credits"
11248
+ ).hideHelp()
11159
11249
  ).option(
11160
- "--purchase-limit-cents <cents>",
11161
- "Limit automatic purchases over rolling 30 days (USD cents)"
11250
+ "--purchase-limit-credits <credits>",
11251
+ "Limit automatic credit purchases over rolling 30 days (or none to remove)"
11162
11252
  ).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeSet)
11163
11253
  ).addCommand(
11164
11254
  new Command("off").description(
@@ -11429,9 +11519,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
11429
11519
  }
11430
11520
  if (ancestors.has(value)) return value;
11431
11521
  ancestors.add(value);
11432
- const record2 = value;
11522
+ const record3 = value;
11433
11523
  const normalized = Object.fromEntries(
11434
- Object.keys(record2).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record2[key], ancestors)])
11524
+ Object.keys(record3).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record3[key], ancestors)])
11435
11525
  );
11436
11526
  ancestors.delete(value);
11437
11527
  return normalized;
@@ -12628,16 +12718,16 @@ function collectErrorText(value) {
12628
12718
  if (!value || typeof value !== "object" || Array.isArray(value)) {
12629
12719
  return errorMessage(value);
12630
12720
  }
12631
- const record2 = value;
12721
+ const record3 = value;
12632
12722
  return [
12633
12723
  errorMessage(value),
12634
- typeof record2.error === "string" ? record2.error : "",
12635
- typeof record2.message === "string" ? record2.message : "",
12636
- typeof record2.detail === "string" ? record2.detail : "",
12637
- typeof record2.hint === "string" ? record2.hint : "",
12638
- typeof record2.code === "string" ? record2.code : "",
12639
- record2.response ? collectErrorText(record2.response) : "",
12640
- record2.details ? collectErrorText(record2.details) : ""
12724
+ typeof record3.error === "string" ? record3.error : "",
12725
+ typeof record3.message === "string" ? record3.message : "",
12726
+ typeof record3.detail === "string" ? record3.detail : "",
12727
+ typeof record3.hint === "string" ? record3.hint : "",
12728
+ typeof record3.code === "string" ? record3.code : "",
12729
+ record3.response ? collectErrorText(record3.response) : "",
12730
+ record3.details ? collectErrorText(record3.details) : ""
12641
12731
  ].filter(Boolean).join("\n");
12642
12732
  }
12643
12733
  function formatDbQueryError(sql, error) {
@@ -12988,7 +13078,7 @@ import {
12988
13078
  } from "fs/promises";
12989
13079
  import { homedir as homedir6, tmpdir as tmpdir4 } from "os";
12990
13080
  import { basename as basename4, dirname as dirname11, extname as extname3, join as join11, resolve as resolve12 } from "path";
12991
- import { Option } from "commander";
13081
+ import { Option as Option2 } from "commander";
12992
13082
 
12993
13083
  // src/cli/commands/play.ts
12994
13084
  import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
@@ -13689,8 +13779,8 @@ function getterNamesFromTool(tool, kind) {
13689
13779
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
13690
13780
  }
13691
13781
  function targetGettersFromTool(tool) {
13692
- const record2 = isRecord9(tool) ? tool : {};
13693
- const raw = record2.targetGetters ?? record2.target_getters;
13782
+ const record3 = isRecord9(tool) ? tool : {};
13783
+ const raw = record3.targetGetters ?? record3.target_getters;
13694
13784
  if (!isRecord9(raw)) return {};
13695
13785
  const entries = [];
13696
13786
  for (const [target, value] of Object.entries(raw)) {
@@ -17805,13 +17895,13 @@ function validateFixtureBehavior(value) {
17805
17895
  if (!value || typeof value !== "object" || Array.isArray(value)) {
17806
17896
  return { ok: false, error: "fixtureBehavior must be a JSON object." };
17807
17897
  }
17808
- const record2 = value;
17809
- const supportedKeys = record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
17898
+ const record3 = value;
17899
+ const supportedKeys = record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
17810
17900
  "version",
17811
17901
  "responseSamples",
17812
- ...record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
17902
+ ...record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
17813
17903
  ]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
17814
- const unknownKeys = Object.keys(record2).filter(
17904
+ const unknownKeys = Object.keys(record3).filter(
17815
17905
  (key) => !supportedKeys.has(key)
17816
17906
  );
17817
17907
  if (unknownKeys.length > 0) {
@@ -17820,22 +17910,22 @@ function validateFixtureBehavior(value) {
17820
17910
  error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
17821
17911
  };
17822
17912
  }
17823
- if (record2.version !== FIXTURE_BEHAVIOR_VERSION && record2.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record2.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17913
+ if (record3.version !== FIXTURE_BEHAVIOR_VERSION && record3.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record3.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17824
17914
  return {
17825
17915
  ok: false,
17826
17916
  error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
17827
17917
  };
17828
17918
  }
17829
- if (record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17830
- if (!Array.isArray(record2.responseSamples) || record2.responseSamples.length === 0 || record2.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
17919
+ if (record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17920
+ if (!Array.isArray(record3.responseSamples) || record3.responseSamples.length === 0 || record3.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
17831
17921
  return {
17832
17922
  ok: false,
17833
17923
  error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
17834
17924
  };
17835
17925
  }
17836
17926
  const samples2 = [];
17837
- for (let index = 0; index < record2.responseSamples.length; index += 1) {
17838
- const value2 = record2.responseSamples[index];
17927
+ for (let index = 0; index < record3.responseSamples.length; index += 1) {
17928
+ const value2 = record3.responseSamples[index];
17839
17929
  if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
17840
17930
  return {
17841
17931
  ok: false,
@@ -17934,14 +18024,14 @@ function validateFixtureBehavior(value) {
17934
18024
  });
17935
18025
  }
17936
18026
  let replayBundle;
17937
- if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17938
- if (!record2.replayBundle || typeof record2.replayBundle !== "object" || Array.isArray(record2.replayBundle)) {
18027
+ if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
18028
+ if (!record3.replayBundle || typeof record3.replayBundle !== "object" || Array.isArray(record3.replayBundle)) {
17939
18029
  return {
17940
18030
  ok: false,
17941
18031
  error: "fixtureBehavior.replayBundle must be an object."
17942
18032
  };
17943
18033
  }
17944
- const replay = record2.replayBundle;
18034
+ const replay = record3.replayBundle;
17945
18035
  const replayUnknownKeys = Object.keys(replay).filter(
17946
18036
  (key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
17947
18037
  );
@@ -17989,7 +18079,7 @@ function validateFixtureBehavior(value) {
17989
18079
  ...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
17990
18080
  };
17991
18081
  }
17992
- if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
18082
+ if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17993
18083
  return {
17994
18084
  ok: true,
17995
18085
  behavior: {
@@ -18007,15 +18097,15 @@ function validateFixtureBehavior(value) {
18007
18097
  }
18008
18098
  };
18009
18099
  }
18010
- if (!Array.isArray(record2.responseDelaySamplesMs) || record2.responseDelaySamplesMs.length === 0 || record2.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
18100
+ if (!Array.isArray(record3.responseDelaySamplesMs) || record3.responseDelaySamplesMs.length === 0 || record3.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
18011
18101
  return {
18012
18102
  ok: false,
18013
18103
  error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
18014
18104
  };
18015
18105
  }
18016
18106
  const samples = [];
18017
- for (let index = 0; index < record2.responseDelaySamplesMs.length; index += 1) {
18018
- const value2 = record2.responseDelaySamplesMs[index];
18107
+ for (let index = 0; index < record3.responseDelaySamplesMs.length; index += 1) {
18108
+ const value2 = record3.responseDelaySamplesMs[index];
18019
18109
  if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
18020
18110
  return {
18021
18111
  ok: false,
@@ -18794,8 +18884,8 @@ function looksLikeStagedFileRef(value) {
18794
18884
  if (!value || typeof value !== "object" || Array.isArray(value)) {
18795
18885
  return false;
18796
18886
  }
18797
- const record2 = value;
18798
- return typeof record2.contentHash === "string" || typeof record2.contentBase64 === "string" || typeof record2.logicalPath === "string" && typeof record2.bytes === "number";
18887
+ const record3 = value;
18888
+ return typeof record3.contentHash === "string" || typeof record3.contentBase64 === "string" || typeof record3.logicalPath === "string" && typeof record3.bytes === "number";
18799
18889
  }
18800
18890
  var CSV_DATA_INPUT_KEY = "csv";
18801
18891
  function collectLocalFileInputRefs(value, inputPath, key, out) {
@@ -19308,8 +19398,8 @@ function readLiveRunField(event, field) {
19308
19398
  const records = [payload, payload.progress, run, run?.progress].filter(
19309
19399
  (value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
19310
19400
  );
19311
- for (const record2 of records) {
19312
- if (record2[field] !== void 0) return record2[field];
19401
+ for (const record3 of records) {
19402
+ if (record3[field] !== void 0) return record3[field];
19313
19403
  }
19314
19404
  return void 0;
19315
19405
  }
@@ -19611,8 +19701,8 @@ function getProgressLinesFromLiveEvent(event) {
19611
19701
  if (!state || typeof state !== "object" || Array.isArray(state)) {
19612
19702
  continue;
19613
19703
  }
19614
- const record2 = state;
19615
- const progress = record2.progress && typeof record2.progress === "object" && !Array.isArray(record2.progress) ? record2.progress : null;
19704
+ const record3 = state;
19705
+ const progress = record3.progress && typeof record3.progress === "object" && !Array.isArray(record3.progress) ? record3.progress : null;
19616
19706
  if (!progress) {
19617
19707
  continue;
19618
19708
  }
@@ -19629,7 +19719,7 @@ function getProgressLinesFromLiveEvent(event) {
19629
19719
  completed: progress.completed
19630
19720
  });
19631
19721
  lines.push(
19632
- `progress ${formatProgressLabel(record2.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
19722
+ `progress ${formatProgressLabel(record3.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
19633
19723
  );
19634
19724
  }
19635
19725
  return lines;
@@ -20309,11 +20399,11 @@ function truncateErrorForDisplay(message, runId, maxChars = RUN_ERROR_DISPLAY_MA
20309
20399
  const fullErrorHint = runId ? ` (full error: deepline runs get ${runId} --full)` : " (full error: deepline runs get <runId> --full)";
20310
20400
  return `${wordBoundary}\u2026${fullErrorHint}`;
20311
20401
  }
20312
- function clampJsonPreviewText(json, maxChars) {
20313
- if (json.length <= maxChars) {
20314
- return json;
20402
+ function clampJsonPreviewText(json2, maxChars) {
20403
+ if (json2.length <= maxChars) {
20404
+ return json2;
20315
20405
  }
20316
- const slice = json.slice(0, maxChars);
20406
+ const slice = json2.slice(0, maxChars);
20317
20407
  const lastNewline = slice.lastIndexOf("\n");
20318
20408
  const head = lastNewline > 0 ? slice.slice(0, lastNewline) : slice;
20319
20409
  return `${head}
@@ -20439,12 +20529,12 @@ function defaultResultForEnvelope(value, depth = 0) {
20439
20529
  return output2;
20440
20530
  }
20441
20531
  function formatJsonPreview(value) {
20442
- const json = JSON.stringify(value, null, 2);
20443
- if (!json || json === "{}") {
20532
+ const json2 = JSON.stringify(value, null, 2);
20533
+ if (!json2 || json2 === "{}") {
20444
20534
  return [];
20445
20535
  }
20446
20536
  const MAX_CHARS = 4e3;
20447
- const truncated = clampJsonPreviewText(json, MAX_CHARS);
20537
+ const truncated = clampJsonPreviewText(json2, MAX_CHARS);
20448
20538
  return truncated.split("\n").map((line) => ` ${line}`);
20449
20539
  }
20450
20540
  function formatReturnValue(result) {
@@ -20472,17 +20562,17 @@ function collectDatasetHandleLines(value, path = "result") {
20472
20562
  return [];
20473
20563
  }
20474
20564
  if (isDatasetHandle(value)) {
20475
- const record2 = value;
20476
- const count = typeof record2.count === "number" ? record2.count : typeof record2.rowCount === "number" ? record2.rowCount : null;
20477
- const preview = Array.isArray(record2.preview) ? record2.preview : [];
20565
+ const record3 = value;
20566
+ const count = typeof record3.count === "number" ? record3.count : typeof record3.rowCount === "number" ? record3.rowCount : null;
20567
+ const preview = Array.isArray(record3.preview) ? record3.preview : [];
20478
20568
  const lines2 = [
20479
- ` dataset ${typeof record2.path === "string" ? record2.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
20569
+ ` dataset ${typeof record3.path === "string" ? record3.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
20480
20570
  ];
20481
- if (typeof record2.queryDatasetCommand === "string") {
20482
- lines2.push(` query dataset: ${record2.queryDatasetCommand}`);
20571
+ if (typeof record3.queryDatasetCommand === "string") {
20572
+ lines2.push(` query dataset: ${record3.queryDatasetCommand}`);
20483
20573
  }
20484
- if (typeof record2.slowExportAsCsvCommand === "string") {
20485
- lines2.push(` export CSV: ${record2.slowExportAsCsvCommand}`);
20574
+ if (typeof record3.slowExportAsCsvCommand === "string") {
20575
+ lines2.push(` export CSV: ${record3.slowExportAsCsvCommand}`);
20486
20576
  }
20487
20577
  return lines2;
20488
20578
  }
@@ -20879,8 +20969,8 @@ function withTerminalPlayIdentity(status, playName) {
20879
20969
  if (!playName.trim() || getPlayRunPackage(status)) {
20880
20970
  return status;
20881
20971
  }
20882
- const record2 = status;
20883
- const hasIdentity = typeof record2.playName === "string" && record2.playName.trim().length > 0 || typeof record2.name === "string" && record2.name.trim().length > 0 || Boolean(getStringField(record2.run, "playName"));
20972
+ const record3 = status;
20973
+ const hasIdentity = typeof record3.playName === "string" && record3.playName.trim().length > 0 || typeof record3.name === "string" && record3.name.trim().length > 0 || Boolean(getStringField(record3.run, "playName"));
20884
20974
  if (hasIdentity) {
20885
20975
  return status;
20886
20976
  }
@@ -20993,9 +21083,9 @@ function formatSummaryScalar(value) {
20993
21083
  }
20994
21084
  return null;
20995
21085
  }
20996
- function formatSummaryScalarParts(record2, skipKeys = /* @__PURE__ */ new Set()) {
21086
+ function formatSummaryScalarParts(record3, skipKeys = /* @__PURE__ */ new Set()) {
20997
21087
  const parts = [];
20998
- for (const [key, value] of Object.entries(record2)) {
21088
+ for (const [key, value] of Object.entries(record3)) {
20999
21089
  if (skipKeys.has(key)) {
21000
21090
  continue;
21001
21091
  }
@@ -21022,13 +21112,13 @@ function formatTopValuesPart(value) {
21022
21112
  return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
21023
21113
  }
21024
21114
  function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
21025
- const record2 = readRecord(summary);
21026
- const columnStats = readRecord(record2?.columnStats);
21027
- if (!record2 || !columnStats) {
21115
+ const record3 = readRecord(summary);
21116
+ const columnStats = readRecord(record3?.columnStats);
21117
+ if (!record3 || !columnStats) {
21028
21118
  return [];
21029
21119
  }
21030
21120
  const lines = [];
21031
- const rowCounts = readRecord(record2.rowCounts);
21121
+ const rowCounts = readRecord(record3.rowCounts);
21032
21122
  if (rowCounts) {
21033
21123
  const persisted = readNonNegativeInteger(rowCounts.persisted);
21034
21124
  const succeeded = readNonNegativeInteger(rowCounts.succeeded);
@@ -21044,7 +21134,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
21044
21134
  }
21045
21135
  }
21046
21136
  const parts = formatSummaryScalarParts(
21047
- record2,
21137
+ record3,
21048
21138
  /* @__PURE__ */ new Set(["columnStats", "rowCounts"])
21049
21139
  );
21050
21140
  if (parts.length > 0) {
@@ -21074,35 +21164,35 @@ function actionToCommand(action) {
21074
21164
  if (!action || typeof action !== "object" || Array.isArray(action)) {
21075
21165
  return null;
21076
21166
  }
21077
- const record2 = action;
21078
- if (typeof record2.command === "string" && record2.command.trim()) {
21079
- return record2.command.trim();
21167
+ const record3 = action;
21168
+ if (typeof record3.command === "string" && record3.command.trim()) {
21169
+ return record3.command.trim();
21080
21170
  }
21081
- if (record2.kind === "deepline_run_inspect" && typeof record2.runId === "string") {
21082
- return `deepline runs get ${record2.runId} --json`;
21171
+ if (record3.kind === "deepline_run_inspect" && typeof record3.runId === "string") {
21172
+ return `deepline runs get ${record3.runId} --json`;
21083
21173
  }
21084
- if (record2.kind === "deepline_run_full" && typeof record2.runId === "string") {
21085
- return `deepline runs get ${record2.runId} --full --json`;
21174
+ if (record3.kind === "deepline_run_full" && typeof record3.runId === "string") {
21175
+ return `deepline runs get ${record3.runId} --full --json`;
21086
21176
  }
21087
- if (record2.kind === "deepline_run_billing" && typeof record2.runId === "string") {
21088
- return `deepline runs get ${record2.runId} --full --json | jq '.billing'`;
21177
+ if (record3.kind === "deepline_run_billing" && typeof record3.runId === "string") {
21178
+ return `deepline runs get ${record3.runId} --full --json | jq '.billing'`;
21089
21179
  }
21090
- if (record2.kind === "deepline_run_export" && typeof record2.runId === "string" && typeof record2.datasetPath === "string") {
21091
- return `deepline runs export ${record2.runId} --dataset ${shellSingleQuote(
21092
- record2.datasetPath
21093
- )} --out ${shellSingleQuote(`${record2.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
21180
+ if (record3.kind === "deepline_run_export" && typeof record3.runId === "string" && typeof record3.datasetPath === "string") {
21181
+ return `deepline runs export ${record3.runId} --dataset ${shellSingleQuote(
21182
+ record3.datasetPath
21183
+ )} --out ${shellSingleQuote(`${record3.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
21094
21184
  }
21095
- if (record2.kind === "deepline_run_logs") {
21096
- if (typeof record2.command === "string" && record2.command.trim()) {
21097
- return record2.command;
21185
+ if (record3.kind === "deepline_run_logs") {
21186
+ if (typeof record3.command === "string" && record3.command.trim()) {
21187
+ return record3.command;
21098
21188
  }
21099
- if (typeof record2.runId === "string") {
21100
- return record2.view === "failed" ? `deepline runs get ${record2.runId} --log-failed --json` : `deepline runs logs ${record2.runId} --json`;
21189
+ if (typeof record3.runId === "string") {
21190
+ return record3.view === "failed" ? `deepline runs get ${record3.runId} --log-failed --json` : `deepline runs logs ${record3.runId} --json`;
21101
21191
  }
21102
21192
  }
21103
- if (record2.kind === "deepline_db_query" && typeof record2.sql === "string") {
21104
- const maxRows = typeof record2.maxRows === "number" && Number.isFinite(record2.maxRows) ? Math.trunc(record2.maxRows) : 20;
21105
- return `deepline db query --sql ${shellSingleQuote(record2.sql)} --max-rows ${maxRows} --json`;
21193
+ if (record3.kind === "deepline_db_query" && typeof record3.sql === "string") {
21194
+ const maxRows = typeof record3.maxRows === "number" && Number.isFinite(record3.maxRows) ? Math.trunc(record3.maxRows) : 20;
21195
+ return `deepline db query --sql ${shellSingleQuote(record3.sql)} --max-rows ${maxRows} --json`;
21106
21196
  }
21107
21197
  return null;
21108
21198
  }
@@ -21177,8 +21267,8 @@ function formatPackageDatasetActionLines(packaged) {
21177
21267
  }
21178
21268
  function formatInlinePackageValue(value) {
21179
21269
  const compacted = compactReturnValue(value);
21180
- const json = JSON.stringify(compacted);
21181
- return clampJsonPreviewText(json ?? String(compacted), 500);
21270
+ const json2 = JSON.stringify(compacted);
21271
+ return clampJsonPreviewText(json2 ?? String(compacted), 500);
21182
21272
  }
21183
21273
  function formatPackageValueOutputLines(packaged) {
21184
21274
  const outputs = packaged.outputs && typeof packaged.outputs === "object" && !Array.isArray(packaged.outputs) ? packaged.outputs : null;
@@ -21511,12 +21601,12 @@ function exportableSheetRow(row) {
21511
21601
  if (!row || typeof row !== "object" || Array.isArray(row)) {
21512
21602
  return null;
21513
21603
  }
21514
- const record2 = row;
21515
- const data = record2.data;
21604
+ const record3 = row;
21605
+ const data = record3.data;
21516
21606
  if (data && typeof data === "object" && !Array.isArray(data)) {
21517
21607
  return data;
21518
21608
  }
21519
- const fallback = { ...record2 };
21609
+ const fallback = { ...record3 };
21520
21610
  for (const key of [
21521
21611
  "key",
21522
21612
  "status",
@@ -21864,8 +21954,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
21864
21954
  "ctx.map(...) has been replaced by ctx.dataset(...)",
21865
21955
  "Dataset .step(...) has been replaced by .withColumn(...)"
21866
21956
  ];
21867
- function stringArrayField(record2, key) {
21868
- const value = record2[key];
21957
+ function stringArrayField(record3, key) {
21958
+ const value = record3[key];
21869
21959
  if (!Array.isArray(value)) return [];
21870
21960
  return value.filter((entry) => typeof entry === "string");
21871
21961
  }
@@ -22696,8 +22786,8 @@ function cronExecutionLabel(status) {
22696
22786
  return status;
22697
22787
  }
22698
22788
  function readLiveCronMetadata(play) {
22699
- const record2 = readRecord(play);
22700
- const metadata = readRecord(record2?.triggerMetadata);
22789
+ const record3 = readRecord(play);
22790
+ const metadata = readRecord(record3?.triggerMetadata);
22701
22791
  return {
22702
22792
  schedule: typeof metadata?.cronSchedule === "string" ? metadata.cronSchedule : null,
22703
22793
  timezone: typeof metadata?.cronTimezone === "string" ? metadata.cronTimezone : null,
@@ -28028,9 +28118,9 @@ async function expandCompiledConfigAtFiles(value) {
28028
28118
  if (!value || typeof value !== "object") {
28029
28119
  return value;
28030
28120
  }
28031
- const record2 = value;
28121
+ const record3 = value;
28032
28122
  const expanded = {};
28033
- for (const [key, entry] of Object.entries(record2)) {
28123
+ for (const [key, entry] of Object.entries(record3)) {
28034
28124
  expanded[key] = await expandCompiledConfigAtFiles(entry);
28035
28125
  }
28036
28126
  for (const field of ["extract_js", "run_if_js"]) {
@@ -28828,26 +28918,26 @@ function readFirstEnrichDatasetActions(value) {
28828
28918
  }
28829
28919
  return null;
28830
28920
  }
28831
- const record2 = candidate;
28832
- const actions = isRecord11(record2.actions) ? record2.actions : null;
28921
+ const record3 = candidate;
28922
+ const actions = isRecord11(record3.actions) ? record3.actions : null;
28833
28923
  const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
28834
28924
  const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
28835
28925
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
28836
28926
  if (query?.kind === "deepline_db_query") {
28837
28927
  return {
28838
- dataset: record2,
28928
+ dataset: record3,
28839
28929
  query,
28840
28930
  ...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
28841
28931
  };
28842
28932
  }
28843
- if (options.allowLegacy && record2.kind === "dataset" && typeof record2.queryDatasetCommand === "string" && record2.queryDatasetCommand.trim()) {
28933
+ if (options.allowLegacy && record3.kind === "dataset" && typeof record3.queryDatasetCommand === "string" && record3.queryDatasetCommand.trim()) {
28844
28934
  return {
28845
- dataset: record2,
28846
- queryDatasetCommand: record2.queryDatasetCommand.trim(),
28847
- ...typeof record2.slowExportAsCsvCommand === "string" && record2.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record2.slowExportAsCsvCommand.trim() } : {}
28935
+ dataset: record3,
28936
+ queryDatasetCommand: record3.queryDatasetCommand.trim(),
28937
+ ...typeof record3.slowExportAsCsvCommand === "string" && record3.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record3.slowExportAsCsvCommand.trim() } : {}
28848
28938
  };
28849
28939
  }
28850
- for (const [key, entry] of Object.entries(record2)) {
28940
+ for (const [key, entry] of Object.entries(record3)) {
28851
28941
  if (key === "preview") {
28852
28942
  continue;
28853
28943
  }
@@ -28863,8 +28953,8 @@ function readFirstEnrichDatasetActions(value) {
28863
28953
  seen.clear();
28864
28954
  return walk(value, { allowLegacy: true });
28865
28955
  }
28866
- function actionStringField(record2, key) {
28867
- const value = record2[key];
28956
+ function actionStringField(record3, key) {
28957
+ const value = record3[key];
28868
28958
  return typeof value === "string" && value.trim() ? value.trim() : null;
28869
28959
  }
28870
28960
  function parseSqlFromDbQueryCommand(command) {
@@ -29208,12 +29298,12 @@ function collectStringFields(value, key, output2, depth = 0) {
29208
29298
  }
29209
29299
  return;
29210
29300
  }
29211
- const record2 = value;
29212
- const direct = record2[key];
29301
+ const record3 = value;
29302
+ const direct = record3[key];
29213
29303
  if (typeof direct === "string" && direct.trim()) {
29214
29304
  output2.add(direct.trim());
29215
29305
  }
29216
- for (const child of Object.values(record2)) {
29306
+ for (const child of Object.values(record3)) {
29217
29307
  collectStringFields(child, key, output2, depth + 1);
29218
29308
  }
29219
29309
  }
@@ -29399,23 +29489,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
29399
29489
  if (!row || typeof row !== "object" || Array.isArray(row)) {
29400
29490
  return null;
29401
29491
  }
29402
- const record2 = row;
29403
- const data = record2.data;
29492
+ const record3 = row;
29493
+ const data = record3.data;
29404
29494
  if (data && typeof data === "object" && !Array.isArray(data)) {
29405
29495
  const exported = { ...data };
29406
29496
  applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
29407
- rowError: record2.error
29497
+ rowError: record3.error
29408
29498
  });
29409
- applyFailureCellMeta(exported, record2.cellMeta, { rowError: record2.error });
29410
- applyFailureCellMeta(exported, record2.cellMetaPatch, {
29411
- rowError: record2.error
29499
+ applyFailureCellMeta(exported, record3.cellMeta, { rowError: record3.error });
29500
+ applyFailureCellMeta(exported, record3.cellMetaPatch, {
29501
+ rowError: record3.error
29412
29502
  });
29413
- applyFailureCellMeta(exported, record2[ENRICH_CELL_META_PATCH_FIELD], {
29414
- rowError: record2.error
29503
+ applyFailureCellMeta(exported, record3[ENRICH_CELL_META_PATCH_FIELD], {
29504
+ rowError: record3.error
29415
29505
  });
29416
29506
  delete exported[ENRICH_CELL_META_FIELD];
29417
29507
  delete exported[ENRICH_CELL_META_PATCH_FIELD];
29418
- const inputIndex = typeof record2.inputIndex === "number" ? record2.inputIndex : typeof record2.inputIndex === "string" && record2.inputIndex.trim() ? Number(record2.inputIndex) : Number.NaN;
29508
+ const inputIndex = typeof record3.inputIndex === "number" ? record3.inputIndex : typeof record3.inputIndex === "string" && record3.inputIndex.trim() ? Number(record3.inputIndex) : Number.NaN;
29419
29509
  if (Number.isInteger(inputIndex) && inputIndex >= 0) {
29420
29510
  if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
29421
29511
  exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
@@ -29424,18 +29514,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
29424
29514
  }
29425
29515
  return exported;
29426
29516
  }
29427
- const fallback = { ...record2 };
29517
+ const fallback = { ...record3 };
29428
29518
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
29429
- rowError: record2.error
29519
+ rowError: record3.error
29430
29520
  });
29431
- applyFailureCellMeta(fallback, record2.cellMeta, {
29432
- rowError: record2.error
29521
+ applyFailureCellMeta(fallback, record3.cellMeta, {
29522
+ rowError: record3.error
29433
29523
  });
29434
- applyFailureCellMeta(fallback, record2.cellMetaPatch, {
29435
- rowError: record2.error
29524
+ applyFailureCellMeta(fallback, record3.cellMetaPatch, {
29525
+ rowError: record3.error
29436
29526
  });
29437
29527
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
29438
- rowError: record2.error
29528
+ rowError: record3.error
29439
29529
  });
29440
29530
  for (const key of [
29441
29531
  "key",
@@ -29654,16 +29744,16 @@ function isWaterfallResultMeaningful(value) {
29654
29744
  return value.some(isWaterfallResultMeaningful);
29655
29745
  }
29656
29746
  if (value && typeof value === "object") {
29657
- const record2 = value;
29658
- const status = typeof record2.status === "string" ? record2.status.trim().toLowerCase() : "";
29747
+ const record3 = value;
29748
+ const status = typeof record3.status === "string" ? record3.status.trim().toLowerCase() : "";
29659
29749
  if (status === "error" || status === "failed") {
29660
29750
  return false;
29661
29751
  }
29662
- if (typeof record2.error === "string" && record2.error.trim()) {
29752
+ if (typeof record3.error === "string" && record3.error.trim()) {
29663
29753
  return false;
29664
29754
  }
29665
- if (Object.prototype.hasOwnProperty.call(record2, "matched_result")) {
29666
- return isWaterfallResultMeaningful(record2.matched_result);
29755
+ if (Object.prototype.hasOwnProperty.call(record3, "matched_result")) {
29756
+ return isWaterfallResultMeaningful(record3.matched_result);
29667
29757
  }
29668
29758
  for (const key of [
29669
29759
  "value",
@@ -29678,11 +29768,11 @@ function isWaterfallResultMeaningful(value) {
29678
29768
  "result",
29679
29769
  "data"
29680
29770
  ]) {
29681
- if (isWaterfallResultMeaningful(record2[key])) {
29771
+ if (isWaterfallResultMeaningful(record3[key])) {
29682
29772
  return true;
29683
29773
  }
29684
29774
  }
29685
- return Object.entries(record2).some(
29775
+ return Object.entries(record3).some(
29686
29776
  ([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
29687
29777
  );
29688
29778
  }
@@ -29698,8 +29788,8 @@ function stableRowSnapshot(value) {
29698
29788
  return `[${value.map(stableRowSnapshot).join(",")}]`;
29699
29789
  }
29700
29790
  if (value && typeof value === "object") {
29701
- const record2 = value;
29702
- return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record2[key])}`).join(",")}}`;
29791
+ const record3 = value;
29792
+ return `{${Object.keys(record3).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record3[key])}`).join(",")}}`;
29703
29793
  }
29704
29794
  return JSON.stringify(value);
29705
29795
  }
@@ -30286,8 +30376,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
30286
30376
  seen.add(normalized);
30287
30377
  commands.push({ ...command, command: normalized });
30288
30378
  }
30289
- function datasetSelectorForEnrichCommand(record2, fallbackPath) {
30290
- const candidates = [record2.path, record2.tableNamespace, fallbackPath];
30379
+ function datasetSelectorForEnrichCommand(record3, fallbackPath) {
30380
+ const candidates = [record3.path, record3.tableNamespace, fallbackPath];
30291
30381
  for (const candidate of candidates) {
30292
30382
  if (typeof candidate === "string" && candidate.trim()) {
30293
30383
  return candidate.trim();
@@ -30349,19 +30439,19 @@ function collectDatasetFollowUpCommands(value, state) {
30349
30439
  );
30350
30440
  return;
30351
30441
  }
30352
- const record2 = value;
30353
- const isDataset = record2.kind === "dataset";
30442
+ const record3 = value;
30443
+ const isDataset = record3.kind === "dataset";
30354
30444
  if (isDataset) {
30355
- const selector = datasetSelectorForEnrichCommand(record2, state.path);
30356
- const labelPath = typeof record2.path === "string" && record2.path.trim() ? record2.path.trim() : selector ?? state.path;
30357
- if (typeof record2.queryDatasetCommand === "string") {
30445
+ const selector = datasetSelectorForEnrichCommand(record3, state.path);
30446
+ const labelPath = typeof record3.path === "string" && record3.path.trim() ? record3.path.trim() : selector ?? state.path;
30447
+ if (typeof record3.queryDatasetCommand === "string") {
30358
30448
  addEnrichFollowUpCommand(state.commands, state.seen, {
30359
30449
  label: `query ${labelPath}`,
30360
30450
  path: labelPath,
30361
- command: record2.queryDatasetCommand
30451
+ command: record3.queryDatasetCommand
30362
30452
  });
30363
30453
  }
30364
- const exportCommand = typeof record2.slowExportAsCsvCommand === "string" ? record2.slowExportAsCsvCommand : typeof record2.fullExportCommand === "string" ? record2.fullExportCommand : null;
30454
+ const exportCommand = typeof record3.slowExportAsCsvCommand === "string" ? record3.slowExportAsCsvCommand : typeof record3.fullExportCommand === "string" ? record3.fullExportCommand : null;
30365
30455
  if (exportCommand) {
30366
30456
  addEnrichFollowUpCommand(state.commands, state.seen, {
30367
30457
  label: `export ${labelPath}`,
@@ -30378,7 +30468,7 @@ function collectDatasetFollowUpCommands(value, state) {
30378
30468
  });
30379
30469
  }
30380
30470
  }
30381
- for (const [key, child] of Object.entries(record2)) {
30471
+ for (const [key, child] of Object.entries(record3)) {
30382
30472
  if (key === "preview" || key === "access") {
30383
30473
  continue;
30384
30474
  }
@@ -31236,7 +31326,7 @@ function registerEnrichCommand(program) {
31236
31326
  "--open",
31237
31327
  "Open the generated play page in a browser after the run starts."
31238
31328
  ).addOption(
31239
- new Option(
31329
+ new Option2(
31240
31330
  "--no-open [legacy-value]",
31241
31331
  "Removed legacy option"
31242
31332
  ).hideHelp()
@@ -31612,7 +31702,7 @@ function registerEnrichCommand(program) {
31612
31702
  }
31613
31703
 
31614
31704
  // src/cli/commands/feedback.ts
31615
- import { Option as Option2 } from "commander";
31705
+ import { Option as Option3 } from "commander";
31616
31706
  import { readFileSync as readFileSync9 } from "fs";
31617
31707
  async function handleFeedback(text, options) {
31618
31708
  const message = resolveFeedbackText(text, options.file);
@@ -31693,7 +31783,7 @@ Examples:
31693
31783
  deepline feedback send "plays run failed after upload" --command "deepline plays run my.play.ts --watch" --error-outcome terminal
31694
31784
  `
31695
31785
  ).argument("[text]", "Feedback text").option("--file <path>", "Read feedback text from a file, or - for stdin").option("--command <command>", "Command that reproduced the issue").option("--payload <payload>", "JSON or plain-text payload for the repro").addOption(
31696
- new Option2(
31786
+ new Option3(
31697
31787
  "--error-outcome <outcome>",
31698
31788
  "Error impact on the task: terminal or continued"
31699
31789
  ).choices(["terminal", "continued"])
@@ -31852,9 +31942,9 @@ function readCodexSessionId(filePath) {
31852
31942
  )) {
31853
31943
  const parsed = parseJsonLine(line);
31854
31944
  if (!parsed || typeof parsed !== "object") continue;
31855
- const record2 = parsed;
31856
- const payload = record2.payload && typeof record2.payload === "object" ? record2.payload : null;
31857
- const id = record2.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
31945
+ const record3 = parsed;
31946
+ const payload = record3.payload && typeof record3.payload === "object" ? record3.payload : null;
31947
+ const id = record3.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
31858
31948
  if (id && UUID_RE.test(id)) return id;
31859
31949
  }
31860
31950
  } catch {
@@ -31953,15 +32043,15 @@ function messageContentKey(value) {
31953
32043
  if (!Array.isArray(content)) return null;
31954
32044
  return content.map((block) => {
31955
32045
  if (!block || typeof block !== "object") return String(block);
31956
- const record2 = block;
31957
- const type = String(record2.type ?? "");
32046
+ const record3 = block;
32047
+ const type = String(record3.type ?? "");
31958
32048
  if (type === "tool_use") {
31959
- return `tool_use:${String(record2.name ?? "")}:${String(record2.id ?? "")}`;
32049
+ return `tool_use:${String(record3.name ?? "")}:${String(record3.id ?? "")}`;
31960
32050
  }
31961
32051
  if (type === "tool_result") {
31962
- return `tool_result:${String(record2.tool_use_id ?? "")}`;
32052
+ return `tool_result:${String(record3.tool_use_id ?? "")}`;
31963
32053
  }
31964
- return String(record2.text ?? type);
32054
+ return String(record3.text ?? type);
31965
32055
  }).join("\n");
31966
32056
  }
31967
32057
  function dedupConsecutiveEvents(raw) {
@@ -31976,9 +32066,9 @@ function dedupConsecutiveEvents(raw) {
31976
32066
  index += 1;
31977
32067
  continue;
31978
32068
  }
31979
- const record2 = event;
31980
- const eventType = String(record2.type ?? "");
31981
- const eventKey = messageContentKey(record2);
32069
+ const record3 = event;
32070
+ const eventType = String(record3.type ?? "");
32071
+ const eventKey = messageContentKey(record3);
31982
32072
  if (!["user", "assistant"].includes(eventType) || !eventKey) {
31983
32073
  output2.push(rawLines[index] ?? "");
31984
32074
  index += 1;
@@ -31997,9 +32087,9 @@ function dedupConsecutiveEvents(raw) {
31997
32087
  cursor += 1;
31998
32088
  }
31999
32089
  if (runCount > 1) {
32000
- record2._repeat_count = runCount;
32001
- record2._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
32002
- output2.push(JSON.stringify(record2));
32090
+ record3._repeat_count = runCount;
32091
+ record3._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
32092
+ output2.push(JSON.stringify(record3));
32003
32093
  index = cursor;
32004
32094
  continue;
32005
32095
  }
@@ -32044,9 +32134,9 @@ function selectiveCompactToolResults(raw) {
32044
32134
  lines.push(line);
32045
32135
  continue;
32046
32136
  }
32047
- const record2 = parsed;
32048
- if (record2.type === "user") {
32049
- const message = record2.message;
32137
+ const record3 = parsed;
32138
+ if (record3.type === "user") {
32139
+ const message = record3.message;
32050
32140
  const content = message && typeof message === "object" ? message.content : null;
32051
32141
  if (Array.isArray(content)) {
32052
32142
  message.content = content.map(
@@ -32054,7 +32144,7 @@ function selectiveCompactToolResults(raw) {
32054
32144
  );
32055
32145
  }
32056
32146
  }
32057
- lines.push(JSON.stringify(record2));
32147
+ lines.push(JSON.stringify(record3));
32058
32148
  }
32059
32149
  return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
32060
32150
  ` : "", "utf8");
@@ -32080,15 +32170,15 @@ function compactCodexEvents(raw) {
32080
32170
  lines.push(rawLines[index] ?? "");
32081
32171
  return;
32082
32172
  }
32083
- const record2 = event;
32084
- if (record2.type === "world_state") return;
32085
- const payload = record2.payload;
32173
+ const record3 = event;
32174
+ if (record3.type === "world_state") return;
32175
+ const payload = record3.payload;
32086
32176
  const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
32087
32177
  if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
32088
32178
  if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
32089
32179
  const record_payload = payload;
32090
32180
  record_payload.output = compactEventValue(record_payload.output);
32091
- lines.push(JSON.stringify(record2));
32181
+ lines.push(JSON.stringify(record3));
32092
32182
  return;
32093
32183
  }
32094
32184
  lines.push(rawLines[index] ?? "");
@@ -32294,8 +32384,8 @@ function parsePreparedEvents(buffer) {
32294
32384
  return parsed ?? line;
32295
32385
  });
32296
32386
  }
32297
- function escapeJsonForHtmlScript(json) {
32298
- return json.replace(/</g, "\\u003c");
32387
+ function escapeJsonForHtmlScript(json2) {
32388
+ return json2.replace(/</g, "\\u003c");
32299
32389
  }
32300
32390
  async function handleSessionsRender(options) {
32301
32391
  const targets = resolveSessionTargets({
@@ -32556,11 +32646,317 @@ import { readFileSync as readFileSync11, writeFileSync as writeFileSync12 } from
32556
32646
  import { resolve as resolve14 } from "path";
32557
32647
  import { createInterface } from "readline/promises";
32558
32648
 
32649
+ // ../integration-contracts/monitor-input-contract.ts
32650
+ import Handlebars from "handlebars";
32651
+ function authoredMonitorFieldPath(path, field) {
32652
+ const batch = /^monitors\.(\d+)$/.exec(path);
32653
+ return `${batch ? `monitors[${batch[1]}]` : path}.${field}`;
32654
+ }
32655
+ function record(value) {
32656
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
32657
+ }
32658
+ function json(value, path, issues) {
32659
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
32660
+ return;
32661
+ }
32662
+ if (Array.isArray(value)) {
32663
+ value.forEach((child, index) => json(child, `${path}.${index}`, issues));
32664
+ return;
32665
+ }
32666
+ const object = record(value);
32667
+ if (!object) {
32668
+ issues.push({
32669
+ severity: "error",
32670
+ code: "invalid_monitor_json_value",
32671
+ path,
32672
+ message: "Monitor values must be JSON values."
32673
+ });
32674
+ return;
32675
+ }
32676
+ for (const [key, child] of Object.entries(object)) {
32677
+ json(child, `${path}.${key}`, issues);
32678
+ }
32679
+ }
32680
+ function monitorSpec(value, path, issues) {
32681
+ const input2 = record(value);
32682
+ if (!input2) {
32683
+ issues.push({
32684
+ severity: "error",
32685
+ code: "invalid_monitor_spec",
32686
+ path,
32687
+ message: "A monitor must be a JSON object."
32688
+ });
32689
+ return null;
32690
+ }
32691
+ const allowed = /* @__PURE__ */ new Set(["key", "tool", "name", "payload"]);
32692
+ for (const key2 of Object.keys(input2)) {
32693
+ if (!allowed.has(key2)) {
32694
+ if (key2 === "controls") {
32695
+ issues.push({
32696
+ severity: "error",
32697
+ code: "CONTROLS_NOT_SUPPORTED",
32698
+ path: authoredMonitorFieldPath(path, "controls"),
32699
+ message: "Operational controls are managed by Deepline and cannot be authored in Batch or Fleet JSON.",
32700
+ suggestion: "Remove controls. Bind downstream automation in a Play with sqlListeners."
32701
+ });
32702
+ continue;
32703
+ }
32704
+ if (key2 === "play") {
32705
+ issues.push({
32706
+ severity: "error",
32707
+ code: "PLAY_BINDING_NOT_IN_MONITOR_SPEC",
32708
+ path: authoredMonitorFieldPath(path, "play"),
32709
+ message: "A monitor does not own Play bindings.",
32710
+ suggestion: "Declare sqlListeners in the Play, or run: deepline plays bootstrap monitor-triggered --out on-event.play.ts"
32711
+ });
32712
+ continue;
32713
+ }
32714
+ issues.push({
32715
+ severity: "error",
32716
+ code: "unknown_monitor_field",
32717
+ path: `${path}.${key2}`,
32718
+ message: `Monitor definitions do not accept '${key2}'.`
32719
+ });
32720
+ }
32721
+ }
32722
+ const key = typeof input2.key === "string" ? input2.key.trim() : "";
32723
+ const tool = typeof input2.tool === "string" ? input2.tool.trim() : "";
32724
+ const name = input2.name === void 0 ? void 0 : typeof input2.name === "string" && input2.name.trim() ? input2.name.trim() : null;
32725
+ const payload = record(input2.payload);
32726
+ if (!key) {
32727
+ issues.push({
32728
+ severity: "error",
32729
+ code: "invalid_monitor_key",
32730
+ path: `${path}.key`,
32731
+ message: "Monitor key must be a non-empty string."
32732
+ });
32733
+ }
32734
+ if (!tool) {
32735
+ issues.push({
32736
+ severity: "error",
32737
+ code: "invalid_monitor_tool",
32738
+ path: `${path}.tool`,
32739
+ message: "Monitor tool must be a non-empty literal string."
32740
+ });
32741
+ }
32742
+ if (name === null) {
32743
+ issues.push({
32744
+ severity: "error",
32745
+ code: "invalid_monitor_name",
32746
+ path: `${path}.name`,
32747
+ message: "Monitor name must be a non-empty string when supplied."
32748
+ });
32749
+ }
32750
+ if (!payload) {
32751
+ issues.push({
32752
+ severity: "error",
32753
+ code: "invalid_monitor_payload",
32754
+ path: `${path}.payload`,
32755
+ message: "Monitor payload must be an object."
32756
+ });
32757
+ } else {
32758
+ json(payload, `${path}.payload`, issues);
32759
+ }
32760
+ if (!key || !tool || !payload || name === null) {
32761
+ return null;
32762
+ }
32763
+ return {
32764
+ key,
32765
+ tool,
32766
+ ...name ? { name } : {},
32767
+ payload
32768
+ };
32769
+ }
32770
+ function issueOrder(left, right) {
32771
+ return left.path.localeCompare(right.path) || left.severity.localeCompare(right.severity) || left.code.localeCompare(right.code);
32772
+ }
32773
+ function lintMonitorBatchInput(value) {
32774
+ const issues = [];
32775
+ const versionlessEnvelope = !Array.isArray(value) && (() => {
32776
+ const candidate = record(value);
32777
+ return candidate !== null && Object.keys(candidate).length === 1 && Object.prototype.hasOwnProperty.call(candidate, "monitors");
32778
+ })();
32779
+ const legacy = Array.isArray(value) || versionlessEnvelope;
32780
+ const input2 = legacy ? null : record(value);
32781
+ let monitors = Array.isArray(value) ? value : versionlessEnvelope ? (() => {
32782
+ const candidate = record(value)?.monitors;
32783
+ return Array.isArray(candidate) ? candidate : null;
32784
+ })() : null;
32785
+ if (Array.isArray(value)) {
32786
+ issues.push({
32787
+ severity: "warning",
32788
+ code: "deprecated_batch_array",
32789
+ path: "",
32790
+ message: "Bare monitor arrays are supported for compatibility.",
32791
+ suggestion: 'Wrap the list in {"version":1,"kind":"batch","monitors":[...]}.'
32792
+ });
32793
+ } else if (versionlessEnvelope) {
32794
+ issues.push({
32795
+ severity: "warning",
32796
+ code: "deprecated_batch_missing_envelope_fields",
32797
+ path: "",
32798
+ message: "Versionless monitor envelopes are supported for compatibility.",
32799
+ suggestion: 'Add "version": 1 and "kind": "batch".'
32800
+ });
32801
+ if (!monitors) {
32802
+ issues.push({
32803
+ severity: "error",
32804
+ code: "invalid_batch_monitors",
32805
+ path: "monitors",
32806
+ message: "Batch monitors must be an array."
32807
+ });
32808
+ }
32809
+ } else if (!input2) {
32810
+ issues.push({
32811
+ severity: "error",
32812
+ code: "invalid_batch",
32813
+ path: "",
32814
+ message: "Batch input must be an object or a legacy array."
32815
+ });
32816
+ } else {
32817
+ for (const key of Object.keys(input2)) {
32818
+ if (!["version", "kind", "monitors"].includes(key)) {
32819
+ issues.push({
32820
+ severity: "error",
32821
+ code: key === "source" || key === "monitor" ? "batch_fleet_shape_mixup" : "unknown_batch_field",
32822
+ path: key,
32823
+ message: `Batch input does not accept '${key}'.`
32824
+ });
32825
+ }
32826
+ }
32827
+ if (input2.version !== 1) {
32828
+ issues.push({
32829
+ severity: "error",
32830
+ code: "unsupported_batch_version",
32831
+ path: "version",
32832
+ message: "Batch input version must be 1."
32833
+ });
32834
+ }
32835
+ if (input2.kind !== "batch") {
32836
+ issues.push({
32837
+ severity: "error",
32838
+ code: "invalid_batch_kind",
32839
+ path: "kind",
32840
+ message: 'Batch input kind must be "batch".'
32841
+ });
32842
+ }
32843
+ monitors = Array.isArray(input2.monitors) ? input2.monitors : null;
32844
+ if (!monitors) {
32845
+ issues.push({
32846
+ severity: "error",
32847
+ code: "invalid_batch_monitors",
32848
+ path: "monitors",
32849
+ message: "Batch monitors must be an array."
32850
+ });
32851
+ }
32852
+ }
32853
+ if (!monitors || monitors.length === 0) {
32854
+ if (monitors?.length === 0) {
32855
+ issues.push({
32856
+ severity: "error",
32857
+ code: "empty_batch",
32858
+ path: "monitors",
32859
+ message: "A Batch needs at least one monitor."
32860
+ });
32861
+ }
32862
+ return { issues: issues.sort(issueOrder) };
32863
+ }
32864
+ const normalized = monitors.map(
32865
+ (item, index) => monitorSpec(item, `monitors.${index}`, issues)
32866
+ );
32867
+ const seen = /* @__PURE__ */ new Map();
32868
+ normalized.forEach((item, index) => {
32869
+ if (!item) return;
32870
+ const first = seen.get(item.key);
32871
+ if (first !== void 0) {
32872
+ for (const position of [first, index]) {
32873
+ issues.push({
32874
+ severity: "error",
32875
+ code: "duplicate_monitor_key",
32876
+ path: `monitors.${position}.key`,
32877
+ message: `Duplicate monitor key '${item.key}'.`
32878
+ });
32879
+ }
32880
+ } else {
32881
+ seen.set(item.key, index);
32882
+ }
32883
+ });
32884
+ const ordered = issues.sort(issueOrder);
32885
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : {
32886
+ normalized: {
32887
+ version: 1,
32888
+ kind: "batch",
32889
+ monitors: normalized
32890
+ },
32891
+ issues: ordered
32892
+ };
32893
+ }
32894
+ function validateHandlebars(value, path, issues) {
32895
+ if (!value.includes("{{")) return;
32896
+ try {
32897
+ Handlebars.parse(value);
32898
+ } catch (error) {
32899
+ issues.push({
32900
+ severity: "error",
32901
+ code: "invalid_handlebars_template",
32902
+ path,
32903
+ message: error instanceof Error ? error.message : "Invalid Handlebars template."
32904
+ });
32905
+ return;
32906
+ }
32907
+ const expressions = value.match(/{{[\s\S]*?}}/g) ?? [];
32908
+ if (expressions.some(
32909
+ (expression) => !/^{{\s*[A-Za-z_][A-Za-z0-9_]*\s*}}$/.test(expression)
32910
+ )) {
32911
+ issues.push({
32912
+ severity: "error",
32913
+ code: "unsupported_handlebars_expression",
32914
+ path,
32915
+ message: "Fleet templates allow only direct source-row fields such as {{domain}}; helpers, blocks, partials, paths, and prototype access are disabled."
32916
+ });
32917
+ }
32918
+ }
32919
+ function walkTemplates(value, path, issues) {
32920
+ if (typeof value === "string") return validateHandlebars(value, path, issues);
32921
+ if (Array.isArray(value)) {
32922
+ value.forEach(
32923
+ (item, index) => walkTemplates(item, `${path}.${index}`, issues)
32924
+ );
32925
+ return;
32926
+ }
32927
+ const input2 = record(value);
32928
+ if (!input2) return;
32929
+ for (const [key, child] of Object.entries(input2)) {
32930
+ walkTemplates(child, `${path}.${key}`, issues);
32931
+ }
32932
+ }
32933
+ function lintMonitorSpecTemplate(value, path = "monitor") {
32934
+ const issues = [];
32935
+ const normalized = monitorSpec(value, path, issues);
32936
+ const input2 = record(value);
32937
+ if (input2 && typeof input2.tool === "string" && input2.tool.includes("{{")) {
32938
+ issues.push({
32939
+ severity: "error",
32940
+ code: "templated_monitor_tool",
32941
+ path: `${path}.tool`,
32942
+ message: "Fleet monitor tool must be literal; only key, name, and payload may be templated."
32943
+ });
32944
+ }
32945
+ if (input2) {
32946
+ for (const field of ["key", "name", "payload"]) {
32947
+ if (input2[field] !== void 0)
32948
+ walkTemplates(input2[field], `${path}.${field}`, issues);
32949
+ }
32950
+ }
32951
+ const ordered = issues.sort(issueOrder);
32952
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : { normalized, issues: ordered };
32953
+ }
32954
+
32559
32955
  // ../integration-contracts/monitor-fleet-contract.ts
32560
32956
  var MONITOR_FLEET_MAX_MEMBERS = 1e3;
32561
- var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
32562
32957
  var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
32563
- MONITOR_FLEET_AUTHORING_CONTRACT_EDITION
32958
+ 1,
32959
+ 2
32564
32960
  ];
32565
32961
  var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
32566
32962
  var MONITOR_FLEET_DOCUMENTATION = {
@@ -32568,11 +32964,11 @@ var MONITOR_FLEET_DOCUMENTATION = {
32568
32964
  authoredFields: {
32569
32965
  id: "Stable lowercase fleet id used by sync, get, and deactivate.",
32570
32966
  source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
32571
- member: "Ordinary monitor tool, stable key template, and payload evaluated for each selected source row.",
32967
+ monitor: "One Batch-compatible MonitorSpec. Direct Handlebars source-row fields such as {{domain}} are rendered for each selected row.",
32572
32968
  selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
32573
32969
  },
32574
32970
  fixedPolicy: {
32575
- cadence: "daily",
32971
+ cadence: "60s fair bounded source refresh",
32576
32972
  membership: "sticky",
32577
32973
  removalGrace: "7d",
32578
32974
  onRemoved: "deactivate",
@@ -32580,9 +32976,10 @@ var MONITOR_FLEET_DOCUMENTATION = {
32580
32976
  billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
32581
32977
  },
32582
32978
  stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
32583
- columnExpression: 'Use { "$fleet": "column", "name": "column_name" } in a member key or payload to read a value from each source row.'
32979
+ templating: "Use direct Handlebars fields such as {{domain}} in monitor key, name, or payload. Helpers, blocks, partials, paths, and prototype access are disabled.",
32980
+ legacyCompatibility: 'Edition 1 member/$fleet files remain readable with a lint warning; new files should use version: 2, kind: "fleet", and monitor.'
32584
32981
  };
32585
- function record(value) {
32982
+ function record2(value) {
32586
32983
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
32587
32984
  }
32588
32985
  function identifier(value) {
@@ -32607,7 +33004,7 @@ function jsonValue(value, path, issues) {
32607
33004
  value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
32608
33005
  return;
32609
33006
  }
32610
- const input2 = record(value);
33007
+ const input2 = record2(value);
32611
33008
  if (!input2) {
32612
33009
  issues.push({
32613
33010
  path,
@@ -32621,7 +33018,7 @@ function jsonValue(value, path, issues) {
32621
33018
  }
32622
33019
  }
32623
33020
  function validateExpression(value, path, issues) {
32624
- const input2 = record(value);
33021
+ const input2 = record2(value);
32625
33022
  if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
32626
33023
  issues.push({
32627
33024
  path,
@@ -32639,7 +33036,7 @@ function walkPayload(value, path, issues) {
32639
33036
  );
32640
33037
  return;
32641
33038
  }
32642
- const input2 = record(value);
33039
+ const input2 = record2(value);
32643
33040
  if (!input2) return;
32644
33041
  if ("$fleet" in input2) {
32645
33042
  validateExpression(input2, path, issues);
@@ -32649,9 +33046,9 @@ function walkPayload(value, path, issues) {
32649
33046
  walkPayload(item, `${path}.${key}`, issues);
32650
33047
  }
32651
33048
  }
32652
- function validateMonitorFleetDefinition(value) {
33049
+ function validateMonitorFleetDefinitionV1(value) {
32653
33050
  const issues = [];
32654
- const input2 = record(value);
33051
+ const input2 = record2(value);
32655
33052
  if (!input2) {
32656
33053
  return {
32657
33054
  valid: false,
@@ -32672,7 +33069,7 @@ function validateMonitorFleetDefinition(value) {
32672
33069
  message: "Fleet id must be lowercase kebab-case."
32673
33070
  });
32674
33071
  }
32675
- const source = record(input2.source);
33072
+ const source = record2(input2.source);
32676
33073
  exactKeys(
32677
33074
  source,
32678
33075
  ["kind", "schema", "table", "key", "where"],
@@ -32693,7 +33090,7 @@ function validateMonitorFleetDefinition(value) {
32693
33090
  message: "Source schema and table must be SQL identifiers."
32694
33091
  });
32695
33092
  }
32696
- const sourceKey = record(source?.key);
33093
+ const sourceKey = record2(source?.key);
32697
33094
  exactKeys(sourceKey, ["column", "type"], "source.key", issues);
32698
33095
  if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
32699
33096
  issues.push({
@@ -32703,7 +33100,7 @@ function validateMonitorFleetDefinition(value) {
32703
33100
  });
32704
33101
  }
32705
33102
  if (source?.where !== void 0) {
32706
- const where = record(source.where);
33103
+ const where = record2(source.where);
32707
33104
  if (!where) {
32708
33105
  issues.push({
32709
33106
  path: "source.where",
@@ -32729,9 +33126,9 @@ function validateMonitorFleetDefinition(value) {
32729
33126
  }
32730
33127
  }
32731
33128
  }
32732
- const member = record(input2.member);
33129
+ const member = record2(input2.member);
32733
33130
  exactKeys(member, ["tool", "key", "payload"], "member", issues);
32734
- const key = record(member?.key);
33131
+ const key = record2(member?.key);
32735
33132
  if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
32736
33133
  issues.push({
32737
33134
  path: "member.tool",
@@ -32752,7 +33149,7 @@ function validateMonitorFleetDefinition(value) {
32752
33149
  validateExpression(part, `member.key.parts.${index}`, issues);
32753
33150
  }
32754
33151
  if (sourceKey && !key.parts.some(
32755
- (part) => record(part)?.$fleet === "column" && record(part)?.name === sourceKey.column
33152
+ (part) => record2(part)?.$fleet === "column" && record2(part)?.name === sourceKey.column
32756
33153
  )) {
32757
33154
  issues.push({
32758
33155
  path: "member.key.parts",
@@ -32771,7 +33168,7 @@ function validateMonitorFleetDefinition(value) {
32771
33168
  jsonValue(member.payload, "member.payload", issues);
32772
33169
  }
32773
33170
  walkPayload(member?.payload, "member.payload", issues);
32774
- const selection = record(input2.selection);
33171
+ const selection = record2(input2.selection);
32775
33172
  exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
32776
33173
  if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
32777
33174
  issues.push({
@@ -32797,7 +33194,7 @@ function validateMonitorFleetDefinition(value) {
32797
33194
  } else {
32798
33195
  const orderColumns = /* @__PURE__ */ new Set();
32799
33196
  for (const [index, order] of orderBy.entries()) {
32800
- const item = record(order);
33197
+ const item = record2(order);
32801
33198
  exactKeys(
32802
33199
  item,
32803
33200
  ["column", "direction"],
@@ -32820,7 +33217,7 @@ function validateMonitorFleetDefinition(value) {
32820
33217
  orderColumns.add(item.column);
32821
33218
  }
32822
33219
  }
32823
- if (sourceKey && record(orderBy.at(-1))?.column !== sourceKey.column) {
33220
+ if (sourceKey && record2(orderBy.at(-1))?.column !== sourceKey.column) {
32824
33221
  issues.push({
32825
33222
  path: "selection.orderBy",
32826
33223
  code: "fleet_order_missing_key",
@@ -32839,9 +33236,100 @@ function validateMonitorFleetDefinition(value) {
32839
33236
  }
32840
33237
  return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
32841
33238
  }
32842
- function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHORING_CONTRACT_EDITION) {
33239
+ function v2Issue(issue) {
33240
+ return { path: issue.path, code: issue.code, message: issue.message };
33241
+ }
33242
+ function validateMonitorFleetDefinitionV2(value) {
33243
+ const issues = [];
33244
+ const input2 = record2(value);
33245
+ if (!input2) {
33246
+ return {
33247
+ valid: false,
33248
+ issues: [
33249
+ {
33250
+ path: "",
33251
+ code: "invalid_fleet",
33252
+ message: "Fleet must be an object."
33253
+ }
33254
+ ]
33255
+ };
33256
+ }
33257
+ exactKeys(
33258
+ input2,
33259
+ ["version", "kind", "id", "source", "monitor", "selection"],
33260
+ "",
33261
+ issues
33262
+ );
33263
+ if (input2.version !== 2) {
33264
+ issues.push({
33265
+ path: "version",
33266
+ code: "unsupported_fleet_version",
33267
+ message: "Canonical Fleet input version must be 2."
33268
+ });
33269
+ }
33270
+ if (input2.kind !== "fleet") {
33271
+ issues.push({
33272
+ path: "kind",
33273
+ code: "invalid_fleet_kind",
33274
+ message: 'Canonical Fleet input kind must be "fleet".'
33275
+ });
33276
+ }
33277
+ const source = record2(input2.source);
33278
+ const sourceKey = record2(source?.key);
33279
+ const legacyShape = {
33280
+ id: input2.id,
33281
+ source: input2.source,
33282
+ member: {
33283
+ tool: record2(input2.monitor)?.tool,
33284
+ key: {
33285
+ $fleet: "template",
33286
+ parts: [
33287
+ "fleet-",
33288
+ {
33289
+ $fleet: "column",
33290
+ name: typeof sourceKey?.column === "string" ? sourceKey.column : "invalid_source_key"
33291
+ }
33292
+ ]
33293
+ },
33294
+ payload: record2(input2.monitor)?.payload
33295
+ },
33296
+ selection: input2.selection
33297
+ };
33298
+ const legacyCheck = validateMonitorFleetDefinitionV1(legacyShape);
33299
+ for (const issue of legacyCheck.issues) {
33300
+ issues.push({
33301
+ ...issue,
33302
+ path: issue.path.replace(/^member\./, "monitor.")
33303
+ });
33304
+ }
33305
+ const monitorInput = record2(input2.monitor);
33306
+ const monitorKey = monitorInput?.key;
33307
+ const monitor = lintMonitorSpecTemplate(input2.monitor);
33308
+ issues.push(...monitor.issues.map(v2Issue));
33309
+ if (typeof monitorKey === "string" && typeof sourceKey?.column === "string" && !monitorKey.includes(`{{${sourceKey.column}}}`)) {
33310
+ issues.push({
33311
+ path: "monitor.key",
33312
+ code: "fleet_key_missing_source_key",
33313
+ message: "Monitor key must include the source key as a direct Handlebars expression."
33314
+ });
33315
+ }
33316
+ return issues.length === 0 && monitor.normalized ? {
33317
+ valid: true,
33318
+ definition: {
33319
+ version: 2,
33320
+ kind: "fleet",
33321
+ id: String(input2.id),
33322
+ source: input2.source,
33323
+ monitor: monitor.normalized,
33324
+ selection: input2.selection
33325
+ },
33326
+ issues
33327
+ } : { valid: false, issues };
33328
+ }
33329
+ function admitMonitorFleetAuthoringContract(value, edition) {
33330
+ const detectedEdition = edition ?? (record2(value)?.version === 2 || record2(value)?.kind === "fleet" ? 2 : 1);
32843
33331
  if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
32844
- edition
33332
+ detectedEdition
32845
33333
  )) {
32846
33334
  return {
32847
33335
  valid: false,
@@ -32849,16 +33337,16 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
32849
33337
  {
32850
33338
  path: "authoring_contract_edition",
32851
33339
  code: "unsupported_fleet_authoring_contract_edition",
32852
- message: `Monitor Fleet authoring contract edition ${edition} is not supported.`
33340
+ message: `Monitor Fleet authoring contract edition ${detectedEdition} is not supported.`
32853
33341
  }
32854
33342
  ]
32855
33343
  };
32856
33344
  }
32857
- const result = validateMonitorFleetDefinition(value);
33345
+ const result = detectedEdition === 2 ? validateMonitorFleetDefinitionV2(value) : validateMonitorFleetDefinitionV1(value);
32858
33346
  return result.valid && result.definition ? {
32859
33347
  valid: true,
32860
33348
  contract: {
32861
- edition,
33349
+ edition: detectedEdition,
32862
33350
  // JSON cloning prevents later caller mutation from changing the
32863
33351
  // admitted snapshot.
32864
33352
  definition: JSON.parse(
@@ -32868,6 +33356,32 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
32868
33356
  issues: []
32869
33357
  } : { valid: false, issues: result.issues };
32870
33358
  }
33359
+ function lintMonitorFleetInput(value) {
33360
+ const input2 = record2(value);
33361
+ const legacy = input2?.member !== void 0;
33362
+ const admitted = admitMonitorFleetAuthoringContract(value);
33363
+ const issues = admitted.issues.map((issue) => ({
33364
+ ...issue,
33365
+ severity: "error"
33366
+ }));
33367
+ if (legacy) {
33368
+ issues.push({
33369
+ severity: "warning",
33370
+ code: "deprecated_fleet_member",
33371
+ path: "member",
33372
+ message: "Legacy Fleet member syntax remains supported."
33373
+ });
33374
+ if (JSON.stringify(input2).includes('"$fleet"')) {
33375
+ issues.push({
33376
+ severity: "warning",
33377
+ code: "deprecated_fleet_expression",
33378
+ path: "member",
33379
+ message: "Legacy $fleet expressions remain supported; use direct Handlebars fields in monitor instead."
33380
+ });
33381
+ }
33382
+ }
33383
+ return admitted.valid && admitted.contract ? { normalized: admitted.contract.definition, issues } : { issues };
33384
+ }
32871
33385
 
32872
33386
  // src/cli/commands/monitors.ts
32873
33387
  var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
@@ -33553,6 +34067,155 @@ function fleetIdempotencyKey(operation, supplied) {
33553
34067
  }
33554
34068
  return normalized ?? `monitor-fleet-${operation}-${randomUUID5()}`;
33555
34069
  }
34070
+ function monitorJobIdempotencyKey(operation, supplied) {
34071
+ const normalized = supplied?.trim();
34072
+ if (supplied !== void 0 && !normalized) {
34073
+ throw new MonitorsUsageError("--idempotency-key must not be empty.");
34074
+ }
34075
+ return normalized ?? `monitor-job-${operation}-${randomUUID5()}`;
34076
+ }
34077
+ function readMonitorDefinitionsJsonFile(file) {
34078
+ let raw;
34079
+ try {
34080
+ raw = file === "-" ? readFileSync11(0, "utf8") : readFileSync11(file, "utf8");
34081
+ } catch (error) {
34082
+ throw new MonitorsUsageError(
34083
+ `Could not read --file ${file}: ${error instanceof Error ? error.message : String(error)}`
34084
+ );
34085
+ }
34086
+ try {
34087
+ return JSON.parse(raw);
34088
+ } catch (error) {
34089
+ throw new MonitorsUsageError(
34090
+ `Monitor definitions must be valid JSON. ${error instanceof Error ? error.message : String(error)}`
34091
+ );
34092
+ }
34093
+ }
34094
+ function renderMonitorJob(payload) {
34095
+ const job = asRecord2(payload.job);
34096
+ if (!job) return void 0;
34097
+ const id = asString(job.id) ?? "<unknown>";
34098
+ const state = asString(job.state) ?? "unknown";
34099
+ const phase = asString(job.phase);
34100
+ const counts = asRecord2(job.counts);
34101
+ const reconciliation = asRecord2(job.reconciliation);
34102
+ const lines = [
34103
+ `Monitor job: ${id}`,
34104
+ `State: ${state}${phase ? ` (${phase})` : ""}`
34105
+ ];
34106
+ if (counts) {
34107
+ lines.push(
34108
+ `Counts: requested ${asFiniteNumber(counts.requested) ?? 0}, created ${asFiniteNumber(counts.created) ?? 0}, unchanged ${asFiniteNumber(counts.unchanged) ?? 0}, verified ${asFiniteNumber(counts.verified) ?? 0}, failed ${asFiniteNumber(counts.failed) ?? 0}`
34109
+ );
34110
+ }
34111
+ if (reconciliation) {
34112
+ lines.push(
34113
+ `Reconciliation: ${asString(reconciliation.state) ?? "pending"} (${asFiniteNumber(reconciliation.observed_bindings) ?? 0}/${asFiniteNumber(reconciliation.expected_bindings) ?? 0} bindings observed)`
34114
+ );
34115
+ }
34116
+ const next = asString(payload.next);
34117
+ if (next) lines.push(`Next: ${next}`);
34118
+ return `${lines.join("\n")}
34119
+ `;
34120
+ }
34121
+ async function handleMonitorJobBatchDeploy(options, idempotencyKey) {
34122
+ if (!options.file) {
34123
+ throw new MonitorsUsageError(
34124
+ "A Batch file is required. Pass --file batch.json (or --file - for stdin)."
34125
+ );
34126
+ }
34127
+ const lint = lintMonitorBatchInput(
34128
+ readMonitorDefinitionsJsonFile(options.file)
34129
+ );
34130
+ if (!lint.normalized) {
34131
+ throw new MonitorsUsageError(
34132
+ lint.issues.filter((issue) => issue.severity === "error").map((issue) => `${issue.path || "batch"}: ${issue.message}`).join("; ")
34133
+ );
34134
+ }
34135
+ const payload = await new DeeplineClient().monitors.batch.deploy(
34136
+ lint.normalized.monitors,
34137
+ { idempotencyKey }
34138
+ );
34139
+ printCommandEnvelope(
34140
+ {
34141
+ ...payload,
34142
+ idempotency_key: idempotencyKey,
34143
+ ...lint.issues.length ? { lint: { issues: lint.issues } } : {}
34144
+ },
34145
+ { json: options.json, text: renderMonitorJob(payload) }
34146
+ );
34147
+ }
34148
+ async function handleMonitorBatchLint(options) {
34149
+ if (!options.file) {
34150
+ throw new MonitorsUsageError(
34151
+ "monitors batch lint requires --file <batch.json>."
34152
+ );
34153
+ }
34154
+ const result = lintMonitorBatchInput(
34155
+ readMonitorDefinitionsJsonFile(options.file)
34156
+ );
34157
+ printCommandEnvelope(
34158
+ {
34159
+ ok: !result.issues.some((issue) => issue.severity === "error"),
34160
+ ...result.normalized ? { normalized: result.normalized } : {},
34161
+ issues: result.issues
34162
+ },
34163
+ { json: options.json }
34164
+ );
34165
+ if (result.issues.some((issue) => issue.severity === "error"))
34166
+ process.exitCode = 2;
34167
+ }
34168
+ async function handleMonitorFleetLint(options) {
34169
+ if (!options.file) {
34170
+ throw new MonitorsUsageError(
34171
+ "monitors fleets lint requires --file <fleet.json>."
34172
+ );
34173
+ }
34174
+ const result = lintMonitorFleetInput(
34175
+ readMonitorDefinitionsJsonFile(options.file)
34176
+ );
34177
+ printCommandEnvelope(
34178
+ {
34179
+ ok: !result.issues.some((issue) => issue.severity === "error"),
34180
+ ...result.normalized ? { normalized: result.normalized } : {},
34181
+ issues: result.issues
34182
+ },
34183
+ { json: options.json }
34184
+ );
34185
+ if (result.issues.some((issue) => issue.severity === "error"))
34186
+ process.exitCode = 2;
34187
+ }
34188
+ async function handleMonitorJobGet(jobId, options) {
34189
+ const payload = await new DeeplineClient().monitors.jobs.get(jobId);
34190
+ printCommandEnvelope(payload, {
34191
+ json: options.json,
34192
+ text: renderMonitorJob(payload)
34193
+ });
34194
+ }
34195
+ async function handleMonitorJobWait(jobId, options) {
34196
+ const payload = await new DeeplineClient().monitors.jobs.wait(jobId, {
34197
+ timeoutMs: fleetTimeoutMs(options.timeout),
34198
+ pollIntervalMs: FLEET_POLL_INTERVAL_MS
34199
+ });
34200
+ printCommandEnvelope(payload, {
34201
+ json: options.json,
34202
+ text: renderMonitorJob(payload)
34203
+ });
34204
+ }
34205
+ async function handleMonitorJobLogs(jobId, options) {
34206
+ const limit = options.limit ? fleetIntegerOption(options.limit, "--limit") : void 0;
34207
+ const payload = await new DeeplineClient().monitors.jobs.logs(jobId, {
34208
+ ...limit === void 0 ? {} : { limit }
34209
+ });
34210
+ printCommandEnvelope(payload, { json: options.json });
34211
+ }
34212
+ async function handleMonitorJobCancel(jobId, options) {
34213
+ const payload = await new DeeplineClient().monitors.jobs.cancel(jobId);
34214
+ printCommandEnvelope(payload, {
34215
+ json: options.json,
34216
+ text: renderMonitorJob(payload)
34217
+ });
34218
+ }
33556
34219
  var FLEET_COUNT_KEYS = [
33557
34220
  "pending",
33558
34221
  "submitting",
@@ -33574,12 +34237,12 @@ var MONITOR_FLEET_LIFECYCLE = [
33574
34237
  {
33575
34238
  step: 2,
33576
34239
  what: "See the plan and the credits before anything changes.",
33577
- command: "deepline monitors fleets sync --file fleet.json --dry-run"
34240
+ command: "deepline monitors fleets deploy --file fleet.json --dry-run"
33578
34241
  },
33579
34242
  {
33580
34243
  step: 3,
33581
34244
  what: "Apply it and wait for the server to call it converged.",
33582
- command: "deepline monitors fleets sync --file fleet.json --wait"
34245
+ command: "deepline monitors fleets deploy --file fleet.json --wait"
33583
34246
  },
33584
34247
  {
33585
34248
  step: 4,
@@ -33588,6 +34251,11 @@ var MONITOR_FLEET_LIFECYCLE = [
33588
34251
  }
33589
34252
  ];
33590
34253
  var MONITOR_FLEET_COMMANDS = [
34254
+ {
34255
+ name: "deploy",
34256
+ summary: "Create or update one table-backed Fleet from Customer DB rows."
34257
+ },
34258
+ { name: "lint", summary: "Validate and normalize Fleet JSON locally." },
33591
34259
  { name: "init", summary: "Write a Fleet definition JSON file." },
33592
34260
  {
33593
34261
  name: "sync",
@@ -33733,6 +34401,26 @@ function renderFleetGet(payload) {
33733
34401
  ` counts ${fleetCountsLine(payload)}`,
33734
34402
  ` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
33735
34403
  ];
34404
+ const boundPlays = Array.isArray(payload.bound_plays) ? payload.bound_plays.flatMap((value) => {
34405
+ const play = asRecord2(value);
34406
+ return play ? [play] : [];
34407
+ }) : [];
34408
+ lines.push("", `Observed Play bindings (${boundPlays.length}):`);
34409
+ if (boundPlays.length === 0) {
34410
+ lines.push(" none");
34411
+ } else {
34412
+ for (const play of boundPlays) {
34413
+ const name = asString(play.name) ?? "unnamed Play";
34414
+ const listeners = asFiniteNumber(play.listener_count) ?? 0;
34415
+ const status2 = asString(play.status);
34416
+ lines.push(
34417
+ ` ${name}${listeners ? ` (${listeners} listener${listeners === 1 ? "" : "s"})` : ""}${status2 ? ` \u2014 ${status2}` : ""}`
34418
+ );
34419
+ }
34420
+ }
34421
+ lines.push(
34422
+ " Read-only observation. Define or change bindings in the Play with sqlListeners."
34423
+ );
33736
34424
  lines.push(...renderFleetDriftRows(payload));
33737
34425
  const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
33738
34426
  if (next) lines.push(`Next: ${next}`);
@@ -33909,6 +34597,8 @@ async function handleMonitorFleetsInit(fleetId, options) {
33909
34597
  const out = options.out?.trim();
33910
34598
  if (!out) throw new MonitorsUsageError("--out is required.");
33911
34599
  const authoredDefinition = {
34600
+ version: 2,
34601
+ kind: "fleet",
33912
34602
  id: fleetId,
33913
34603
  source: {
33914
34604
  kind: "customer_db_table",
@@ -33917,12 +34607,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
33917
34607
  key: { column: key, type: keyType },
33918
34608
  ...where ? { where } : {}
33919
34609
  },
33920
- member: {
34610
+ monitor: {
33921
34611
  tool,
33922
- key: {
33923
- $fleet: "template",
33924
- parts: [`${fleetId}-`, { $fleet: "column", name: key }]
33925
- },
34612
+ key: `${fleetId}-{{${key}}}`,
33926
34613
  payload
33927
34614
  },
33928
34615
  selection: {
@@ -33935,9 +34622,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
33935
34622
  const file = resolve14(out);
33936
34623
  writeFileSync12(file, `${JSON.stringify(definition, null, 2)}
33937
34624
  `, "utf8");
33938
- const next = `deepline monitors fleets sync --file ${fleetShellArg(file)} --dry-run --json`;
34625
+ const next = `deepline monitors fleets deploy --file ${fleetShellArg(file)} --dry-run --json`;
33939
34626
  printCommandEnvelope(
33940
- { schemaVersion: 1, file, definition, next },
34627
+ { schemaVersion: 2, file, definition, next },
33941
34628
  {
33942
34629
  json: options.json,
33943
34630
  text: `Wrote ${file}
@@ -33947,8 +34634,8 @@ Next: ${next}
33947
34634
  );
33948
34635
  }
33949
34636
  function requireCompiledFleetDefinition(definition) {
33950
- const result = admitMonitorFleetAuthoringContract(definition);
33951
- if (result.valid && result.contract) return result.contract.definition;
34637
+ const result = lintMonitorFleetInput(definition);
34638
+ if (result.normalized) return result.normalized;
33952
34639
  const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
33953
34640
  throw new MonitorsUsageError(
33954
34641
  `Monitor Fleet definition failed local contract check. ${messages}
@@ -33975,6 +34662,7 @@ function fleetSyncCommandLine(target, options) {
33975
34662
  return parts.join(" ");
33976
34663
  }
33977
34664
  async function handleMonitorFleetsSync(target, options, idempotencyKey) {
34665
+ const fileDefinitions = options.file ? readMonitorDefinitionsJsonFile(options.file) : void 0;
33978
34666
  const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
33979
34667
  if (!usesDefinition && !target?.trim()) {
33980
34668
  throw new MonitorsUsageError(
@@ -33982,12 +34670,14 @@ async function handleMonitorFleetsSync(target, options, idempotencyKey) {
33982
34670
  );
33983
34671
  }
33984
34672
  const definition = usesDefinition ? requireCompiledFleetDefinition(
33985
- resolveMonitorJsonBody({
33986
- positional: target,
33987
- file: options.file,
33988
- argLabel: "<definition>",
33989
- command: "deepline monitors fleets sync"
33990
- })
34673
+ asRecord2(
34674
+ fileDefinitions ?? resolveMonitorJsonBody({
34675
+ positional: target,
34676
+ file: options.file,
34677
+ argLabel: "<definition>",
34678
+ command: "deepline monitors fleets sync"
34679
+ })
34680
+ ) ?? {}
33991
34681
  ) : void 0;
33992
34682
  const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
33993
34683
  if (!fleetId) {
@@ -34388,14 +35078,14 @@ function renderMonitorGet(payload) {
34388
35078
  ` deepline monitors test ${key} '${JSON.stringify(samplePayload2)}' --json`
34389
35079
  );
34390
35080
  }
34391
- const monitorSpec = asRecord2(payload.monitor_spec);
34392
- if (monitorSpec?.available === false) {
35081
+ const monitorSpec2 = asRecord2(payload.monitor_spec);
35082
+ if (monitorSpec2?.available === false) {
34393
35083
  lines.push(
34394
35084
  "",
34395
- `Monitor spec: unavailable \u2014 ${asString(monitorSpec.message) ?? "use the stored definition and check before an update."}`
35085
+ `Monitor spec: unavailable \u2014 ${asString(monitorSpec2.message) ?? "use the stored definition and check before an update."}`
34396
35086
  );
34397
35087
  }
34398
- const specFields = Array.isArray(monitorSpec?.fields) ? monitorSpec.fields.flatMap((value) => {
35088
+ const specFields = Array.isArray(monitorSpec2?.fields) ? monitorSpec2.fields.flatMap((value) => {
34399
35089
  const field = asRecord2(value);
34400
35090
  const path = asString(field?.path);
34401
35091
  const description = asString(field?.description);
@@ -34869,6 +35559,8 @@ Notes:
34869
35559
  Deepline monitors are Deepline-native signal feeds: a monitor writes events
34870
35560
  into a Customer DB table; a play reacts to each new row via a
34871
35561
  sqlListeners trigger \u2014 see \`deepline plays bootstrap monitor-triggered\`.
35562
+ Monitor JSON declares only what to watch (key, tool, optional name, payload).
35563
+ Play bindings belong in the Play; monitor deployment never changes them.
34872
35564
  The Monitors rollout controls access to the live provider catalog; use
34873
35565
  \`deepline tools list --categories monitors\` for the exact tool ids available to you.
34874
35566
  Contact the Deepline team to request access; until access is enabled, these
@@ -34981,19 +35673,31 @@ Examples:
34981
35673
  );
34982
35674
  withJsonOption(
34983
35675
  batch.command("deploy").description(
34984
- "Durably create complete NDJSON monitor definitions through provider bulk create."
35676
+ "Create a Monitor Job from canonical Batch JSON; legacy NDJSON remains available with --yes or --dry-run."
34985
35677
  ).requiredOption(
34986
35678
  "--file <path>",
34987
- "NDJSON file of complete monitor definitions"
34988
- ).option("--dry-run", "Validate and record the durable deploy plan").option("--yes", "Confirm asynchronous provider creation").option(
35679
+ 'Batch JSON ({"version":1,"kind":"batch","monitors":[...]}), or legacy NDJSON with --yes/--dry-run'
35680
+ ).option("--dry-run", "Use the retained legacy batch-operation plan").option("--yes", "Use the retained legacy NDJSON batch operation").option(
34989
35681
  "--idempotency-key <key>",
34990
35682
  "Stable retry key (generated when omitted)"
34991
35683
  )
34992
35684
  ).action(
34993
- monitorsAction(
34994
- (options) => handleMonitorBatchDeploy(options)
34995
- )
35685
+ monitorsAction(async (options) => {
35686
+ if (options.dryRun === true || options.yes === true) {
35687
+ return await handleMonitorBatchDeploy(options);
35688
+ }
35689
+ const idempotencyKey = monitorJobIdempotencyKey(
35690
+ "batch-deploy",
35691
+ options.idempotencyKey
35692
+ );
35693
+ return await handleMonitorJobBatchDeploy(options, idempotencyKey);
35694
+ })
34996
35695
  );
35696
+ withJsonOption(
35697
+ batch.command("lint").description(
35698
+ "Validate and normalize Batch JSON without network or provider work."
35699
+ ).requiredOption("--file <path>", "Batch JSON file, or - for stdin")
35700
+ ).action(monitorsAction(handleMonitorBatchLint));
34997
35701
  withJsonOption(
34998
35702
  batchSelectorOptions(
34999
35703
  batch.command("audit").description("Durably audit a selection; defaults to --target all.")
@@ -35162,9 +35866,8 @@ Examples:
35162
35866
  "after",
35163
35867
  `
35164
35868
  Notes:
35165
- Read-only validation. <definition> is a JSON object with key, tool, payload,
35166
- and optional controls (Deepline lifecycle metadata). Pass it positionally,
35167
- via --file <path>, or
35869
+ Read-only validation. <definition> is a JSON object with key, tool, optional
35870
+ name, and payload. Pass it positionally, via --file <path>, or
35168
35871
  from stdin with --file -. Does not deploy or spend credits.
35169
35872
  Check validates the local definition only. It does not contact an existing
35170
35873
  upstream resource, prove that future events will arrive, or verify downstream
@@ -35172,12 +35875,8 @@ Notes:
35172
35875
  Provider-specific grammar, precedence, enum applicability, examples, and
35173
35876
  update semantics are returned by the live monitor contract. Inspect it with
35174
35877
  \`deepline tools get deepline_native.company_radar --json\`.
35175
- For a bounded urgent Deepline Native preview, use
35176
- controls.execution_type="priority". Deepline injects the upstream marker;
35177
- do not author custom_fields yourself. Priority is capped at ten upstream or
35178
- reserved recovery, replacement, or reactivation slots per org. Use
35179
- \`monitors list --status all\` to find priority holders; it is not for regular
35180
- or bulk-scale monitoring.
35878
+ Operational controls are Deepline-managed. Bind downstream automation in a
35879
+ Play with sqlListeners; monitor definitions never name Plays.
35181
35880
 
35182
35881
  Examples:
35183
35882
  deepline monitors check '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
@@ -35195,8 +35894,8 @@ Examples:
35195
35894
  `
35196
35895
  Notes:
35197
35896
  Mutates workspace state and may spend Deepline credits. <definition> is a JSON
35198
- object with key, tool, payload, and optional controls. Pass it positionally,
35199
- via --file <path>, or from stdin with --file -.
35897
+ object with key, tool, optional name, and payload. Pass it positionally, via
35898
+ --file <path>, or from stdin with --file -.
35200
35899
  --dry-run validates the definition and shows the plan (deploy cost in Deepline
35201
35900
  credits when the server reports it, plus any existing monitors that may
35202
35901
  already cover this scope) WITHOUT deploying. Exits 0 when valid, 7 when not.
@@ -35213,10 +35912,8 @@ Notes:
35213
35912
  historical replay request, including when redeploying a disabled monitor.
35214
35913
  Deepline preserves that selected boundary; filter-only deploys and ordinary
35215
35914
  reactivation start from a fresh future-only source boundary instead.
35216
- For a bounded urgent Deepline Native preview, set
35217
- controls.execution_type="priority". Deepline injects the provider custom
35218
- field and enforces a ten-slot per-org cap; do not use it for regular or bulk
35219
- monitoring, and do not delete another radar automatically to make room.
35915
+ Operational controls are Deepline-managed. A monitor writes rows; downstream
35916
+ automation belongs in a Play with sqlListeners.
35220
35917
 
35221
35918
  Examples:
35222
35919
  deepline monitors deploy '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
@@ -35247,10 +35944,6 @@ request. Deepline passes that requested boundary upstream, but previously
35247
35944
  delivered canonical findings are deduplicated before dispatch and billing; only
35248
35945
  previously unseen historical findings are chargeable. Filter-only updates,
35249
35946
  repair, and reactivation instead use a fresh future-only source boundary.
35250
- Use {"controls":{"execution_type":"priority"}} only for a bounded urgent
35251
- Deepline Native preview. The ten-radar priority cap applies on update too.
35252
- Use {"controls":{"execution_type":null}} to release priority without
35253
- deleting the monitor.
35254
35947
 
35255
35948
  Examples:
35256
35949
  deepline monitors update my-monitor '{"name":"Interested replies"}' --json
@@ -35298,13 +35991,30 @@ Examples:
35298
35991
  `
35299
35992
  ).option("--dry-run", "Show the reactivation cost without reactivating")
35300
35993
  ).action(monitorsAction(handleMonitorsReactivate));
35301
- const fleets = monitors.command("fleets").description("Define and reconcile table-backed Monitor Fleets.").addHelpText(
35994
+ const jobs = monitors.command("jobs").description("Read, wait for, inspect, or cancel Monitor Jobs.");
35995
+ withJsonOption(jobs);
35996
+ withJsonOption(
35997
+ jobs.command("get <job-id>").description("Read the durable Monitor Job state.")
35998
+ ).action(monitorsAction(handleMonitorJobGet));
35999
+ withJsonOption(
36000
+ jobs.command("wait <job-id>").description(
36001
+ "Wait for real provider reconciliation, not request acceptance."
36002
+ ).option("--timeout <duration>", "How long to wait (default 10m)")
36003
+ ).action(monitorsAction(handleMonitorJobWait));
36004
+ withJsonOption(
36005
+ jobs.command("logs <job-id>").description("Read bounded operator logs for one Monitor Job.").option("--limit <n>", "Maximum log entries (1..200)")
36006
+ ).action(monitorsAction(handleMonitorJobLogs));
36007
+ withJsonOption(
36008
+ jobs.command("cancel <job-id>").description("Stop unscheduled work and reconcile the partial result.")
36009
+ ).action(monitorsAction(handleMonitorJobCancel));
36010
+ const fleets = monitors.command("fleets").description("Manage table-backed Fleets.").addHelpText(
35302
36011
  "after",
35303
36012
  `
35304
36013
  Notes:
35305
36014
  A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
35306
- monitors. Fleet definitions are canonical JSON, and \`sync\` is the only verb
35307
- that changes one: applying the same definition twice is the same operation,
36015
+ monitors. Fleet definitions are canonical JSON, and \`deploy\` applies one;
36016
+ \`sync\` remains its exact compatibility alias. Applying the same definition
36017
+ twice is the same operation,
35308
36018
  so the server answers \`replayed: true\` instead of building a second fleet.
35309
36019
  The fleet's status is computed by Deepline; this CLI reports it and never
35310
36020
  recomputes a verdict from the counts.
@@ -35326,6 +36036,29 @@ ${MONITOR_FLEET_HELP_EPILOG}`
35326
36036
  })
35327
36037
  );
35328
36038
  withJsonOption(fleets);
36039
+ withJsonOption(
36040
+ fleets.command("deploy [fleet-id]").description(
36041
+ "Apply a table-backed Fleet definition; sync remains an exact alias."
36042
+ ).option("-f, --file <path>", "Fleet JSON file, or - for stdin").option("--dry-run", "Show the table-backed convergence plan").option("--wait", "Wait for the current Fleet generation to converge").option("--timeout <duration>", "How long --wait may poll (default 10m)").option(
36043
+ "--expected-generation <generation>",
36044
+ "Optimistic generation fence"
36045
+ ).option("--idempotency-key <key>", "Stable retry key")
36046
+ ).action(
36047
+ monitorsAction(
36048
+ async (fleetId, options) => {
36049
+ const idempotencyKey = fleetIdempotencyKey(
36050
+ "deploy",
36051
+ options.idempotencyKey
36052
+ );
36053
+ await handleMonitorFleetsSync(fleetId, options, idempotencyKey);
36054
+ }
36055
+ )
36056
+ );
36057
+ withJsonOption(
36058
+ fleets.command("lint").description(
36059
+ "Validate and normalize Fleet JSON without network or provider work."
36060
+ ).requiredOption("--file <path>", "Fleet JSON file, or - for stdin")
36061
+ ).action(monitorsAction(handleMonitorFleetLint));
35329
36062
  withJsonOption(
35330
36063
  fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
35331
36064
  "after",
@@ -35339,13 +36072,13 @@ Example:
35339
36072
  deepline monitors fleets init account-job-openings \\
35340
36073
  --source public.accounts --key account_id --key-type uuid \\
35341
36074
  --tool deepline_native.company_radar \\
35342
- --payload '{"domain":{"$fleet":"column","name":"domain"},"radar_type":"company_job_openings"}' \\
36075
+ --payload '{"domain":"{{domain}}","radar_type":"company_job_openings"}' \\
35343
36076
  --order-by intent_score:desc \\
35344
36077
  --out fleet.json
35345
36078
  `
35346
36079
  ).requiredOption("--source <schema.table>", "Customer DB source table").requiredOption("--key <column>", "Unique source-row key column").option("--key-type <type>", "text, uuid, int4, or int8 (default text)").requiredOption("--tool <tool>", "Monitor tool to create per source row").requiredOption(
35347
36080
  "--payload <json>",
35348
- "Monitor payload JSON for --tool; use $fleet column tags for row values"
36081
+ "Monitor payload JSON for --tool; use Handlebars fields such as {{domain}} for row values"
35349
36082
  ).option(
35350
36083
  "--where <json>",
35351
36084
  "Optional source-row equality filter JSON; not arbitrary SQL"
@@ -35421,7 +36154,9 @@ Examples:
35421
36154
  Notes:
35422
36155
  Status is the server's verdict. --check turns it into an exit code so a
35423
36156
  script can branch without parsing output: 0 converged, 6 anything else.
35424
- --drift lists the members that have not settled and why.
36157
+ --drift lists the members that have not settled and why. The detail also
36158
+ shows the current Plays that observe this Fleet's output; those bindings are
36159
+ read-only here and are defined by each Play's sqlListeners.
35425
36160
 
35426
36161
  Examples:
35427
36162
  deepline monitors fleets get --json
@@ -37549,8 +38284,8 @@ function classifyNetworkFailure(error) {
37549
38284
  let current = error;
37550
38285
  while (current && !seen.has(current)) {
37551
38286
  seen.add(current);
37552
- const record2 = typeof current === "object" && current !== null ? current : {};
37553
- const code = String(record2.code ?? "").toLowerCase();
38287
+ const record3 = typeof current === "object" && current !== null ? current : {};
38288
+ const code = String(record3.code ?? "").toLowerCase();
37554
38289
  const name = current instanceof Error ? current.name.toLowerCase() : "";
37555
38290
  const text = String(
37556
38291
  current instanceof Error ? current.message : current
@@ -37577,7 +38312,7 @@ function classifyNetworkFailure(error) {
37577
38312
  if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
37578
38313
  return "network_ssl_error";
37579
38314
  }
37580
- current = record2.cause ?? record2.context;
38315
+ current = record3.cause ?? record3.context;
37581
38316
  }
37582
38317
  return "network_error";
37583
38318
  }
@@ -38654,26 +39389,26 @@ function parseSetupPhases(value) {
38654
39389
  if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
38655
39390
  return null;
38656
39391
  }
38657
- const record2 = phase;
38658
- if (!isSetupPhaseStatus(record2.status)) return null;
38659
- switch (record2.status) {
39392
+ const record3 = phase;
39393
+ if (!isSetupPhaseStatus(record3.status)) return null;
39394
+ switch (record3.status) {
38660
39395
  case "pending":
38661
39396
  case "in_progress":
38662
- phases[name] = { status: record2.status };
39397
+ phases[name] = { status: record3.status };
38663
39398
  break;
38664
39399
  case "complete":
38665
39400
  phases[name] = {
38666
39401
  status: "complete",
38667
- ...typeof record2.outcome === "string" ? { outcome: record2.outcome } : {}
39402
+ ...typeof record3.outcome === "string" ? { outcome: record3.outcome } : {}
38668
39403
  };
38669
39404
  break;
38670
39405
  case "waiting":
38671
- if (typeof record2.outcome !== "string") return null;
38672
- phases[name] = { status: "waiting", outcome: record2.outcome };
39406
+ if (typeof record3.outcome !== "string") return null;
39407
+ phases[name] = { status: "waiting", outcome: record3.outcome };
38673
39408
  break;
38674
39409
  case "failed":
38675
- if (typeof record2.code !== "string") return null;
38676
- phases[name] = { status: "failed", code: record2.code };
39410
+ if (typeof record3.code !== "string") return null;
39411
+ phases[name] = { status: "failed", code: record3.code };
38677
39412
  break;
38678
39413
  }
38679
39414
  }
@@ -41618,7 +42353,7 @@ Examples:
41618
42353
  }
41619
42354
 
41620
42355
  // src/cli/commands/tools.ts
41621
- import { Option as Option3 } from "commander";
42356
+ import { Option as Option4 } from "commander";
41622
42357
  import {
41623
42358
  chmodSync,
41624
42359
  existsSync as existsSync19,
@@ -42124,9 +42859,9 @@ function requiredInputIds(tool) {
42124
42859
  return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
42125
42860
  }
42126
42861
  function notConnectedSuffix(tool) {
42127
- const record2 = tool;
42128
- const status = stringField2(record2, "credentialStatus", "credential_status");
42129
- const connected = record2.connected;
42862
+ const record3 = tool;
42863
+ const status = stringField2(record3, "credentialStatus", "credential_status");
42864
+ const connected = record3.connected;
42130
42865
  const message = toolConnectionStatusMessage({
42131
42866
  connected: connected === false ? false : void 0,
42132
42867
  credentialStatus: status || void 0
@@ -42505,19 +43240,19 @@ function printPlayAliasToolError(toolId, play) {
42505
43240
  console.error(playAliasToolErrorMessage(toolId, play));
42506
43241
  }
42507
43242
  function isPlayLikeTool(tool) {
42508
- const record2 = tool;
42509
- if (record2.isPlay === true || record2.is_play === true) return true;
42510
- const playExpansion = recordField2(record2, "playExpansion", "play_expansion");
43243
+ const record3 = tool;
43244
+ if (record3.isPlay === true || record3.is_play === true) return true;
43245
+ const playExpansion = recordField2(record3, "playExpansion", "play_expansion");
42511
43246
  if (Object.keys(playExpansion).length > 0) return true;
42512
- const toolId = typeof record2.toolId === "string" ? record2.toolId : "";
43247
+ const toolId = typeof record3.toolId === "string" ? record3.toolId : "";
42513
43248
  return toolId.endsWith("_waterfall");
42514
43249
  }
42515
43250
  function isMonitorTypeTool(tool) {
42516
43251
  return stringField2(tool, "kind") === "monitor_type";
42517
43252
  }
42518
43253
  function playReferenceForTool(tool) {
42519
- const record2 = tool;
42520
- const declared = stringField2(record2, "playReference", "play_reference");
43254
+ const record3 = tool;
43255
+ const declared = stringField2(record3, "playReference", "play_reference");
42521
43256
  if (declared.startsWith("prebuilt/")) {
42522
43257
  return declared;
42523
43258
  }
@@ -42690,12 +43425,12 @@ Examples:
42690
43425
  "--examples-only",
42691
43426
  "Only print runnable examples and sample payloads"
42692
43427
  ).option("--getters-only", "Only print extracted list/value getters").addOption(
42693
- new Option3(
43428
+ new Option4(
42694
43429
  "--compact",
42695
43430
  "Compatibility alias for the default compact view"
42696
43431
  ).hideHelp()
42697
43432
  ).addOption(
42698
- new Option3(
43433
+ new Option4(
42699
43434
  "--contract-json",
42700
43435
  "Compatibility alias for compact contract JSON"
42701
43436
  ).hideHelp()
@@ -43457,12 +44192,12 @@ function singleLineText(value, maxLength = 260) {
43457
44192
  return `${text.slice(0, maxLength - 3).trimEnd()}...`;
43458
44193
  }
43459
44194
  function listedToolDescription(tool) {
43460
- const record2 = tool;
43461
- return singleLineText(record2.bestFor ?? record2.best_for ?? tool.description);
44195
+ const record3 = tool;
44196
+ return singleLineText(record3.bestFor ?? record3.best_for ?? tool.description);
43462
44197
  }
43463
44198
  function formatListedToolCost(tool) {
43464
- const record2 = tool;
43465
- const pricing = recordField2(record2, "pricing");
44199
+ const record3 = tool;
44200
+ const pricing = recordField2(record3, "pricing");
43466
44201
  const displayText = stringField2(pricing, "displayText", "display_text");
43467
44202
  return displayText ? `Cost: ${displayText}` : "";
43468
44203
  }
@@ -44518,9 +45253,9 @@ function noticeToStderr(command) {
44518
45253
  );
44519
45254
  }
44520
45255
  function emitPassThrough(command, payload, options) {
44521
- const json = shouldEmitJson(options.json);
45256
+ const json2 = shouldEmitJson(options.json);
44522
45257
  const deprecation = migrationDeprecation(command);
44523
- if (json) {
45258
+ if (json2) {
44524
45259
  const enriched = payload && typeof payload === "object" && !Array.isArray(payload) ? { ...payload, deprecation } : { result: payload, deprecation };
44525
45260
  printJson(enriched);
44526
45261
  return;
@@ -44541,9 +45276,9 @@ function clientWithTimeout(timeoutSeconds) {
44541
45276
  }
44542
45277
  function readStatus(payload) {
44543
45278
  if (!payload || typeof payload !== "object") return null;
44544
- const record2 = payload;
44545
- if (typeof record2.status === "string") return record2.status;
44546
- const run = record2.run;
45279
+ const record3 = payload;
45280
+ if (typeof record3.status === "string") return record3.status;
45281
+ const run = record3.run;
44547
45282
  if (run && typeof run === "object") {
44548
45283
  const status = run.status;
44549
45284
  if (typeof status === "string") return status;