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
@@ -1271,7 +1271,7 @@ var SDK_RELEASE = {
1271
1271
  // getters keep their established compatibility behavior.
1272
1272
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1273
1273
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1274
- version: "0.3.96",
1274
+ version: "0.3.98",
1275
1275
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
1276
1276
  packageCapabilities: {
1277
1277
  updatePreferences: 1
@@ -3343,9 +3343,9 @@ function nonEmptyString(value) {
3343
3343
  }
3344
3344
  function normalizeDatasetBornFrom(value) {
3345
3345
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
3346
- const record2 = value;
3347
- const table = nonEmptyString(record2.table);
3348
- const rowCountIn = finiteNonNegativeInteger2(record2.rowCountIn);
3346
+ const record3 = value;
3347
+ const table = nonEmptyString(record3.table);
3348
+ const rowCountIn = finiteNonNegativeInteger2(record3.rowCountIn);
3349
3349
  if (!table || rowCountIn === null) return null;
3350
3350
  return { table, rowCountIn };
3351
3351
  }
@@ -4534,21 +4534,21 @@ function normalizePlayRuntimeNamespace(value) {
4534
4534
  }
4535
4535
  function normalizePlayRuntimeSelection(value) {
4536
4536
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
4537
- const record2 = value;
4538
- if (Object.keys(record2).some(
4537
+ const record3 = value;
4538
+ if (Object.keys(record3).some(
4539
4539
  (key) => key !== "environment" && key !== "namespace" && key !== "backend"
4540
- ) || record2.environment !== "preview") {
4540
+ ) || record3.environment !== "preview") {
4541
4541
  return null;
4542
4542
  }
4543
- const namespace = normalizePlayRuntimeNamespace(record2.namespace);
4543
+ const namespace = normalizePlayRuntimeNamespace(record3.namespace);
4544
4544
  if (!namespace) return null;
4545
- if (record2.backend === void 0) {
4545
+ if (record3.backend === void 0) {
4546
4546
  return { environment: "preview", namespace };
4547
4547
  }
4548
- if (record2.backend !== PLAY_RUNTIME_BACKENDS.daytona && record2.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4548
+ if (record3.backend !== PLAY_RUNTIME_BACKENDS.daytona && record3.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4549
4549
  return null;
4550
4550
  }
4551
- return { environment: "preview", namespace, backend: record2.backend };
4551
+ return { environment: "preview", namespace, backend: record3.backend };
4552
4552
  }
4553
4553
  function normalizePlayRuntimeEnvironment(value) {
4554
4554
  return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
@@ -5193,10 +5193,18 @@ var DeeplineClient = class {
5193
5193
  repair: (options2) => this.repairMonitors(options2),
5194
5194
  health: (options2) => this.readMonitorsHealth(options2),
5195
5195
  batch: {
5196
+ deploy: (definitions, options2) => this.deployMonitorBatch(definitions, options2),
5196
5197
  submit: (options2) => this.submitMonitorBatch(options2),
5197
5198
  get: (operationId, options2) => this.getMonitorBatch(operationId, options2)
5198
5199
  },
5200
+ jobs: {
5201
+ get: (jobId) => this.getMonitorJob(jobId),
5202
+ logs: (jobId, options2) => this.getMonitorJobLogs(jobId, options2),
5203
+ cancel: (jobId) => this.cancelMonitorJob(jobId),
5204
+ wait: (jobId, options2) => this.waitForMonitorJob(jobId, options2)
5205
+ },
5199
5206
  fleets: {
5207
+ deploy: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
5200
5208
  sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
5201
5209
  get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
5202
5210
  list: () => this.listMonitorFleets(),
@@ -7948,6 +7956,68 @@ var DeeplineClient = class {
7948
7956
  );
7949
7957
  }
7950
7958
  // ——————————————————————————————————————————————————————————
7959
+ // Monitor Jobs, Batches, and Fleets
7960
+ // ——————————————————————————————————————————————————————————
7961
+ monitorJobIdempotencyKey(operation) {
7962
+ const uuid = globalThis.crypto?.randomUUID?.();
7963
+ return `monitor-job-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
7964
+ }
7965
+ monitorJobHeaders(operation, idempotencyKey) {
7966
+ return {
7967
+ "Idempotency-Key": idempotencyKey?.trim() || this.monitorJobIdempotencyKey(operation)
7968
+ };
7969
+ }
7970
+ async deployMonitorBatch(definitions, options) {
7971
+ return this.http.request(
7972
+ "/api/v2/monitors/batch/deploy",
7973
+ {
7974
+ method: "POST",
7975
+ body: { version: 1, kind: "batch", monitors: definitions },
7976
+ headers: this.monitorJobHeaders(
7977
+ "batch-deploy",
7978
+ options?.idempotencyKey
7979
+ ),
7980
+ maxRetries: 0,
7981
+ exactUrlOnly: true
7982
+ }
7983
+ );
7984
+ }
7985
+ async getMonitorJob(jobId) {
7986
+ return this.http.request(
7987
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}`,
7988
+ { method: "GET" }
7989
+ );
7990
+ }
7991
+ async getMonitorJobLogs(jobId, options) {
7992
+ const query = options?.limit === void 0 ? "" : `?limit=${encodeURIComponent(String(options.limit))}`;
7993
+ return this.http.request(
7994
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/logs${query}`,
7995
+ { method: "GET" }
7996
+ );
7997
+ }
7998
+ async cancelMonitorJob(jobId) {
7999
+ return this.http.request(
8000
+ `/api/v2/monitors/jobs/${encodeURIComponent(jobId)}/cancel`,
8001
+ { method: "POST", body: {}, maxRetries: 0, exactUrlOnly: true }
8002
+ );
8003
+ }
8004
+ async waitForMonitorJob(jobId, options) {
8005
+ const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
8006
+ const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
8007
+ const terminal = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
8008
+ const startedAt = Date.now();
8009
+ let latest = await this.getMonitorJob(jobId);
8010
+ while (true) {
8011
+ options?.onProgress?.(latest);
8012
+ const job = latest.job;
8013
+ const state = typeof job?.state === "string" ? job.state : void 0;
8014
+ if (state && terminal.has(state)) return latest;
8015
+ if (Date.now() - startedAt >= timeoutMs) return latest;
8016
+ await sleep2(pollIntervalMs);
8017
+ latest = await this.getMonitorJob(jobId);
8018
+ }
8019
+ }
8020
+ // ——————————————————————————————————————————————————————————
7951
8021
  // Monitor Fleets
7952
8022
  // ——————————————————————————————————————————————————————————
7953
8023
  monitorFleetIdempotencyKey(operation) {
@@ -8731,30 +8801,30 @@ function flattenObjectColumns(row, options = {}) {
8731
8801
  continue;
8732
8802
  }
8733
8803
  if (value && typeof value === "object" && !Array.isArray(value)) {
8734
- const record2 = value;
8804
+ const record3 = value;
8735
8805
  if (options.objectColumns === "json") {
8736
- flattened[key] = csvSafeJsonString(record2);
8806
+ flattened[key] = csvSafeJsonString(record3);
8737
8807
  continue;
8738
8808
  }
8739
- const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record2, "matched_result") || Object.prototype.hasOwnProperty.call(record2, "matchedResult");
8809
+ const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record3, "matched_result") || Object.prototype.hasOwnProperty.call(record3, "matchedResult");
8740
8810
  if (hasMatchedEnvelope) {
8741
- flattened[key] = csvSafeJsonString(record2);
8811
+ flattened[key] = csvSafeJsonString(record3);
8742
8812
  continue;
8743
8813
  }
8744
8814
  if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
8745
8815
  flattened[key] = rawValue;
8746
8816
  continue;
8747
8817
  } else {
8748
- const failureMessage = failureMessageFromRecord(record2);
8818
+ const failureMessage = failureMessageFromRecord(record3);
8749
8819
  if (failureMessage) {
8750
8820
  flattened[key] = failureMessage;
8751
8821
  continue;
8752
- } else if (Object.prototype.hasOwnProperty.call(record2, "result")) {
8753
- flattened[key] = csvSafeJsonString(record2);
8822
+ } else if (Object.prototype.hasOwnProperty.call(record3, "result")) {
8823
+ flattened[key] = csvSafeJsonString(record3);
8754
8824
  continue;
8755
8825
  }
8756
8826
  }
8757
- for (const [nestedKey, nestedValue] of Object.entries(record2)) {
8827
+ for (const [nestedKey, nestedValue] of Object.entries(record3)) {
8758
8828
  flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
8759
8829
  }
8760
8830
  continue;
@@ -11429,9 +11499,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
11429
11499
  }
11430
11500
  if (ancestors.has(value)) return value;
11431
11501
  ancestors.add(value);
11432
- const record2 = value;
11502
+ const record3 = value;
11433
11503
  const normalized = Object.fromEntries(
11434
- Object.keys(record2).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record2[key], ancestors)])
11504
+ Object.keys(record3).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record3[key], ancestors)])
11435
11505
  );
11436
11506
  ancestors.delete(value);
11437
11507
  return normalized;
@@ -12628,16 +12698,16 @@ function collectErrorText(value) {
12628
12698
  if (!value || typeof value !== "object" || Array.isArray(value)) {
12629
12699
  return errorMessage(value);
12630
12700
  }
12631
- const record2 = value;
12701
+ const record3 = value;
12632
12702
  return [
12633
12703
  errorMessage(value),
12634
- typeof record2.error === "string" ? record2.error : "",
12635
- typeof record2.message === "string" ? record2.message : "",
12636
- typeof record2.detail === "string" ? record2.detail : "",
12637
- typeof record2.hint === "string" ? record2.hint : "",
12638
- typeof record2.code === "string" ? record2.code : "",
12639
- record2.response ? collectErrorText(record2.response) : "",
12640
- record2.details ? collectErrorText(record2.details) : ""
12704
+ typeof record3.error === "string" ? record3.error : "",
12705
+ typeof record3.message === "string" ? record3.message : "",
12706
+ typeof record3.detail === "string" ? record3.detail : "",
12707
+ typeof record3.hint === "string" ? record3.hint : "",
12708
+ typeof record3.code === "string" ? record3.code : "",
12709
+ record3.response ? collectErrorText(record3.response) : "",
12710
+ record3.details ? collectErrorText(record3.details) : ""
12641
12711
  ].filter(Boolean).join("\n");
12642
12712
  }
12643
12713
  function formatDbQueryError(sql, error) {
@@ -13689,8 +13759,8 @@ function getterNamesFromTool(tool, kind) {
13689
13759
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
13690
13760
  }
13691
13761
  function targetGettersFromTool(tool) {
13692
- const record2 = isRecord9(tool) ? tool : {};
13693
- const raw = record2.targetGetters ?? record2.target_getters;
13762
+ const record3 = isRecord9(tool) ? tool : {};
13763
+ const raw = record3.targetGetters ?? record3.target_getters;
13694
13764
  if (!isRecord9(raw)) return {};
13695
13765
  const entries = [];
13696
13766
  for (const [target, value] of Object.entries(raw)) {
@@ -17805,13 +17875,13 @@ function validateFixtureBehavior(value) {
17805
17875
  if (!value || typeof value !== "object" || Array.isArray(value)) {
17806
17876
  return { ok: false, error: "fixtureBehavior must be a JSON object." };
17807
17877
  }
17808
- const record2 = value;
17809
- const supportedKeys = record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
17878
+ const record3 = value;
17879
+ const supportedKeys = record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
17810
17880
  "version",
17811
17881
  "responseSamples",
17812
- ...record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
17882
+ ...record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
17813
17883
  ]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
17814
- const unknownKeys = Object.keys(record2).filter(
17884
+ const unknownKeys = Object.keys(record3).filter(
17815
17885
  (key) => !supportedKeys.has(key)
17816
17886
  );
17817
17887
  if (unknownKeys.length > 0) {
@@ -17820,22 +17890,22 @@ function validateFixtureBehavior(value) {
17820
17890
  error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
17821
17891
  };
17822
17892
  }
17823
- if (record2.version !== FIXTURE_BEHAVIOR_VERSION && record2.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record2.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17893
+ if (record3.version !== FIXTURE_BEHAVIOR_VERSION && record3.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record3.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17824
17894
  return {
17825
17895
  ok: false,
17826
17896
  error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
17827
17897
  };
17828
17898
  }
17829
- if (record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17830
- if (!Array.isArray(record2.responseSamples) || record2.responseSamples.length === 0 || record2.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
17899
+ if (record3.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17900
+ if (!Array.isArray(record3.responseSamples) || record3.responseSamples.length === 0 || record3.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
17831
17901
  return {
17832
17902
  ok: false,
17833
17903
  error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
17834
17904
  };
17835
17905
  }
17836
17906
  const samples2 = [];
17837
- for (let index = 0; index < record2.responseSamples.length; index += 1) {
17838
- const value2 = record2.responseSamples[index];
17907
+ for (let index = 0; index < record3.responseSamples.length; index += 1) {
17908
+ const value2 = record3.responseSamples[index];
17839
17909
  if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
17840
17910
  return {
17841
17911
  ok: false,
@@ -17934,14 +18004,14 @@ function validateFixtureBehavior(value) {
17934
18004
  });
17935
18005
  }
17936
18006
  let replayBundle;
17937
- if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17938
- if (!record2.replayBundle || typeof record2.replayBundle !== "object" || Array.isArray(record2.replayBundle)) {
18007
+ if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
18008
+ if (!record3.replayBundle || typeof record3.replayBundle !== "object" || Array.isArray(record3.replayBundle)) {
17939
18009
  return {
17940
18010
  ok: false,
17941
18011
  error: "fixtureBehavior.replayBundle must be an object."
17942
18012
  };
17943
18013
  }
17944
- const replay = record2.replayBundle;
18014
+ const replay = record3.replayBundle;
17945
18015
  const replayUnknownKeys = Object.keys(replay).filter(
17946
18016
  (key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
17947
18017
  );
@@ -17989,7 +18059,7 @@ function validateFixtureBehavior(value) {
17989
18059
  ...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
17990
18060
  };
17991
18061
  }
17992
- if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
18062
+ if (record3.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17993
18063
  return {
17994
18064
  ok: true,
17995
18065
  behavior: {
@@ -18007,15 +18077,15 @@ function validateFixtureBehavior(value) {
18007
18077
  }
18008
18078
  };
18009
18079
  }
18010
- if (!Array.isArray(record2.responseDelaySamplesMs) || record2.responseDelaySamplesMs.length === 0 || record2.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
18080
+ if (!Array.isArray(record3.responseDelaySamplesMs) || record3.responseDelaySamplesMs.length === 0 || record3.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
18011
18081
  return {
18012
18082
  ok: false,
18013
18083
  error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
18014
18084
  };
18015
18085
  }
18016
18086
  const samples = [];
18017
- for (let index = 0; index < record2.responseDelaySamplesMs.length; index += 1) {
18018
- const value2 = record2.responseDelaySamplesMs[index];
18087
+ for (let index = 0; index < record3.responseDelaySamplesMs.length; index += 1) {
18088
+ const value2 = record3.responseDelaySamplesMs[index];
18019
18089
  if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
18020
18090
  return {
18021
18091
  ok: false,
@@ -18794,8 +18864,8 @@ function looksLikeStagedFileRef(value) {
18794
18864
  if (!value || typeof value !== "object" || Array.isArray(value)) {
18795
18865
  return false;
18796
18866
  }
18797
- const record2 = value;
18798
- return typeof record2.contentHash === "string" || typeof record2.contentBase64 === "string" || typeof record2.logicalPath === "string" && typeof record2.bytes === "number";
18867
+ const record3 = value;
18868
+ return typeof record3.contentHash === "string" || typeof record3.contentBase64 === "string" || typeof record3.logicalPath === "string" && typeof record3.bytes === "number";
18799
18869
  }
18800
18870
  var CSV_DATA_INPUT_KEY = "csv";
18801
18871
  function collectLocalFileInputRefs(value, inputPath, key, out) {
@@ -19308,8 +19378,8 @@ function readLiveRunField(event, field) {
19308
19378
  const records = [payload, payload.progress, run, run?.progress].filter(
19309
19379
  (value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
19310
19380
  );
19311
- for (const record2 of records) {
19312
- if (record2[field] !== void 0) return record2[field];
19381
+ for (const record3 of records) {
19382
+ if (record3[field] !== void 0) return record3[field];
19313
19383
  }
19314
19384
  return void 0;
19315
19385
  }
@@ -19611,8 +19681,8 @@ function getProgressLinesFromLiveEvent(event) {
19611
19681
  if (!state || typeof state !== "object" || Array.isArray(state)) {
19612
19682
  continue;
19613
19683
  }
19614
- const record2 = state;
19615
- const progress = record2.progress && typeof record2.progress === "object" && !Array.isArray(record2.progress) ? record2.progress : null;
19684
+ const record3 = state;
19685
+ const progress = record3.progress && typeof record3.progress === "object" && !Array.isArray(record3.progress) ? record3.progress : null;
19616
19686
  if (!progress) {
19617
19687
  continue;
19618
19688
  }
@@ -19629,7 +19699,7 @@ function getProgressLinesFromLiveEvent(event) {
19629
19699
  completed: progress.completed
19630
19700
  });
19631
19701
  lines.push(
19632
- `progress ${formatProgressLabel(record2.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
19702
+ `progress ${formatProgressLabel(record3.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
19633
19703
  );
19634
19704
  }
19635
19705
  return lines;
@@ -20309,11 +20379,11 @@ function truncateErrorForDisplay(message, runId, maxChars = RUN_ERROR_DISPLAY_MA
20309
20379
  const fullErrorHint = runId ? ` (full error: deepline runs get ${runId} --full)` : " (full error: deepline runs get <runId> --full)";
20310
20380
  return `${wordBoundary}\u2026${fullErrorHint}`;
20311
20381
  }
20312
- function clampJsonPreviewText(json, maxChars) {
20313
- if (json.length <= maxChars) {
20314
- return json;
20382
+ function clampJsonPreviewText(json2, maxChars) {
20383
+ if (json2.length <= maxChars) {
20384
+ return json2;
20315
20385
  }
20316
- const slice = json.slice(0, maxChars);
20386
+ const slice = json2.slice(0, maxChars);
20317
20387
  const lastNewline = slice.lastIndexOf("\n");
20318
20388
  const head = lastNewline > 0 ? slice.slice(0, lastNewline) : slice;
20319
20389
  return `${head}
@@ -20439,12 +20509,12 @@ function defaultResultForEnvelope(value, depth = 0) {
20439
20509
  return output2;
20440
20510
  }
20441
20511
  function formatJsonPreview(value) {
20442
- const json = JSON.stringify(value, null, 2);
20443
- if (!json || json === "{}") {
20512
+ const json2 = JSON.stringify(value, null, 2);
20513
+ if (!json2 || json2 === "{}") {
20444
20514
  return [];
20445
20515
  }
20446
20516
  const MAX_CHARS = 4e3;
20447
- const truncated = clampJsonPreviewText(json, MAX_CHARS);
20517
+ const truncated = clampJsonPreviewText(json2, MAX_CHARS);
20448
20518
  return truncated.split("\n").map((line) => ` ${line}`);
20449
20519
  }
20450
20520
  function formatReturnValue(result) {
@@ -20472,17 +20542,17 @@ function collectDatasetHandleLines(value, path = "result") {
20472
20542
  return [];
20473
20543
  }
20474
20544
  if (isDatasetHandle(value)) {
20475
- const record2 = value;
20476
- const count = typeof record2.count === "number" ? record2.count : typeof record2.rowCount === "number" ? record2.rowCount : null;
20477
- const preview = Array.isArray(record2.preview) ? record2.preview : [];
20545
+ const record3 = value;
20546
+ const count = typeof record3.count === "number" ? record3.count : typeof record3.rowCount === "number" ? record3.rowCount : null;
20547
+ const preview = Array.isArray(record3.preview) ? record3.preview : [];
20478
20548
  const lines2 = [
20479
- ` dataset ${typeof record2.path === "string" ? record2.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
20549
+ ` dataset ${typeof record3.path === "string" ? record3.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
20480
20550
  ];
20481
- if (typeof record2.queryDatasetCommand === "string") {
20482
- lines2.push(` query dataset: ${record2.queryDatasetCommand}`);
20551
+ if (typeof record3.queryDatasetCommand === "string") {
20552
+ lines2.push(` query dataset: ${record3.queryDatasetCommand}`);
20483
20553
  }
20484
- if (typeof record2.slowExportAsCsvCommand === "string") {
20485
- lines2.push(` export CSV: ${record2.slowExportAsCsvCommand}`);
20554
+ if (typeof record3.slowExportAsCsvCommand === "string") {
20555
+ lines2.push(` export CSV: ${record3.slowExportAsCsvCommand}`);
20486
20556
  }
20487
20557
  return lines2;
20488
20558
  }
@@ -20879,8 +20949,8 @@ function withTerminalPlayIdentity(status, playName) {
20879
20949
  if (!playName.trim() || getPlayRunPackage(status)) {
20880
20950
  return status;
20881
20951
  }
20882
- const record2 = status;
20883
- const hasIdentity = typeof record2.playName === "string" && record2.playName.trim().length > 0 || typeof record2.name === "string" && record2.name.trim().length > 0 || Boolean(getStringField(record2.run, "playName"));
20952
+ const record3 = status;
20953
+ const hasIdentity = typeof record3.playName === "string" && record3.playName.trim().length > 0 || typeof record3.name === "string" && record3.name.trim().length > 0 || Boolean(getStringField(record3.run, "playName"));
20884
20954
  if (hasIdentity) {
20885
20955
  return status;
20886
20956
  }
@@ -20993,9 +21063,9 @@ function formatSummaryScalar(value) {
20993
21063
  }
20994
21064
  return null;
20995
21065
  }
20996
- function formatSummaryScalarParts(record2, skipKeys = /* @__PURE__ */ new Set()) {
21066
+ function formatSummaryScalarParts(record3, skipKeys = /* @__PURE__ */ new Set()) {
20997
21067
  const parts = [];
20998
- for (const [key, value] of Object.entries(record2)) {
21068
+ for (const [key, value] of Object.entries(record3)) {
20999
21069
  if (skipKeys.has(key)) {
21000
21070
  continue;
21001
21071
  }
@@ -21022,13 +21092,13 @@ function formatTopValuesPart(value) {
21022
21092
  return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
21023
21093
  }
21024
21094
  function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
21025
- const record2 = readRecord(summary);
21026
- const columnStats = readRecord(record2?.columnStats);
21027
- if (!record2 || !columnStats) {
21095
+ const record3 = readRecord(summary);
21096
+ const columnStats = readRecord(record3?.columnStats);
21097
+ if (!record3 || !columnStats) {
21028
21098
  return [];
21029
21099
  }
21030
21100
  const lines = [];
21031
- const rowCounts = readRecord(record2.rowCounts);
21101
+ const rowCounts = readRecord(record3.rowCounts);
21032
21102
  if (rowCounts) {
21033
21103
  const persisted = readNonNegativeInteger(rowCounts.persisted);
21034
21104
  const succeeded = readNonNegativeInteger(rowCounts.succeeded);
@@ -21044,7 +21114,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
21044
21114
  }
21045
21115
  }
21046
21116
  const parts = formatSummaryScalarParts(
21047
- record2,
21117
+ record3,
21048
21118
  /* @__PURE__ */ new Set(["columnStats", "rowCounts"])
21049
21119
  );
21050
21120
  if (parts.length > 0) {
@@ -21074,35 +21144,35 @@ function actionToCommand(action) {
21074
21144
  if (!action || typeof action !== "object" || Array.isArray(action)) {
21075
21145
  return null;
21076
21146
  }
21077
- const record2 = action;
21078
- if (typeof record2.command === "string" && record2.command.trim()) {
21079
- return record2.command.trim();
21147
+ const record3 = action;
21148
+ if (typeof record3.command === "string" && record3.command.trim()) {
21149
+ return record3.command.trim();
21080
21150
  }
21081
- if (record2.kind === "deepline_run_inspect" && typeof record2.runId === "string") {
21082
- return `deepline runs get ${record2.runId} --json`;
21151
+ if (record3.kind === "deepline_run_inspect" && typeof record3.runId === "string") {
21152
+ return `deepline runs get ${record3.runId} --json`;
21083
21153
  }
21084
- if (record2.kind === "deepline_run_full" && typeof record2.runId === "string") {
21085
- return `deepline runs get ${record2.runId} --full --json`;
21154
+ if (record3.kind === "deepline_run_full" && typeof record3.runId === "string") {
21155
+ return `deepline runs get ${record3.runId} --full --json`;
21086
21156
  }
21087
- if (record2.kind === "deepline_run_billing" && typeof record2.runId === "string") {
21088
- return `deepline runs get ${record2.runId} --full --json | jq '.billing'`;
21157
+ if (record3.kind === "deepline_run_billing" && typeof record3.runId === "string") {
21158
+ return `deepline runs get ${record3.runId} --full --json | jq '.billing'`;
21089
21159
  }
21090
- if (record2.kind === "deepline_run_export" && typeof record2.runId === "string" && typeof record2.datasetPath === "string") {
21091
- return `deepline runs export ${record2.runId} --dataset ${shellSingleQuote(
21092
- record2.datasetPath
21093
- )} --out ${shellSingleQuote(`${record2.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
21160
+ if (record3.kind === "deepline_run_export" && typeof record3.runId === "string" && typeof record3.datasetPath === "string") {
21161
+ return `deepline runs export ${record3.runId} --dataset ${shellSingleQuote(
21162
+ record3.datasetPath
21163
+ )} --out ${shellSingleQuote(`${record3.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
21094
21164
  }
21095
- if (record2.kind === "deepline_run_logs") {
21096
- if (typeof record2.command === "string" && record2.command.trim()) {
21097
- return record2.command;
21165
+ if (record3.kind === "deepline_run_logs") {
21166
+ if (typeof record3.command === "string" && record3.command.trim()) {
21167
+ return record3.command;
21098
21168
  }
21099
- if (typeof record2.runId === "string") {
21100
- return record2.view === "failed" ? `deepline runs get ${record2.runId} --log-failed --json` : `deepline runs logs ${record2.runId} --json`;
21169
+ if (typeof record3.runId === "string") {
21170
+ return record3.view === "failed" ? `deepline runs get ${record3.runId} --log-failed --json` : `deepline runs logs ${record3.runId} --json`;
21101
21171
  }
21102
21172
  }
21103
- if (record2.kind === "deepline_db_query" && typeof record2.sql === "string") {
21104
- const maxRows = typeof record2.maxRows === "number" && Number.isFinite(record2.maxRows) ? Math.trunc(record2.maxRows) : 20;
21105
- return `deepline db query --sql ${shellSingleQuote(record2.sql)} --max-rows ${maxRows} --json`;
21173
+ if (record3.kind === "deepline_db_query" && typeof record3.sql === "string") {
21174
+ const maxRows = typeof record3.maxRows === "number" && Number.isFinite(record3.maxRows) ? Math.trunc(record3.maxRows) : 20;
21175
+ return `deepline db query --sql ${shellSingleQuote(record3.sql)} --max-rows ${maxRows} --json`;
21106
21176
  }
21107
21177
  return null;
21108
21178
  }
@@ -21177,8 +21247,8 @@ function formatPackageDatasetActionLines(packaged) {
21177
21247
  }
21178
21248
  function formatInlinePackageValue(value) {
21179
21249
  const compacted = compactReturnValue(value);
21180
- const json = JSON.stringify(compacted);
21181
- return clampJsonPreviewText(json ?? String(compacted), 500);
21250
+ const json2 = JSON.stringify(compacted);
21251
+ return clampJsonPreviewText(json2 ?? String(compacted), 500);
21182
21252
  }
21183
21253
  function formatPackageValueOutputLines(packaged) {
21184
21254
  const outputs = packaged.outputs && typeof packaged.outputs === "object" && !Array.isArray(packaged.outputs) ? packaged.outputs : null;
@@ -21511,12 +21581,12 @@ function exportableSheetRow(row) {
21511
21581
  if (!row || typeof row !== "object" || Array.isArray(row)) {
21512
21582
  return null;
21513
21583
  }
21514
- const record2 = row;
21515
- const data = record2.data;
21584
+ const record3 = row;
21585
+ const data = record3.data;
21516
21586
  if (data && typeof data === "object" && !Array.isArray(data)) {
21517
21587
  return data;
21518
21588
  }
21519
- const fallback = { ...record2 };
21589
+ const fallback = { ...record3 };
21520
21590
  for (const key of [
21521
21591
  "key",
21522
21592
  "status",
@@ -21535,7 +21605,7 @@ function exportableSheetRow(row) {
21535
21605
  return fallback;
21536
21606
  }
21537
21607
  function acceptsSettledRowsAsCompleteExport(status) {
21538
- return status.status === "failed" || status.status === "cancelled";
21608
+ return status.status === "completed" || status.status === "failed" || status.status === "cancelled";
21539
21609
  }
21540
21610
  function mergeExportColumns(preferredColumns, rows) {
21541
21611
  const columns = [];
@@ -21864,8 +21934,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
21864
21934
  "ctx.map(...) has been replaced by ctx.dataset(...)",
21865
21935
  "Dataset .step(...) has been replaced by .withColumn(...)"
21866
21936
  ];
21867
- function stringArrayField(record2, key) {
21868
- const value = record2[key];
21937
+ function stringArrayField(record3, key) {
21938
+ const value = record3[key];
21869
21939
  if (!Array.isArray(value)) return [];
21870
21940
  return value.filter((entry) => typeof entry === "string");
21871
21941
  }
@@ -22696,8 +22766,8 @@ function cronExecutionLabel(status) {
22696
22766
  return status;
22697
22767
  }
22698
22768
  function readLiveCronMetadata(play) {
22699
- const record2 = readRecord(play);
22700
- const metadata = readRecord(record2?.triggerMetadata);
22769
+ const record3 = readRecord(play);
22770
+ const metadata = readRecord(record3?.triggerMetadata);
22701
22771
  return {
22702
22772
  schedule: typeof metadata?.cronSchedule === "string" ? metadata.cronSchedule : null,
22703
22773
  timezone: typeof metadata?.cronTimezone === "string" ? metadata.cronTimezone : null,
@@ -28028,9 +28098,9 @@ async function expandCompiledConfigAtFiles(value) {
28028
28098
  if (!value || typeof value !== "object") {
28029
28099
  return value;
28030
28100
  }
28031
- const record2 = value;
28101
+ const record3 = value;
28032
28102
  const expanded = {};
28033
- for (const [key, entry] of Object.entries(record2)) {
28103
+ for (const [key, entry] of Object.entries(record3)) {
28034
28104
  expanded[key] = await expandCompiledConfigAtFiles(entry);
28035
28105
  }
28036
28106
  for (const field of ["extract_js", "run_if_js"]) {
@@ -28828,26 +28898,26 @@ function readFirstEnrichDatasetActions(value) {
28828
28898
  }
28829
28899
  return null;
28830
28900
  }
28831
- const record2 = candidate;
28832
- const actions = isRecord11(record2.actions) ? record2.actions : null;
28901
+ const record3 = candidate;
28902
+ const actions = isRecord11(record3.actions) ? record3.actions : null;
28833
28903
  const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
28834
28904
  const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
28835
28905
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
28836
28906
  if (query?.kind === "deepline_db_query") {
28837
28907
  return {
28838
- dataset: record2,
28908
+ dataset: record3,
28839
28909
  query,
28840
28910
  ...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
28841
28911
  };
28842
28912
  }
28843
- if (options.allowLegacy && record2.kind === "dataset" && typeof record2.queryDatasetCommand === "string" && record2.queryDatasetCommand.trim()) {
28913
+ if (options.allowLegacy && record3.kind === "dataset" && typeof record3.queryDatasetCommand === "string" && record3.queryDatasetCommand.trim()) {
28844
28914
  return {
28845
- dataset: record2,
28846
- queryDatasetCommand: record2.queryDatasetCommand.trim(),
28847
- ...typeof record2.slowExportAsCsvCommand === "string" && record2.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record2.slowExportAsCsvCommand.trim() } : {}
28915
+ dataset: record3,
28916
+ queryDatasetCommand: record3.queryDatasetCommand.trim(),
28917
+ ...typeof record3.slowExportAsCsvCommand === "string" && record3.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record3.slowExportAsCsvCommand.trim() } : {}
28848
28918
  };
28849
28919
  }
28850
- for (const [key, entry] of Object.entries(record2)) {
28920
+ for (const [key, entry] of Object.entries(record3)) {
28851
28921
  if (key === "preview") {
28852
28922
  continue;
28853
28923
  }
@@ -28863,8 +28933,8 @@ function readFirstEnrichDatasetActions(value) {
28863
28933
  seen.clear();
28864
28934
  return walk(value, { allowLegacy: true });
28865
28935
  }
28866
- function actionStringField(record2, key) {
28867
- const value = record2[key];
28936
+ function actionStringField(record3, key) {
28937
+ const value = record3[key];
28868
28938
  return typeof value === "string" && value.trim() ? value.trim() : null;
28869
28939
  }
28870
28940
  function parseSqlFromDbQueryCommand(command) {
@@ -29208,12 +29278,12 @@ function collectStringFields(value, key, output2, depth = 0) {
29208
29278
  }
29209
29279
  return;
29210
29280
  }
29211
- const record2 = value;
29212
- const direct = record2[key];
29281
+ const record3 = value;
29282
+ const direct = record3[key];
29213
29283
  if (typeof direct === "string" && direct.trim()) {
29214
29284
  output2.add(direct.trim());
29215
29285
  }
29216
- for (const child of Object.values(record2)) {
29286
+ for (const child of Object.values(record3)) {
29217
29287
  collectStringFields(child, key, output2, depth + 1);
29218
29288
  }
29219
29289
  }
@@ -29399,23 +29469,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
29399
29469
  if (!row || typeof row !== "object" || Array.isArray(row)) {
29400
29470
  return null;
29401
29471
  }
29402
- const record2 = row;
29403
- const data = record2.data;
29472
+ const record3 = row;
29473
+ const data = record3.data;
29404
29474
  if (data && typeof data === "object" && !Array.isArray(data)) {
29405
29475
  const exported = { ...data };
29406
29476
  applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
29407
- rowError: record2.error
29477
+ rowError: record3.error
29408
29478
  });
29409
- applyFailureCellMeta(exported, record2.cellMeta, { rowError: record2.error });
29410
- applyFailureCellMeta(exported, record2.cellMetaPatch, {
29411
- rowError: record2.error
29479
+ applyFailureCellMeta(exported, record3.cellMeta, { rowError: record3.error });
29480
+ applyFailureCellMeta(exported, record3.cellMetaPatch, {
29481
+ rowError: record3.error
29412
29482
  });
29413
- applyFailureCellMeta(exported, record2[ENRICH_CELL_META_PATCH_FIELD], {
29414
- rowError: record2.error
29483
+ applyFailureCellMeta(exported, record3[ENRICH_CELL_META_PATCH_FIELD], {
29484
+ rowError: record3.error
29415
29485
  });
29416
29486
  delete exported[ENRICH_CELL_META_FIELD];
29417
29487
  delete exported[ENRICH_CELL_META_PATCH_FIELD];
29418
- const inputIndex = typeof record2.inputIndex === "number" ? record2.inputIndex : typeof record2.inputIndex === "string" && record2.inputIndex.trim() ? Number(record2.inputIndex) : Number.NaN;
29488
+ const inputIndex = typeof record3.inputIndex === "number" ? record3.inputIndex : typeof record3.inputIndex === "string" && record3.inputIndex.trim() ? Number(record3.inputIndex) : Number.NaN;
29419
29489
  if (Number.isInteger(inputIndex) && inputIndex >= 0) {
29420
29490
  if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
29421
29491
  exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
@@ -29424,18 +29494,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
29424
29494
  }
29425
29495
  return exported;
29426
29496
  }
29427
- const fallback = { ...record2 };
29497
+ const fallback = { ...record3 };
29428
29498
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
29429
- rowError: record2.error
29499
+ rowError: record3.error
29430
29500
  });
29431
- applyFailureCellMeta(fallback, record2.cellMeta, {
29432
- rowError: record2.error
29501
+ applyFailureCellMeta(fallback, record3.cellMeta, {
29502
+ rowError: record3.error
29433
29503
  });
29434
- applyFailureCellMeta(fallback, record2.cellMetaPatch, {
29435
- rowError: record2.error
29504
+ applyFailureCellMeta(fallback, record3.cellMetaPatch, {
29505
+ rowError: record3.error
29436
29506
  });
29437
29507
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
29438
- rowError: record2.error
29508
+ rowError: record3.error
29439
29509
  });
29440
29510
  for (const key of [
29441
29511
  "key",
@@ -29654,16 +29724,16 @@ function isWaterfallResultMeaningful(value) {
29654
29724
  return value.some(isWaterfallResultMeaningful);
29655
29725
  }
29656
29726
  if (value && typeof value === "object") {
29657
- const record2 = value;
29658
- const status = typeof record2.status === "string" ? record2.status.trim().toLowerCase() : "";
29727
+ const record3 = value;
29728
+ const status = typeof record3.status === "string" ? record3.status.trim().toLowerCase() : "";
29659
29729
  if (status === "error" || status === "failed") {
29660
29730
  return false;
29661
29731
  }
29662
- if (typeof record2.error === "string" && record2.error.trim()) {
29732
+ if (typeof record3.error === "string" && record3.error.trim()) {
29663
29733
  return false;
29664
29734
  }
29665
- if (Object.prototype.hasOwnProperty.call(record2, "matched_result")) {
29666
- return isWaterfallResultMeaningful(record2.matched_result);
29735
+ if (Object.prototype.hasOwnProperty.call(record3, "matched_result")) {
29736
+ return isWaterfallResultMeaningful(record3.matched_result);
29667
29737
  }
29668
29738
  for (const key of [
29669
29739
  "value",
@@ -29678,11 +29748,11 @@ function isWaterfallResultMeaningful(value) {
29678
29748
  "result",
29679
29749
  "data"
29680
29750
  ]) {
29681
- if (isWaterfallResultMeaningful(record2[key])) {
29751
+ if (isWaterfallResultMeaningful(record3[key])) {
29682
29752
  return true;
29683
29753
  }
29684
29754
  }
29685
- return Object.entries(record2).some(
29755
+ return Object.entries(record3).some(
29686
29756
  ([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
29687
29757
  );
29688
29758
  }
@@ -29698,8 +29768,8 @@ function stableRowSnapshot(value) {
29698
29768
  return `[${value.map(stableRowSnapshot).join(",")}]`;
29699
29769
  }
29700
29770
  if (value && typeof value === "object") {
29701
- const record2 = value;
29702
- return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record2[key])}`).join(",")}}`;
29771
+ const record3 = value;
29772
+ return `{${Object.keys(record3).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record3[key])}`).join(",")}}`;
29703
29773
  }
29704
29774
  return JSON.stringify(value);
29705
29775
  }
@@ -30286,8 +30356,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
30286
30356
  seen.add(normalized);
30287
30357
  commands.push({ ...command, command: normalized });
30288
30358
  }
30289
- function datasetSelectorForEnrichCommand(record2, fallbackPath) {
30290
- const candidates = [record2.path, record2.tableNamespace, fallbackPath];
30359
+ function datasetSelectorForEnrichCommand(record3, fallbackPath) {
30360
+ const candidates = [record3.path, record3.tableNamespace, fallbackPath];
30291
30361
  for (const candidate of candidates) {
30292
30362
  if (typeof candidate === "string" && candidate.trim()) {
30293
30363
  return candidate.trim();
@@ -30349,19 +30419,19 @@ function collectDatasetFollowUpCommands(value, state) {
30349
30419
  );
30350
30420
  return;
30351
30421
  }
30352
- const record2 = value;
30353
- const isDataset = record2.kind === "dataset";
30422
+ const record3 = value;
30423
+ const isDataset = record3.kind === "dataset";
30354
30424
  if (isDataset) {
30355
- const selector = datasetSelectorForEnrichCommand(record2, state.path);
30356
- const labelPath = typeof record2.path === "string" && record2.path.trim() ? record2.path.trim() : selector ?? state.path;
30357
- if (typeof record2.queryDatasetCommand === "string") {
30425
+ const selector = datasetSelectorForEnrichCommand(record3, state.path);
30426
+ const labelPath = typeof record3.path === "string" && record3.path.trim() ? record3.path.trim() : selector ?? state.path;
30427
+ if (typeof record3.queryDatasetCommand === "string") {
30358
30428
  addEnrichFollowUpCommand(state.commands, state.seen, {
30359
30429
  label: `query ${labelPath}`,
30360
30430
  path: labelPath,
30361
- command: record2.queryDatasetCommand
30431
+ command: record3.queryDatasetCommand
30362
30432
  });
30363
30433
  }
30364
- const exportCommand = typeof record2.slowExportAsCsvCommand === "string" ? record2.slowExportAsCsvCommand : typeof record2.fullExportCommand === "string" ? record2.fullExportCommand : null;
30434
+ const exportCommand = typeof record3.slowExportAsCsvCommand === "string" ? record3.slowExportAsCsvCommand : typeof record3.fullExportCommand === "string" ? record3.fullExportCommand : null;
30365
30435
  if (exportCommand) {
30366
30436
  addEnrichFollowUpCommand(state.commands, state.seen, {
30367
30437
  label: `export ${labelPath}`,
@@ -30378,7 +30448,7 @@ function collectDatasetFollowUpCommands(value, state) {
30378
30448
  });
30379
30449
  }
30380
30450
  }
30381
- for (const [key, child] of Object.entries(record2)) {
30451
+ for (const [key, child] of Object.entries(record3)) {
30382
30452
  if (key === "preview" || key === "access") {
30383
30453
  continue;
30384
30454
  }
@@ -31852,9 +31922,9 @@ function readCodexSessionId(filePath) {
31852
31922
  )) {
31853
31923
  const parsed = parseJsonLine(line);
31854
31924
  if (!parsed || typeof parsed !== "object") continue;
31855
- const record2 = parsed;
31856
- const payload = record2.payload && typeof record2.payload === "object" ? record2.payload : null;
31857
- const id = record2.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
31925
+ const record3 = parsed;
31926
+ const payload = record3.payload && typeof record3.payload === "object" ? record3.payload : null;
31927
+ const id = record3.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
31858
31928
  if (id && UUID_RE.test(id)) return id;
31859
31929
  }
31860
31930
  } catch {
@@ -31953,15 +32023,15 @@ function messageContentKey(value) {
31953
32023
  if (!Array.isArray(content)) return null;
31954
32024
  return content.map((block) => {
31955
32025
  if (!block || typeof block !== "object") return String(block);
31956
- const record2 = block;
31957
- const type = String(record2.type ?? "");
32026
+ const record3 = block;
32027
+ const type = String(record3.type ?? "");
31958
32028
  if (type === "tool_use") {
31959
- return `tool_use:${String(record2.name ?? "")}:${String(record2.id ?? "")}`;
32029
+ return `tool_use:${String(record3.name ?? "")}:${String(record3.id ?? "")}`;
31960
32030
  }
31961
32031
  if (type === "tool_result") {
31962
- return `tool_result:${String(record2.tool_use_id ?? "")}`;
32032
+ return `tool_result:${String(record3.tool_use_id ?? "")}`;
31963
32033
  }
31964
- return String(record2.text ?? type);
32034
+ return String(record3.text ?? type);
31965
32035
  }).join("\n");
31966
32036
  }
31967
32037
  function dedupConsecutiveEvents(raw) {
@@ -31976,9 +32046,9 @@ function dedupConsecutiveEvents(raw) {
31976
32046
  index += 1;
31977
32047
  continue;
31978
32048
  }
31979
- const record2 = event;
31980
- const eventType = String(record2.type ?? "");
31981
- const eventKey = messageContentKey(record2);
32049
+ const record3 = event;
32050
+ const eventType = String(record3.type ?? "");
32051
+ const eventKey = messageContentKey(record3);
31982
32052
  if (!["user", "assistant"].includes(eventType) || !eventKey) {
31983
32053
  output2.push(rawLines[index] ?? "");
31984
32054
  index += 1;
@@ -31997,9 +32067,9 @@ function dedupConsecutiveEvents(raw) {
31997
32067
  cursor += 1;
31998
32068
  }
31999
32069
  if (runCount > 1) {
32000
- record2._repeat_count = runCount;
32001
- record2._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
32002
- output2.push(JSON.stringify(record2));
32070
+ record3._repeat_count = runCount;
32071
+ record3._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
32072
+ output2.push(JSON.stringify(record3));
32003
32073
  index = cursor;
32004
32074
  continue;
32005
32075
  }
@@ -32044,9 +32114,9 @@ function selectiveCompactToolResults(raw) {
32044
32114
  lines.push(line);
32045
32115
  continue;
32046
32116
  }
32047
- const record2 = parsed;
32048
- if (record2.type === "user") {
32049
- const message = record2.message;
32117
+ const record3 = parsed;
32118
+ if (record3.type === "user") {
32119
+ const message = record3.message;
32050
32120
  const content = message && typeof message === "object" ? message.content : null;
32051
32121
  if (Array.isArray(content)) {
32052
32122
  message.content = content.map(
@@ -32054,7 +32124,7 @@ function selectiveCompactToolResults(raw) {
32054
32124
  );
32055
32125
  }
32056
32126
  }
32057
- lines.push(JSON.stringify(record2));
32127
+ lines.push(JSON.stringify(record3));
32058
32128
  }
32059
32129
  return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
32060
32130
  ` : "", "utf8");
@@ -32080,15 +32150,15 @@ function compactCodexEvents(raw) {
32080
32150
  lines.push(rawLines[index] ?? "");
32081
32151
  return;
32082
32152
  }
32083
- const record2 = event;
32084
- if (record2.type === "world_state") return;
32085
- const payload = record2.payload;
32153
+ const record3 = event;
32154
+ if (record3.type === "world_state") return;
32155
+ const payload = record3.payload;
32086
32156
  const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
32087
32157
  if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
32088
32158
  if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
32089
32159
  const record_payload = payload;
32090
32160
  record_payload.output = compactEventValue(record_payload.output);
32091
- lines.push(JSON.stringify(record2));
32161
+ lines.push(JSON.stringify(record3));
32092
32162
  return;
32093
32163
  }
32094
32164
  lines.push(rawLines[index] ?? "");
@@ -32294,8 +32364,8 @@ function parsePreparedEvents(buffer) {
32294
32364
  return parsed ?? line;
32295
32365
  });
32296
32366
  }
32297
- function escapeJsonForHtmlScript(json) {
32298
- return json.replace(/</g, "\\u003c");
32367
+ function escapeJsonForHtmlScript(json2) {
32368
+ return json2.replace(/</g, "\\u003c");
32299
32369
  }
32300
32370
  async function handleSessionsRender(options) {
32301
32371
  const targets = resolveSessionTargets({
@@ -32556,11 +32626,317 @@ import { readFileSync as readFileSync11, writeFileSync as writeFileSync12 } from
32556
32626
  import { resolve as resolve14 } from "path";
32557
32627
  import { createInterface } from "readline/promises";
32558
32628
 
32629
+ // ../integration-contracts/monitor-input-contract.ts
32630
+ import Handlebars from "handlebars";
32631
+ function authoredMonitorFieldPath(path, field) {
32632
+ const batch = /^monitors\.(\d+)$/.exec(path);
32633
+ return `${batch ? `monitors[${batch[1]}]` : path}.${field}`;
32634
+ }
32635
+ function record(value) {
32636
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
32637
+ }
32638
+ function json(value, path, issues) {
32639
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
32640
+ return;
32641
+ }
32642
+ if (Array.isArray(value)) {
32643
+ value.forEach((child, index) => json(child, `${path}.${index}`, issues));
32644
+ return;
32645
+ }
32646
+ const object = record(value);
32647
+ if (!object) {
32648
+ issues.push({
32649
+ severity: "error",
32650
+ code: "invalid_monitor_json_value",
32651
+ path,
32652
+ message: "Monitor values must be JSON values."
32653
+ });
32654
+ return;
32655
+ }
32656
+ for (const [key, child] of Object.entries(object)) {
32657
+ json(child, `${path}.${key}`, issues);
32658
+ }
32659
+ }
32660
+ function monitorSpec(value, path, issues) {
32661
+ const input2 = record(value);
32662
+ if (!input2) {
32663
+ issues.push({
32664
+ severity: "error",
32665
+ code: "invalid_monitor_spec",
32666
+ path,
32667
+ message: "A monitor must be a JSON object."
32668
+ });
32669
+ return null;
32670
+ }
32671
+ const allowed = /* @__PURE__ */ new Set(["key", "tool", "name", "payload"]);
32672
+ for (const key2 of Object.keys(input2)) {
32673
+ if (!allowed.has(key2)) {
32674
+ if (key2 === "controls") {
32675
+ issues.push({
32676
+ severity: "error",
32677
+ code: "CONTROLS_NOT_SUPPORTED",
32678
+ path: authoredMonitorFieldPath(path, "controls"),
32679
+ message: "Operational controls are managed by Deepline and cannot be authored in Batch or Fleet JSON.",
32680
+ suggestion: "Remove controls. Bind downstream automation in a Play with sqlListeners."
32681
+ });
32682
+ continue;
32683
+ }
32684
+ if (key2 === "play") {
32685
+ issues.push({
32686
+ severity: "error",
32687
+ code: "PLAY_BINDING_NOT_IN_MONITOR_SPEC",
32688
+ path: authoredMonitorFieldPath(path, "play"),
32689
+ message: "A monitor does not own Play bindings.",
32690
+ suggestion: "Declare sqlListeners in the Play, or run: deepline plays bootstrap monitor-triggered --out on-event.play.ts"
32691
+ });
32692
+ continue;
32693
+ }
32694
+ issues.push({
32695
+ severity: "error",
32696
+ code: "unknown_monitor_field",
32697
+ path: `${path}.${key2}`,
32698
+ message: `Monitor definitions do not accept '${key2}'.`
32699
+ });
32700
+ }
32701
+ }
32702
+ const key = typeof input2.key === "string" ? input2.key.trim() : "";
32703
+ const tool = typeof input2.tool === "string" ? input2.tool.trim() : "";
32704
+ const name = input2.name === void 0 ? void 0 : typeof input2.name === "string" && input2.name.trim() ? input2.name.trim() : null;
32705
+ const payload = record(input2.payload);
32706
+ if (!key) {
32707
+ issues.push({
32708
+ severity: "error",
32709
+ code: "invalid_monitor_key",
32710
+ path: `${path}.key`,
32711
+ message: "Monitor key must be a non-empty string."
32712
+ });
32713
+ }
32714
+ if (!tool) {
32715
+ issues.push({
32716
+ severity: "error",
32717
+ code: "invalid_monitor_tool",
32718
+ path: `${path}.tool`,
32719
+ message: "Monitor tool must be a non-empty literal string."
32720
+ });
32721
+ }
32722
+ if (name === null) {
32723
+ issues.push({
32724
+ severity: "error",
32725
+ code: "invalid_monitor_name",
32726
+ path: `${path}.name`,
32727
+ message: "Monitor name must be a non-empty string when supplied."
32728
+ });
32729
+ }
32730
+ if (!payload) {
32731
+ issues.push({
32732
+ severity: "error",
32733
+ code: "invalid_monitor_payload",
32734
+ path: `${path}.payload`,
32735
+ message: "Monitor payload must be an object."
32736
+ });
32737
+ } else {
32738
+ json(payload, `${path}.payload`, issues);
32739
+ }
32740
+ if (!key || !tool || !payload || name === null) {
32741
+ return null;
32742
+ }
32743
+ return {
32744
+ key,
32745
+ tool,
32746
+ ...name ? { name } : {},
32747
+ payload
32748
+ };
32749
+ }
32750
+ function issueOrder(left, right) {
32751
+ return left.path.localeCompare(right.path) || left.severity.localeCompare(right.severity) || left.code.localeCompare(right.code);
32752
+ }
32753
+ function lintMonitorBatchInput(value) {
32754
+ const issues = [];
32755
+ const versionlessEnvelope = !Array.isArray(value) && (() => {
32756
+ const candidate = record(value);
32757
+ return candidate !== null && Object.keys(candidate).length === 1 && Object.prototype.hasOwnProperty.call(candidate, "monitors");
32758
+ })();
32759
+ const legacy = Array.isArray(value) || versionlessEnvelope;
32760
+ const input2 = legacy ? null : record(value);
32761
+ let monitors = Array.isArray(value) ? value : versionlessEnvelope ? (() => {
32762
+ const candidate = record(value)?.monitors;
32763
+ return Array.isArray(candidate) ? candidate : null;
32764
+ })() : null;
32765
+ if (Array.isArray(value)) {
32766
+ issues.push({
32767
+ severity: "warning",
32768
+ code: "deprecated_batch_array",
32769
+ path: "",
32770
+ message: "Bare monitor arrays are supported for compatibility.",
32771
+ suggestion: 'Wrap the list in {"version":1,"kind":"batch","monitors":[...]}.'
32772
+ });
32773
+ } else if (versionlessEnvelope) {
32774
+ issues.push({
32775
+ severity: "warning",
32776
+ code: "deprecated_batch_missing_envelope_fields",
32777
+ path: "",
32778
+ message: "Versionless monitor envelopes are supported for compatibility.",
32779
+ suggestion: 'Add "version": 1 and "kind": "batch".'
32780
+ });
32781
+ if (!monitors) {
32782
+ issues.push({
32783
+ severity: "error",
32784
+ code: "invalid_batch_monitors",
32785
+ path: "monitors",
32786
+ message: "Batch monitors must be an array."
32787
+ });
32788
+ }
32789
+ } else if (!input2) {
32790
+ issues.push({
32791
+ severity: "error",
32792
+ code: "invalid_batch",
32793
+ path: "",
32794
+ message: "Batch input must be an object or a legacy array."
32795
+ });
32796
+ } else {
32797
+ for (const key of Object.keys(input2)) {
32798
+ if (!["version", "kind", "monitors"].includes(key)) {
32799
+ issues.push({
32800
+ severity: "error",
32801
+ code: key === "source" || key === "monitor" ? "batch_fleet_shape_mixup" : "unknown_batch_field",
32802
+ path: key,
32803
+ message: `Batch input does not accept '${key}'.`
32804
+ });
32805
+ }
32806
+ }
32807
+ if (input2.version !== 1) {
32808
+ issues.push({
32809
+ severity: "error",
32810
+ code: "unsupported_batch_version",
32811
+ path: "version",
32812
+ message: "Batch input version must be 1."
32813
+ });
32814
+ }
32815
+ if (input2.kind !== "batch") {
32816
+ issues.push({
32817
+ severity: "error",
32818
+ code: "invalid_batch_kind",
32819
+ path: "kind",
32820
+ message: 'Batch input kind must be "batch".'
32821
+ });
32822
+ }
32823
+ monitors = Array.isArray(input2.monitors) ? input2.monitors : null;
32824
+ if (!monitors) {
32825
+ issues.push({
32826
+ severity: "error",
32827
+ code: "invalid_batch_monitors",
32828
+ path: "monitors",
32829
+ message: "Batch monitors must be an array."
32830
+ });
32831
+ }
32832
+ }
32833
+ if (!monitors || monitors.length === 0) {
32834
+ if (monitors?.length === 0) {
32835
+ issues.push({
32836
+ severity: "error",
32837
+ code: "empty_batch",
32838
+ path: "monitors",
32839
+ message: "A Batch needs at least one monitor."
32840
+ });
32841
+ }
32842
+ return { issues: issues.sort(issueOrder) };
32843
+ }
32844
+ const normalized = monitors.map(
32845
+ (item, index) => monitorSpec(item, `monitors.${index}`, issues)
32846
+ );
32847
+ const seen = /* @__PURE__ */ new Map();
32848
+ normalized.forEach((item, index) => {
32849
+ if (!item) return;
32850
+ const first = seen.get(item.key);
32851
+ if (first !== void 0) {
32852
+ for (const position of [first, index]) {
32853
+ issues.push({
32854
+ severity: "error",
32855
+ code: "duplicate_monitor_key",
32856
+ path: `monitors.${position}.key`,
32857
+ message: `Duplicate monitor key '${item.key}'.`
32858
+ });
32859
+ }
32860
+ } else {
32861
+ seen.set(item.key, index);
32862
+ }
32863
+ });
32864
+ const ordered = issues.sort(issueOrder);
32865
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : {
32866
+ normalized: {
32867
+ version: 1,
32868
+ kind: "batch",
32869
+ monitors: normalized
32870
+ },
32871
+ issues: ordered
32872
+ };
32873
+ }
32874
+ function validateHandlebars(value, path, issues) {
32875
+ if (!value.includes("{{")) return;
32876
+ try {
32877
+ Handlebars.parse(value);
32878
+ } catch (error) {
32879
+ issues.push({
32880
+ severity: "error",
32881
+ code: "invalid_handlebars_template",
32882
+ path,
32883
+ message: error instanceof Error ? error.message : "Invalid Handlebars template."
32884
+ });
32885
+ return;
32886
+ }
32887
+ const expressions = value.match(/{{[\s\S]*?}}/g) ?? [];
32888
+ if (expressions.some(
32889
+ (expression) => !/^{{\s*[A-Za-z_][A-Za-z0-9_]*\s*}}$/.test(expression)
32890
+ )) {
32891
+ issues.push({
32892
+ severity: "error",
32893
+ code: "unsupported_handlebars_expression",
32894
+ path,
32895
+ message: "Fleet templates allow only direct source-row fields such as {{domain}}; helpers, blocks, partials, paths, and prototype access are disabled."
32896
+ });
32897
+ }
32898
+ }
32899
+ function walkTemplates(value, path, issues) {
32900
+ if (typeof value === "string") return validateHandlebars(value, path, issues);
32901
+ if (Array.isArray(value)) {
32902
+ value.forEach(
32903
+ (item, index) => walkTemplates(item, `${path}.${index}`, issues)
32904
+ );
32905
+ return;
32906
+ }
32907
+ const input2 = record(value);
32908
+ if (!input2) return;
32909
+ for (const [key, child] of Object.entries(input2)) {
32910
+ walkTemplates(child, `${path}.${key}`, issues);
32911
+ }
32912
+ }
32913
+ function lintMonitorSpecTemplate(value, path = "monitor") {
32914
+ const issues = [];
32915
+ const normalized = monitorSpec(value, path, issues);
32916
+ const input2 = record(value);
32917
+ if (input2 && typeof input2.tool === "string" && input2.tool.includes("{{")) {
32918
+ issues.push({
32919
+ severity: "error",
32920
+ code: "templated_monitor_tool",
32921
+ path: `${path}.tool`,
32922
+ message: "Fleet monitor tool must be literal; only key, name, and payload may be templated."
32923
+ });
32924
+ }
32925
+ if (input2) {
32926
+ for (const field of ["key", "name", "payload"]) {
32927
+ if (input2[field] !== void 0)
32928
+ walkTemplates(input2[field], `${path}.${field}`, issues);
32929
+ }
32930
+ }
32931
+ const ordered = issues.sort(issueOrder);
32932
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : { normalized, issues: ordered };
32933
+ }
32934
+
32559
32935
  // ../integration-contracts/monitor-fleet-contract.ts
32560
32936
  var MONITOR_FLEET_MAX_MEMBERS = 1e3;
32561
- var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
32562
32937
  var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
32563
- MONITOR_FLEET_AUTHORING_CONTRACT_EDITION
32938
+ 1,
32939
+ 2
32564
32940
  ];
32565
32941
  var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
32566
32942
  var MONITOR_FLEET_DOCUMENTATION = {
@@ -32568,11 +32944,11 @@ var MONITOR_FLEET_DOCUMENTATION = {
32568
32944
  authoredFields: {
32569
32945
  id: "Stable lowercase fleet id used by sync, get, and deactivate.",
32570
32946
  source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
32571
- member: "Ordinary monitor tool, stable key template, and payload evaluated for each selected source row.",
32947
+ monitor: "One Batch-compatible MonitorSpec. Direct Handlebars source-row fields such as {{domain}} are rendered for each selected row.",
32572
32948
  selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
32573
32949
  },
32574
32950
  fixedPolicy: {
32575
- cadence: "daily",
32951
+ cadence: "60s fair bounded source refresh",
32576
32952
  membership: "sticky",
32577
32953
  removalGrace: "7d",
32578
32954
  onRemoved: "deactivate",
@@ -32580,9 +32956,10 @@ var MONITOR_FLEET_DOCUMENTATION = {
32580
32956
  billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
32581
32957
  },
32582
32958
  stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
32583
- columnExpression: 'Use { "$fleet": "column", "name": "column_name" } in a member key or payload to read a value from each source row.'
32959
+ templating: "Use direct Handlebars fields such as {{domain}} in monitor key, name, or payload. Helpers, blocks, partials, paths, and prototype access are disabled.",
32960
+ legacyCompatibility: 'Edition 1 member/$fleet files remain readable with a lint warning; new files should use version: 2, kind: "fleet", and monitor.'
32584
32961
  };
32585
- function record(value) {
32962
+ function record2(value) {
32586
32963
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
32587
32964
  }
32588
32965
  function identifier(value) {
@@ -32607,7 +32984,7 @@ function jsonValue(value, path, issues) {
32607
32984
  value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
32608
32985
  return;
32609
32986
  }
32610
- const input2 = record(value);
32987
+ const input2 = record2(value);
32611
32988
  if (!input2) {
32612
32989
  issues.push({
32613
32990
  path,
@@ -32621,7 +32998,7 @@ function jsonValue(value, path, issues) {
32621
32998
  }
32622
32999
  }
32623
33000
  function validateExpression(value, path, issues) {
32624
- const input2 = record(value);
33001
+ const input2 = record2(value);
32625
33002
  if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
32626
33003
  issues.push({
32627
33004
  path,
@@ -32639,7 +33016,7 @@ function walkPayload(value, path, issues) {
32639
33016
  );
32640
33017
  return;
32641
33018
  }
32642
- const input2 = record(value);
33019
+ const input2 = record2(value);
32643
33020
  if (!input2) return;
32644
33021
  if ("$fleet" in input2) {
32645
33022
  validateExpression(input2, path, issues);
@@ -32649,9 +33026,9 @@ function walkPayload(value, path, issues) {
32649
33026
  walkPayload(item, `${path}.${key}`, issues);
32650
33027
  }
32651
33028
  }
32652
- function validateMonitorFleetDefinition(value) {
33029
+ function validateMonitorFleetDefinitionV1(value) {
32653
33030
  const issues = [];
32654
- const input2 = record(value);
33031
+ const input2 = record2(value);
32655
33032
  if (!input2) {
32656
33033
  return {
32657
33034
  valid: false,
@@ -32672,7 +33049,7 @@ function validateMonitorFleetDefinition(value) {
32672
33049
  message: "Fleet id must be lowercase kebab-case."
32673
33050
  });
32674
33051
  }
32675
- const source = record(input2.source);
33052
+ const source = record2(input2.source);
32676
33053
  exactKeys(
32677
33054
  source,
32678
33055
  ["kind", "schema", "table", "key", "where"],
@@ -32693,7 +33070,7 @@ function validateMonitorFleetDefinition(value) {
32693
33070
  message: "Source schema and table must be SQL identifiers."
32694
33071
  });
32695
33072
  }
32696
- const sourceKey = record(source?.key);
33073
+ const sourceKey = record2(source?.key);
32697
33074
  exactKeys(sourceKey, ["column", "type"], "source.key", issues);
32698
33075
  if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
32699
33076
  issues.push({
@@ -32703,7 +33080,7 @@ function validateMonitorFleetDefinition(value) {
32703
33080
  });
32704
33081
  }
32705
33082
  if (source?.where !== void 0) {
32706
- const where = record(source.where);
33083
+ const where = record2(source.where);
32707
33084
  if (!where) {
32708
33085
  issues.push({
32709
33086
  path: "source.where",
@@ -32729,9 +33106,9 @@ function validateMonitorFleetDefinition(value) {
32729
33106
  }
32730
33107
  }
32731
33108
  }
32732
- const member = record(input2.member);
33109
+ const member = record2(input2.member);
32733
33110
  exactKeys(member, ["tool", "key", "payload"], "member", issues);
32734
- const key = record(member?.key);
33111
+ const key = record2(member?.key);
32735
33112
  if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
32736
33113
  issues.push({
32737
33114
  path: "member.tool",
@@ -32752,7 +33129,7 @@ function validateMonitorFleetDefinition(value) {
32752
33129
  validateExpression(part, `member.key.parts.${index}`, issues);
32753
33130
  }
32754
33131
  if (sourceKey && !key.parts.some(
32755
- (part) => record(part)?.$fleet === "column" && record(part)?.name === sourceKey.column
33132
+ (part) => record2(part)?.$fleet === "column" && record2(part)?.name === sourceKey.column
32756
33133
  )) {
32757
33134
  issues.push({
32758
33135
  path: "member.key.parts",
@@ -32771,7 +33148,7 @@ function validateMonitorFleetDefinition(value) {
32771
33148
  jsonValue(member.payload, "member.payload", issues);
32772
33149
  }
32773
33150
  walkPayload(member?.payload, "member.payload", issues);
32774
- const selection = record(input2.selection);
33151
+ const selection = record2(input2.selection);
32775
33152
  exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
32776
33153
  if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
32777
33154
  issues.push({
@@ -32797,7 +33174,7 @@ function validateMonitorFleetDefinition(value) {
32797
33174
  } else {
32798
33175
  const orderColumns = /* @__PURE__ */ new Set();
32799
33176
  for (const [index, order] of orderBy.entries()) {
32800
- const item = record(order);
33177
+ const item = record2(order);
32801
33178
  exactKeys(
32802
33179
  item,
32803
33180
  ["column", "direction"],
@@ -32820,7 +33197,7 @@ function validateMonitorFleetDefinition(value) {
32820
33197
  orderColumns.add(item.column);
32821
33198
  }
32822
33199
  }
32823
- if (sourceKey && record(orderBy.at(-1))?.column !== sourceKey.column) {
33200
+ if (sourceKey && record2(orderBy.at(-1))?.column !== sourceKey.column) {
32824
33201
  issues.push({
32825
33202
  path: "selection.orderBy",
32826
33203
  code: "fleet_order_missing_key",
@@ -32839,9 +33216,100 @@ function validateMonitorFleetDefinition(value) {
32839
33216
  }
32840
33217
  return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
32841
33218
  }
32842
- function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHORING_CONTRACT_EDITION) {
33219
+ function v2Issue(issue) {
33220
+ return { path: issue.path, code: issue.code, message: issue.message };
33221
+ }
33222
+ function validateMonitorFleetDefinitionV2(value) {
33223
+ const issues = [];
33224
+ const input2 = record2(value);
33225
+ if (!input2) {
33226
+ return {
33227
+ valid: false,
33228
+ issues: [
33229
+ {
33230
+ path: "",
33231
+ code: "invalid_fleet",
33232
+ message: "Fleet must be an object."
33233
+ }
33234
+ ]
33235
+ };
33236
+ }
33237
+ exactKeys(
33238
+ input2,
33239
+ ["version", "kind", "id", "source", "monitor", "selection"],
33240
+ "",
33241
+ issues
33242
+ );
33243
+ if (input2.version !== 2) {
33244
+ issues.push({
33245
+ path: "version",
33246
+ code: "unsupported_fleet_version",
33247
+ message: "Canonical Fleet input version must be 2."
33248
+ });
33249
+ }
33250
+ if (input2.kind !== "fleet") {
33251
+ issues.push({
33252
+ path: "kind",
33253
+ code: "invalid_fleet_kind",
33254
+ message: 'Canonical Fleet input kind must be "fleet".'
33255
+ });
33256
+ }
33257
+ const source = record2(input2.source);
33258
+ const sourceKey = record2(source?.key);
33259
+ const legacyShape = {
33260
+ id: input2.id,
33261
+ source: input2.source,
33262
+ member: {
33263
+ tool: record2(input2.monitor)?.tool,
33264
+ key: {
33265
+ $fleet: "template",
33266
+ parts: [
33267
+ "fleet-",
33268
+ {
33269
+ $fleet: "column",
33270
+ name: typeof sourceKey?.column === "string" ? sourceKey.column : "invalid_source_key"
33271
+ }
33272
+ ]
33273
+ },
33274
+ payload: record2(input2.monitor)?.payload
33275
+ },
33276
+ selection: input2.selection
33277
+ };
33278
+ const legacyCheck = validateMonitorFleetDefinitionV1(legacyShape);
33279
+ for (const issue of legacyCheck.issues) {
33280
+ issues.push({
33281
+ ...issue,
33282
+ path: issue.path.replace(/^member\./, "monitor.")
33283
+ });
33284
+ }
33285
+ const monitorInput = record2(input2.monitor);
33286
+ const monitorKey = monitorInput?.key;
33287
+ const monitor = lintMonitorSpecTemplate(input2.monitor);
33288
+ issues.push(...monitor.issues.map(v2Issue));
33289
+ if (typeof monitorKey === "string" && typeof sourceKey?.column === "string" && !monitorKey.includes(`{{${sourceKey.column}}}`)) {
33290
+ issues.push({
33291
+ path: "monitor.key",
33292
+ code: "fleet_key_missing_source_key",
33293
+ message: "Monitor key must include the source key as a direct Handlebars expression."
33294
+ });
33295
+ }
33296
+ return issues.length === 0 && monitor.normalized ? {
33297
+ valid: true,
33298
+ definition: {
33299
+ version: 2,
33300
+ kind: "fleet",
33301
+ id: String(input2.id),
33302
+ source: input2.source,
33303
+ monitor: monitor.normalized,
33304
+ selection: input2.selection
33305
+ },
33306
+ issues
33307
+ } : { valid: false, issues };
33308
+ }
33309
+ function admitMonitorFleetAuthoringContract(value, edition) {
33310
+ const detectedEdition = edition ?? (record2(value)?.version === 2 || record2(value)?.kind === "fleet" ? 2 : 1);
32843
33311
  if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
32844
- edition
33312
+ detectedEdition
32845
33313
  )) {
32846
33314
  return {
32847
33315
  valid: false,
@@ -32849,16 +33317,16 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
32849
33317
  {
32850
33318
  path: "authoring_contract_edition",
32851
33319
  code: "unsupported_fleet_authoring_contract_edition",
32852
- message: `Monitor Fleet authoring contract edition ${edition} is not supported.`
33320
+ message: `Monitor Fleet authoring contract edition ${detectedEdition} is not supported.`
32853
33321
  }
32854
33322
  ]
32855
33323
  };
32856
33324
  }
32857
- const result = validateMonitorFleetDefinition(value);
33325
+ const result = detectedEdition === 2 ? validateMonitorFleetDefinitionV2(value) : validateMonitorFleetDefinitionV1(value);
32858
33326
  return result.valid && result.definition ? {
32859
33327
  valid: true,
32860
33328
  contract: {
32861
- edition,
33329
+ edition: detectedEdition,
32862
33330
  // JSON cloning prevents later caller mutation from changing the
32863
33331
  // admitted snapshot.
32864
33332
  definition: JSON.parse(
@@ -32868,6 +33336,32 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
32868
33336
  issues: []
32869
33337
  } : { valid: false, issues: result.issues };
32870
33338
  }
33339
+ function lintMonitorFleetInput(value) {
33340
+ const input2 = record2(value);
33341
+ const legacy = input2?.member !== void 0;
33342
+ const admitted = admitMonitorFleetAuthoringContract(value);
33343
+ const issues = admitted.issues.map((issue) => ({
33344
+ ...issue,
33345
+ severity: "error"
33346
+ }));
33347
+ if (legacy) {
33348
+ issues.push({
33349
+ severity: "warning",
33350
+ code: "deprecated_fleet_member",
33351
+ path: "member",
33352
+ message: "Legacy Fleet member syntax remains supported."
33353
+ });
33354
+ if (JSON.stringify(input2).includes('"$fleet"')) {
33355
+ issues.push({
33356
+ severity: "warning",
33357
+ code: "deprecated_fleet_expression",
33358
+ path: "member",
33359
+ message: "Legacy $fleet expressions remain supported; use direct Handlebars fields in monitor instead."
33360
+ });
33361
+ }
33362
+ }
33363
+ return admitted.valid && admitted.contract ? { normalized: admitted.contract.definition, issues } : { issues };
33364
+ }
32871
33365
 
32872
33366
  // src/cli/commands/monitors.ts
32873
33367
  var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
@@ -33553,6 +34047,155 @@ function fleetIdempotencyKey(operation, supplied) {
33553
34047
  }
33554
34048
  return normalized ?? `monitor-fleet-${operation}-${randomUUID5()}`;
33555
34049
  }
34050
+ function monitorJobIdempotencyKey(operation, supplied) {
34051
+ const normalized = supplied?.trim();
34052
+ if (supplied !== void 0 && !normalized) {
34053
+ throw new MonitorsUsageError("--idempotency-key must not be empty.");
34054
+ }
34055
+ return normalized ?? `monitor-job-${operation}-${randomUUID5()}`;
34056
+ }
34057
+ function readMonitorDefinitionsJsonFile(file) {
34058
+ let raw;
34059
+ try {
34060
+ raw = file === "-" ? readFileSync11(0, "utf8") : readFileSync11(file, "utf8");
34061
+ } catch (error) {
34062
+ throw new MonitorsUsageError(
34063
+ `Could not read --file ${file}: ${error instanceof Error ? error.message : String(error)}`
34064
+ );
34065
+ }
34066
+ try {
34067
+ return JSON.parse(raw);
34068
+ } catch (error) {
34069
+ throw new MonitorsUsageError(
34070
+ `Monitor definitions must be valid JSON. ${error instanceof Error ? error.message : String(error)}`
34071
+ );
34072
+ }
34073
+ }
34074
+ function renderMonitorJob(payload) {
34075
+ const job = asRecord2(payload.job);
34076
+ if (!job) return void 0;
34077
+ const id = asString(job.id) ?? "<unknown>";
34078
+ const state = asString(job.state) ?? "unknown";
34079
+ const phase = asString(job.phase);
34080
+ const counts = asRecord2(job.counts);
34081
+ const reconciliation = asRecord2(job.reconciliation);
34082
+ const lines = [
34083
+ `Monitor job: ${id}`,
34084
+ `State: ${state}${phase ? ` (${phase})` : ""}`
34085
+ ];
34086
+ if (counts) {
34087
+ lines.push(
34088
+ `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}`
34089
+ );
34090
+ }
34091
+ if (reconciliation) {
34092
+ lines.push(
34093
+ `Reconciliation: ${asString(reconciliation.state) ?? "pending"} (${asFiniteNumber(reconciliation.observed_bindings) ?? 0}/${asFiniteNumber(reconciliation.expected_bindings) ?? 0} bindings observed)`
34094
+ );
34095
+ }
34096
+ const next = asString(payload.next);
34097
+ if (next) lines.push(`Next: ${next}`);
34098
+ return `${lines.join("\n")}
34099
+ `;
34100
+ }
34101
+ async function handleMonitorJobBatchDeploy(options, idempotencyKey) {
34102
+ if (!options.file) {
34103
+ throw new MonitorsUsageError(
34104
+ "A Batch file is required. Pass --file batch.json (or --file - for stdin)."
34105
+ );
34106
+ }
34107
+ const lint = lintMonitorBatchInput(
34108
+ readMonitorDefinitionsJsonFile(options.file)
34109
+ );
34110
+ if (!lint.normalized) {
34111
+ throw new MonitorsUsageError(
34112
+ lint.issues.filter((issue) => issue.severity === "error").map((issue) => `${issue.path || "batch"}: ${issue.message}`).join("; ")
34113
+ );
34114
+ }
34115
+ const payload = await new DeeplineClient().monitors.batch.deploy(
34116
+ lint.normalized.monitors,
34117
+ { idempotencyKey }
34118
+ );
34119
+ printCommandEnvelope(
34120
+ {
34121
+ ...payload,
34122
+ idempotency_key: idempotencyKey,
34123
+ ...lint.issues.length ? { lint: { issues: lint.issues } } : {}
34124
+ },
34125
+ { json: options.json, text: renderMonitorJob(payload) }
34126
+ );
34127
+ }
34128
+ async function handleMonitorBatchLint(options) {
34129
+ if (!options.file) {
34130
+ throw new MonitorsUsageError(
34131
+ "monitors batch lint requires --file <batch.json>."
34132
+ );
34133
+ }
34134
+ const result = lintMonitorBatchInput(
34135
+ readMonitorDefinitionsJsonFile(options.file)
34136
+ );
34137
+ printCommandEnvelope(
34138
+ {
34139
+ ok: !result.issues.some((issue) => issue.severity === "error"),
34140
+ ...result.normalized ? { normalized: result.normalized } : {},
34141
+ issues: result.issues
34142
+ },
34143
+ { json: options.json }
34144
+ );
34145
+ if (result.issues.some((issue) => issue.severity === "error"))
34146
+ process.exitCode = 2;
34147
+ }
34148
+ async function handleMonitorFleetLint(options) {
34149
+ if (!options.file) {
34150
+ throw new MonitorsUsageError(
34151
+ "monitors fleets lint requires --file <fleet.json>."
34152
+ );
34153
+ }
34154
+ const result = lintMonitorFleetInput(
34155
+ readMonitorDefinitionsJsonFile(options.file)
34156
+ );
34157
+ printCommandEnvelope(
34158
+ {
34159
+ ok: !result.issues.some((issue) => issue.severity === "error"),
34160
+ ...result.normalized ? { normalized: result.normalized } : {},
34161
+ issues: result.issues
34162
+ },
34163
+ { json: options.json }
34164
+ );
34165
+ if (result.issues.some((issue) => issue.severity === "error"))
34166
+ process.exitCode = 2;
34167
+ }
34168
+ async function handleMonitorJobGet(jobId, options) {
34169
+ const payload = await new DeeplineClient().monitors.jobs.get(jobId);
34170
+ printCommandEnvelope(payload, {
34171
+ json: options.json,
34172
+ text: renderMonitorJob(payload)
34173
+ });
34174
+ }
34175
+ async function handleMonitorJobWait(jobId, options) {
34176
+ const payload = await new DeeplineClient().monitors.jobs.wait(jobId, {
34177
+ timeoutMs: fleetTimeoutMs(options.timeout),
34178
+ pollIntervalMs: FLEET_POLL_INTERVAL_MS
34179
+ });
34180
+ printCommandEnvelope(payload, {
34181
+ json: options.json,
34182
+ text: renderMonitorJob(payload)
34183
+ });
34184
+ }
34185
+ async function handleMonitorJobLogs(jobId, options) {
34186
+ const limit = options.limit ? fleetIntegerOption(options.limit, "--limit") : void 0;
34187
+ const payload = await new DeeplineClient().monitors.jobs.logs(jobId, {
34188
+ ...limit === void 0 ? {} : { limit }
34189
+ });
34190
+ printCommandEnvelope(payload, { json: options.json });
34191
+ }
34192
+ async function handleMonitorJobCancel(jobId, options) {
34193
+ const payload = await new DeeplineClient().monitors.jobs.cancel(jobId);
34194
+ printCommandEnvelope(payload, {
34195
+ json: options.json,
34196
+ text: renderMonitorJob(payload)
34197
+ });
34198
+ }
33556
34199
  var FLEET_COUNT_KEYS = [
33557
34200
  "pending",
33558
34201
  "submitting",
@@ -33574,12 +34217,12 @@ var MONITOR_FLEET_LIFECYCLE = [
33574
34217
  {
33575
34218
  step: 2,
33576
34219
  what: "See the plan and the credits before anything changes.",
33577
- command: "deepline monitors fleets sync --file fleet.json --dry-run"
34220
+ command: "deepline monitors fleets deploy --file fleet.json --dry-run"
33578
34221
  },
33579
34222
  {
33580
34223
  step: 3,
33581
34224
  what: "Apply it and wait for the server to call it converged.",
33582
- command: "deepline monitors fleets sync --file fleet.json --wait"
34225
+ command: "deepline monitors fleets deploy --file fleet.json --wait"
33583
34226
  },
33584
34227
  {
33585
34228
  step: 4,
@@ -33588,6 +34231,11 @@ var MONITOR_FLEET_LIFECYCLE = [
33588
34231
  }
33589
34232
  ];
33590
34233
  var MONITOR_FLEET_COMMANDS = [
34234
+ {
34235
+ name: "deploy",
34236
+ summary: "Create or update one table-backed Fleet from Customer DB rows."
34237
+ },
34238
+ { name: "lint", summary: "Validate and normalize Fleet JSON locally." },
33591
34239
  { name: "init", summary: "Write a Fleet definition JSON file." },
33592
34240
  {
33593
34241
  name: "sync",
@@ -33733,6 +34381,26 @@ function renderFleetGet(payload) {
33733
34381
  ` counts ${fleetCountsLine(payload)}`,
33734
34382
  ` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
33735
34383
  ];
34384
+ const boundPlays = Array.isArray(payload.bound_plays) ? payload.bound_plays.flatMap((value) => {
34385
+ const play = asRecord2(value);
34386
+ return play ? [play] : [];
34387
+ }) : [];
34388
+ lines.push("", `Observed Play bindings (${boundPlays.length}):`);
34389
+ if (boundPlays.length === 0) {
34390
+ lines.push(" none");
34391
+ } else {
34392
+ for (const play of boundPlays) {
34393
+ const name = asString(play.name) ?? "unnamed Play";
34394
+ const listeners = asFiniteNumber(play.listener_count) ?? 0;
34395
+ const status2 = asString(play.status);
34396
+ lines.push(
34397
+ ` ${name}${listeners ? ` (${listeners} listener${listeners === 1 ? "" : "s"})` : ""}${status2 ? ` \u2014 ${status2}` : ""}`
34398
+ );
34399
+ }
34400
+ }
34401
+ lines.push(
34402
+ " Read-only observation. Define or change bindings in the Play with sqlListeners."
34403
+ );
33736
34404
  lines.push(...renderFleetDriftRows(payload));
33737
34405
  const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
33738
34406
  if (next) lines.push(`Next: ${next}`);
@@ -33909,6 +34577,8 @@ async function handleMonitorFleetsInit(fleetId, options) {
33909
34577
  const out = options.out?.trim();
33910
34578
  if (!out) throw new MonitorsUsageError("--out is required.");
33911
34579
  const authoredDefinition = {
34580
+ version: 2,
34581
+ kind: "fleet",
33912
34582
  id: fleetId,
33913
34583
  source: {
33914
34584
  kind: "customer_db_table",
@@ -33917,12 +34587,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
33917
34587
  key: { column: key, type: keyType },
33918
34588
  ...where ? { where } : {}
33919
34589
  },
33920
- member: {
34590
+ monitor: {
33921
34591
  tool,
33922
- key: {
33923
- $fleet: "template",
33924
- parts: [`${fleetId}-`, { $fleet: "column", name: key }]
33925
- },
34592
+ key: `${fleetId}-{{${key}}}`,
33926
34593
  payload
33927
34594
  },
33928
34595
  selection: {
@@ -33935,9 +34602,9 @@ async function handleMonitorFleetsInit(fleetId, options) {
33935
34602
  const file = resolve14(out);
33936
34603
  writeFileSync12(file, `${JSON.stringify(definition, null, 2)}
33937
34604
  `, "utf8");
33938
- const next = `deepline monitors fleets sync --file ${fleetShellArg(file)} --dry-run --json`;
34605
+ const next = `deepline monitors fleets deploy --file ${fleetShellArg(file)} --dry-run --json`;
33939
34606
  printCommandEnvelope(
33940
- { schemaVersion: 1, file, definition, next },
34607
+ { schemaVersion: 2, file, definition, next },
33941
34608
  {
33942
34609
  json: options.json,
33943
34610
  text: `Wrote ${file}
@@ -33947,8 +34614,8 @@ Next: ${next}
33947
34614
  );
33948
34615
  }
33949
34616
  function requireCompiledFleetDefinition(definition) {
33950
- const result = admitMonitorFleetAuthoringContract(definition);
33951
- if (result.valid && result.contract) return result.contract.definition;
34617
+ const result = lintMonitorFleetInput(definition);
34618
+ if (result.normalized) return result.normalized;
33952
34619
  const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
33953
34620
  throw new MonitorsUsageError(
33954
34621
  `Monitor Fleet definition failed local contract check. ${messages}
@@ -33975,6 +34642,7 @@ function fleetSyncCommandLine(target, options) {
33975
34642
  return parts.join(" ");
33976
34643
  }
33977
34644
  async function handleMonitorFleetsSync(target, options, idempotencyKey) {
34645
+ const fileDefinitions = options.file ? readMonitorDefinitionsJsonFile(options.file) : void 0;
33978
34646
  const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
33979
34647
  if (!usesDefinition && !target?.trim()) {
33980
34648
  throw new MonitorsUsageError(
@@ -33982,12 +34650,14 @@ async function handleMonitorFleetsSync(target, options, idempotencyKey) {
33982
34650
  );
33983
34651
  }
33984
34652
  const definition = usesDefinition ? requireCompiledFleetDefinition(
33985
- resolveMonitorJsonBody({
33986
- positional: target,
33987
- file: options.file,
33988
- argLabel: "<definition>",
33989
- command: "deepline monitors fleets sync"
33990
- })
34653
+ asRecord2(
34654
+ fileDefinitions ?? resolveMonitorJsonBody({
34655
+ positional: target,
34656
+ file: options.file,
34657
+ argLabel: "<definition>",
34658
+ command: "deepline monitors fleets sync"
34659
+ })
34660
+ ) ?? {}
33991
34661
  ) : void 0;
33992
34662
  const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
33993
34663
  if (!fleetId) {
@@ -34388,14 +35058,14 @@ function renderMonitorGet(payload) {
34388
35058
  ` deepline monitors test ${key} '${JSON.stringify(samplePayload2)}' --json`
34389
35059
  );
34390
35060
  }
34391
- const monitorSpec = asRecord2(payload.monitor_spec);
34392
- if (monitorSpec?.available === false) {
35061
+ const monitorSpec2 = asRecord2(payload.monitor_spec);
35062
+ if (monitorSpec2?.available === false) {
34393
35063
  lines.push(
34394
35064
  "",
34395
- `Monitor spec: unavailable \u2014 ${asString(monitorSpec.message) ?? "use the stored definition and check before an update."}`
35065
+ `Monitor spec: unavailable \u2014 ${asString(monitorSpec2.message) ?? "use the stored definition and check before an update."}`
34396
35066
  );
34397
35067
  }
34398
- const specFields = Array.isArray(monitorSpec?.fields) ? monitorSpec.fields.flatMap((value) => {
35068
+ const specFields = Array.isArray(monitorSpec2?.fields) ? monitorSpec2.fields.flatMap((value) => {
34399
35069
  const field = asRecord2(value);
34400
35070
  const path = asString(field?.path);
34401
35071
  const description = asString(field?.description);
@@ -34869,6 +35539,8 @@ Notes:
34869
35539
  Deepline monitors are Deepline-native signal feeds: a monitor writes events
34870
35540
  into a Customer DB table; a play reacts to each new row via a
34871
35541
  sqlListeners trigger \u2014 see \`deepline plays bootstrap monitor-triggered\`.
35542
+ Monitor JSON declares only what to watch (key, tool, optional name, payload).
35543
+ Play bindings belong in the Play; monitor deployment never changes them.
34872
35544
  The Monitors rollout controls access to the live provider catalog; use
34873
35545
  \`deepline tools list --categories monitors\` for the exact tool ids available to you.
34874
35546
  Contact the Deepline team to request access; until access is enabled, these
@@ -34981,19 +35653,31 @@ Examples:
34981
35653
  );
34982
35654
  withJsonOption(
34983
35655
  batch.command("deploy").description(
34984
- "Durably create complete NDJSON monitor definitions through provider bulk create."
35656
+ "Create a Monitor Job from canonical Batch JSON; legacy NDJSON remains available with --yes or --dry-run."
34985
35657
  ).requiredOption(
34986
35658
  "--file <path>",
34987
- "NDJSON file of complete monitor definitions"
34988
- ).option("--dry-run", "Validate and record the durable deploy plan").option("--yes", "Confirm asynchronous provider creation").option(
35659
+ 'Batch JSON ({"version":1,"kind":"batch","monitors":[...]}), or legacy NDJSON with --yes/--dry-run'
35660
+ ).option("--dry-run", "Use the retained legacy batch-operation plan").option("--yes", "Use the retained legacy NDJSON batch operation").option(
34989
35661
  "--idempotency-key <key>",
34990
35662
  "Stable retry key (generated when omitted)"
34991
35663
  )
34992
35664
  ).action(
34993
- monitorsAction(
34994
- (options) => handleMonitorBatchDeploy(options)
34995
- )
35665
+ monitorsAction(async (options) => {
35666
+ if (options.dryRun === true || options.yes === true) {
35667
+ return await handleMonitorBatchDeploy(options);
35668
+ }
35669
+ const idempotencyKey = monitorJobIdempotencyKey(
35670
+ "batch-deploy",
35671
+ options.idempotencyKey
35672
+ );
35673
+ return await handleMonitorJobBatchDeploy(options, idempotencyKey);
35674
+ })
34996
35675
  );
35676
+ withJsonOption(
35677
+ batch.command("lint").description(
35678
+ "Validate and normalize Batch JSON without network or provider work."
35679
+ ).requiredOption("--file <path>", "Batch JSON file, or - for stdin")
35680
+ ).action(monitorsAction(handleMonitorBatchLint));
34997
35681
  withJsonOption(
34998
35682
  batchSelectorOptions(
34999
35683
  batch.command("audit").description("Durably audit a selection; defaults to --target all.")
@@ -35162,9 +35846,8 @@ Examples:
35162
35846
  "after",
35163
35847
  `
35164
35848
  Notes:
35165
- Read-only validation. <definition> is a JSON object with key, tool, payload,
35166
- and optional controls (Deepline lifecycle metadata). Pass it positionally,
35167
- via --file <path>, or
35849
+ Read-only validation. <definition> is a JSON object with key, tool, optional
35850
+ name, and payload. Pass it positionally, via --file <path>, or
35168
35851
  from stdin with --file -. Does not deploy or spend credits.
35169
35852
  Check validates the local definition only. It does not contact an existing
35170
35853
  upstream resource, prove that future events will arrive, or verify downstream
@@ -35172,12 +35855,8 @@ Notes:
35172
35855
  Provider-specific grammar, precedence, enum applicability, examples, and
35173
35856
  update semantics are returned by the live monitor contract. Inspect it with
35174
35857
  \`deepline tools get deepline_native.company_radar --json\`.
35175
- For a bounded urgent Deepline Native preview, use
35176
- controls.execution_type="priority". Deepline injects the upstream marker;
35177
- do not author custom_fields yourself. Priority is capped at ten upstream or
35178
- reserved recovery, replacement, or reactivation slots per org. Use
35179
- \`monitors list --status all\` to find priority holders; it is not for regular
35180
- or bulk-scale monitoring.
35858
+ Operational controls are Deepline-managed. Bind downstream automation in a
35859
+ Play with sqlListeners; monitor definitions never name Plays.
35181
35860
 
35182
35861
  Examples:
35183
35862
  deepline monitors check '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
@@ -35195,8 +35874,8 @@ Examples:
35195
35874
  `
35196
35875
  Notes:
35197
35876
  Mutates workspace state and may spend Deepline credits. <definition> is a JSON
35198
- object with key, tool, payload, and optional controls. Pass it positionally,
35199
- via --file <path>, or from stdin with --file -.
35877
+ object with key, tool, optional name, and payload. Pass it positionally, via
35878
+ --file <path>, or from stdin with --file -.
35200
35879
  --dry-run validates the definition and shows the plan (deploy cost in Deepline
35201
35880
  credits when the server reports it, plus any existing monitors that may
35202
35881
  already cover this scope) WITHOUT deploying. Exits 0 when valid, 7 when not.
@@ -35213,10 +35892,8 @@ Notes:
35213
35892
  historical replay request, including when redeploying a disabled monitor.
35214
35893
  Deepline preserves that selected boundary; filter-only deploys and ordinary
35215
35894
  reactivation start from a fresh future-only source boundary instead.
35216
- For a bounded urgent Deepline Native preview, set
35217
- controls.execution_type="priority". Deepline injects the provider custom
35218
- field and enforces a ten-slot per-org cap; do not use it for regular or bulk
35219
- monitoring, and do not delete another radar automatically to make room.
35895
+ Operational controls are Deepline-managed. A monitor writes rows; downstream
35896
+ automation belongs in a Play with sqlListeners.
35220
35897
 
35221
35898
  Examples:
35222
35899
  deepline monitors deploy '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
@@ -35247,10 +35924,6 @@ request. Deepline passes that requested boundary upstream, but previously
35247
35924
  delivered canonical findings are deduplicated before dispatch and billing; only
35248
35925
  previously unseen historical findings are chargeable. Filter-only updates,
35249
35926
  repair, and reactivation instead use a fresh future-only source boundary.
35250
- Use {"controls":{"execution_type":"priority"}} only for a bounded urgent
35251
- Deepline Native preview. The ten-radar priority cap applies on update too.
35252
- Use {"controls":{"execution_type":null}} to release priority without
35253
- deleting the monitor.
35254
35927
 
35255
35928
  Examples:
35256
35929
  deepline monitors update my-monitor '{"name":"Interested replies"}' --json
@@ -35298,13 +35971,30 @@ Examples:
35298
35971
  `
35299
35972
  ).option("--dry-run", "Show the reactivation cost without reactivating")
35300
35973
  ).action(monitorsAction(handleMonitorsReactivate));
35301
- const fleets = monitors.command("fleets").description("Define and reconcile table-backed Monitor Fleets.").addHelpText(
35974
+ const jobs = monitors.command("jobs").description("Read, wait for, inspect, or cancel Monitor Jobs.");
35975
+ withJsonOption(jobs);
35976
+ withJsonOption(
35977
+ jobs.command("get <job-id>").description("Read the durable Monitor Job state.")
35978
+ ).action(monitorsAction(handleMonitorJobGet));
35979
+ withJsonOption(
35980
+ jobs.command("wait <job-id>").description(
35981
+ "Wait for real provider reconciliation, not request acceptance."
35982
+ ).option("--timeout <duration>", "How long to wait (default 10m)")
35983
+ ).action(monitorsAction(handleMonitorJobWait));
35984
+ withJsonOption(
35985
+ jobs.command("logs <job-id>").description("Read bounded operator logs for one Monitor Job.").option("--limit <n>", "Maximum log entries (1..200)")
35986
+ ).action(monitorsAction(handleMonitorJobLogs));
35987
+ withJsonOption(
35988
+ jobs.command("cancel <job-id>").description("Stop unscheduled work and reconcile the partial result.")
35989
+ ).action(monitorsAction(handleMonitorJobCancel));
35990
+ const fleets = monitors.command("fleets").description("Manage table-backed Fleets.").addHelpText(
35302
35991
  "after",
35303
35992
  `
35304
35993
  Notes:
35305
35994
  A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
35306
- monitors. Fleet definitions are canonical JSON, and \`sync\` is the only verb
35307
- that changes one: applying the same definition twice is the same operation,
35995
+ monitors. Fleet definitions are canonical JSON, and \`deploy\` applies one;
35996
+ \`sync\` remains its exact compatibility alias. Applying the same definition
35997
+ twice is the same operation,
35308
35998
  so the server answers \`replayed: true\` instead of building a second fleet.
35309
35999
  The fleet's status is computed by Deepline; this CLI reports it and never
35310
36000
  recomputes a verdict from the counts.
@@ -35326,6 +36016,29 @@ ${MONITOR_FLEET_HELP_EPILOG}`
35326
36016
  })
35327
36017
  );
35328
36018
  withJsonOption(fleets);
36019
+ withJsonOption(
36020
+ fleets.command("deploy [fleet-id]").description(
36021
+ "Apply a table-backed Fleet definition; sync remains an exact alias."
36022
+ ).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(
36023
+ "--expected-generation <generation>",
36024
+ "Optimistic generation fence"
36025
+ ).option("--idempotency-key <key>", "Stable retry key")
36026
+ ).action(
36027
+ monitorsAction(
36028
+ async (fleetId, options) => {
36029
+ const idempotencyKey = fleetIdempotencyKey(
36030
+ "deploy",
36031
+ options.idempotencyKey
36032
+ );
36033
+ await handleMonitorFleetsSync(fleetId, options, idempotencyKey);
36034
+ }
36035
+ )
36036
+ );
36037
+ withJsonOption(
36038
+ fleets.command("lint").description(
36039
+ "Validate and normalize Fleet JSON without network or provider work."
36040
+ ).requiredOption("--file <path>", "Fleet JSON file, or - for stdin")
36041
+ ).action(monitorsAction(handleMonitorFleetLint));
35329
36042
  withJsonOption(
35330
36043
  fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
35331
36044
  "after",
@@ -35339,13 +36052,13 @@ Example:
35339
36052
  deepline monitors fleets init account-job-openings \\
35340
36053
  --source public.accounts --key account_id --key-type uuid \\
35341
36054
  --tool deepline_native.company_radar \\
35342
- --payload '{"domain":{"$fleet":"column","name":"domain"},"radar_type":"company_job_openings"}' \\
36055
+ --payload '{"domain":"{{domain}}","radar_type":"company_job_openings"}' \\
35343
36056
  --order-by intent_score:desc \\
35344
36057
  --out fleet.json
35345
36058
  `
35346
36059
  ).requiredOption("--source <schema.table>", "Customer DB source table").requiredOption("--key <column>", "Unique source-row key column").option("--key-type <type>", "text, uuid, int4, or int8 (default text)").requiredOption("--tool <tool>", "Monitor tool to create per source row").requiredOption(
35347
36060
  "--payload <json>",
35348
- "Monitor payload JSON for --tool; use $fleet column tags for row values"
36061
+ "Monitor payload JSON for --tool; use Handlebars fields such as {{domain}} for row values"
35349
36062
  ).option(
35350
36063
  "--where <json>",
35351
36064
  "Optional source-row equality filter JSON; not arbitrary SQL"
@@ -35421,7 +36134,9 @@ Examples:
35421
36134
  Notes:
35422
36135
  Status is the server's verdict. --check turns it into an exit code so a
35423
36136
  script can branch without parsing output: 0 converged, 6 anything else.
35424
- --drift lists the members that have not settled and why.
36137
+ --drift lists the members that have not settled and why. The detail also
36138
+ shows the current Plays that observe this Fleet's output; those bindings are
36139
+ read-only here and are defined by each Play's sqlListeners.
35425
36140
 
35426
36141
  Examples:
35427
36142
  deepline monitors fleets get --json
@@ -37549,8 +38264,8 @@ function classifyNetworkFailure(error) {
37549
38264
  let current = error;
37550
38265
  while (current && !seen.has(current)) {
37551
38266
  seen.add(current);
37552
- const record2 = typeof current === "object" && current !== null ? current : {};
37553
- const code = String(record2.code ?? "").toLowerCase();
38267
+ const record3 = typeof current === "object" && current !== null ? current : {};
38268
+ const code = String(record3.code ?? "").toLowerCase();
37554
38269
  const name = current instanceof Error ? current.name.toLowerCase() : "";
37555
38270
  const text = String(
37556
38271
  current instanceof Error ? current.message : current
@@ -37577,7 +38292,7 @@ function classifyNetworkFailure(error) {
37577
38292
  if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
37578
38293
  return "network_ssl_error";
37579
38294
  }
37580
- current = record2.cause ?? record2.context;
38295
+ current = record3.cause ?? record3.context;
37581
38296
  }
37582
38297
  return "network_error";
37583
38298
  }
@@ -38654,26 +39369,26 @@ function parseSetupPhases(value) {
38654
39369
  if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
38655
39370
  return null;
38656
39371
  }
38657
- const record2 = phase;
38658
- if (!isSetupPhaseStatus(record2.status)) return null;
38659
- switch (record2.status) {
39372
+ const record3 = phase;
39373
+ if (!isSetupPhaseStatus(record3.status)) return null;
39374
+ switch (record3.status) {
38660
39375
  case "pending":
38661
39376
  case "in_progress":
38662
- phases[name] = { status: record2.status };
39377
+ phases[name] = { status: record3.status };
38663
39378
  break;
38664
39379
  case "complete":
38665
39380
  phases[name] = {
38666
39381
  status: "complete",
38667
- ...typeof record2.outcome === "string" ? { outcome: record2.outcome } : {}
39382
+ ...typeof record3.outcome === "string" ? { outcome: record3.outcome } : {}
38668
39383
  };
38669
39384
  break;
38670
39385
  case "waiting":
38671
- if (typeof record2.outcome !== "string") return null;
38672
- phases[name] = { status: "waiting", outcome: record2.outcome };
39386
+ if (typeof record3.outcome !== "string") return null;
39387
+ phases[name] = { status: "waiting", outcome: record3.outcome };
38673
39388
  break;
38674
39389
  case "failed":
38675
- if (typeof record2.code !== "string") return null;
38676
- phases[name] = { status: "failed", code: record2.code };
39390
+ if (typeof record3.code !== "string") return null;
39391
+ phases[name] = { status: "failed", code: record3.code };
38677
39392
  break;
38678
39393
  }
38679
39394
  }
@@ -42124,9 +42839,9 @@ function requiredInputIds(tool) {
42124
42839
  return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
42125
42840
  }
42126
42841
  function notConnectedSuffix(tool) {
42127
- const record2 = tool;
42128
- const status = stringField2(record2, "credentialStatus", "credential_status");
42129
- const connected = record2.connected;
42842
+ const record3 = tool;
42843
+ const status = stringField2(record3, "credentialStatus", "credential_status");
42844
+ const connected = record3.connected;
42130
42845
  const message = toolConnectionStatusMessage({
42131
42846
  connected: connected === false ? false : void 0,
42132
42847
  credentialStatus: status || void 0
@@ -42505,19 +43220,19 @@ function printPlayAliasToolError(toolId, play) {
42505
43220
  console.error(playAliasToolErrorMessage(toolId, play));
42506
43221
  }
42507
43222
  function isPlayLikeTool(tool) {
42508
- const record2 = tool;
42509
- if (record2.isPlay === true || record2.is_play === true) return true;
42510
- const playExpansion = recordField2(record2, "playExpansion", "play_expansion");
43223
+ const record3 = tool;
43224
+ if (record3.isPlay === true || record3.is_play === true) return true;
43225
+ const playExpansion = recordField2(record3, "playExpansion", "play_expansion");
42511
43226
  if (Object.keys(playExpansion).length > 0) return true;
42512
- const toolId = typeof record2.toolId === "string" ? record2.toolId : "";
43227
+ const toolId = typeof record3.toolId === "string" ? record3.toolId : "";
42513
43228
  return toolId.endsWith("_waterfall");
42514
43229
  }
42515
43230
  function isMonitorTypeTool(tool) {
42516
43231
  return stringField2(tool, "kind") === "monitor_type";
42517
43232
  }
42518
43233
  function playReferenceForTool(tool) {
42519
- const record2 = tool;
42520
- const declared = stringField2(record2, "playReference", "play_reference");
43234
+ const record3 = tool;
43235
+ const declared = stringField2(record3, "playReference", "play_reference");
42521
43236
  if (declared.startsWith("prebuilt/")) {
42522
43237
  return declared;
42523
43238
  }
@@ -43457,12 +44172,12 @@ function singleLineText(value, maxLength = 260) {
43457
44172
  return `${text.slice(0, maxLength - 3).trimEnd()}...`;
43458
44173
  }
43459
44174
  function listedToolDescription(tool) {
43460
- const record2 = tool;
43461
- return singleLineText(record2.bestFor ?? record2.best_for ?? tool.description);
44175
+ const record3 = tool;
44176
+ return singleLineText(record3.bestFor ?? record3.best_for ?? tool.description);
43462
44177
  }
43463
44178
  function formatListedToolCost(tool) {
43464
- const record2 = tool;
43465
- const pricing = recordField2(record2, "pricing");
44179
+ const record3 = tool;
44180
+ const pricing = recordField2(record3, "pricing");
43466
44181
  const displayText = stringField2(pricing, "displayText", "display_text");
43467
44182
  return displayText ? `Cost: ${displayText}` : "";
43468
44183
  }
@@ -44518,9 +45233,9 @@ function noticeToStderr(command) {
44518
45233
  );
44519
45234
  }
44520
45235
  function emitPassThrough(command, payload, options) {
44521
- const json = shouldEmitJson(options.json);
45236
+ const json2 = shouldEmitJson(options.json);
44522
45237
  const deprecation = migrationDeprecation(command);
44523
- if (json) {
45238
+ if (json2) {
44524
45239
  const enriched = payload && typeof payload === "object" && !Array.isArray(payload) ? { ...payload, deprecation } : { result: payload, deprecation };
44525
45240
  printJson(enriched);
44526
45241
  return;
@@ -44541,9 +45256,9 @@ function clientWithTimeout(timeoutSeconds) {
44541
45256
  }
44542
45257
  function readStatus(payload) {
44543
45258
  if (!payload || typeof payload !== "object") return null;
44544
- const record2 = payload;
44545
- if (typeof record2.status === "string") return record2.status;
44546
- const run = record2.run;
45259
+ const record3 = payload;
45260
+ if (typeof record3.status === "string") return record3.status;
45261
+ const run = record3.run;
44547
45262
  if (run && typeof run === "object") {
44548
45263
  const status = run.status;
44549
45264
  if (typeof status === "string") return status;