deepline 0.3.96 → 0.3.98

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 +144 -4
  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 +1005 -290
  17. package/dist/cli/index.mjs +1005 -290
  18. package/dist/index.d.mts +43 -24
  19. package/dist/index.d.ts +43 -24
  20. package/dist/index.js +604 -41
  21. package/dist/index.mjs +600 -41
  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
package/dist/cli/index.js CHANGED
@@ -1298,7 +1298,7 @@ var SDK_RELEASE = {
1298
1298
  // getters keep their established compatibility behavior.
1299
1299
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1300
1300
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1301
- version: "0.3.96",
1301
+ version: "0.3.98",
1302
1302
  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.",
1303
1303
  packageCapabilities: {
1304
1304
  updatePreferences: 1
@@ -3370,9 +3370,9 @@ function nonEmptyString(value) {
3370
3370
  }
3371
3371
  function normalizeDatasetBornFrom(value) {
3372
3372
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
3373
- const record2 = value;
3374
- const table = nonEmptyString(record2.table);
3375
- const rowCountIn = finiteNonNegativeInteger2(record2.rowCountIn);
3373
+ const record3 = value;
3374
+ const table = nonEmptyString(record3.table);
3375
+ const rowCountIn = finiteNonNegativeInteger2(record3.rowCountIn);
3376
3376
  if (!table || rowCountIn === null) return null;
3377
3377
  return { table, rowCountIn };
3378
3378
  }
@@ -4561,21 +4561,21 @@ function normalizePlayRuntimeNamespace(value) {
4561
4561
  }
4562
4562
  function normalizePlayRuntimeSelection(value) {
4563
4563
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
4564
- const record2 = value;
4565
- if (Object.keys(record2).some(
4564
+ const record3 = value;
4565
+ if (Object.keys(record3).some(
4566
4566
  (key) => key !== "environment" && key !== "namespace" && key !== "backend"
4567
- ) || record2.environment !== "preview") {
4567
+ ) || record3.environment !== "preview") {
4568
4568
  return null;
4569
4569
  }
4570
- const namespace = normalizePlayRuntimeNamespace(record2.namespace);
4570
+ const namespace = normalizePlayRuntimeNamespace(record3.namespace);
4571
4571
  if (!namespace) return null;
4572
- if (record2.backend === void 0) {
4572
+ if (record3.backend === void 0) {
4573
4573
  return { environment: "preview", namespace };
4574
4574
  }
4575
- if (record2.backend !== PLAY_RUNTIME_BACKENDS.daytona && record2.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4575
+ if (record3.backend !== PLAY_RUNTIME_BACKENDS.daytona && record3.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4576
4576
  return null;
4577
4577
  }
4578
- return { environment: "preview", namespace, backend: record2.backend };
4578
+ return { environment: "preview", namespace, backend: record3.backend };
4579
4579
  }
4580
4580
  function normalizePlayRuntimeEnvironment(value) {
4581
4581
  return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
@@ -5220,10 +5220,18 @@ var DeeplineClient = class {
5220
5220
  repair: (options2) => this.repairMonitors(options2),
5221
5221
  health: (options2) => this.readMonitorsHealth(options2),
5222
5222
  batch: {
5223
+ deploy: (definitions, options2) => this.deployMonitorBatch(definitions, options2),
5223
5224
  submit: (options2) => this.submitMonitorBatch(options2),
5224
5225
  get: (operationId, options2) => this.getMonitorBatch(operationId, options2)
5225
5226
  },
5227
+ jobs: {
5228
+ get: (jobId) => this.getMonitorJob(jobId),
5229
+ logs: (jobId, options2) => this.getMonitorJobLogs(jobId, options2),
5230
+ cancel: (jobId) => this.cancelMonitorJob(jobId),
5231
+ wait: (jobId, options2) => this.waitForMonitorJob(jobId, options2)
5232
+ },
5226
5233
  fleets: {
5234
+ deploy: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
5227
5235
  sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
5228
5236
  get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
5229
5237
  list: () => this.listMonitorFleets(),
@@ -7975,6 +7983,68 @@ var DeeplineClient = class {
7975
7983
  );
7976
7984
  }
7977
7985
  // ——————————————————————————————————————————————————————————
7986
+ // Monitor Jobs, Batches, and Fleets
7987
+ // ——————————————————————————————————————————————————————————
7988
+ monitorJobIdempotencyKey(operation) {
7989
+ const uuid = globalThis.crypto?.randomUUID?.();
7990
+ return `monitor-job-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
7991
+ }
7992
+ monitorJobHeaders(operation, idempotencyKey) {
7993
+ return {
7994
+ "Idempotency-Key": idempotencyKey?.trim() || this.monitorJobIdempotencyKey(operation)
7995
+ };
7996
+ }
7997
+ async deployMonitorBatch(definitions, options) {
7998
+ return this.http.request(
7999
+ "/api/v2/monitors/batch/deploy",
8000
+ {
8001
+ method: "POST",
8002
+ body: { version: 1, kind: "batch", monitors: definitions },
8003
+ headers: this.monitorJobHeaders(
8004
+ "batch-deploy",
8005
+ options?.idempotencyKey
8006
+ ),
8007
+ maxRetries: 0,
8008
+ exactUrlOnly: true
8009
+ }
8010
+ );
8011
+ }
8012
+ async getMonitorJob(jobId) {
8013
+ return this.http.request(
8014
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}`,
8015
+ { method: "GET" }
8016
+ );
8017
+ }
8018
+ async getMonitorJobLogs(jobId, options) {
8019
+ const query = options?.limit === void 0 ? "" : `?limit=${encodeURIComponent(String(options.limit))}`;
8020
+ return this.http.request(
8021
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/logs${query}`,
8022
+ { method: "GET" }
8023
+ );
8024
+ }
8025
+ async cancelMonitorJob(jobId) {
8026
+ return this.http.request(
8027
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/cancel`,
8028
+ { method: "POST", body: {}, maxRetries: 0, exactUrlOnly: true }
8029
+ );
8030
+ }
8031
+ async waitForMonitorJob(jobId, options) {
8032
+ const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
8033
+ const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
8034
+ const terminal = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
8035
+ const startedAt = Date.now();
8036
+ let latest = await this.getMonitorJob(jobId);
8037
+ while (true) {
8038
+ options?.onProgress?.(latest);
8039
+ const job = latest.job;
8040
+ const state = typeof job?.state === "string" ? job.state : void 0;
8041
+ if (state && terminal.has(state)) return latest;
8042
+ if (Date.now() - startedAt >= timeoutMs) return latest;
8043
+ await sleep2(pollIntervalMs);
8044
+ latest = await this.getMonitorJob(jobId);
8045
+ }
8046
+ }
8047
+ // ——————————————————————————————————————————————————————————
7978
8048
  // Monitor Fleets
7979
8049
  // ——————————————————————————————————————————————————————————
7980
8050
  monitorFleetIdempotencyKey(operation) {
@@ -8746,30 +8816,30 @@ function flattenObjectColumns(row, options = {}) {
8746
8816
  continue;
8747
8817
  }
8748
8818
  if (value && typeof value === "object" && !Array.isArray(value)) {
8749
- const record2 = value;
8819
+ const record3 = value;
8750
8820
  if (options.objectColumns === "json") {
8751
- flattened[key] = csvSafeJsonString(record2);
8821
+ flattened[key] = csvSafeJsonString(record3);
8752
8822
  continue;
8753
8823
  }
8754
- const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record2, "matched_result") || Object.prototype.hasOwnProperty.call(record2, "matchedResult");
8824
+ const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record3, "matched_result") || Object.prototype.hasOwnProperty.call(record3, "matchedResult");
8755
8825
  if (hasMatchedEnvelope) {
8756
- flattened[key] = csvSafeJsonString(record2);
8826
+ flattened[key] = csvSafeJsonString(record3);
8757
8827
  continue;
8758
8828
  }
8759
8829
  if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
8760
8830
  flattened[key] = rawValue;
8761
8831
  continue;
8762
8832
  } else {
8763
- const failureMessage = failureMessageFromRecord(record2);
8833
+ const failureMessage = failureMessageFromRecord(record3);
8764
8834
  if (failureMessage) {
8765
8835
  flattened[key] = failureMessage;
8766
8836
  continue;
8767
- } else if (Object.prototype.hasOwnProperty.call(record2, "result")) {
8768
- flattened[key] = csvSafeJsonString(record2);
8837
+ } else if (Object.prototype.hasOwnProperty.call(record3, "result")) {
8838
+ flattened[key] = csvSafeJsonString(record3);
8769
8839
  continue;
8770
8840
  }
8771
8841
  }
8772
- for (const [nestedKey, nestedValue] of Object.entries(record2)) {
8842
+ for (const [nestedKey, nestedValue] of Object.entries(record3)) {
8773
8843
  flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
8774
8844
  }
8775
8845
  continue;
@@ -11436,9 +11506,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
11436
11506
  }
11437
11507
  if (ancestors.has(value)) return value;
11438
11508
  ancestors.add(value);
11439
- const record2 = value;
11509
+ const record3 = value;
11440
11510
  const normalized = Object.fromEntries(
11441
- Object.keys(record2).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record2[key], ancestors)])
11511
+ Object.keys(record3).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record3[key], ancestors)])
11442
11512
  );
11443
11513
  ancestors.delete(value);
11444
11514
  return normalized;
@@ -12635,16 +12705,16 @@ function collectErrorText(value) {
12635
12705
  if (!value || typeof value !== "object" || Array.isArray(value)) {
12636
12706
  return errorMessage(value);
12637
12707
  }
12638
- const record2 = value;
12708
+ const record3 = value;
12639
12709
  return [
12640
12710
  errorMessage(value),
12641
- typeof record2.error === "string" ? record2.error : "",
12642
- typeof record2.message === "string" ? record2.message : "",
12643
- typeof record2.detail === "string" ? record2.detail : "",
12644
- typeof record2.hint === "string" ? record2.hint : "",
12645
- typeof record2.code === "string" ? record2.code : "",
12646
- record2.response ? collectErrorText(record2.response) : "",
12647
- record2.details ? collectErrorText(record2.details) : ""
12711
+ typeof record3.error === "string" ? record3.error : "",
12712
+ typeof record3.message === "string" ? record3.message : "",
12713
+ typeof record3.detail === "string" ? record3.detail : "",
12714
+ typeof record3.hint === "string" ? record3.hint : "",
12715
+ typeof record3.code === "string" ? record3.code : "",
12716
+ record3.response ? collectErrorText(record3.response) : "",
12717
+ record3.details ? collectErrorText(record3.details) : ""
12648
12718
  ].filter(Boolean).join("\n");
12649
12719
  }
12650
12720
  function formatDbQueryError(sql, error) {
@@ -13658,8 +13728,8 @@ function getterNamesFromTool(tool, kind) {
13658
13728
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
13659
13729
  }
13660
13730
  function targetGettersFromTool(tool) {
13661
- const record2 = isRecord9(tool) ? tool : {};
13662
- const raw = record2.targetGetters ?? record2.target_getters;
13731
+ const record3 = isRecord9(tool) ? tool : {};
13732
+ const raw = record3.targetGetters ?? record3.target_getters;
13663
13733
  if (!isRecord9(raw)) return {};
13664
13734
  const entries = [];
13665
13735
  for (const [target, value] of Object.entries(raw)) {
@@ -17755,13 +17825,13 @@ function validateFixtureBehavior(value) {
17755
17825
  if (!value || typeof value !== "object" || Array.isArray(value)) {
17756
17826
  return { ok: false, error: "fixtureBehavior must be a JSON object." };
17757
17827
  }
17758
- const record2 = value;
17759
- const supportedKeys = record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
17828
+ const record3 = value;
17829
+ const supportedKeys = record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
17760
17830
  "version",
17761
17831
  "responseSamples",
17762
- ...record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
17832
+ ...record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
17763
17833
  ]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
17764
- const unknownKeys = Object.keys(record2).filter(
17834
+ const unknownKeys = Object.keys(record3).filter(
17765
17835
  (key) => !supportedKeys.has(key)
17766
17836
  );
17767
17837
  if (unknownKeys.length > 0) {
@@ -17770,22 +17840,22 @@ function validateFixtureBehavior(value) {
17770
17840
  error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
17771
17841
  };
17772
17842
  }
17773
- if (record2.version !== FIXTURE_BEHAVIOR_VERSION && record2.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record2.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17843
+ if (record3.version !== FIXTURE_BEHAVIOR_VERSION && record3.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record3.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17774
17844
  return {
17775
17845
  ok: false,
17776
17846
  error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
17777
17847
  };
17778
17848
  }
17779
- if (record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17780
- if (!Array.isArray(record2.responseSamples) || record2.responseSamples.length === 0 || record2.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
17849
+ if (record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17850
+ if (!Array.isArray(record3.responseSamples) || record3.responseSamples.length === 0 || record3.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
17781
17851
  return {
17782
17852
  ok: false,
17783
17853
  error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
17784
17854
  };
17785
17855
  }
17786
17856
  const samples2 = [];
17787
- for (let index = 0; index < record2.responseSamples.length; index += 1) {
17788
- const value2 = record2.responseSamples[index];
17857
+ for (let index = 0; index < record3.responseSamples.length; index += 1) {
17858
+ const value2 = record3.responseSamples[index];
17789
17859
  if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
17790
17860
  return {
17791
17861
  ok: false,
@@ -17884,14 +17954,14 @@ function validateFixtureBehavior(value) {
17884
17954
  });
17885
17955
  }
17886
17956
  let replayBundle;
17887
- if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17888
- if (!record2.replayBundle || typeof record2.replayBundle !== "object" || Array.isArray(record2.replayBundle)) {
17957
+ if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17958
+ if (!record3.replayBundle || typeof record3.replayBundle !== "object" || Array.isArray(record3.replayBundle)) {
17889
17959
  return {
17890
17960
  ok: false,
17891
17961
  error: "fixtureBehavior.replayBundle must be an object."
17892
17962
  };
17893
17963
  }
17894
- const replay = record2.replayBundle;
17964
+ const replay = record3.replayBundle;
17895
17965
  const replayUnknownKeys = Object.keys(replay).filter(
17896
17966
  (key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
17897
17967
  );
@@ -17939,7 +18009,7 @@ function validateFixtureBehavior(value) {
17939
18009
  ...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
17940
18010
  };
17941
18011
  }
17942
- if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
18012
+ if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17943
18013
  return {
17944
18014
  ok: true,
17945
18015
  behavior: {
@@ -17957,15 +18027,15 @@ function validateFixtureBehavior(value) {
17957
18027
  }
17958
18028
  };
17959
18029
  }
17960
- if (!Array.isArray(record2.responseDelaySamplesMs) || record2.responseDelaySamplesMs.length === 0 || record2.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
18030
+ if (!Array.isArray(record3.responseDelaySamplesMs) || record3.responseDelaySamplesMs.length === 0 || record3.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
17961
18031
  return {
17962
18032
  ok: false,
17963
18033
  error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
17964
18034
  };
17965
18035
  }
17966
18036
  const samples = [];
17967
- for (let index = 0; index < record2.responseDelaySamplesMs.length; index += 1) {
17968
- const value2 = record2.responseDelaySamplesMs[index];
18037
+ for (let index = 0; index < record3.responseDelaySamplesMs.length; index += 1) {
18038
+ const value2 = record3.responseDelaySamplesMs[index];
17969
18039
  if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
17970
18040
  return {
17971
18041
  ok: false,
@@ -18744,8 +18814,8 @@ function looksLikeStagedFileRef(value) {
18744
18814
  if (!value || typeof value !== "object" || Array.isArray(value)) {
18745
18815
  return false;
18746
18816
  }
18747
- const record2 = value;
18748
- return typeof record2.contentHash === "string" || typeof record2.contentBase64 === "string" || typeof record2.logicalPath === "string" && typeof record2.bytes === "number";
18817
+ const record3 = value;
18818
+ return typeof record3.contentHash === "string" || typeof record3.contentBase64 === "string" || typeof record3.logicalPath === "string" && typeof record3.bytes === "number";
18749
18819
  }
18750
18820
  var CSV_DATA_INPUT_KEY = "csv";
18751
18821
  function collectLocalFileInputRefs(value, inputPath, key, out) {
@@ -19258,8 +19328,8 @@ function readLiveRunField(event, field) {
19258
19328
  const records = [payload, payload.progress, run, run?.progress].filter(
19259
19329
  (value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
19260
19330
  );
19261
- for (const record2 of records) {
19262
- if (record2[field] !== void 0) return record2[field];
19331
+ for (const record3 of records) {
19332
+ if (record3[field] !== void 0) return record3[field];
19263
19333
  }
19264
19334
  return void 0;
19265
19335
  }
@@ -19561,8 +19631,8 @@ function getProgressLinesFromLiveEvent(event) {
19561
19631
  if (!state || typeof state !== "object" || Array.isArray(state)) {
19562
19632
  continue;
19563
19633
  }
19564
- const record2 = state;
19565
- const progress = record2.progress && typeof record2.progress === "object" && !Array.isArray(record2.progress) ? record2.progress : null;
19634
+ const record3 = state;
19635
+ const progress = record3.progress && typeof record3.progress === "object" && !Array.isArray(record3.progress) ? record3.progress : null;
19566
19636
  if (!progress) {
19567
19637
  continue;
19568
19638
  }
@@ -19579,7 +19649,7 @@ function getProgressLinesFromLiveEvent(event) {
19579
19649
  completed: progress.completed
19580
19650
  });
19581
19651
  lines.push(
19582
- `progress ${formatProgressLabel(record2.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
19652
+ `progress ${formatProgressLabel(record3.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
19583
19653
  );
19584
19654
  }
19585
19655
  return lines;
@@ -20259,11 +20329,11 @@ function truncateErrorForDisplay(message, runId, maxChars = RUN_ERROR_DISPLAY_MA
20259
20329
  const fullErrorHint = runId ? ` (full error: deepline runs get ${runId} --full)` : " (full error: deepline runs get <runId> --full)";
20260
20330
  return `${wordBoundary}\u2026${fullErrorHint}`;
20261
20331
  }
20262
- function clampJsonPreviewText(json, maxChars) {
20263
- if (json.length <= maxChars) {
20264
- return json;
20332
+ function clampJsonPreviewText(json2, maxChars) {
20333
+ if (json2.length <= maxChars) {
20334
+ return json2;
20265
20335
  }
20266
- const slice = json.slice(0, maxChars);
20336
+ const slice = json2.slice(0, maxChars);
20267
20337
  const lastNewline = slice.lastIndexOf("\n");
20268
20338
  const head = lastNewline > 0 ? slice.slice(0, lastNewline) : slice;
20269
20339
  return `${head}
@@ -20389,12 +20459,12 @@ function defaultResultForEnvelope(value, depth = 0) {
20389
20459
  return output2;
20390
20460
  }
20391
20461
  function formatJsonPreview(value) {
20392
- const json = JSON.stringify(value, null, 2);
20393
- if (!json || json === "{}") {
20462
+ const json2 = JSON.stringify(value, null, 2);
20463
+ if (!json2 || json2 === "{}") {
20394
20464
  return [];
20395
20465
  }
20396
20466
  const MAX_CHARS = 4e3;
20397
- const truncated = clampJsonPreviewText(json, MAX_CHARS);
20467
+ const truncated = clampJsonPreviewText(json2, MAX_CHARS);
20398
20468
  return truncated.split("\n").map((line) => ` ${line}`);
20399
20469
  }
20400
20470
  function formatReturnValue(result) {
@@ -20422,17 +20492,17 @@ function collectDatasetHandleLines(value, path = "result") {
20422
20492
  return [];
20423
20493
  }
20424
20494
  if (isDatasetHandle(value)) {
20425
- const record2 = value;
20426
- const count = typeof record2.count === "number" ? record2.count : typeof record2.rowCount === "number" ? record2.rowCount : null;
20427
- const preview = Array.isArray(record2.preview) ? record2.preview : [];
20495
+ const record3 = value;
20496
+ const count = typeof record3.count === "number" ? record3.count : typeof record3.rowCount === "number" ? record3.rowCount : null;
20497
+ const preview = Array.isArray(record3.preview) ? record3.preview : [];
20428
20498
  const lines2 = [
20429
- ` dataset ${typeof record2.path === "string" ? record2.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
20499
+ ` dataset ${typeof record3.path === "string" ? record3.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
20430
20500
  ];
20431
- if (typeof record2.queryDatasetCommand === "string") {
20432
- lines2.push(` query dataset: ${record2.queryDatasetCommand}`);
20501
+ if (typeof record3.queryDatasetCommand === "string") {
20502
+ lines2.push(` query dataset: ${record3.queryDatasetCommand}`);
20433
20503
  }
20434
- if (typeof record2.slowExportAsCsvCommand === "string") {
20435
- lines2.push(` export CSV: ${record2.slowExportAsCsvCommand}`);
20504
+ if (typeof record3.slowExportAsCsvCommand === "string") {
20505
+ lines2.push(` export CSV: ${record3.slowExportAsCsvCommand}`);
20436
20506
  }
20437
20507
  return lines2;
20438
20508
  }
@@ -20829,8 +20899,8 @@ function withTerminalPlayIdentity(status, playName) {
20829
20899
  if (!playName.trim() || getPlayRunPackage(status)) {
20830
20900
  return status;
20831
20901
  }
20832
- const record2 = status;
20833
- 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"));
20902
+ const record3 = status;
20903
+ 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"));
20834
20904
  if (hasIdentity) {
20835
20905
  return status;
20836
20906
  }
@@ -20943,9 +21013,9 @@ function formatSummaryScalar(value) {
20943
21013
  }
20944
21014
  return null;
20945
21015
  }
20946
- function formatSummaryScalarParts(record2, skipKeys = /* @__PURE__ */ new Set()) {
21016
+ function formatSummaryScalarParts(record3, skipKeys = /* @__PURE__ */ new Set()) {
20947
21017
  const parts = [];
20948
- for (const [key, value] of Object.entries(record2)) {
21018
+ for (const [key, value] of Object.entries(record3)) {
20949
21019
  if (skipKeys.has(key)) {
20950
21020
  continue;
20951
21021
  }
@@ -20972,13 +21042,13 @@ function formatTopValuesPart(value) {
20972
21042
  return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
20973
21043
  }
20974
21044
  function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
20975
- const record2 = readRecord(summary);
20976
- const columnStats = readRecord(record2?.columnStats);
20977
- if (!record2 || !columnStats) {
21045
+ const record3 = readRecord(summary);
21046
+ const columnStats = readRecord(record3?.columnStats);
21047
+ if (!record3 || !columnStats) {
20978
21048
  return [];
20979
21049
  }
20980
21050
  const lines = [];
20981
- const rowCounts = readRecord(record2.rowCounts);
21051
+ const rowCounts = readRecord(record3.rowCounts);
20982
21052
  if (rowCounts) {
20983
21053
  const persisted = readNonNegativeInteger(rowCounts.persisted);
20984
21054
  const succeeded = readNonNegativeInteger(rowCounts.succeeded);
@@ -20994,7 +21064,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
20994
21064
  }
20995
21065
  }
20996
21066
  const parts = formatSummaryScalarParts(
20997
- record2,
21067
+ record3,
20998
21068
  /* @__PURE__ */ new Set(["columnStats", "rowCounts"])
20999
21069
  );
21000
21070
  if (parts.length > 0) {
@@ -21024,35 +21094,35 @@ function actionToCommand(action) {
21024
21094
  if (!action || typeof action !== "object" || Array.isArray(action)) {
21025
21095
  return null;
21026
21096
  }
21027
- const record2 = action;
21028
- if (typeof record2.command === "string" && record2.command.trim()) {
21029
- return record2.command.trim();
21097
+ const record3 = action;
21098
+ if (typeof record3.command === "string" && record3.command.trim()) {
21099
+ return record3.command.trim();
21030
21100
  }
21031
- if (record2.kind === "deepline_run_inspect" && typeof record2.runId === "string") {
21032
- return `deepline runs get ${record2.runId} --json`;
21101
+ if (record3.kind === "deepline_run_inspect" && typeof record3.runId === "string") {
21102
+ return `deepline runs get ${record3.runId} --json`;
21033
21103
  }
21034
- if (record2.kind === "deepline_run_full" && typeof record2.runId === "string") {
21035
- return `deepline runs get ${record2.runId} --full --json`;
21104
+ if (record3.kind === "deepline_run_full" && typeof record3.runId === "string") {
21105
+ return `deepline runs get ${record3.runId} --full --json`;
21036
21106
  }
21037
- if (record2.kind === "deepline_run_billing" && typeof record2.runId === "string") {
21038
- return `deepline runs get ${record2.runId} --full --json | jq '.billing'`;
21107
+ if (record3.kind === "deepline_run_billing" && typeof record3.runId === "string") {
21108
+ return `deepline runs get ${record3.runId} --full --json | jq '.billing'`;
21039
21109
  }
21040
- if (record2.kind === "deepline_run_export" && typeof record2.runId === "string" && typeof record2.datasetPath === "string") {
21041
- return `deepline runs export ${record2.runId} --dataset ${shellSingleQuote(
21042
- record2.datasetPath
21043
- )} --out ${shellSingleQuote(`${record2.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
21110
+ if (record3.kind === "deepline_run_export" && typeof record3.runId === "string" && typeof record3.datasetPath === "string") {
21111
+ return `deepline runs export ${record3.runId} --dataset ${shellSingleQuote(
21112
+ record3.datasetPath
21113
+ )} --out ${shellSingleQuote(`${record3.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
21044
21114
  }
21045
- if (record2.kind === "deepline_run_logs") {
21046
- if (typeof record2.command === "string" && record2.command.trim()) {
21047
- return record2.command;
21115
+ if (record3.kind === "deepline_run_logs") {
21116
+ if (typeof record3.command === "string" && record3.command.trim()) {
21117
+ return record3.command;
21048
21118
  }
21049
- if (typeof record2.runId === "string") {
21050
- return record2.view === "failed" ? `deepline runs get ${record2.runId} --log-failed --json` : `deepline runs logs ${record2.runId} --json`;
21119
+ if (typeof record3.runId === "string") {
21120
+ return record3.view === "failed" ? `deepline runs get ${record3.runId} --log-failed --json` : `deepline runs logs ${record3.runId} --json`;
21051
21121
  }
21052
21122
  }
21053
- if (record2.kind === "deepline_db_query" && typeof record2.sql === "string") {
21054
- const maxRows = typeof record2.maxRows === "number" && Number.isFinite(record2.maxRows) ? Math.trunc(record2.maxRows) : 20;
21055
- return `deepline db query --sql ${shellSingleQuote(record2.sql)} --max-rows ${maxRows} --json`;
21123
+ if (record3.kind === "deepline_db_query" && typeof record3.sql === "string") {
21124
+ const maxRows = typeof record3.maxRows === "number" && Number.isFinite(record3.maxRows) ? Math.trunc(record3.maxRows) : 20;
21125
+ return `deepline db query --sql ${shellSingleQuote(record3.sql)} --max-rows ${maxRows} --json`;
21056
21126
  }
21057
21127
  return null;
21058
21128
  }
@@ -21127,8 +21197,8 @@ function formatPackageDatasetActionLines(packaged) {
21127
21197
  }
21128
21198
  function formatInlinePackageValue(value) {
21129
21199
  const compacted = compactReturnValue(value);
21130
- const json = JSON.stringify(compacted);
21131
- return clampJsonPreviewText(json ?? String(compacted), 500);
21200
+ const json2 = JSON.stringify(compacted);
21201
+ return clampJsonPreviewText(json2 ?? String(compacted), 500);
21132
21202
  }
21133
21203
  function formatPackageValueOutputLines(packaged) {
21134
21204
  const outputs = packaged.outputs && typeof packaged.outputs === "object" && !Array.isArray(packaged.outputs) ? packaged.outputs : null;
@@ -21461,12 +21531,12 @@ function exportableSheetRow(row) {
21461
21531
  if (!row || typeof row !== "object" || Array.isArray(row)) {
21462
21532
  return null;
21463
21533
  }
21464
- const record2 = row;
21465
- const data = record2.data;
21534
+ const record3 = row;
21535
+ const data = record3.data;
21466
21536
  if (data && typeof data === "object" && !Array.isArray(data)) {
21467
21537
  return data;
21468
21538
  }
21469
- const fallback = { ...record2 };
21539
+ const fallback = { ...record3 };
21470
21540
  for (const key of [
21471
21541
  "key",
21472
21542
  "status",
@@ -21485,7 +21555,7 @@ function exportableSheetRow(row) {
21485
21555
  return fallback;
21486
21556
  }
21487
21557
  function acceptsSettledRowsAsCompleteExport(status) {
21488
- return status.status === "failed" || status.status === "cancelled";
21558
+ return status.status === "completed" || status.status === "failed" || status.status === "cancelled";
21489
21559
  }
21490
21560
  function mergeExportColumns(preferredColumns, rows) {
21491
21561
  const columns = [];
@@ -21814,8 +21884,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
21814
21884
  "ctx.map(...) has been replaced by ctx.dataset(...)",
21815
21885
  "Dataset .step(...) has been replaced by .withColumn(...)"
21816
21886
  ];
21817
- function stringArrayField(record2, key) {
21818
- const value = record2[key];
21887
+ function stringArrayField(record3, key) {
21888
+ const value = record3[key];
21819
21889
  if (!Array.isArray(value)) return [];
21820
21890
  return value.filter((entry) => typeof entry === "string");
21821
21891
  }
@@ -22646,8 +22716,8 @@ function cronExecutionLabel(status) {
22646
22716
  return status;
22647
22717
  }
22648
22718
  function readLiveCronMetadata(play) {
22649
- const record2 = readRecord(play);
22650
- const metadata = readRecord(record2?.triggerMetadata);
22719
+ const record3 = readRecord(play);
22720
+ const metadata = readRecord(record3?.triggerMetadata);
22651
22721
  return {
22652
22722
  schedule: typeof metadata?.cronSchedule === "string" ? metadata.cronSchedule : null,
22653
22723
  timezone: typeof metadata?.cronTimezone === "string" ? metadata.cronTimezone : null,
@@ -27978,9 +28048,9 @@ async function expandCompiledConfigAtFiles(value) {
27978
28048
  if (!value || typeof value !== "object") {
27979
28049
  return value;
27980
28050
  }
27981
- const record2 = value;
28051
+ const record3 = value;
27982
28052
  const expanded = {};
27983
- for (const [key, entry] of Object.entries(record2)) {
28053
+ for (const [key, entry] of Object.entries(record3)) {
27984
28054
  expanded[key] = await expandCompiledConfigAtFiles(entry);
27985
28055
  }
27986
28056
  for (const field of ["extract_js", "run_if_js"]) {
@@ -28778,26 +28848,26 @@ function readFirstEnrichDatasetActions(value) {
28778
28848
  }
28779
28849
  return null;
28780
28850
  }
28781
- const record2 = candidate;
28782
- const actions = isRecord11(record2.actions) ? record2.actions : null;
28851
+ const record3 = candidate;
28852
+ const actions = isRecord11(record3.actions) ? record3.actions : null;
28783
28853
  const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
28784
28854
  const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
28785
28855
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
28786
28856
  if (query?.kind === "deepline_db_query") {
28787
28857
  return {
28788
- dataset: record2,
28858
+ dataset: record3,
28789
28859
  query,
28790
28860
  ...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
28791
28861
  };
28792
28862
  }
28793
- if (options.allowLegacy && record2.kind === "dataset" && typeof record2.queryDatasetCommand === "string" && record2.queryDatasetCommand.trim()) {
28863
+ if (options.allowLegacy && record3.kind === "dataset" && typeof record3.queryDatasetCommand === "string" && record3.queryDatasetCommand.trim()) {
28794
28864
  return {
28795
- dataset: record2,
28796
- queryDatasetCommand: record2.queryDatasetCommand.trim(),
28797
- ...typeof record2.slowExportAsCsvCommand === "string" && record2.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record2.slowExportAsCsvCommand.trim() } : {}
28865
+ dataset: record3,
28866
+ queryDatasetCommand: record3.queryDatasetCommand.trim(),
28867
+ ...typeof record3.slowExportAsCsvCommand === "string" && record3.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record3.slowExportAsCsvCommand.trim() } : {}
28798
28868
  };
28799
28869
  }
28800
- for (const [key, entry] of Object.entries(record2)) {
28870
+ for (const [key, entry] of Object.entries(record3)) {
28801
28871
  if (key === "preview") {
28802
28872
  continue;
28803
28873
  }
@@ -28813,8 +28883,8 @@ function readFirstEnrichDatasetActions(value) {
28813
28883
  seen.clear();
28814
28884
  return walk(value, { allowLegacy: true });
28815
28885
  }
28816
- function actionStringField(record2, key) {
28817
- const value = record2[key];
28886
+ function actionStringField(record3, key) {
28887
+ const value = record3[key];
28818
28888
  return typeof value === "string" && value.trim() ? value.trim() : null;
28819
28889
  }
28820
28890
  function parseSqlFromDbQueryCommand(command) {
@@ -29158,12 +29228,12 @@ function collectStringFields(value, key, output2, depth = 0) {
29158
29228
  }
29159
29229
  return;
29160
29230
  }
29161
- const record2 = value;
29162
- const direct = record2[key];
29231
+ const record3 = value;
29232
+ const direct = record3[key];
29163
29233
  if (typeof direct === "string" && direct.trim()) {
29164
29234
  output2.add(direct.trim());
29165
29235
  }
29166
- for (const child of Object.values(record2)) {
29236
+ for (const child of Object.values(record3)) {
29167
29237
  collectStringFields(child, key, output2, depth + 1);
29168
29238
  }
29169
29239
  }
@@ -29349,23 +29419,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
29349
29419
  if (!row || typeof row !== "object" || Array.isArray(row)) {
29350
29420
  return null;
29351
29421
  }
29352
- const record2 = row;
29353
- const data = record2.data;
29422
+ const record3 = row;
29423
+ const data = record3.data;
29354
29424
  if (data && typeof data === "object" && !Array.isArray(data)) {
29355
29425
  const exported = { ...data };
29356
29426
  applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
29357
- rowError: record2.error
29427
+ rowError: record3.error
29358
29428
  });
29359
- applyFailureCellMeta(exported, record2.cellMeta, { rowError: record2.error });
29360
- applyFailureCellMeta(exported, record2.cellMetaPatch, {
29361
- rowError: record2.error
29429
+ applyFailureCellMeta(exported, record3.cellMeta, { rowError: record3.error });
29430
+ applyFailureCellMeta(exported, record3.cellMetaPatch, {
29431
+ rowError: record3.error
29362
29432
  });
29363
- applyFailureCellMeta(exported, record2[ENRICH_CELL_META_PATCH_FIELD], {
29364
- rowError: record2.error
29433
+ applyFailureCellMeta(exported, record3[ENRICH_CELL_META_PATCH_FIELD], {
29434
+ rowError: record3.error
29365
29435
  });
29366
29436
  delete exported[ENRICH_CELL_META_FIELD];
29367
29437
  delete exported[ENRICH_CELL_META_PATCH_FIELD];
29368
- const inputIndex = typeof record2.inputIndex === "number" ? record2.inputIndex : typeof record2.inputIndex === "string" && record2.inputIndex.trim() ? Number(record2.inputIndex) : Number.NaN;
29438
+ const inputIndex = typeof record3.inputIndex === "number" ? record3.inputIndex : typeof record3.inputIndex === "string" && record3.inputIndex.trim() ? Number(record3.inputIndex) : Number.NaN;
29369
29439
  if (Number.isInteger(inputIndex) && inputIndex >= 0) {
29370
29440
  if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
29371
29441
  exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
@@ -29374,18 +29444,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
29374
29444
  }
29375
29445
  return exported;
29376
29446
  }
29377
- const fallback = { ...record2 };
29447
+ const fallback = { ...record3 };
29378
29448
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
29379
- rowError: record2.error
29449
+ rowError: record3.error
29380
29450
  });
29381
- applyFailureCellMeta(fallback, record2.cellMeta, {
29382
- rowError: record2.error
29451
+ applyFailureCellMeta(fallback, record3.cellMeta, {
29452
+ rowError: record3.error
29383
29453
  });
29384
- applyFailureCellMeta(fallback, record2.cellMetaPatch, {
29385
- rowError: record2.error
29454
+ applyFailureCellMeta(fallback, record3.cellMetaPatch, {
29455
+ rowError: record3.error
29386
29456
  });
29387
29457
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
29388
- rowError: record2.error
29458
+ rowError: record3.error
29389
29459
  });
29390
29460
  for (const key of [
29391
29461
  "key",
@@ -29604,16 +29674,16 @@ function isWaterfallResultMeaningful(value) {
29604
29674
  return value.some(isWaterfallResultMeaningful);
29605
29675
  }
29606
29676
  if (value && typeof value === "object") {
29607
- const record2 = value;
29608
- const status = typeof record2.status === "string" ? record2.status.trim().toLowerCase() : "";
29677
+ const record3 = value;
29678
+ const status = typeof record3.status === "string" ? record3.status.trim().toLowerCase() : "";
29609
29679
  if (status === "error" || status === "failed") {
29610
29680
  return false;
29611
29681
  }
29612
- if (typeof record2.error === "string" && record2.error.trim()) {
29682
+ if (typeof record3.error === "string" && record3.error.trim()) {
29613
29683
  return false;
29614
29684
  }
29615
- if (Object.prototype.hasOwnProperty.call(record2, "matched_result")) {
29616
- return isWaterfallResultMeaningful(record2.matched_result);
29685
+ if (Object.prototype.hasOwnProperty.call(record3, "matched_result")) {
29686
+ return isWaterfallResultMeaningful(record3.matched_result);
29617
29687
  }
29618
29688
  for (const key of [
29619
29689
  "value",
@@ -29628,11 +29698,11 @@ function isWaterfallResultMeaningful(value) {
29628
29698
  "result",
29629
29699
  "data"
29630
29700
  ]) {
29631
- if (isWaterfallResultMeaningful(record2[key])) {
29701
+ if (isWaterfallResultMeaningful(record3[key])) {
29632
29702
  return true;
29633
29703
  }
29634
29704
  }
29635
- return Object.entries(record2).some(
29705
+ return Object.entries(record3).some(
29636
29706
  ([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
29637
29707
  );
29638
29708
  }
@@ -29648,8 +29718,8 @@ function stableRowSnapshot(value) {
29648
29718
  return `[${value.map(stableRowSnapshot).join(",")}]`;
29649
29719
  }
29650
29720
  if (value && typeof value === "object") {
29651
- const record2 = value;
29652
- return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record2[key])}`).join(",")}}`;
29721
+ const record3 = value;
29722
+ return `{${Object.keys(record3).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record3[key])}`).join(",")}}`;
29653
29723
  }
29654
29724
  return JSON.stringify(value);
29655
29725
  }
@@ -30236,8 +30306,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
30236
30306
  seen.add(normalized);
30237
30307
  commands.push({ ...command, command: normalized });
30238
30308
  }
30239
- function datasetSelectorForEnrichCommand(record2, fallbackPath) {
30240
- const candidates = [record2.path, record2.tableNamespace, fallbackPath];
30309
+ function datasetSelectorForEnrichCommand(record3, fallbackPath) {
30310
+ const candidates = [record3.path, record3.tableNamespace, fallbackPath];
30241
30311
  for (const candidate of candidates) {
30242
30312
  if (typeof candidate === "string" && candidate.trim()) {
30243
30313
  return candidate.trim();
@@ -30299,19 +30369,19 @@ function collectDatasetFollowUpCommands(value, state) {
30299
30369
  );
30300
30370
  return;
30301
30371
  }
30302
- const record2 = value;
30303
- const isDataset = record2.kind === "dataset";
30372
+ const record3 = value;
30373
+ const isDataset = record3.kind === "dataset";
30304
30374
  if (isDataset) {
30305
- const selector = datasetSelectorForEnrichCommand(record2, state.path);
30306
- const labelPath = typeof record2.path === "string" && record2.path.trim() ? record2.path.trim() : selector ?? state.path;
30307
- if (typeof record2.queryDatasetCommand === "string") {
30375
+ const selector = datasetSelectorForEnrichCommand(record3, state.path);
30376
+ const labelPath = typeof record3.path === "string" && record3.path.trim() ? record3.path.trim() : selector ?? state.path;
30377
+ if (typeof record3.queryDatasetCommand === "string") {
30308
30378
  addEnrichFollowUpCommand(state.commands, state.seen, {
30309
30379
  label: `query ${labelPath}`,
30310
30380
  path: labelPath,
30311
- command: record2.queryDatasetCommand
30381
+ command: record3.queryDatasetCommand
30312
30382
  });
30313
30383
  }
30314
- const exportCommand = typeof record2.slowExportAsCsvCommand === "string" ? record2.slowExportAsCsvCommand : typeof record2.fullExportCommand === "string" ? record2.fullExportCommand : null;
30384
+ const exportCommand = typeof record3.slowExportAsCsvCommand === "string" ? record3.slowExportAsCsvCommand : typeof record3.fullExportCommand === "string" ? record3.fullExportCommand : null;
30315
30385
  if (exportCommand) {
30316
30386
  addEnrichFollowUpCommand(state.commands, state.seen, {
30317
30387
  label: `export ${labelPath}`,
@@ -30328,7 +30398,7 @@ function collectDatasetFollowUpCommands(value, state) {
30328
30398
  });
30329
30399
  }
30330
30400
  }
30331
- for (const [key, child] of Object.entries(record2)) {
30401
+ for (const [key, child] of Object.entries(record3)) {
30332
30402
  if (key === "preview" || key === "access") {
30333
30403
  continue;
30334
30404
  }
@@ -31795,9 +31865,9 @@ function readCodexSessionId(filePath) {
31795
31865
  )) {
31796
31866
  const parsed = parseJsonLine(line);
31797
31867
  if (!parsed || typeof parsed !== "object") continue;
31798
- const record2 = parsed;
31799
- const payload = record2.payload && typeof record2.payload === "object" ? record2.payload : null;
31800
- const id = record2.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
31868
+ const record3 = parsed;
31869
+ const payload = record3.payload && typeof record3.payload === "object" ? record3.payload : null;
31870
+ const id = record3.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
31801
31871
  if (id && UUID_RE.test(id)) return id;
31802
31872
  }
31803
31873
  } catch {
@@ -31896,15 +31966,15 @@ function messageContentKey(value) {
31896
31966
  if (!Array.isArray(content)) return null;
31897
31967
  return content.map((block) => {
31898
31968
  if (!block || typeof block !== "object") return String(block);
31899
- const record2 = block;
31900
- const type = String(record2.type ?? "");
31969
+ const record3 = block;
31970
+ const type = String(record3.type ?? "");
31901
31971
  if (type === "tool_use") {
31902
- return `tool_use:${String(record2.name ?? "")}:${String(record2.id ?? "")}`;
31972
+ return `tool_use:${String(record3.name ?? "")}:${String(record3.id ?? "")}`;
31903
31973
  }
31904
31974
  if (type === "tool_result") {
31905
- return `tool_result:${String(record2.tool_use_id ?? "")}`;
31975
+ return `tool_result:${String(record3.tool_use_id ?? "")}`;
31906
31976
  }
31907
- return String(record2.text ?? type);
31977
+ return String(record3.text ?? type);
31908
31978
  }).join("\n");
31909
31979
  }
31910
31980
  function dedupConsecutiveEvents(raw) {
@@ -31919,9 +31989,9 @@ function dedupConsecutiveEvents(raw) {
31919
31989
  index += 1;
31920
31990
  continue;
31921
31991
  }
31922
- const record2 = event;
31923
- const eventType = String(record2.type ?? "");
31924
- const eventKey = messageContentKey(record2);
31992
+ const record3 = event;
31993
+ const eventType = String(record3.type ?? "");
31994
+ const eventKey = messageContentKey(record3);
31925
31995
  if (!["user", "assistant"].includes(eventType) || !eventKey) {
31926
31996
  output2.push(rawLines[index] ?? "");
31927
31997
  index += 1;
@@ -31940,9 +32010,9 @@ function dedupConsecutiveEvents(raw) {
31940
32010
  cursor += 1;
31941
32011
  }
31942
32012
  if (runCount > 1) {
31943
- record2._repeat_count = runCount;
31944
- record2._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
31945
- output2.push(JSON.stringify(record2));
32013
+ record3._repeat_count = runCount;
32014
+ record3._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
32015
+ output2.push(JSON.stringify(record3));
31946
32016
  index = cursor;
31947
32017
  continue;
31948
32018
  }
@@ -31987,9 +32057,9 @@ function selectiveCompactToolResults(raw) {
31987
32057
  lines.push(line);
31988
32058
  continue;
31989
32059
  }
31990
- const record2 = parsed;
31991
- if (record2.type === "user") {
31992
- const message = record2.message;
32060
+ const record3 = parsed;
32061
+ if (record3.type === "user") {
32062
+ const message = record3.message;
31993
32063
  const content = message && typeof message === "object" ? message.content : null;
31994
32064
  if (Array.isArray(content)) {
31995
32065
  message.content = content.map(
@@ -31997,7 +32067,7 @@ function selectiveCompactToolResults(raw) {
31997
32067
  );
31998
32068
  }
31999
32069
  }
32000
- lines.push(JSON.stringify(record2));
32070
+ lines.push(JSON.stringify(record3));
32001
32071
  }
32002
32072
  return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
32003
32073
  ` : "", "utf8");
@@ -32023,15 +32093,15 @@ function compactCodexEvents(raw) {
32023
32093
  lines.push(rawLines[index] ?? "");
32024
32094
  return;
32025
32095
  }
32026
- const record2 = event;
32027
- if (record2.type === "world_state") return;
32028
- const payload = record2.payload;
32096
+ const record3 = event;
32097
+ if (record3.type === "world_state") return;
32098
+ const payload = record3.payload;
32029
32099
  const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
32030
32100
  if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
32031
32101
  if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
32032
32102
  const record_payload = payload;
32033
32103
  record_payload.output = compactEventValue(record_payload.output);
32034
- lines.push(JSON.stringify(record2));
32104
+ lines.push(JSON.stringify(record3));
32035
32105
  return;
32036
32106
  }
32037
32107
  lines.push(rawLines[index] ?? "");
@@ -32237,8 +32307,8 @@ function parsePreparedEvents(buffer) {
32237
32307
  return parsed ?? line;
32238
32308
  });
32239
32309
  }
32240
- function escapeJsonForHtmlScript(json) {
32241
- return json.replace(/</g, "\\u003c");
32310
+ function escapeJsonForHtmlScript(json2) {
32311
+ return json2.replace(/</g, "\\u003c");
32242
32312
  }
32243
32313
  async function handleSessionsRender(options) {
32244
32314
  const targets = resolveSessionTargets({
@@ -32499,11 +32569,317 @@ var import_node_fs15 = require("fs");
32499
32569
  var import_node_path17 = require("path");
32500
32570
  var import_promises8 = require("readline/promises");
32501
32571
 
32572
+ // ../integration-contracts/monitor-input-contract.ts
32573
+ var import_handlebars = __toESM(require("handlebars"), 1);
32574
+ function authoredMonitorFieldPath(path, field) {
32575
+ const batch = /^monitors\.(\d+)$/.exec(path);
32576
+ return `${batch ? `monitors[${batch[1]}]` : path}.${field}`;
32577
+ }
32578
+ function record(value) {
32579
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
32580
+ }
32581
+ function json(value, path, issues) {
32582
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
32583
+ return;
32584
+ }
32585
+ if (Array.isArray(value)) {
32586
+ value.forEach((child, index) => json(child, `${path}.${index}`, issues));
32587
+ return;
32588
+ }
32589
+ const object = record(value);
32590
+ if (!object) {
32591
+ issues.push({
32592
+ severity: "error",
32593
+ code: "invalid_monitor_json_value",
32594
+ path,
32595
+ message: "Monitor values must be JSON values."
32596
+ });
32597
+ return;
32598
+ }
32599
+ for (const [key, child] of Object.entries(object)) {
32600
+ json(child, `${path}.${key}`, issues);
32601
+ }
32602
+ }
32603
+ function monitorSpec(value, path, issues) {
32604
+ const input2 = record(value);
32605
+ if (!input2) {
32606
+ issues.push({
32607
+ severity: "error",
32608
+ code: "invalid_monitor_spec",
32609
+ path,
32610
+ message: "A monitor must be a JSON object."
32611
+ });
32612
+ return null;
32613
+ }
32614
+ const allowed = /* @__PURE__ */ new Set(["key", "tool", "name", "payload"]);
32615
+ for (const key2 of Object.keys(input2)) {
32616
+ if (!allowed.has(key2)) {
32617
+ if (key2 === "controls") {
32618
+ issues.push({
32619
+ severity: "error",
32620
+ code: "CONTROLS_NOT_SUPPORTED",
32621
+ path: authoredMonitorFieldPath(path, "controls"),
32622
+ message: "Operational controls are managed by Deepline and cannot be authored in Batch or Fleet JSON.",
32623
+ suggestion: "Remove controls. Bind downstream automation in a Play with sqlListeners."
32624
+ });
32625
+ continue;
32626
+ }
32627
+ if (key2 === "play") {
32628
+ issues.push({
32629
+ severity: "error",
32630
+ code: "PLAY_BINDING_NOT_IN_MONITOR_SPEC",
32631
+ path: authoredMonitorFieldPath(path, "play"),
32632
+ message: "A monitor does not own Play bindings.",
32633
+ suggestion: "Declare sqlListeners in the Play, or run: deepline plays bootstrap monitor-triggered --out on-event.play.ts"
32634
+ });
32635
+ continue;
32636
+ }
32637
+ issues.push({
32638
+ severity: "error",
32639
+ code: "unknown_monitor_field",
32640
+ path: `${path}.${key2}`,
32641
+ message: `Monitor definitions do not accept '${key2}'.`
32642
+ });
32643
+ }
32644
+ }
32645
+ const key = typeof input2.key === "string" ? input2.key.trim() : "";
32646
+ const tool = typeof input2.tool === "string" ? input2.tool.trim() : "";
32647
+ const name = input2.name === void 0 ? void 0 : typeof input2.name === "string" && input2.name.trim() ? input2.name.trim() : null;
32648
+ const payload = record(input2.payload);
32649
+ if (!key) {
32650
+ issues.push({
32651
+ severity: "error",
32652
+ code: "invalid_monitor_key",
32653
+ path: `${path}.key`,
32654
+ message: "Monitor key must be a non-empty string."
32655
+ });
32656
+ }
32657
+ if (!tool) {
32658
+ issues.push({
32659
+ severity: "error",
32660
+ code: "invalid_monitor_tool",
32661
+ path: `${path}.tool`,
32662
+ message: "Monitor tool must be a non-empty literal string."
32663
+ });
32664
+ }
32665
+ if (name === null) {
32666
+ issues.push({
32667
+ severity: "error",
32668
+ code: "invalid_monitor_name",
32669
+ path: `${path}.name`,
32670
+ message: "Monitor name must be a non-empty string when supplied."
32671
+ });
32672
+ }
32673
+ if (!payload) {
32674
+ issues.push({
32675
+ severity: "error",
32676
+ code: "invalid_monitor_payload",
32677
+ path: `${path}.payload`,
32678
+ message: "Monitor payload must be an object."
32679
+ });
32680
+ } else {
32681
+ json(payload, `${path}.payload`, issues);
32682
+ }
32683
+ if (!key || !tool || !payload || name === null) {
32684
+ return null;
32685
+ }
32686
+ return {
32687
+ key,
32688
+ tool,
32689
+ ...name ? { name } : {},
32690
+ payload
32691
+ };
32692
+ }
32693
+ function issueOrder(left, right) {
32694
+ return left.path.localeCompare(right.path) || left.severity.localeCompare(right.severity) || left.code.localeCompare(right.code);
32695
+ }
32696
+ function lintMonitorBatchInput(value) {
32697
+ const issues = [];
32698
+ const versionlessEnvelope = !Array.isArray(value) && (() => {
32699
+ const candidate = record(value);
32700
+ return candidate !== null && Object.keys(candidate).length === 1 && Object.prototype.hasOwnProperty.call(candidate, "monitors");
32701
+ })();
32702
+ const legacy = Array.isArray(value) || versionlessEnvelope;
32703
+ const input2 = legacy ? null : record(value);
32704
+ let monitors = Array.isArray(value) ? value : versionlessEnvelope ? (() => {
32705
+ const candidate = record(value)?.monitors;
32706
+ return Array.isArray(candidate) ? candidate : null;
32707
+ })() : null;
32708
+ if (Array.isArray(value)) {
32709
+ issues.push({
32710
+ severity: "warning",
32711
+ code: "deprecated_batch_array",
32712
+ path: "",
32713
+ message: "Bare monitor arrays are supported for compatibility.",
32714
+ suggestion: 'Wrap the list in {"version":1,"kind":"batch","monitors":[...]}.'
32715
+ });
32716
+ } else if (versionlessEnvelope) {
32717
+ issues.push({
32718
+ severity: "warning",
32719
+ code: "deprecated_batch_missing_envelope_fields",
32720
+ path: "",
32721
+ message: "Versionless monitor envelopes are supported for compatibility.",
32722
+ suggestion: 'Add "version": 1 and "kind": "batch".'
32723
+ });
32724
+ if (!monitors) {
32725
+ issues.push({
32726
+ severity: "error",
32727
+ code: "invalid_batch_monitors",
32728
+ path: "monitors",
32729
+ message: "Batch monitors must be an array."
32730
+ });
32731
+ }
32732
+ } else if (!input2) {
32733
+ issues.push({
32734
+ severity: "error",
32735
+ code: "invalid_batch",
32736
+ path: "",
32737
+ message: "Batch input must be an object or a legacy array."
32738
+ });
32739
+ } else {
32740
+ for (const key of Object.keys(input2)) {
32741
+ if (!["version", "kind", "monitors"].includes(key)) {
32742
+ issues.push({
32743
+ severity: "error",
32744
+ code: key === "source" || key === "monitor" ? "batch_fleet_shape_mixup" : "unknown_batch_field",
32745
+ path: key,
32746
+ message: `Batch input does not accept '${key}'.`
32747
+ });
32748
+ }
32749
+ }
32750
+ if (input2.version !== 1) {
32751
+ issues.push({
32752
+ severity: "error",
32753
+ code: "unsupported_batch_version",
32754
+ path: "version",
32755
+ message: "Batch input version must be 1."
32756
+ });
32757
+ }
32758
+ if (input2.kind !== "batch") {
32759
+ issues.push({
32760
+ severity: "error",
32761
+ code: "invalid_batch_kind",
32762
+ path: "kind",
32763
+ message: 'Batch input kind must be "batch".'
32764
+ });
32765
+ }
32766
+ monitors = Array.isArray(input2.monitors) ? input2.monitors : null;
32767
+ if (!monitors) {
32768
+ issues.push({
32769
+ severity: "error",
32770
+ code: "invalid_batch_monitors",
32771
+ path: "monitors",
32772
+ message: "Batch monitors must be an array."
32773
+ });
32774
+ }
32775
+ }
32776
+ if (!monitors || monitors.length === 0) {
32777
+ if (monitors?.length === 0) {
32778
+ issues.push({
32779
+ severity: "error",
32780
+ code: "empty_batch",
32781
+ path: "monitors",
32782
+ message: "A Batch needs at least one monitor."
32783
+ });
32784
+ }
32785
+ return { issues: issues.sort(issueOrder) };
32786
+ }
32787
+ const normalized = monitors.map(
32788
+ (item, index) => monitorSpec(item, `monitors.${index}`, issues)
32789
+ );
32790
+ const seen = /* @__PURE__ */ new Map();
32791
+ normalized.forEach((item, index) => {
32792
+ if (!item) return;
32793
+ const first = seen.get(item.key);
32794
+ if (first !== void 0) {
32795
+ for (const position of [first, index]) {
32796
+ issues.push({
32797
+ severity: "error",
32798
+ code: "duplicate_monitor_key",
32799
+ path: `monitors.${position}.key`,
32800
+ message: `Duplicate monitor key '${item.key}'.`
32801
+ });
32802
+ }
32803
+ } else {
32804
+ seen.set(item.key, index);
32805
+ }
32806
+ });
32807
+ const ordered = issues.sort(issueOrder);
32808
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : {
32809
+ normalized: {
32810
+ version: 1,
32811
+ kind: "batch",
32812
+ monitors: normalized
32813
+ },
32814
+ issues: ordered
32815
+ };
32816
+ }
32817
+ function validateHandlebars(value, path, issues) {
32818
+ if (!value.includes("{{")) return;
32819
+ try {
32820
+ import_handlebars.default.parse(value);
32821
+ } catch (error) {
32822
+ issues.push({
32823
+ severity: "error",
32824
+ code: "invalid_handlebars_template",
32825
+ path,
32826
+ message: error instanceof Error ? error.message : "Invalid Handlebars template."
32827
+ });
32828
+ return;
32829
+ }
32830
+ const expressions = value.match(/{{[\s\S]*?}}/g) ?? [];
32831
+ if (expressions.some(
32832
+ (expression) => !/^{{\s*[A-Za-z_][A-Za-z0-9_]*\s*}}$/.test(expression)
32833
+ )) {
32834
+ issues.push({
32835
+ severity: "error",
32836
+ code: "unsupported_handlebars_expression",
32837
+ path,
32838
+ message: "Fleet templates allow only direct source-row fields such as {{domain}}; helpers, blocks, partials, paths, and prototype access are disabled."
32839
+ });
32840
+ }
32841
+ }
32842
+ function walkTemplates(value, path, issues) {
32843
+ if (typeof value === "string") return validateHandlebars(value, path, issues);
32844
+ if (Array.isArray(value)) {
32845
+ value.forEach(
32846
+ (item, index) => walkTemplates(item, `${path}.${index}`, issues)
32847
+ );
32848
+ return;
32849
+ }
32850
+ const input2 = record(value);
32851
+ if (!input2) return;
32852
+ for (const [key, child] of Object.entries(input2)) {
32853
+ walkTemplates(child, `${path}.${key}`, issues);
32854
+ }
32855
+ }
32856
+ function lintMonitorSpecTemplate(value, path = "monitor") {
32857
+ const issues = [];
32858
+ const normalized = monitorSpec(value, path, issues);
32859
+ const input2 = record(value);
32860
+ if (input2 && typeof input2.tool === "string" && input2.tool.includes("{{")) {
32861
+ issues.push({
32862
+ severity: "error",
32863
+ code: "templated_monitor_tool",
32864
+ path: `${path}.tool`,
32865
+ message: "Fleet monitor tool must be literal; only key, name, and payload may be templated."
32866
+ });
32867
+ }
32868
+ if (input2) {
32869
+ for (const field of ["key", "name", "payload"]) {
32870
+ if (input2[field] !== void 0)
32871
+ walkTemplates(input2[field], `${path}.${field}`, issues);
32872
+ }
32873
+ }
32874
+ const ordered = issues.sort(issueOrder);
32875
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : { normalized, issues: ordered };
32876
+ }
32877
+
32502
32878
  // ../integration-contracts/monitor-fleet-contract.ts
32503
32879
  var MONITOR_FLEET_MAX_MEMBERS = 1e3;
32504
- var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
32505
32880
  var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
32506
- MONITOR_FLEET_AUTHORING_CONTRACT_EDITION
32881
+ 1,
32882
+ 2
32507
32883
  ];
32508
32884
  var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
32509
32885
  var MONITOR_FLEET_DOCUMENTATION = {
@@ -32511,11 +32887,11 @@ var MONITOR_FLEET_DOCUMENTATION = {
32511
32887
  authoredFields: {
32512
32888
  id: "Stable lowercase fleet id used by sync, get, and deactivate.",
32513
32889
  source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
32514
- member: "Ordinary monitor tool, stable key template, and payload evaluated for each selected source row.",
32890
+ monitor: "One Batch-compatible MonitorSpec. Direct Handlebars source-row fields such as {{domain}} are rendered for each selected row.",
32515
32891
  selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
32516
32892
  },
32517
32893
  fixedPolicy: {
32518
- cadence: "daily",
32894
+ cadence: "60s fair bounded source refresh",
32519
32895
  membership: "sticky",
32520
32896
  removalGrace: "7d",
32521
32897
  onRemoved: "deactivate",
@@ -32523,9 +32899,10 @@ var MONITOR_FLEET_DOCUMENTATION = {
32523
32899
  billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
32524
32900
  },
32525
32901
  stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
32526
- columnExpression: 'Use { "$fleet": "column", "name": "column_name" } in a member key or payload to read a value from each source row.'
32902
+ templating: "Use direct Handlebars fields such as {{domain}} in monitor key, name, or payload. Helpers, blocks, partials, paths, and prototype access are disabled.",
32903
+ legacyCompatibility: 'Edition 1 member/$fleet files remain readable with a lint warning; new files should use version: 2, kind: "fleet", and monitor.'
32527
32904
  };
32528
- function record(value) {
32905
+ function record2(value) {
32529
32906
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
32530
32907
  }
32531
32908
  function identifier(value) {
@@ -32550,7 +32927,7 @@ function jsonValue(value, path, issues) {
32550
32927
  value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
32551
32928
  return;
32552
32929
  }
32553
- const input2 = record(value);
32930
+ const input2 = record2(value);
32554
32931
  if (!input2) {
32555
32932
  issues.push({
32556
32933
  path,
@@ -32564,7 +32941,7 @@ function jsonValue(value, path, issues) {
32564
32941
  }
32565
32942
  }
32566
32943
  function validateExpression(value, path, issues) {
32567
- const input2 = record(value);
32944
+ const input2 = record2(value);
32568
32945
  if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
32569
32946
  issues.push({
32570
32947
  path,
@@ -32582,7 +32959,7 @@ function walkPayload(value, path, issues) {
32582
32959
  );
32583
32960
  return;
32584
32961
  }
32585
- const input2 = record(value);
32962
+ const input2 = record2(value);
32586
32963
  if (!input2) return;
32587
32964
  if ("$fleet" in input2) {
32588
32965
  validateExpression(input2, path, issues);
@@ -32592,9 +32969,9 @@ function walkPayload(value, path, issues) {
32592
32969
  walkPayload(item, `${path}.${key}`, issues);
32593
32970
  }
32594
32971
  }
32595
- function validateMonitorFleetDefinition(value) {
32972
+ function validateMonitorFleetDefinitionV1(value) {
32596
32973
  const issues = [];
32597
- const input2 = record(value);
32974
+ const input2 = record2(value);
32598
32975
  if (!input2) {
32599
32976
  return {
32600
32977
  valid: false,
@@ -32615,7 +32992,7 @@ function validateMonitorFleetDefinition(value) {
32615
32992
  message: "Fleet id must be lowercase kebab-case."
32616
32993
  });
32617
32994
  }
32618
- const source = record(input2.source);
32995
+ const source = record2(input2.source);
32619
32996
  exactKeys(
32620
32997
  source,
32621
32998
  ["kind", "schema", "table", "key", "where"],
@@ -32636,7 +33013,7 @@ function validateMonitorFleetDefinition(value) {
32636
33013
  message: "Source schema and table must be SQL identifiers."
32637
33014
  });
32638
33015
  }
32639
- const sourceKey = record(source?.key);
33016
+ const sourceKey = record2(source?.key);
32640
33017
  exactKeys(sourceKey, ["column", "type"], "source.key", issues);
32641
33018
  if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
32642
33019
  issues.push({
@@ -32646,7 +33023,7 @@ function validateMonitorFleetDefinition(value) {
32646
33023
  });
32647
33024
  }
32648
33025
  if (source?.where !== void 0) {
32649
- const where = record(source.where);
33026
+ const where = record2(source.where);
32650
33027
  if (!where) {
32651
33028
  issues.push({
32652
33029
  path: "source.where",
@@ -32672,9 +33049,9 @@ function validateMonitorFleetDefinition(value) {
32672
33049
  }
32673
33050
  }
32674
33051
  }
32675
- const member = record(input2.member);
33052
+ const member = record2(input2.member);
32676
33053
  exactKeys(member, ["tool", "key", "payload"], "member", issues);
32677
- const key = record(member?.key);
33054
+ const key = record2(member?.key);
32678
33055
  if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
32679
33056
  issues.push({
32680
33057
  path: "member.tool",
@@ -32695,7 +33072,7 @@ function validateMonitorFleetDefinition(value) {
32695
33072
  validateExpression(part, `member.key.parts.${index}`, issues);
32696
33073
  }
32697
33074
  if (sourceKey && !key.parts.some(
32698
- (part) => record(part)?.$fleet === "column" && record(part)?.name === sourceKey.column
33075
+ (part) => record2(part)?.$fleet === "column" && record2(part)?.name === sourceKey.column
32699
33076
  )) {
32700
33077
  issues.push({
32701
33078
  path: "member.key.parts",
@@ -32714,7 +33091,7 @@ function validateMonitorFleetDefinition(value) {
32714
33091
  jsonValue(member.payload, "member.payload", issues);
32715
33092
  }
32716
33093
  walkPayload(member?.payload, "member.payload", issues);
32717
- const selection = record(input2.selection);
33094
+ const selection = record2(input2.selection);
32718
33095
  exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
32719
33096
  if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
32720
33097
  issues.push({
@@ -32740,7 +33117,7 @@ function validateMonitorFleetDefinition(value) {
32740
33117
  } else {
32741
33118
  const orderColumns = /* @__PURE__ */ new Set();
32742
33119
  for (const [index, order] of orderBy.entries()) {
32743
- const item = record(order);
33120
+ const item = record2(order);
32744
33121
  exactKeys(
32745
33122
  item,
32746
33123
  ["column", "direction"],
@@ -32763,7 +33140,7 @@ function validateMonitorFleetDefinition(value) {
32763
33140
  orderColumns.add(item.column);
32764
33141
  }
32765
33142
  }
32766
- if (sourceKey && record(orderBy.at(-1))?.column !== sourceKey.column) {
33143
+ if (sourceKey && record2(orderBy.at(-1))?.column !== sourceKey.column) {
32767
33144
  issues.push({
32768
33145
  path: "selection.orderBy",
32769
33146
  code: "fleet_order_missing_key",
@@ -32782,9 +33159,100 @@ function validateMonitorFleetDefinition(value) {
32782
33159
  }
32783
33160
  return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
32784
33161
  }
32785
- function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHORING_CONTRACT_EDITION) {
33162
+ function v2Issue(issue) {
33163
+ return { path: issue.path, code: issue.code, message: issue.message };
33164
+ }
33165
+ function validateMonitorFleetDefinitionV2(value) {
33166
+ const issues = [];
33167
+ const input2 = record2(value);
33168
+ if (!input2) {
33169
+ return {
33170
+ valid: false,
33171
+ issues: [
33172
+ {
33173
+ path: "",
33174
+ code: "invalid_fleet",
33175
+ message: "Fleet must be an object."
33176
+ }
33177
+ ]
33178
+ };
33179
+ }
33180
+ exactKeys(
33181
+ input2,
33182
+ ["version", "kind", "id", "source", "monitor", "selection"],
33183
+ "",
33184
+ issues
33185
+ );
33186
+ if (input2.version !== 2) {
33187
+ issues.push({
33188
+ path: "version",
33189
+ code: "unsupported_fleet_version",
33190
+ message: "Canonical Fleet input version must be 2."
33191
+ });
33192
+ }
33193
+ if (input2.kind !== "fleet") {
33194
+ issues.push({
33195
+ path: "kind",
33196
+ code: "invalid_fleet_kind",
33197
+ message: 'Canonical Fleet input kind must be "fleet".'
33198
+ });
33199
+ }
33200
+ const source = record2(input2.source);
33201
+ const sourceKey = record2(source?.key);
33202
+ const legacyShape = {
33203
+ id: input2.id,
33204
+ source: input2.source,
33205
+ member: {
33206
+ tool: record2(input2.monitor)?.tool,
33207
+ key: {
33208
+ $fleet: "template",
33209
+ parts: [
33210
+ "fleet-",
33211
+ {
33212
+ $fleet: "column",
33213
+ name: typeof sourceKey?.column === "string" ? sourceKey.column : "invalid_source_key"
33214
+ }
33215
+ ]
33216
+ },
33217
+ payload: record2(input2.monitor)?.payload
33218
+ },
33219
+ selection: input2.selection
33220
+ };
33221
+ const legacyCheck = validateMonitorFleetDefinitionV1(legacyShape);
33222
+ for (const issue of legacyCheck.issues) {
33223
+ issues.push({
33224
+ ...issue,
33225
+ path: issue.path.replace(/^member\./, "monitor.")
33226
+ });
33227
+ }
33228
+ const monitorInput = record2(input2.monitor);
33229
+ const monitorKey = monitorInput?.key;
33230
+ const monitor = lintMonitorSpecTemplate(input2.monitor);
33231
+ issues.push(...monitor.issues.map(v2Issue));
33232
+ if (typeof monitorKey === "string" && typeof sourceKey?.column === "string" && !monitorKey.includes(`{{${sourceKey.column}}}`)) {
33233
+ issues.push({
33234
+ path: "monitor.key",
33235
+ code: "fleet_key_missing_source_key",
33236
+ message: "Monitor key must include the source key as a direct Handlebars expression."
33237
+ });
33238
+ }
33239
+ return issues.length === 0 && monitor.normalized ? {
33240
+ valid: true,
33241
+ definition: {
33242
+ version: 2,
33243
+ kind: "fleet",
33244
+ id: String(input2.id),
33245
+ source: input2.source,
33246
+ monitor: monitor.normalized,
33247
+ selection: input2.selection
33248
+ },
33249
+ issues
33250
+ } : { valid: false, issues };
33251
+ }
33252
+ function admitMonitorFleetAuthoringContract(value, edition) {
33253
+ const detectedEdition = edition ?? (record2(value)?.version === 2 || record2(value)?.kind === "fleet" ? 2 : 1);
32786
33254
  if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
32787
- edition
33255
+ detectedEdition
32788
33256
  )) {
32789
33257
  return {
32790
33258
  valid: false,
@@ -32792,16 +33260,16 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
32792
33260
  {
32793
33261
  path: "authoring_contract_edition",
32794
33262
  code: "unsupported_fleet_authoring_contract_edition",
32795
- message: `Monitor Fleet authoring contract edition ${edition} is not supported.`
33263
+ message: `Monitor Fleet authoring contract edition ${detectedEdition} is not supported.`
32796
33264
  }
32797
33265
  ]
32798
33266
  };
32799
33267
  }
32800
- const result = validateMonitorFleetDefinition(value);
33268
+ const result = detectedEdition === 2 ? validateMonitorFleetDefinitionV2(value) : validateMonitorFleetDefinitionV1(value);
32801
33269
  return result.valid && result.definition ? {
32802
33270
  valid: true,
32803
33271
  contract: {
32804
- edition,
33272
+ edition: detectedEdition,
32805
33273
  // JSON cloning prevents later caller mutation from changing the
32806
33274
  // admitted snapshot.
32807
33275
  definition: JSON.parse(
@@ -32811,6 +33279,32 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
32811
33279
  issues: []
32812
33280
  } : { valid: false, issues: result.issues };
32813
33281
  }
33282
+ function lintMonitorFleetInput(value) {
33283
+ const input2 = record2(value);
33284
+ const legacy = input2?.member !== void 0;
33285
+ const admitted = admitMonitorFleetAuthoringContract(value);
33286
+ const issues = admitted.issues.map((issue) => ({
33287
+ ...issue,
33288
+ severity: "error"
33289
+ }));
33290
+ if (legacy) {
33291
+ issues.push({
33292
+ severity: "warning",
33293
+ code: "deprecated_fleet_member",
33294
+ path: "member",
33295
+ message: "Legacy Fleet member syntax remains supported."
33296
+ });
33297
+ if (JSON.stringify(input2).includes('"$fleet"')) {
33298
+ issues.push({
33299
+ severity: "warning",
33300
+ code: "deprecated_fleet_expression",
33301
+ path: "member",
33302
+ message: "Legacy $fleet expressions remain supported; use direct Handlebars fields in monitor instead."
33303
+ });
33304
+ }
33305
+ }
33306
+ return admitted.valid && admitted.contract ? { normalized: admitted.contract.definition, issues } : { issues };
33307
+ }
32814
33308
 
32815
33309
  // src/cli/commands/monitors.ts
32816
33310
  var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
@@ -33496,6 +33990,155 @@ function fleetIdempotencyKey(operation, supplied) {
33496
33990
  }
33497
33991
  return normalized ?? `monitor-fleet-${operation}-${(0, import_node_crypto8.randomUUID)()}`;
33498
33992
  }
33993
+ function monitorJobIdempotencyKey(operation, supplied) {
33994
+ const normalized = supplied?.trim();
33995
+ if (supplied !== void 0 && !normalized) {
33996
+ throw new MonitorsUsageError("--idempotency-key must not be empty.");
33997
+ }
33998
+ return normalized ?? `monitor-job-${operation}-${(0, import_node_crypto8.randomUUID)()}`;
33999
+ }
34000
+ function readMonitorDefinitionsJsonFile(file) {
34001
+ let raw;
34002
+ try {
34003
+ raw = file === "-" ? (0, import_node_fs15.readFileSync)(0, "utf8") : (0, import_node_fs15.readFileSync)(file, "utf8");
34004
+ } catch (error) {
34005
+ throw new MonitorsUsageError(
34006
+ `Could not read --file ${file}: ${error instanceof Error ? error.message : String(error)}`
34007
+ );
34008
+ }
34009
+ try {
34010
+ return JSON.parse(raw);
34011
+ } catch (error) {
34012
+ throw new MonitorsUsageError(
34013
+ `Monitor definitions must be valid JSON. ${error instanceof Error ? error.message : String(error)}`
34014
+ );
34015
+ }
34016
+ }
34017
+ function renderMonitorJob(payload) {
34018
+ const job = asRecord2(payload.job);
34019
+ if (!job) return void 0;
34020
+ const id = asString(job.id) ?? "<unknown>";
34021
+ const state = asString(job.state) ?? "unknown";
34022
+ const phase = asString(job.phase);
34023
+ const counts = asRecord2(job.counts);
34024
+ const reconciliation = asRecord2(job.reconciliation);
34025
+ const lines = [
34026
+ `Monitor job: ${id}`,
34027
+ `State: ${state}${phase ? ` (${phase})` : ""}`
34028
+ ];
34029
+ if (counts) {
34030
+ lines.push(
34031
+ `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}`
34032
+ );
34033
+ }
34034
+ if (reconciliation) {
34035
+ lines.push(
34036
+ `Reconciliation: ${asString(reconciliation.state) ?? "pending"} (${asFiniteNumber(reconciliation.observed_bindings) ?? 0}/${asFiniteNumber(reconciliation.expected_bindings) ?? 0} bindings observed)`
34037
+ );
34038
+ }
34039
+ const next = asString(payload.next);
34040
+ if (next) lines.push(`Next: ${next}`);
34041
+ return `${lines.join("\n")}
34042
+ `;
34043
+ }
34044
+ async function handleMonitorJobBatchDeploy(options, idempotencyKey) {
34045
+ if (!options.file) {
34046
+ throw new MonitorsUsageError(
34047
+ "A Batch file is required. Pass --file batch.json (or --file - for stdin)."
34048
+ );
34049
+ }
34050
+ const lint = lintMonitorBatchInput(
34051
+ readMonitorDefinitionsJsonFile(options.file)
34052
+ );
34053
+ if (!lint.normalized) {
34054
+ throw new MonitorsUsageError(
34055
+ lint.issues.filter((issue) => issue.severity === "error").map((issue) => `${issue.path || "batch"}: ${issue.message}`).join("; ")
34056
+ );
34057
+ }
34058
+ const payload = await new DeeplineClient().monitors.batch.deploy(
34059
+ lint.normalized.monitors,
34060
+ { idempotencyKey }
34061
+ );
34062
+ printCommandEnvelope(
34063
+ {
34064
+ ...payload,
34065
+ idempotency_key: idempotencyKey,
34066
+ ...lint.issues.length ? { lint: { issues: lint.issues } } : {}
34067
+ },
34068
+ { json: options.json, text: renderMonitorJob(payload) }
34069
+ );
34070
+ }
34071
+ async function handleMonitorBatchLint(options) {
34072
+ if (!options.file) {
34073
+ throw new MonitorsUsageError(
34074
+ "monitors batch lint requires --file <batch.json>."
34075
+ );
34076
+ }
34077
+ const result = lintMonitorBatchInput(
34078
+ readMonitorDefinitionsJsonFile(options.file)
34079
+ );
34080
+ printCommandEnvelope(
34081
+ {
34082
+ ok: !result.issues.some((issue) => issue.severity === "error"),
34083
+ ...result.normalized ? { normalized: result.normalized } : {},
34084
+ issues: result.issues
34085
+ },
34086
+ { json: options.json }
34087
+ );
34088
+ if (result.issues.some((issue) => issue.severity === "error"))
34089
+ process.exitCode = 2;
34090
+ }
34091
+ async function handleMonitorFleetLint(options) {
34092
+ if (!options.file) {
34093
+ throw new MonitorsUsageError(
34094
+ "monitors fleets lint requires --file <fleet.json>."
34095
+ );
34096
+ }
34097
+ const result = lintMonitorFleetInput(
34098
+ readMonitorDefinitionsJsonFile(options.file)
34099
+ );
34100
+ printCommandEnvelope(
34101
+ {
34102
+ ok: !result.issues.some((issue) => issue.severity === "error"),
34103
+ ...result.normalized ? { normalized: result.normalized } : {},
34104
+ issues: result.issues
34105
+ },
34106
+ { json: options.json }
34107
+ );
34108
+ if (result.issues.some((issue) => issue.severity === "error"))
34109
+ process.exitCode = 2;
34110
+ }
34111
+ async function handleMonitorJobGet(jobId, options) {
34112
+ const payload = await new DeeplineClient().monitors.jobs.get(jobId);
34113
+ printCommandEnvelope(payload, {
34114
+ json: options.json,
34115
+ text: renderMonitorJob(payload)
34116
+ });
34117
+ }
34118
+ async function handleMonitorJobWait(jobId, options) {
34119
+ const payload = await new DeeplineClient().monitors.jobs.wait(jobId, {
34120
+ timeoutMs: fleetTimeoutMs(options.timeout),
34121
+ pollIntervalMs: FLEET_POLL_INTERVAL_MS
34122
+ });
34123
+ printCommandEnvelope(payload, {
34124
+ json: options.json,
34125
+ text: renderMonitorJob(payload)
34126
+ });
34127
+ }
34128
+ async function handleMonitorJobLogs(jobId, options) {
34129
+ const limit = options.limit ? fleetIntegerOption(options.limit, "--limit") : void 0;
34130
+ const payload = await new DeeplineClient().monitors.jobs.logs(jobId, {
34131
+ ...limit === void 0 ? {} : { limit }
34132
+ });
34133
+ printCommandEnvelope(payload, { json: options.json });
34134
+ }
34135
+ async function handleMonitorJobCancel(jobId, options) {
34136
+ const payload = await new DeeplineClient().monitors.jobs.cancel(jobId);
34137
+ printCommandEnvelope(payload, {
34138
+ json: options.json,
34139
+ text: renderMonitorJob(payload)
34140
+ });
34141
+ }
33499
34142
  var FLEET_COUNT_KEYS = [
33500
34143
  "pending",
33501
34144
  "submitting",
@@ -33517,12 +34160,12 @@ var MONITOR_FLEET_LIFECYCLE = [
33517
34160
  {
33518
34161
  step: 2,
33519
34162
  what: "See the plan and the credits before anything changes.",
33520
- command: "deepline monitors fleets sync --file fleet.json --dry-run"
34163
+ command: "deepline monitors fleets deploy --file fleet.json --dry-run"
33521
34164
  },
33522
34165
  {
33523
34166
  step: 3,
33524
34167
  what: "Apply it and wait for the server to call it converged.",
33525
- command: "deepline monitors fleets sync --file fleet.json --wait"
34168
+ command: "deepline monitors fleets deploy --file fleet.json --wait"
33526
34169
  },
33527
34170
  {
33528
34171
  step: 4,
@@ -33531,6 +34174,11 @@ var MONITOR_FLEET_LIFECYCLE = [
33531
34174
  }
33532
34175
  ];
33533
34176
  var MONITOR_FLEET_COMMANDS = [
34177
+ {
34178
+ name: "deploy",
34179
+ summary: "Create or update one table-backed Fleet from Customer DB rows."
34180
+ },
34181
+ { name: "lint", summary: "Validate and normalize Fleet JSON locally." },
33534
34182
  { name: "init", summary: "Write a Fleet definition JSON file." },
33535
34183
  {
33536
34184
  name: "sync",
@@ -33676,6 +34324,26 @@ function renderFleetGet(payload) {
33676
34324
  ` counts ${fleetCountsLine(payload)}`,
33677
34325
  ` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
33678
34326
  ];
34327
+ const boundPlays = Array.isArray(payload.bound_plays) ? payload.bound_plays.flatMap((value) => {
34328
+ const play = asRecord2(value);
34329
+ return play ? [play] : [];
34330
+ }) : [];
34331
+ lines.push("", `Observed Play bindings (${boundPlays.length}):`);
34332
+ if (boundPlays.length === 0) {
34333
+ lines.push(" none");
34334
+ } else {
34335
+ for (const play of boundPlays) {
34336
+ const name = asString(play.name) ?? "unnamed Play";
34337
+ const listeners = asFiniteNumber(play.listener_count) ?? 0;
34338
+ const status2 = asString(play.status);
34339
+ lines.push(
34340
+ ` ${name}${listeners ? ` (${listeners} listener${listeners === 1 ? "" : "s"})` : ""}${status2 ? ` \u2014 ${status2}` : ""}`
34341
+ );
34342
+ }
34343
+ }
34344
+ lines.push(
34345
+ " Read-only observation. Define or change bindings in the Play with sqlListeners."
34346
+ );
33679
34347
  lines.push(...renderFleetDriftRows(payload));
33680
34348
  const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
33681
34349
  if (next) lines.push(`Next: ${next}`);
@@ -33852,6 +34520,8 @@ async function handleMonitorFleetsInit(fleetId, options) {
33852
34520
  const out = options.out?.trim();
33853
34521
  if (!out) throw new MonitorsUsageError("--out is required.");
33854
34522
  const authoredDefinition = {
34523
+ version: 2,
34524
+ kind: "fleet",
33855
34525
  id: fleetId,
33856
34526
  source: {
33857
34527
  kind: "customer_db_table",
@@ -33860,12 +34530,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
33860
34530
  key: { column: key, type: keyType },
33861
34531
  ...where ? { where } : {}
33862
34532
  },
33863
- member: {
34533
+ monitor: {
33864
34534
  tool,
33865
- key: {
33866
- $fleet: "template",
33867
- parts: [`${fleetId}-`, { $fleet: "column", name: key }]
33868
- },
34535
+ key: `${fleetId}-{{${key}}}`,
33869
34536
  payload
33870
34537
  },
33871
34538
  selection: {
@@ -33878,9 +34545,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
33878
34545
  const file = (0, import_node_path17.resolve)(out);
33879
34546
  (0, import_node_fs15.writeFileSync)(file, `${JSON.stringify(definition, null, 2)}
33880
34547
  `, "utf8");
33881
- const next = `deepline monitors fleets sync --file ${fleetShellArg(file)} --dry-run --json`;
34548
+ const next = `deepline monitors fleets deploy --file ${fleetShellArg(file)} --dry-run --json`;
33882
34549
  printCommandEnvelope(
33883
- { schemaVersion: 1, file, definition, next },
34550
+ { schemaVersion: 2, file, definition, next },
33884
34551
  {
33885
34552
  json: options.json,
33886
34553
  text: `Wrote ${file}
@@ -33890,8 +34557,8 @@ Next: ${next}
33890
34557
  );
33891
34558
  }
33892
34559
  function requireCompiledFleetDefinition(definition) {
33893
- const result = admitMonitorFleetAuthoringContract(definition);
33894
- if (result.valid && result.contract) return result.contract.definition;
34560
+ const result = lintMonitorFleetInput(definition);
34561
+ if (result.normalized) return result.normalized;
33895
34562
  const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
33896
34563
  throw new MonitorsUsageError(
33897
34564
  `Monitor Fleet definition failed local contract check. ${messages}
@@ -33918,6 +34585,7 @@ function fleetSyncCommandLine(target, options) {
33918
34585
  return parts.join(" ");
33919
34586
  }
33920
34587
  async function handleMonitorFleetsSync(target, options, idempotencyKey) {
34588
+ const fileDefinitions = options.file ? readMonitorDefinitionsJsonFile(options.file) : void 0;
33921
34589
  const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
33922
34590
  if (!usesDefinition && !target?.trim()) {
33923
34591
  throw new MonitorsUsageError(
@@ -33925,12 +34593,14 @@ async function handleMonitorFleetsSync(target, options, idempotencyKey) {
33925
34593
  );
33926
34594
  }
33927
34595
  const definition = usesDefinition ? requireCompiledFleetDefinition(
33928
- resolveMonitorJsonBody({
33929
- positional: target,
33930
- file: options.file,
33931
- argLabel: "<definition>",
33932
- command: "deepline monitors fleets sync"
33933
- })
34596
+ asRecord2(
34597
+ fileDefinitions ?? resolveMonitorJsonBody({
34598
+ positional: target,
34599
+ file: options.file,
34600
+ argLabel: "<definition>",
34601
+ command: "deepline monitors fleets sync"
34602
+ })
34603
+ ) ?? {}
33934
34604
  ) : void 0;
33935
34605
  const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
33936
34606
  if (!fleetId) {
@@ -34331,14 +35001,14 @@ function renderMonitorGet(payload) {
34331
35001
  ` deepline monitors test ${key} '${JSON.stringify(samplePayload2)}' --json`
34332
35002
  );
34333
35003
  }
34334
- const monitorSpec = asRecord2(payload.monitor_spec);
34335
- if (monitorSpec?.available === false) {
35004
+ const monitorSpec2 = asRecord2(payload.monitor_spec);
35005
+ if (monitorSpec2?.available === false) {
34336
35006
  lines.push(
34337
35007
  "",
34338
- `Monitor spec: unavailable \u2014 ${asString(monitorSpec.message) ?? "use the stored definition and check before an update."}`
35008
+ `Monitor spec: unavailable \u2014 ${asString(monitorSpec2.message) ?? "use the stored definition and check before an update."}`
34339
35009
  );
34340
35010
  }
34341
- const specFields = Array.isArray(monitorSpec?.fields) ? monitorSpec.fields.flatMap((value) => {
35011
+ const specFields = Array.isArray(monitorSpec2?.fields) ? monitorSpec2.fields.flatMap((value) => {
34342
35012
  const field = asRecord2(value);
34343
35013
  const path = asString(field?.path);
34344
35014
  const description = asString(field?.description);
@@ -34812,6 +35482,8 @@ Notes:
34812
35482
  Deepline monitors are Deepline-native signal feeds: a monitor writes events
34813
35483
  into a Customer DB table; a play reacts to each new row via a
34814
35484
  sqlListeners trigger \u2014 see \`deepline plays bootstrap monitor-triggered\`.
35485
+ Monitor JSON declares only what to watch (key, tool, optional name, payload).
35486
+ Play bindings belong in the Play; monitor deployment never changes them.
34815
35487
  The Monitors rollout controls access to the live provider catalog; use
34816
35488
  \`deepline tools list --categories monitors\` for the exact tool ids available to you.
34817
35489
  Contact the Deepline team to request access; until access is enabled, these
@@ -34924,19 +35596,31 @@ Examples:
34924
35596
  );
34925
35597
  withJsonOption(
34926
35598
  batch.command("deploy").description(
34927
- "Durably create complete NDJSON monitor definitions through provider bulk create."
35599
+ "Create a Monitor Job from canonical Batch JSON; legacy NDJSON remains available with --yes or --dry-run."
34928
35600
  ).requiredOption(
34929
35601
  "--file <path>",
34930
- "NDJSON file of complete monitor definitions"
34931
- ).option("--dry-run", "Validate and record the durable deploy plan").option("--yes", "Confirm asynchronous provider creation").option(
35602
+ 'Batch JSON ({"version":1,"kind":"batch","monitors":[...]}), or legacy NDJSON with --yes/--dry-run'
35603
+ ).option("--dry-run", "Use the retained legacy batch-operation plan").option("--yes", "Use the retained legacy NDJSON batch operation").option(
34932
35604
  "--idempotency-key <key>",
34933
35605
  "Stable retry key (generated when omitted)"
34934
35606
  )
34935
35607
  ).action(
34936
- monitorsAction(
34937
- (options) => handleMonitorBatchDeploy(options)
34938
- )
35608
+ monitorsAction(async (options) => {
35609
+ if (options.dryRun === true || options.yes === true) {
35610
+ return await handleMonitorBatchDeploy(options);
35611
+ }
35612
+ const idempotencyKey = monitorJobIdempotencyKey(
35613
+ "batch-deploy",
35614
+ options.idempotencyKey
35615
+ );
35616
+ return await handleMonitorJobBatchDeploy(options, idempotencyKey);
35617
+ })
34939
35618
  );
35619
+ withJsonOption(
35620
+ batch.command("lint").description(
35621
+ "Validate and normalize Batch JSON without network or provider work."
35622
+ ).requiredOption("--file <path>", "Batch JSON file, or - for stdin")
35623
+ ).action(monitorsAction(handleMonitorBatchLint));
34940
35624
  withJsonOption(
34941
35625
  batchSelectorOptions(
34942
35626
  batch.command("audit").description("Durably audit a selection; defaults to --target all.")
@@ -35105,9 +35789,8 @@ Examples:
35105
35789
  "after",
35106
35790
  `
35107
35791
  Notes:
35108
- Read-only validation. <definition> is a JSON object with key, tool, payload,
35109
- and optional controls (Deepline lifecycle metadata). Pass it positionally,
35110
- via --file <path>, or
35792
+ Read-only validation. <definition> is a JSON object with key, tool, optional
35793
+ name, and payload. Pass it positionally, via --file <path>, or
35111
35794
  from stdin with --file -. Does not deploy or spend credits.
35112
35795
  Check validates the local definition only. It does not contact an existing
35113
35796
  upstream resource, prove that future events will arrive, or verify downstream
@@ -35115,12 +35798,8 @@ Notes:
35115
35798
  Provider-specific grammar, precedence, enum applicability, examples, and
35116
35799
  update semantics are returned by the live monitor contract. Inspect it with
35117
35800
  \`deepline tools get deepline_native.company_radar --json\`.
35118
- For a bounded urgent Deepline Native preview, use
35119
- controls.execution_type="priority". Deepline injects the upstream marker;
35120
- do not author custom_fields yourself. Priority is capped at ten upstream or
35121
- reserved recovery, replacement, or reactivation slots per org. Use
35122
- \`monitors list --status all\` to find priority holders; it is not for regular
35123
- or bulk-scale monitoring.
35801
+ Operational controls are Deepline-managed. Bind downstream automation in a
35802
+ Play with sqlListeners; monitor definitions never name Plays.
35124
35803
 
35125
35804
  Examples:
35126
35805
  deepline monitors check '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
@@ -35138,8 +35817,8 @@ Examples:
35138
35817
  `
35139
35818
  Notes:
35140
35819
  Mutates workspace state and may spend Deepline credits. <definition> is a JSON
35141
- object with key, tool, payload, and optional controls. Pass it positionally,
35142
- via --file <path>, or from stdin with --file -.
35820
+ object with key, tool, optional name, and payload. Pass it positionally, via
35821
+ --file <path>, or from stdin with --file -.
35143
35822
  --dry-run validates the definition and shows the plan (deploy cost in Deepline
35144
35823
  credits when the server reports it, plus any existing monitors that may
35145
35824
  already cover this scope) WITHOUT deploying. Exits 0 when valid, 7 when not.
@@ -35156,10 +35835,8 @@ Notes:
35156
35835
  historical replay request, including when redeploying a disabled monitor.
35157
35836
  Deepline preserves that selected boundary; filter-only deploys and ordinary
35158
35837
  reactivation start from a fresh future-only source boundary instead.
35159
- For a bounded urgent Deepline Native preview, set
35160
- controls.execution_type="priority". Deepline injects the provider custom
35161
- field and enforces a ten-slot per-org cap; do not use it for regular or bulk
35162
- monitoring, and do not delete another radar automatically to make room.
35838
+ Operational controls are Deepline-managed. A monitor writes rows; downstream
35839
+ automation belongs in a Play with sqlListeners.
35163
35840
 
35164
35841
  Examples:
35165
35842
  deepline monitors deploy '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
@@ -35190,10 +35867,6 @@ request. Deepline passes that requested boundary upstream, but previously
35190
35867
  delivered canonical findings are deduplicated before dispatch and billing; only
35191
35868
  previously unseen historical findings are chargeable. Filter-only updates,
35192
35869
  repair, and reactivation instead use a fresh future-only source boundary.
35193
- Use {"controls":{"execution_type":"priority"}} only for a bounded urgent
35194
- Deepline Native preview. The ten-radar priority cap applies on update too.
35195
- Use {"controls":{"execution_type":null}} to release priority without
35196
- deleting the monitor.
35197
35870
 
35198
35871
  Examples:
35199
35872
  deepline monitors update my-monitor '{"name":"Interested replies"}' --json
@@ -35241,13 +35914,30 @@ Examples:
35241
35914
  `
35242
35915
  ).option("--dry-run", "Show the reactivation cost without reactivating")
35243
35916
  ).action(monitorsAction(handleMonitorsReactivate));
35244
- const fleets = monitors.command("fleets").description("Define and reconcile table-backed Monitor Fleets.").addHelpText(
35917
+ const jobs = monitors.command("jobs").description("Read, wait for, inspect, or cancel Monitor Jobs.");
35918
+ withJsonOption(jobs);
35919
+ withJsonOption(
35920
+ jobs.command("get <job-id>").description("Read the durable Monitor Job state.")
35921
+ ).action(monitorsAction(handleMonitorJobGet));
35922
+ withJsonOption(
35923
+ jobs.command("wait <job-id>").description(
35924
+ "Wait for real provider reconciliation, not request acceptance."
35925
+ ).option("--timeout <duration>", "How long to wait (default 10m)")
35926
+ ).action(monitorsAction(handleMonitorJobWait));
35927
+ withJsonOption(
35928
+ jobs.command("logs <job-id>").description("Read bounded operator logs for one Monitor Job.").option("--limit <n>", "Maximum log entries (1..200)")
35929
+ ).action(monitorsAction(handleMonitorJobLogs));
35930
+ withJsonOption(
35931
+ jobs.command("cancel <job-id>").description("Stop unscheduled work and reconcile the partial result.")
35932
+ ).action(monitorsAction(handleMonitorJobCancel));
35933
+ const fleets = monitors.command("fleets").description("Manage table-backed Fleets.").addHelpText(
35245
35934
  "after",
35246
35935
  `
35247
35936
  Notes:
35248
35937
  A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
35249
- monitors. Fleet definitions are canonical JSON, and \`sync\` is the only verb
35250
- that changes one: applying the same definition twice is the same operation,
35938
+ monitors. Fleet definitions are canonical JSON, and \`deploy\` applies one;
35939
+ \`sync\` remains its exact compatibility alias. Applying the same definition
35940
+ twice is the same operation,
35251
35941
  so the server answers \`replayed: true\` instead of building a second fleet.
35252
35942
  The fleet's status is computed by Deepline; this CLI reports it and never
35253
35943
  recomputes a verdict from the counts.
@@ -35269,6 +35959,29 @@ ${MONITOR_FLEET_HELP_EPILOG}`
35269
35959
  })
35270
35960
  );
35271
35961
  withJsonOption(fleets);
35962
+ withJsonOption(
35963
+ fleets.command("deploy [fleet-id]").description(
35964
+ "Apply a table-backed Fleet definition; sync remains an exact alias."
35965
+ ).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(
35966
+ "--expected-generation <generation>",
35967
+ "Optimistic generation fence"
35968
+ ).option("--idempotency-key <key>", "Stable retry key")
35969
+ ).action(
35970
+ monitorsAction(
35971
+ async (fleetId, options) => {
35972
+ const idempotencyKey = fleetIdempotencyKey(
35973
+ "deploy",
35974
+ options.idempotencyKey
35975
+ );
35976
+ await handleMonitorFleetsSync(fleetId, options, idempotencyKey);
35977
+ }
35978
+ )
35979
+ );
35980
+ withJsonOption(
35981
+ fleets.command("lint").description(
35982
+ "Validate and normalize Fleet JSON without network or provider work."
35983
+ ).requiredOption("--file <path>", "Fleet JSON file, or - for stdin")
35984
+ ).action(monitorsAction(handleMonitorFleetLint));
35272
35985
  withJsonOption(
35273
35986
  fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
35274
35987
  "after",
@@ -35282,13 +35995,13 @@ Example:
35282
35995
  deepline monitors fleets init account-job-openings \\
35283
35996
  --source public.accounts --key account_id --key-type uuid \\
35284
35997
  --tool deepline_native.company_radar \\
35285
- --payload '{"domain":{"$fleet":"column","name":"domain"},"radar_type":"company_job_openings"}' \\
35998
+ --payload '{"domain":"{{domain}}","radar_type":"company_job_openings"}' \\
35286
35999
  --order-by intent_score:desc \\
35287
36000
  --out fleet.json
35288
36001
  `
35289
36002
  ).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(
35290
36003
  "--payload <json>",
35291
- "Monitor payload JSON for --tool; use $fleet column tags for row values"
36004
+ "Monitor payload JSON for --tool; use Handlebars fields such as {{domain}} for row values"
35292
36005
  ).option(
35293
36006
  "--where <json>",
35294
36007
  "Optional source-row equality filter JSON; not arbitrary SQL"
@@ -35364,7 +36077,9 @@ Examples:
35364
36077
  Notes:
35365
36078
  Status is the server's verdict. --check turns it into an exit code so a
35366
36079
  script can branch without parsing output: 0 converged, 6 anything else.
35367
- --drift lists the members that have not settled and why.
36080
+ --drift lists the members that have not settled and why. The detail also
36081
+ shows the current Plays that observe this Fleet's output; those bindings are
36082
+ read-only here and are defined by each Play's sqlListeners.
35368
36083
 
35369
36084
  Examples:
35370
36085
  deepline monitors fleets get --json
@@ -37463,8 +38178,8 @@ function classifyNetworkFailure(error) {
37463
38178
  let current = error;
37464
38179
  while (current && !seen.has(current)) {
37465
38180
  seen.add(current);
37466
- const record2 = typeof current === "object" && current !== null ? current : {};
37467
- const code = String(record2.code ?? "").toLowerCase();
38181
+ const record3 = typeof current === "object" && current !== null ? current : {};
38182
+ const code = String(record3.code ?? "").toLowerCase();
37468
38183
  const name = current instanceof Error ? current.name.toLowerCase() : "";
37469
38184
  const text = String(
37470
38185
  current instanceof Error ? current.message : current
@@ -37491,7 +38206,7 @@ function classifyNetworkFailure(error) {
37491
38206
  if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
37492
38207
  return "network_ssl_error";
37493
38208
  }
37494
- current = record2.cause ?? record2.context;
38209
+ current = record3.cause ?? record3.context;
37495
38210
  }
37496
38211
  return "network_error";
37497
38212
  }
@@ -38568,26 +39283,26 @@ function parseSetupPhases(value) {
38568
39283
  if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
38569
39284
  return null;
38570
39285
  }
38571
- const record2 = phase;
38572
- if (!isSetupPhaseStatus(record2.status)) return null;
38573
- switch (record2.status) {
39286
+ const record3 = phase;
39287
+ if (!isSetupPhaseStatus(record3.status)) return null;
39288
+ switch (record3.status) {
38574
39289
  case "pending":
38575
39290
  case "in_progress":
38576
- phases[name] = { status: record2.status };
39291
+ phases[name] = { status: record3.status };
38577
39292
  break;
38578
39293
  case "complete":
38579
39294
  phases[name] = {
38580
39295
  status: "complete",
38581
- ...typeof record2.outcome === "string" ? { outcome: record2.outcome } : {}
39296
+ ...typeof record3.outcome === "string" ? { outcome: record3.outcome } : {}
38582
39297
  };
38583
39298
  break;
38584
39299
  case "waiting":
38585
- if (typeof record2.outcome !== "string") return null;
38586
- phases[name] = { status: "waiting", outcome: record2.outcome };
39300
+ if (typeof record3.outcome !== "string") return null;
39301
+ phases[name] = { status: "waiting", outcome: record3.outcome };
38587
39302
  break;
38588
39303
  case "failed":
38589
- if (typeof record2.code !== "string") return null;
38590
- phases[name] = { status: "failed", code: record2.code };
39304
+ if (typeof record3.code !== "string") return null;
39305
+ phases[name] = { status: "failed", code: record3.code };
38591
39306
  break;
38592
39307
  }
38593
39308
  }
@@ -42003,9 +42718,9 @@ function requiredInputIds(tool) {
42003
42718
  return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
42004
42719
  }
42005
42720
  function notConnectedSuffix(tool) {
42006
- const record2 = tool;
42007
- const status = stringField2(record2, "credentialStatus", "credential_status");
42008
- const connected = record2.connected;
42721
+ const record3 = tool;
42722
+ const status = stringField2(record3, "credentialStatus", "credential_status");
42723
+ const connected = record3.connected;
42009
42724
  const message = toolConnectionStatusMessage({
42010
42725
  connected: connected === false ? false : void 0,
42011
42726
  credentialStatus: status || void 0
@@ -42384,19 +43099,19 @@ function printPlayAliasToolError(toolId, play) {
42384
43099
  console.error(playAliasToolErrorMessage(toolId, play));
42385
43100
  }
42386
43101
  function isPlayLikeTool(tool) {
42387
- const record2 = tool;
42388
- if (record2.isPlay === true || record2.is_play === true) return true;
42389
- const playExpansion = recordField2(record2, "playExpansion", "play_expansion");
43102
+ const record3 = tool;
43103
+ if (record3.isPlay === true || record3.is_play === true) return true;
43104
+ const playExpansion = recordField2(record3, "playExpansion", "play_expansion");
42390
43105
  if (Object.keys(playExpansion).length > 0) return true;
42391
- const toolId = typeof record2.toolId === "string" ? record2.toolId : "";
43106
+ const toolId = typeof record3.toolId === "string" ? record3.toolId : "";
42392
43107
  return toolId.endsWith("_waterfall");
42393
43108
  }
42394
43109
  function isMonitorTypeTool(tool) {
42395
43110
  return stringField2(tool, "kind") === "monitor_type";
42396
43111
  }
42397
43112
  function playReferenceForTool(tool) {
42398
- const record2 = tool;
42399
- const declared = stringField2(record2, "playReference", "play_reference");
43113
+ const record3 = tool;
43114
+ const declared = stringField2(record3, "playReference", "play_reference");
42400
43115
  if (declared.startsWith("prebuilt/")) {
42401
43116
  return declared;
42402
43117
  }
@@ -43336,12 +44051,12 @@ function singleLineText(value, maxLength = 260) {
43336
44051
  return `${text.slice(0, maxLength - 3).trimEnd()}...`;
43337
44052
  }
43338
44053
  function listedToolDescription(tool) {
43339
- const record2 = tool;
43340
- return singleLineText(record2.bestFor ?? record2.best_for ?? tool.description);
44054
+ const record3 = tool;
44055
+ return singleLineText(record3.bestFor ?? record3.best_for ?? tool.description);
43341
44056
  }
43342
44057
  function formatListedToolCost(tool) {
43343
- const record2 = tool;
43344
- const pricing = recordField2(record2, "pricing");
44058
+ const record3 = tool;
44059
+ const pricing = recordField2(record3, "pricing");
43345
44060
  const displayText = stringField2(pricing, "displayText", "display_text");
43346
44061
  return displayText ? `Cost: ${displayText}` : "";
43347
44062
  }
@@ -44397,9 +45112,9 @@ function noticeToStderr(command) {
44397
45112
  );
44398
45113
  }
44399
45114
  function emitPassThrough(command, payload, options) {
44400
- const json = shouldEmitJson(options.json);
45115
+ const json2 = shouldEmitJson(options.json);
44401
45116
  const deprecation = migrationDeprecation(command);
44402
- if (json) {
45117
+ if (json2) {
44403
45118
  const enriched = payload && typeof payload === "object" && !Array.isArray(payload) ? { ...payload, deprecation } : { result: payload, deprecation };
44404
45119
  printJson(enriched);
44405
45120
  return;
@@ -44420,9 +45135,9 @@ function clientWithTimeout(timeoutSeconds) {
44420
45135
  }
44421
45136
  function readStatus(payload) {
44422
45137
  if (!payload || typeof payload !== "object") return null;
44423
- const record2 = payload;
44424
- if (typeof record2.status === "string") return record2.status;
44425
- const run = record2.run;
45138
+ const record3 = payload;
45139
+ if (typeof record3.status === "string") return record3.status;
45140
+ const run = record3.run;
44426
45141
  if (run && typeof run === "object") {
44427
45142
  const status = run.status;
44428
45143
  if (typeof status === "string") return status;