deepline 0.3.55 → 0.3.57

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.
@@ -1060,7 +1060,7 @@ var SDK_RELEASE = {
1060
1060
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1061
1061
  // getters keep their established compatibility behavior.
1062
1062
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1063
- version: "0.3.55",
1063
+ version: "0.3.57",
1064
1064
  updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
1065
1065
  packageCapabilities: {
1066
1066
  updatePreferences: 1
@@ -2197,7 +2197,7 @@ function decodeSseFrame(frame) {
2197
2197
  return parsed;
2198
2198
  }
2199
2199
  function sleep(ms) {
2200
- return new Promise((resolve20) => setTimeout(resolve20, ms));
2200
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
2201
2201
  }
2202
2202
  function withCoworkNetworkHint(message) {
2203
2203
  if (!isCoworkLikeSandbox2() || message.includes(COWORK_NETWORK_HINT)) {
@@ -3100,9 +3100,9 @@ function nonEmptyString(value) {
3100
3100
  }
3101
3101
  function normalizeDatasetBornFrom(value) {
3102
3102
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
3103
- const record = value;
3104
- const table = nonEmptyString(record.table);
3105
- const rowCountIn = finiteNonNegativeInteger2(record.rowCountIn);
3103
+ const record2 = value;
3104
+ const table = nonEmptyString(record2.table);
3105
+ const rowCountIn = finiteNonNegativeInteger2(record2.rowCountIn);
3106
3106
  if (!table || rowCountIn === null) return null;
3107
3107
  return { table, rowCountIn };
3108
3108
  }
@@ -3962,14 +3962,14 @@ async function* observeRunEvents(options) {
3962
3962
  try {
3963
3963
  for (; ; ) {
3964
3964
  if (queue.length === 0) {
3965
- const waitForItem = new Promise((resolve20) => {
3966
- wake = resolve20;
3965
+ const waitForItem = new Promise((resolve21) => {
3966
+ wake = resolve21;
3967
3967
  });
3968
3968
  if (!sawFirstSnapshot) {
3969
3969
  const timedOut = await Promise.race([
3970
3970
  waitForItem.then(() => false),
3971
3971
  new Promise(
3972
- (resolve20) => setTimeout(() => resolve20(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
3972
+ (resolve21) => setTimeout(() => resolve21(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
3973
3973
  )
3974
3974
  ]);
3975
3975
  if (timedOut && queue.length === 0) {
@@ -4162,21 +4162,21 @@ function normalizePlayRuntimeNamespace(value) {
4162
4162
  }
4163
4163
  function normalizePlayRuntimeSelection(value) {
4164
4164
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
4165
- const record = value;
4166
- if (Object.keys(record).some(
4165
+ const record2 = value;
4166
+ if (Object.keys(record2).some(
4167
4167
  (key) => key !== "environment" && key !== "namespace" && key !== "backend"
4168
- ) || record.environment !== "preview") {
4168
+ ) || record2.environment !== "preview") {
4169
4169
  return null;
4170
4170
  }
4171
- const namespace = normalizePlayRuntimeNamespace(record.namespace);
4171
+ const namespace = normalizePlayRuntimeNamespace(record2.namespace);
4172
4172
  if (!namespace) return null;
4173
- if (record.backend === void 0) {
4173
+ if (record2.backend === void 0) {
4174
4174
  return { environment: "preview", namespace };
4175
4175
  }
4176
- if (record.backend !== PLAY_RUNTIME_BACKENDS.daytona && record.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4176
+ if (record2.backend !== PLAY_RUNTIME_BACKENDS.daytona && record2.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4177
4177
  return null;
4178
4178
  }
4179
- return { environment: "preview", namespace, backend: record.backend };
4179
+ return { environment: "preview", namespace, backend: record2.backend };
4180
4180
  }
4181
4181
  function normalizePlayRuntimeEnvironment(value) {
4182
4182
  return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
@@ -4328,7 +4328,7 @@ function parseEnvTestPolicyOverrides() {
4328
4328
  return normalizeTestPolicyOverrides(parsed, "DEEPLINE_TEST_POLICY_OVERRIDES");
4329
4329
  }
4330
4330
  function sleep2(ms) {
4331
- return new Promise((resolve20) => setTimeout(resolve20, ms));
4331
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
4332
4332
  }
4333
4333
  function isTransientCompileManifestError(error) {
4334
4334
  if (error instanceof DeeplineError && typeof error.statusCode === "number") {
@@ -4760,7 +4760,14 @@ var DeeplineClient = class {
4760
4760
  dependents: (key) => this.getMonitorDependents(key),
4761
4761
  update: (key, patch) => this.updateMonitor(key, patch),
4762
4762
  delete: (key, options2) => this.deleteMonitor(key, options2),
4763
- reactivate: (key, options2) => this.reactivateMonitor(key, options2)
4763
+ reactivate: (key, options2) => this.reactivateMonitor(key, options2),
4764
+ fleets: {
4765
+ sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
4766
+ get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
4767
+ list: () => this.listMonitorFleets(),
4768
+ deactivate: (fleetId, options2) => this.deactivateMonitorFleet(fleetId, options2),
4769
+ waitForConvergence: (fleetId, options2) => this.waitForMonitorFleetConvergence(fleetId, options2)
4770
+ }
4764
4771
  };
4765
4772
  }
4766
4773
  /** The resolved base URL this client is targeting (e.g. `"http://localhost:3000"`). */
@@ -7068,6 +7075,104 @@ var DeeplineClient = class {
7068
7075
  { method: "POST", body: {} }
7069
7076
  );
7070
7077
  }
7078
+ // ——————————————————————————————————————————————————————————
7079
+ // Monitor Fleets
7080
+ // ——————————————————————————————————————————————————————————
7081
+ monitorFleetIdempotencyKey(operation) {
7082
+ const uuid = globalThis.crypto?.randomUUID?.();
7083
+ return `monitor-fleet-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
7084
+ }
7085
+ monitorFleetHeaders(operation, idempotencyKey) {
7086
+ return {
7087
+ "Idempotency-Key": idempotencyKey?.trim() || this.monitorFleetIdempotencyKey(operation)
7088
+ };
7089
+ }
7090
+ monitorFleetPath(fleetId) {
7091
+ return `/api/v2/monitors/fleets/${encodeURIComponent(fleetId)}`;
7092
+ }
7093
+ /**
7094
+ * Create, update, or re-plan one fleet.
7095
+ *
7096
+ * The fleet id is always the resource path, so the same definition PUT twice
7097
+ * is the same operation and the server can answer `replayed: true` instead of
7098
+ * building a second set of monitors. Re-planning an existing fleet from its
7099
+ * stored definition sends an EMPTY body: there is no second definition to
7100
+ * send, and an empty body cannot be mistaken for "replace the definition with
7101
+ * nothing".
7102
+ */
7103
+ async syncMonitorFleet(definitionOrId, options) {
7104
+ const fleetId = typeof definitionOrId === "string" ? definitionOrId : definitionOrId.id;
7105
+ const body = {
7106
+ ...typeof definitionOrId === "string" ? {} : { definition: definitionOrId },
7107
+ ...options?.dryRun ? { dry_run: true } : {},
7108
+ ...options?.expectedGeneration !== void 0 ? { expected_generation: options.expectedGeneration } : {}
7109
+ };
7110
+ return this.http.request(
7111
+ this.monitorFleetPath(fleetId),
7112
+ {
7113
+ method: "PUT",
7114
+ body,
7115
+ headers: this.monitorFleetHeaders("sync", options?.idempotencyKey),
7116
+ maxRetries: 0,
7117
+ exactUrlOnly: true
7118
+ }
7119
+ );
7120
+ }
7121
+ async listMonitorFleets() {
7122
+ return this.http.request("/api/v2/monitors/fleets", {
7123
+ method: "GET"
7124
+ });
7125
+ }
7126
+ async getMonitorFleet(fleetId, options) {
7127
+ const params = new URLSearchParams();
7128
+ if (options?.drift) params.set("drift", "1");
7129
+ if (options?.limit !== void 0)
7130
+ params.set("limit", String(options.limit));
7131
+ const query = params.toString();
7132
+ return this.http.request(
7133
+ `${this.monitorFleetPath(fleetId)}${query ? `?${query}` : ""}`,
7134
+ { method: "GET" }
7135
+ );
7136
+ }
7137
+ async deactivateMonitorFleet(fleetId, options) {
7138
+ return this.http.request(
7139
+ this.monitorFleetPath(fleetId),
7140
+ {
7141
+ method: "DELETE",
7142
+ body: options?.dryRun ? { dry_run: true } : {},
7143
+ headers: this.monitorFleetHeaders(
7144
+ "deactivate",
7145
+ options?.idempotencyKey
7146
+ ),
7147
+ maxRetries: 0,
7148
+ exactUrlOnly: true
7149
+ }
7150
+ );
7151
+ }
7152
+ /**
7153
+ * Poll one fleet until the server reports a terminal status.
7154
+ *
7155
+ * Convergence is the server's verdict, read from `status`. The timeout is not
7156
+ * a failure and does not throw: a fleet still `converging` after ten minutes
7157
+ * is healthy and slow, not broken, so the caller gets the last snapshot and
7158
+ * decides what that means. Throwing here would have made "still working" look
7159
+ * identical to "the request failed".
7160
+ */
7161
+ async waitForMonitorFleetConvergence(fleetId, options) {
7162
+ const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
7163
+ const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
7164
+ const terminal = options?.until === "deactivated" ? /* @__PURE__ */ new Set(["deactivated", "degraded"]) : /* @__PURE__ */ new Set(["converged", "degraded", "deactivated"]);
7165
+ const startedAt = Date.now();
7166
+ let latest = await this.getMonitorFleet(fleetId);
7167
+ while (true) {
7168
+ options?.onProgress?.(latest);
7169
+ const status = typeof latest.status === "string" ? latest.status : void 0;
7170
+ if (status && terminal.has(status)) return latest;
7171
+ if (Date.now() - startedAt >= timeoutMs) return latest;
7172
+ await sleep2(pollIntervalMs);
7173
+ latest = await this.getMonitorFleet(fleetId);
7174
+ }
7175
+ }
7071
7176
  /**
7072
7177
  * Check API connectivity and server health.
7073
7178
  *
@@ -7746,30 +7851,30 @@ function flattenObjectColumns(row, options = {}) {
7746
7851
  continue;
7747
7852
  }
7748
7853
  if (value && typeof value === "object" && !Array.isArray(value)) {
7749
- const record = value;
7854
+ const record2 = value;
7750
7855
  if (options.objectColumns === "json") {
7751
- flattened[key] = csvSafeJsonString(record);
7856
+ flattened[key] = csvSafeJsonString(record2);
7752
7857
  continue;
7753
7858
  }
7754
- const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record, "matched_result") || Object.prototype.hasOwnProperty.call(record, "matchedResult");
7859
+ const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record2, "matched_result") || Object.prototype.hasOwnProperty.call(record2, "matchedResult");
7755
7860
  if (hasMatchedEnvelope) {
7756
- flattened[key] = csvSafeJsonString(record);
7861
+ flattened[key] = csvSafeJsonString(record2);
7757
7862
  continue;
7758
7863
  }
7759
7864
  if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
7760
7865
  flattened[key] = rawValue;
7761
7866
  continue;
7762
7867
  } else {
7763
- const failureMessage = failureMessageFromRecord(record);
7868
+ const failureMessage = failureMessageFromRecord(record2);
7764
7869
  if (failureMessage) {
7765
7870
  flattened[key] = failureMessage;
7766
7871
  continue;
7767
- } else if (Object.prototype.hasOwnProperty.call(record, "result")) {
7768
- flattened[key] = csvSafeJsonString(record);
7872
+ } else if (Object.prototype.hasOwnProperty.call(record2, "result")) {
7873
+ flattened[key] = csvSafeJsonString(record2);
7769
7874
  continue;
7770
7875
  }
7771
7876
  }
7772
- for (const [nestedKey, nestedValue] of Object.entries(record)) {
7877
+ for (const [nestedKey, nestedValue] of Object.entries(record2)) {
7773
7878
  flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
7774
7879
  }
7775
7880
  continue;
@@ -8158,7 +8263,7 @@ function buildCandidateUrls2(url) {
8158
8263
  }
8159
8264
  }
8160
8265
  function sleep4(ms) {
8161
- return new Promise((resolve20) => setTimeout(resolve20, ms));
8266
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
8162
8267
  }
8163
8268
  function printDeeplineLogo() {
8164
8269
  if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
@@ -10261,9 +10366,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
10261
10366
  }
10262
10367
  if (ancestors.has(value)) return value;
10263
10368
  ancestors.add(value);
10264
- const record = value;
10369
+ const record2 = value;
10265
10370
  const normalized = Object.fromEntries(
10266
- Object.keys(record).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record[key], ancestors)])
10371
+ Object.keys(record2).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record2[key], ancestors)])
10267
10372
  );
10268
10373
  ancestors.delete(value);
10269
10374
  return normalized;
@@ -11430,16 +11535,16 @@ function collectErrorText(value) {
11430
11535
  if (!value || typeof value !== "object" || Array.isArray(value)) {
11431
11536
  return errorMessage(value);
11432
11537
  }
11433
- const record = value;
11538
+ const record2 = value;
11434
11539
  return [
11435
11540
  errorMessage(value),
11436
- typeof record.error === "string" ? record.error : "",
11437
- typeof record.message === "string" ? record.message : "",
11438
- typeof record.detail === "string" ? record.detail : "",
11439
- typeof record.hint === "string" ? record.hint : "",
11440
- typeof record.code === "string" ? record.code : "",
11441
- record.response ? collectErrorText(record.response) : "",
11442
- record.details ? collectErrorText(record.details) : ""
11541
+ typeof record2.error === "string" ? record2.error : "",
11542
+ typeof record2.message === "string" ? record2.message : "",
11543
+ typeof record2.detail === "string" ? record2.detail : "",
11544
+ typeof record2.hint === "string" ? record2.hint : "",
11545
+ typeof record2.code === "string" ? record2.code : "",
11546
+ record2.response ? collectErrorText(record2.response) : "",
11547
+ record2.details ? collectErrorText(record2.details) : ""
11443
11548
  ].filter(Boolean).join("\n");
11444
11549
  }
11445
11550
  function formatDbQueryError(sql, error) {
@@ -12491,8 +12596,8 @@ function getterNamesFromTool(tool, kind) {
12491
12596
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
12492
12597
  }
12493
12598
  function targetGettersFromTool(tool) {
12494
- const record = isRecord9(tool) ? tool : {};
12495
- const raw = record.targetGetters ?? record.target_getters;
12599
+ const record2 = isRecord9(tool) ? tool : {};
12600
+ const raw = record2.targetGetters ?? record2.target_getters;
12496
12601
  if (!isRecord9(raw)) return {};
12497
12602
  const entries = [];
12498
12603
  for (const [target, value] of Object.entries(raw)) {
@@ -15370,11 +15475,11 @@ function staticStringFromExpression(node, context, seen = /* @__PURE__ */ new Se
15370
15475
  if (!value?.trim()) return null;
15371
15476
  return trimResult ? value.trim() : value;
15372
15477
  }
15373
- const identifier = getIdentifierName2(expression);
15374
- if (!identifier || seen.has(identifier)) return null;
15375
- seen.add(identifier);
15478
+ const identifier2 = getIdentifierName2(expression);
15479
+ if (!identifier2 || seen.has(identifier2)) return null;
15480
+ seen.add(identifier2);
15376
15481
  return staticStringFromExpression(
15377
- context.declarations.get(identifier),
15482
+ context.declarations.get(identifier2),
15378
15483
  context,
15379
15484
  seen,
15380
15485
  trimResult
@@ -15398,11 +15503,11 @@ function objectExpressionFromNode(node, context, seen = /* @__PURE__ */ new Set(
15398
15503
  const expression = unwrapStaticExpression2(node);
15399
15504
  if (!expression) return null;
15400
15505
  if (expression.type === "ObjectExpression") return expression;
15401
- const identifier = getIdentifierName2(expression);
15402
- if (!identifier || seen.has(identifier)) return null;
15403
- seen.add(identifier);
15506
+ const identifier2 = getIdentifierName2(expression);
15507
+ if (!identifier2 || seen.has(identifier2)) return null;
15508
+ seen.add(identifier2);
15404
15509
  return objectExpressionFromNode(
15405
- context.declarations.get(identifier),
15510
+ context.declarations.get(identifier2),
15406
15511
  context,
15407
15512
  seen
15408
15513
  );
@@ -15470,11 +15575,11 @@ function staticNumberFromExpression(node, context, seen = /* @__PURE__ */ new Se
15470
15575
  if (expression.type === "Literal" && typeof expression.value === "number") {
15471
15576
  return expression.value;
15472
15577
  }
15473
- const identifier = getIdentifierName2(expression);
15474
- if (!identifier || seen.has(identifier)) return null;
15475
- seen.add(identifier);
15578
+ const identifier2 = getIdentifierName2(expression);
15579
+ if (!identifier2 || seen.has(identifier2)) return null;
15580
+ seen.add(identifier2);
15476
15581
  return staticNumberFromExpression(
15477
- context.declarations.get(identifier),
15582
+ context.declarations.get(identifier2),
15478
15583
  context,
15479
15584
  seen
15480
15585
  );
@@ -16546,13 +16651,13 @@ function validateFixtureBehavior(value) {
16546
16651
  if (!value || typeof value !== "object" || Array.isArray(value)) {
16547
16652
  return { ok: false, error: "fixtureBehavior must be a JSON object." };
16548
16653
  }
16549
- const record = value;
16550
- const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
16654
+ const record2 = value;
16655
+ const supportedKeys = record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
16551
16656
  "version",
16552
16657
  "responseSamples",
16553
- ...record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
16658
+ ...record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
16554
16659
  ]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
16555
- const unknownKeys = Object.keys(record).filter(
16660
+ const unknownKeys = Object.keys(record2).filter(
16556
16661
  (key) => !supportedKeys.has(key)
16557
16662
  );
16558
16663
  if (unknownKeys.length > 0) {
@@ -16561,22 +16666,22 @@ function validateFixtureBehavior(value) {
16561
16666
  error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
16562
16667
  };
16563
16668
  }
16564
- if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16669
+ if (record2.version !== FIXTURE_BEHAVIOR_VERSION && record2.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record2.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16565
16670
  return {
16566
16671
  ok: false,
16567
16672
  error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
16568
16673
  };
16569
16674
  }
16570
- if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16571
- if (!Array.isArray(record.responseSamples) || record.responseSamples.length === 0 || record.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
16675
+ if (record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16676
+ if (!Array.isArray(record2.responseSamples) || record2.responseSamples.length === 0 || record2.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
16572
16677
  return {
16573
16678
  ok: false,
16574
16679
  error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
16575
16680
  };
16576
16681
  }
16577
16682
  const samples2 = [];
16578
- for (let index = 0; index < record.responseSamples.length; index += 1) {
16579
- const value2 = record.responseSamples[index];
16683
+ for (let index = 0; index < record2.responseSamples.length; index += 1) {
16684
+ const value2 = record2.responseSamples[index];
16580
16685
  if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
16581
16686
  return {
16582
16687
  ok: false,
@@ -16675,14 +16780,14 @@ function validateFixtureBehavior(value) {
16675
16780
  });
16676
16781
  }
16677
16782
  let replayBundle;
16678
- if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16679
- if (!record.replayBundle || typeof record.replayBundle !== "object" || Array.isArray(record.replayBundle)) {
16783
+ if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16784
+ if (!record2.replayBundle || typeof record2.replayBundle !== "object" || Array.isArray(record2.replayBundle)) {
16680
16785
  return {
16681
16786
  ok: false,
16682
16787
  error: "fixtureBehavior.replayBundle must be an object."
16683
16788
  };
16684
16789
  }
16685
- const replay = record.replayBundle;
16790
+ const replay = record2.replayBundle;
16686
16791
  const replayUnknownKeys = Object.keys(replay).filter(
16687
16792
  (key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
16688
16793
  );
@@ -16730,7 +16835,7 @@ function validateFixtureBehavior(value) {
16730
16835
  ...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
16731
16836
  };
16732
16837
  }
16733
- if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16838
+ if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16734
16839
  return {
16735
16840
  ok: true,
16736
16841
  behavior: {
@@ -16748,15 +16853,15 @@ function validateFixtureBehavior(value) {
16748
16853
  }
16749
16854
  };
16750
16855
  }
16751
- if (!Array.isArray(record.responseDelaySamplesMs) || record.responseDelaySamplesMs.length === 0 || record.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
16856
+ if (!Array.isArray(record2.responseDelaySamplesMs) || record2.responseDelaySamplesMs.length === 0 || record2.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
16752
16857
  return {
16753
16858
  ok: false,
16754
16859
  error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
16755
16860
  };
16756
16861
  }
16757
16862
  const samples = [];
16758
- for (let index = 0; index < record.responseDelaySamplesMs.length; index += 1) {
16759
- const value2 = record.responseDelaySamplesMs[index];
16863
+ for (let index = 0; index < record2.responseDelaySamplesMs.length; index += 1) {
16864
+ const value2 = record2.responseDelaySamplesMs[index];
16760
16865
  if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
16761
16866
  return {
16762
16867
  ok: false,
@@ -16965,7 +17070,7 @@ function traceCliSync(phase, fields, run) {
16965
17070
  }
16966
17071
  }
16967
17072
  function sleep5(ms) {
16968
- return new Promise((resolve20) => setTimeout(resolve20, ms));
17073
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
16969
17074
  }
16970
17075
  function parseReferencedPlayTarget2(target) {
16971
17076
  const trimmed = target.trim();
@@ -17498,8 +17603,8 @@ function looksLikeStagedFileRef(value) {
17498
17603
  if (!value || typeof value !== "object" || Array.isArray(value)) {
17499
17604
  return false;
17500
17605
  }
17501
- const record = value;
17502
- return typeof record.contentHash === "string" || typeof record.contentBase64 === "string" || typeof record.logicalPath === "string" && typeof record.bytes === "number";
17606
+ const record2 = value;
17607
+ return typeof record2.contentHash === "string" || typeof record2.contentBase64 === "string" || typeof record2.logicalPath === "string" && typeof record2.bytes === "number";
17503
17608
  }
17504
17609
  var CSV_DATA_INPUT_KEY = "csv";
17505
17610
  function collectLocalFileInputRefs(value, inputPath, key, out) {
@@ -18000,8 +18105,8 @@ function readLiveRunField(event, field) {
18000
18105
  const records = [payload, payload.progress, run, run?.progress].filter(
18001
18106
  (value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
18002
18107
  );
18003
- for (const record of records) {
18004
- if (record[field] !== void 0) return record[field];
18108
+ for (const record2 of records) {
18109
+ if (record2[field] !== void 0) return record2[field];
18005
18110
  }
18006
18111
  return void 0;
18007
18112
  }
@@ -18303,8 +18408,8 @@ function getProgressLinesFromLiveEvent(event) {
18303
18408
  if (!state || typeof state !== "object" || Array.isArray(state)) {
18304
18409
  continue;
18305
18410
  }
18306
- const record = state;
18307
- const progress = record.progress && typeof record.progress === "object" && !Array.isArray(record.progress) ? record.progress : null;
18411
+ const record2 = state;
18412
+ const progress = record2.progress && typeof record2.progress === "object" && !Array.isArray(record2.progress) ? record2.progress : null;
18308
18413
  if (!progress) {
18309
18414
  continue;
18310
18415
  }
@@ -18321,7 +18426,7 @@ function getProgressLinesFromLiveEvent(event) {
18321
18426
  completed: progress.completed
18322
18427
  });
18323
18428
  lines.push(
18324
- `progress ${formatProgressLabel(record.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
18429
+ `progress ${formatProgressLabel(record2.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
18325
18430
  );
18326
18431
  }
18327
18432
  return lines;
@@ -19150,17 +19255,17 @@ function collectDatasetHandleLines(value, path = "result") {
19150
19255
  return [];
19151
19256
  }
19152
19257
  if (isDatasetHandle(value)) {
19153
- const record = value;
19154
- const count = typeof record.count === "number" ? record.count : typeof record.rowCount === "number" ? record.rowCount : null;
19155
- const preview = Array.isArray(record.preview) ? record.preview : [];
19258
+ const record2 = value;
19259
+ const count = typeof record2.count === "number" ? record2.count : typeof record2.rowCount === "number" ? record2.rowCount : null;
19260
+ const preview = Array.isArray(record2.preview) ? record2.preview : [];
19156
19261
  const lines2 = [
19157
- ` dataset ${typeof record.path === "string" ? record.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
19262
+ ` dataset ${typeof record2.path === "string" ? record2.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
19158
19263
  ];
19159
- if (typeof record.queryDatasetCommand === "string") {
19160
- lines2.push(` query dataset: ${record.queryDatasetCommand}`);
19264
+ if (typeof record2.queryDatasetCommand === "string") {
19265
+ lines2.push(` query dataset: ${record2.queryDatasetCommand}`);
19161
19266
  }
19162
- if (typeof record.slowExportAsCsvCommand === "string") {
19163
- lines2.push(` export CSV: ${record.slowExportAsCsvCommand}`);
19267
+ if (typeof record2.slowExportAsCsvCommand === "string") {
19268
+ lines2.push(` export CSV: ${record2.slowExportAsCsvCommand}`);
19164
19269
  }
19165
19270
  return lines2;
19166
19271
  }
@@ -19557,8 +19662,8 @@ function withTerminalPlayIdentity(status, playName) {
19557
19662
  if (!playName.trim() || getPlayRunPackage(status)) {
19558
19663
  return status;
19559
19664
  }
19560
- const record = status;
19561
- const hasIdentity = typeof record.playName === "string" && record.playName.trim().length > 0 || typeof record.name === "string" && record.name.trim().length > 0 || Boolean(getStringField(record.run, "playName"));
19665
+ const record2 = status;
19666
+ 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"));
19562
19667
  if (hasIdentity) {
19563
19668
  return status;
19564
19669
  }
@@ -19671,9 +19776,9 @@ function formatSummaryScalar(value) {
19671
19776
  }
19672
19777
  return null;
19673
19778
  }
19674
- function formatSummaryScalarParts(record, skipKeys = /* @__PURE__ */ new Set()) {
19779
+ function formatSummaryScalarParts(record2, skipKeys = /* @__PURE__ */ new Set()) {
19675
19780
  const parts = [];
19676
- for (const [key, value] of Object.entries(record)) {
19781
+ for (const [key, value] of Object.entries(record2)) {
19677
19782
  if (skipKeys.has(key)) {
19678
19783
  continue;
19679
19784
  }
@@ -19700,13 +19805,13 @@ function formatTopValuesPart(value) {
19700
19805
  return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
19701
19806
  }
19702
19807
  function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
19703
- const record = readRecord(summary);
19704
- const columnStats = readRecord(record?.columnStats);
19705
- if (!record || !columnStats) {
19808
+ const record2 = readRecord(summary);
19809
+ const columnStats = readRecord(record2?.columnStats);
19810
+ if (!record2 || !columnStats) {
19706
19811
  return [];
19707
19812
  }
19708
19813
  const lines = [];
19709
- const rowCounts = readRecord(record.rowCounts);
19814
+ const rowCounts = readRecord(record2.rowCounts);
19710
19815
  if (rowCounts) {
19711
19816
  const persisted = readNonNegativeInteger(rowCounts.persisted);
19712
19817
  const succeeded = readNonNegativeInteger(rowCounts.succeeded);
@@ -19722,7 +19827,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
19722
19827
  }
19723
19828
  }
19724
19829
  const parts = formatSummaryScalarParts(
19725
- record,
19830
+ record2,
19726
19831
  /* @__PURE__ */ new Set(["columnStats", "rowCounts"])
19727
19832
  );
19728
19833
  if (parts.length > 0) {
@@ -19752,35 +19857,35 @@ function actionToCommand(action) {
19752
19857
  if (!action || typeof action !== "object" || Array.isArray(action)) {
19753
19858
  return null;
19754
19859
  }
19755
- const record = action;
19756
- if (typeof record.command === "string" && record.command.trim()) {
19757
- return record.command.trim();
19860
+ const record2 = action;
19861
+ if (typeof record2.command === "string" && record2.command.trim()) {
19862
+ return record2.command.trim();
19758
19863
  }
19759
- if (record.kind === "deepline_run_inspect" && typeof record.runId === "string") {
19760
- return `deepline runs get ${record.runId} --json`;
19864
+ if (record2.kind === "deepline_run_inspect" && typeof record2.runId === "string") {
19865
+ return `deepline runs get ${record2.runId} --json`;
19761
19866
  }
19762
- if (record.kind === "deepline_run_full" && typeof record.runId === "string") {
19763
- return `deepline runs get ${record.runId} --full --json`;
19867
+ if (record2.kind === "deepline_run_full" && typeof record2.runId === "string") {
19868
+ return `deepline runs get ${record2.runId} --full --json`;
19764
19869
  }
19765
- if (record.kind === "deepline_run_billing" && typeof record.runId === "string") {
19766
- return `deepline runs get ${record.runId} --full --json | jq '.billing'`;
19870
+ if (record2.kind === "deepline_run_billing" && typeof record2.runId === "string") {
19871
+ return `deepline runs get ${record2.runId} --full --json | jq '.billing'`;
19767
19872
  }
19768
- if (record.kind === "deepline_run_export" && typeof record.runId === "string" && typeof record.datasetPath === "string") {
19769
- return `deepline runs export ${record.runId} --dataset ${shellSingleQuote(
19770
- record.datasetPath
19771
- )} --out ${shellSingleQuote(`${record.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
19873
+ if (record2.kind === "deepline_run_export" && typeof record2.runId === "string" && typeof record2.datasetPath === "string") {
19874
+ return `deepline runs export ${record2.runId} --dataset ${shellSingleQuote(
19875
+ record2.datasetPath
19876
+ )} --out ${shellSingleQuote(`${record2.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
19772
19877
  }
19773
- if (record.kind === "deepline_run_logs") {
19774
- if (typeof record.command === "string" && record.command.trim()) {
19775
- return record.command;
19878
+ if (record2.kind === "deepline_run_logs") {
19879
+ if (typeof record2.command === "string" && record2.command.trim()) {
19880
+ return record2.command;
19776
19881
  }
19777
- if (typeof record.runId === "string") {
19778
- return record.view === "failed" ? `deepline runs get ${record.runId} --log-failed --json` : `deepline runs logs ${record.runId} --json`;
19882
+ if (typeof record2.runId === "string") {
19883
+ return record2.view === "failed" ? `deepline runs get ${record2.runId} --log-failed --json` : `deepline runs logs ${record2.runId} --json`;
19779
19884
  }
19780
19885
  }
19781
- if (record.kind === "deepline_db_query" && typeof record.sql === "string") {
19782
- const maxRows = typeof record.maxRows === "number" && Number.isFinite(record.maxRows) ? Math.trunc(record.maxRows) : 20;
19783
- return `deepline db query --sql ${shellSingleQuote(record.sql)} --max-rows ${maxRows} --json`;
19886
+ if (record2.kind === "deepline_db_query" && typeof record2.sql === "string") {
19887
+ const maxRows = typeof record2.maxRows === "number" && Number.isFinite(record2.maxRows) ? Math.trunc(record2.maxRows) : 20;
19888
+ return `deepline db query --sql ${shellSingleQuote(record2.sql)} --max-rows ${maxRows} --json`;
19784
19889
  }
19785
19890
  return null;
19786
19891
  }
@@ -20185,12 +20290,12 @@ function exportableSheetRow(row) {
20185
20290
  if (!row || typeof row !== "object" || Array.isArray(row)) {
20186
20291
  return null;
20187
20292
  }
20188
- const record = row;
20189
- const data = record.data;
20293
+ const record2 = row;
20294
+ const data = record2.data;
20190
20295
  if (data && typeof data === "object" && !Array.isArray(data)) {
20191
20296
  return data;
20192
20297
  }
20193
- const fallback = { ...record };
20298
+ const fallback = { ...record2 };
20194
20299
  for (const key of [
20195
20300
  "key",
20196
20301
  "status",
@@ -20542,8 +20647,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
20542
20647
  "ctx.map(...) has been replaced by ctx.dataset(...)",
20543
20648
  "Dataset .step(...) has been replaced by .withColumn(...)"
20544
20649
  ];
20545
- function stringArrayField(record, key) {
20546
- const value = record[key];
20650
+ function stringArrayField(record2, key) {
20651
+ const value = record2[key];
20547
20652
  if (!Array.isArray(value)) return [];
20548
20653
  return value.filter((entry) => typeof entry === "string");
20549
20654
  }
@@ -23716,10 +23821,16 @@ Concepts:
23716
23821
  Authoring:
23717
23822
  Use normal TypeScript interpolation for human-facing strings:
23718
23823
  const readyMessage = \`Put \${input.title} through to send-ready.\`;
23719
- An authored diagram is optional. Docflow parses only an explicit
23824
+ An authored diagram is optional but highly recommended for every new or
23825
+ substantially changed Play. Docflow parses only an explicit
23720
23826
  /** @mermaid ... */ block and its // @mermaid-node annotations; ordinary
23721
23827
  prose comments are never Docflow syntax. When Docflow is enabled, plays check
23722
- gives missing diagrams a non-blocking visualization warning.
23828
+ gives missing diagrams a high-priority, non-blocking warning with the exact
23829
+ Mermaid repair steps. Without a diagram, users see only an inferred execution
23830
+ graph rather than a clear business-language map. It is easy to add: write a
23831
+ short top-of-file flowchart, annotate its visible executable steps, then run
23832
+ plays check again. Treat that warning as an authoring task before finishing
23833
+ Play work unless the caller explicitly asks to leave the inferred graph.
23723
23834
 
23724
23835
  Common commands:
23725
23836
  deepline plays search email --json
@@ -26315,7 +26426,7 @@ function emitEnrichDebug(message) {
26315
26426
  );
26316
26427
  }
26317
26428
  function sleep6(ms) {
26318
- return new Promise((resolve20) => setTimeout(resolve20, ms));
26429
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
26319
26430
  }
26320
26431
  function enrichExportBackingRowsWaitMs() {
26321
26432
  const raw = process.env.DEEPLINE_ENRICH_EXPORT_BACKING_ROWS_WAIT_MS?.trim();
@@ -26424,9 +26535,9 @@ async function expandCompiledConfigAtFiles(value) {
26424
26535
  if (!value || typeof value !== "object") {
26425
26536
  return value;
26426
26537
  }
26427
- const record = value;
26538
+ const record2 = value;
26428
26539
  const expanded = {};
26429
- for (const [key, entry] of Object.entries(record)) {
26540
+ for (const [key, entry] of Object.entries(record2)) {
26430
26541
  expanded[key] = await expandCompiledConfigAtFiles(entry);
26431
26542
  }
26432
26543
  for (const field of ["extract_js", "run_if_js"]) {
@@ -27224,26 +27335,26 @@ function readFirstEnrichDatasetActions(value) {
27224
27335
  }
27225
27336
  return null;
27226
27337
  }
27227
- const record = candidate;
27228
- const actions = isRecord11(record.actions) ? record.actions : null;
27338
+ const record2 = candidate;
27339
+ const actions = isRecord11(record2.actions) ? record2.actions : null;
27229
27340
  const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
27230
27341
  const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
27231
27342
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
27232
27343
  if (query?.kind === "deepline_db_query") {
27233
27344
  return {
27234
- dataset: record,
27345
+ dataset: record2,
27235
27346
  query,
27236
27347
  ...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
27237
27348
  };
27238
27349
  }
27239
- if (options.allowLegacy && record.kind === "dataset" && typeof record.queryDatasetCommand === "string" && record.queryDatasetCommand.trim()) {
27350
+ if (options.allowLegacy && record2.kind === "dataset" && typeof record2.queryDatasetCommand === "string" && record2.queryDatasetCommand.trim()) {
27240
27351
  return {
27241
- dataset: record,
27242
- queryDatasetCommand: record.queryDatasetCommand.trim(),
27243
- ...typeof record.slowExportAsCsvCommand === "string" && record.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record.slowExportAsCsvCommand.trim() } : {}
27352
+ dataset: record2,
27353
+ queryDatasetCommand: record2.queryDatasetCommand.trim(),
27354
+ ...typeof record2.slowExportAsCsvCommand === "string" && record2.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record2.slowExportAsCsvCommand.trim() } : {}
27244
27355
  };
27245
27356
  }
27246
- for (const [key, entry] of Object.entries(record)) {
27357
+ for (const [key, entry] of Object.entries(record2)) {
27247
27358
  if (key === "preview") {
27248
27359
  continue;
27249
27360
  }
@@ -27259,8 +27370,8 @@ function readFirstEnrichDatasetActions(value) {
27259
27370
  seen.clear();
27260
27371
  return walk(value, { allowLegacy: true });
27261
27372
  }
27262
- function actionStringField(record, key) {
27263
- const value = record[key];
27373
+ function actionStringField(record2, key) {
27374
+ const value = record2[key];
27264
27375
  return typeof value === "string" && value.trim() ? value.trim() : null;
27265
27376
  }
27266
27377
  function parseSqlFromDbQueryCommand(command) {
@@ -27604,12 +27715,12 @@ function collectStringFields(value, key, output2, depth = 0) {
27604
27715
  }
27605
27716
  return;
27606
27717
  }
27607
- const record = value;
27608
- const direct = record[key];
27718
+ const record2 = value;
27719
+ const direct = record2[key];
27609
27720
  if (typeof direct === "string" && direct.trim()) {
27610
27721
  output2.add(direct.trim());
27611
27722
  }
27612
- for (const child of Object.values(record)) {
27723
+ for (const child of Object.values(record2)) {
27613
27724
  collectStringFields(child, key, output2, depth + 1);
27614
27725
  }
27615
27726
  }
@@ -27795,23 +27906,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
27795
27906
  if (!row || typeof row !== "object" || Array.isArray(row)) {
27796
27907
  return null;
27797
27908
  }
27798
- const record = row;
27799
- const data = record.data;
27909
+ const record2 = row;
27910
+ const data = record2.data;
27800
27911
  if (data && typeof data === "object" && !Array.isArray(data)) {
27801
27912
  const exported = { ...data };
27802
27913
  applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
27803
- rowError: record.error
27914
+ rowError: record2.error
27804
27915
  });
27805
- applyFailureCellMeta(exported, record.cellMeta, { rowError: record.error });
27806
- applyFailureCellMeta(exported, record.cellMetaPatch, {
27807
- rowError: record.error
27916
+ applyFailureCellMeta(exported, record2.cellMeta, { rowError: record2.error });
27917
+ applyFailureCellMeta(exported, record2.cellMetaPatch, {
27918
+ rowError: record2.error
27808
27919
  });
27809
- applyFailureCellMeta(exported, record[ENRICH_CELL_META_PATCH_FIELD], {
27810
- rowError: record.error
27920
+ applyFailureCellMeta(exported, record2[ENRICH_CELL_META_PATCH_FIELD], {
27921
+ rowError: record2.error
27811
27922
  });
27812
27923
  delete exported[ENRICH_CELL_META_FIELD];
27813
27924
  delete exported[ENRICH_CELL_META_PATCH_FIELD];
27814
- const inputIndex = typeof record.inputIndex === "number" ? record.inputIndex : typeof record.inputIndex === "string" && record.inputIndex.trim() ? Number(record.inputIndex) : Number.NaN;
27925
+ const inputIndex = typeof record2.inputIndex === "number" ? record2.inputIndex : typeof record2.inputIndex === "string" && record2.inputIndex.trim() ? Number(record2.inputIndex) : Number.NaN;
27815
27926
  if (Number.isInteger(inputIndex) && inputIndex >= 0) {
27816
27927
  if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
27817
27928
  exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
@@ -27820,18 +27931,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
27820
27931
  }
27821
27932
  return exported;
27822
27933
  }
27823
- const fallback = { ...record };
27934
+ const fallback = { ...record2 };
27824
27935
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
27825
- rowError: record.error
27936
+ rowError: record2.error
27826
27937
  });
27827
- applyFailureCellMeta(fallback, record.cellMeta, {
27828
- rowError: record.error
27938
+ applyFailureCellMeta(fallback, record2.cellMeta, {
27939
+ rowError: record2.error
27829
27940
  });
27830
- applyFailureCellMeta(fallback, record.cellMetaPatch, {
27831
- rowError: record.error
27941
+ applyFailureCellMeta(fallback, record2.cellMetaPatch, {
27942
+ rowError: record2.error
27832
27943
  });
27833
27944
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
27834
- rowError: record.error
27945
+ rowError: record2.error
27835
27946
  });
27836
27947
  for (const key of [
27837
27948
  "key",
@@ -28050,16 +28161,16 @@ function isWaterfallResultMeaningful(value) {
28050
28161
  return value.some(isWaterfallResultMeaningful);
28051
28162
  }
28052
28163
  if (value && typeof value === "object") {
28053
- const record = value;
28054
- const status = typeof record.status === "string" ? record.status.trim().toLowerCase() : "";
28164
+ const record2 = value;
28165
+ const status = typeof record2.status === "string" ? record2.status.trim().toLowerCase() : "";
28055
28166
  if (status === "error" || status === "failed") {
28056
28167
  return false;
28057
28168
  }
28058
- if (typeof record.error === "string" && record.error.trim()) {
28169
+ if (typeof record2.error === "string" && record2.error.trim()) {
28059
28170
  return false;
28060
28171
  }
28061
- if (Object.prototype.hasOwnProperty.call(record, "matched_result")) {
28062
- return isWaterfallResultMeaningful(record.matched_result);
28172
+ if (Object.prototype.hasOwnProperty.call(record2, "matched_result")) {
28173
+ return isWaterfallResultMeaningful(record2.matched_result);
28063
28174
  }
28064
28175
  for (const key of [
28065
28176
  "value",
@@ -28074,11 +28185,11 @@ function isWaterfallResultMeaningful(value) {
28074
28185
  "result",
28075
28186
  "data"
28076
28187
  ]) {
28077
- if (isWaterfallResultMeaningful(record[key])) {
28188
+ if (isWaterfallResultMeaningful(record2[key])) {
28078
28189
  return true;
28079
28190
  }
28080
28191
  }
28081
- return Object.entries(record).some(
28192
+ return Object.entries(record2).some(
28082
28193
  ([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
28083
28194
  );
28084
28195
  }
@@ -28094,8 +28205,8 @@ function stableRowSnapshot(value) {
28094
28205
  return `[${value.map(stableRowSnapshot).join(",")}]`;
28095
28206
  }
28096
28207
  if (value && typeof value === "object") {
28097
- const record = value;
28098
- return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record[key])}`).join(",")}}`;
28208
+ const record2 = value;
28209
+ return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record2[key])}`).join(",")}}`;
28099
28210
  }
28100
28211
  return JSON.stringify(value);
28101
28212
  }
@@ -28682,8 +28793,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
28682
28793
  seen.add(normalized);
28683
28794
  commands.push({ ...command, command: normalized });
28684
28795
  }
28685
- function datasetSelectorForEnrichCommand(record, fallbackPath) {
28686
- const candidates = [record.path, record.tableNamespace, fallbackPath];
28796
+ function datasetSelectorForEnrichCommand(record2, fallbackPath) {
28797
+ const candidates = [record2.path, record2.tableNamespace, fallbackPath];
28687
28798
  for (const candidate of candidates) {
28688
28799
  if (typeof candidate === "string" && candidate.trim()) {
28689
28800
  return candidate.trim();
@@ -28745,19 +28856,19 @@ function collectDatasetFollowUpCommands(value, state) {
28745
28856
  );
28746
28857
  return;
28747
28858
  }
28748
- const record = value;
28749
- const isDataset = record.kind === "dataset";
28859
+ const record2 = value;
28860
+ const isDataset = record2.kind === "dataset";
28750
28861
  if (isDataset) {
28751
- const selector = datasetSelectorForEnrichCommand(record, state.path);
28752
- const labelPath = typeof record.path === "string" && record.path.trim() ? record.path.trim() : selector ?? state.path;
28753
- if (typeof record.queryDatasetCommand === "string") {
28862
+ const selector = datasetSelectorForEnrichCommand(record2, state.path);
28863
+ const labelPath = typeof record2.path === "string" && record2.path.trim() ? record2.path.trim() : selector ?? state.path;
28864
+ if (typeof record2.queryDatasetCommand === "string") {
28754
28865
  addEnrichFollowUpCommand(state.commands, state.seen, {
28755
28866
  label: `query ${labelPath}`,
28756
28867
  path: labelPath,
28757
- command: record.queryDatasetCommand
28868
+ command: record2.queryDatasetCommand
28758
28869
  });
28759
28870
  }
28760
- const exportCommand = typeof record.slowExportAsCsvCommand === "string" ? record.slowExportAsCsvCommand : typeof record.fullExportCommand === "string" ? record.fullExportCommand : null;
28871
+ const exportCommand = typeof record2.slowExportAsCsvCommand === "string" ? record2.slowExportAsCsvCommand : typeof record2.fullExportCommand === "string" ? record2.fullExportCommand : null;
28761
28872
  if (exportCommand) {
28762
28873
  addEnrichFollowUpCommand(state.commands, state.seen, {
28763
28874
  label: `export ${labelPath}`,
@@ -28774,7 +28885,7 @@ function collectDatasetFollowUpCommands(value, state) {
28774
28885
  });
28775
28886
  }
28776
28887
  }
28777
- for (const [key, child] of Object.entries(record)) {
28888
+ for (const [key, child] of Object.entries(record2)) {
28778
28889
  if (key === "preview" || key === "access") {
28779
28890
  continue;
28780
28891
  }
@@ -30206,9 +30317,9 @@ function readCodexSessionId(filePath) {
30206
30317
  )) {
30207
30318
  const parsed = parseJsonLine(line);
30208
30319
  if (!parsed || typeof parsed !== "object") continue;
30209
- const record = parsed;
30210
- const payload = record.payload && typeof record.payload === "object" ? record.payload : null;
30211
- const id = record.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
30320
+ const record2 = parsed;
30321
+ const payload = record2.payload && typeof record2.payload === "object" ? record2.payload : null;
30322
+ const id = record2.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
30212
30323
  if (id && UUID_RE.test(id)) return id;
30213
30324
  }
30214
30325
  } catch {
@@ -30307,15 +30418,15 @@ function messageContentKey(value) {
30307
30418
  if (!Array.isArray(content)) return null;
30308
30419
  return content.map((block) => {
30309
30420
  if (!block || typeof block !== "object") return String(block);
30310
- const record = block;
30311
- const type = String(record.type ?? "");
30421
+ const record2 = block;
30422
+ const type = String(record2.type ?? "");
30312
30423
  if (type === "tool_use") {
30313
- return `tool_use:${String(record.name ?? "")}:${String(record.id ?? "")}`;
30424
+ return `tool_use:${String(record2.name ?? "")}:${String(record2.id ?? "")}`;
30314
30425
  }
30315
30426
  if (type === "tool_result") {
30316
- return `tool_result:${String(record.tool_use_id ?? "")}`;
30427
+ return `tool_result:${String(record2.tool_use_id ?? "")}`;
30317
30428
  }
30318
- return String(record.text ?? type);
30429
+ return String(record2.text ?? type);
30319
30430
  }).join("\n");
30320
30431
  }
30321
30432
  function dedupConsecutiveEvents(raw) {
@@ -30330,9 +30441,9 @@ function dedupConsecutiveEvents(raw) {
30330
30441
  index += 1;
30331
30442
  continue;
30332
30443
  }
30333
- const record = event;
30334
- const eventType = String(record.type ?? "");
30335
- const eventKey = messageContentKey(record);
30444
+ const record2 = event;
30445
+ const eventType = String(record2.type ?? "");
30446
+ const eventKey = messageContentKey(record2);
30336
30447
  if (!["user", "assistant"].includes(eventType) || !eventKey) {
30337
30448
  output2.push(rawLines[index] ?? "");
30338
30449
  index += 1;
@@ -30351,9 +30462,9 @@ function dedupConsecutiveEvents(raw) {
30351
30462
  cursor += 1;
30352
30463
  }
30353
30464
  if (runCount > 1) {
30354
- record._repeat_count = runCount;
30355
- record._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
30356
- output2.push(JSON.stringify(record));
30465
+ record2._repeat_count = runCount;
30466
+ record2._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
30467
+ output2.push(JSON.stringify(record2));
30357
30468
  index = cursor;
30358
30469
  continue;
30359
30470
  }
@@ -30398,9 +30509,9 @@ function selectiveCompactToolResults(raw) {
30398
30509
  lines.push(line);
30399
30510
  continue;
30400
30511
  }
30401
- const record = parsed;
30402
- if (record.type === "user") {
30403
- const message = record.message;
30512
+ const record2 = parsed;
30513
+ if (record2.type === "user") {
30514
+ const message = record2.message;
30404
30515
  const content = message && typeof message === "object" ? message.content : null;
30405
30516
  if (Array.isArray(content)) {
30406
30517
  message.content = content.map(
@@ -30408,7 +30519,7 @@ function selectiveCompactToolResults(raw) {
30408
30519
  );
30409
30520
  }
30410
30521
  }
30411
- lines.push(JSON.stringify(record));
30522
+ lines.push(JSON.stringify(record2));
30412
30523
  }
30413
30524
  return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
30414
30525
  ` : "", "utf8");
@@ -30434,15 +30545,15 @@ function compactCodexEvents(raw) {
30434
30545
  lines.push(rawLines[index] ?? "");
30435
30546
  return;
30436
30547
  }
30437
- const record = event;
30438
- if (record.type === "world_state") return;
30439
- const payload = record.payload;
30548
+ const record2 = event;
30549
+ if (record2.type === "world_state") return;
30550
+ const payload = record2.payload;
30440
30551
  const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
30441
30552
  if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
30442
30553
  if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
30443
30554
  const record_payload = payload;
30444
30555
  record_payload.output = compactEventValue(record_payload.output);
30445
- lines.push(JSON.stringify(record));
30556
+ lines.push(JSON.stringify(record2));
30446
30557
  return;
30447
30558
  }
30448
30559
  lines.push(rawLines[index] ?? "");
@@ -30905,8 +31016,325 @@ Examples:
30905
31016
  }
30906
31017
 
30907
31018
  // src/cli/commands/monitors.ts
30908
- import { readFileSync as readFileSync10 } from "fs";
31019
+ import { randomUUID as randomUUID5 } from "crypto";
31020
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync12 } from "fs";
31021
+ import { resolve as resolve14 } from "path";
30909
31022
  import { createInterface } from "readline/promises";
31023
+
31024
+ // src/monitor-fleet-contract.ts
31025
+ var MONITOR_FLEET_MAX_MEMBERS = 1e3;
31026
+ var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
31027
+ var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
31028
+ MONITOR_FLEET_AUTHORING_CONTRACT_EDITION
31029
+ ];
31030
+ var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
31031
+ var MONITOR_FLEET_DOCUMENTATION = {
31032
+ summary: "A Monitor Fleet keeps one bounded, sticky set of ordinary monitors aligned with Customer DB rows.",
31033
+ authoredFields: {
31034
+ id: "Stable lowercase fleet id used by sync, pause, resume, and deactivate.",
31035
+ source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
31036
+ member: "Ordinary monitor tool, stable key template, and payload evaluated for each selected source row.",
31037
+ selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
31038
+ },
31039
+ fixedPolicy: {
31040
+ cadence: "daily",
31041
+ membership: "sticky",
31042
+ removalGrace: "7d",
31043
+ onRemoved: "deactivate",
31044
+ ownership: "A Fleet may adopt a same-tool ordinary monitor with its deterministic member key. The first Fleet claim wins; another Fleet or a different tool receives a conflict.",
31045
+ billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
31046
+ },
31047
+ stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
31048
+ columnExpression: 'Use { "$fleet": "column", "name": "column_name" } in a member key or payload to read a value from each source row.'
31049
+ };
31050
+ function record(value) {
31051
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
31052
+ }
31053
+ function identifier(value) {
31054
+ return typeof value === "string" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value);
31055
+ }
31056
+ function exactKeys(input2, keys, path, issues) {
31057
+ if (!input2) return;
31058
+ for (const key of Object.keys(input2)) {
31059
+ if (keys.includes(key)) continue;
31060
+ issues.push({
31061
+ path: path ? `${path}.${key}` : key,
31062
+ code: "unknown_fleet_field",
31063
+ message: `${path || "Fleet"} does not accept '${key}'.`
31064
+ });
31065
+ }
31066
+ }
31067
+ function jsonValue(value, path, issues) {
31068
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
31069
+ return;
31070
+ }
31071
+ if (Array.isArray(value)) {
31072
+ value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
31073
+ return;
31074
+ }
31075
+ const input2 = record(value);
31076
+ if (!input2) {
31077
+ issues.push({
31078
+ path,
31079
+ code: "invalid_fleet_json_value",
31080
+ message: "Fleet payload values must be JSON values."
31081
+ });
31082
+ return;
31083
+ }
31084
+ for (const [key, item] of Object.entries(input2)) {
31085
+ jsonValue(item, `${path}.${key}`, issues);
31086
+ }
31087
+ }
31088
+ function validateExpression(value, path, issues) {
31089
+ const input2 = record(value);
31090
+ if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
31091
+ issues.push({
31092
+ path,
31093
+ code: "invalid_fleet_expression",
31094
+ message: "Fleet expressions must be an exact tagged column reference."
31095
+ });
31096
+ return;
31097
+ }
31098
+ exactKeys(input2, ["$fleet", "name"], path, issues);
31099
+ }
31100
+ function walkPayload(value, path, issues) {
31101
+ if (Array.isArray(value)) {
31102
+ value.forEach(
31103
+ (item, index) => walkPayload(item, `${path}.${index}`, issues)
31104
+ );
31105
+ return;
31106
+ }
31107
+ const input2 = record(value);
31108
+ if (!input2) return;
31109
+ if ("$fleet" in input2) {
31110
+ validateExpression(input2, path, issues);
31111
+ return;
31112
+ }
31113
+ for (const [key, item] of Object.entries(input2)) {
31114
+ walkPayload(item, `${path}.${key}`, issues);
31115
+ }
31116
+ }
31117
+ function validateMonitorFleetDefinition(value) {
31118
+ const issues = [];
31119
+ const input2 = record(value);
31120
+ if (!input2) {
31121
+ return {
31122
+ valid: false,
31123
+ issues: [
31124
+ {
31125
+ path: "",
31126
+ code: "invalid_fleet",
31127
+ message: "Fleet must be an object."
31128
+ }
31129
+ ]
31130
+ };
31131
+ }
31132
+ exactKeys(input2, ["id", "source", "member", "selection"], "", issues);
31133
+ if (typeof input2.id !== "string" || !/^[a-z][a-z0-9-]{0,199}$/.test(input2.id)) {
31134
+ issues.push({
31135
+ path: "id",
31136
+ code: "invalid_fleet_id",
31137
+ message: "Fleet id must be lowercase kebab-case."
31138
+ });
31139
+ }
31140
+ const source = record(input2.source);
31141
+ exactKeys(
31142
+ source,
31143
+ ["kind", "schema", "table", "key", "where"],
31144
+ "source",
31145
+ issues
31146
+ );
31147
+ if (!source || source.kind !== "customer_db_table") {
31148
+ issues.push({
31149
+ path: "source.kind",
31150
+ code: "invalid_fleet_source",
31151
+ message: "Beta fleets require customer_db_table."
31152
+ });
31153
+ }
31154
+ if (!identifier(source?.schema) || !identifier(source?.table)) {
31155
+ issues.push({
31156
+ path: "source",
31157
+ code: "invalid_fleet_table",
31158
+ message: "Source schema and table must be SQL identifiers."
31159
+ });
31160
+ }
31161
+ const sourceKey = record(source?.key);
31162
+ exactKeys(sourceKey, ["column", "type"], "source.key", issues);
31163
+ if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
31164
+ issues.push({
31165
+ path: "source.key",
31166
+ code: "invalid_fleet_source_key",
31167
+ message: "Source key must name a supported typed column."
31168
+ });
31169
+ }
31170
+ if (source?.where !== void 0) {
31171
+ const where = record(source.where);
31172
+ if (!where) {
31173
+ issues.push({
31174
+ path: "source.where",
31175
+ code: "invalid_fleet_where",
31176
+ message: "source.where must be an object of equality values."
31177
+ });
31178
+ } else {
31179
+ for (const [column, expected] of Object.entries(where)) {
31180
+ if (!identifier(column)) {
31181
+ issues.push({
31182
+ path: `source.where.${column}`,
31183
+ code: "invalid_fleet_where_column",
31184
+ message: "source.where keys must be SQL identifiers."
31185
+ });
31186
+ }
31187
+ if (expected !== null && typeof expected !== "string" && typeof expected !== "boolean" && !(typeof expected === "number" && Number.isFinite(expected))) {
31188
+ issues.push({
31189
+ path: `source.where.${column}`,
31190
+ code: "invalid_fleet_where_value",
31191
+ message: "source.where values must be finite JSON scalars or null."
31192
+ });
31193
+ }
31194
+ }
31195
+ }
31196
+ }
31197
+ const member = record(input2.member);
31198
+ exactKeys(member, ["tool", "key", "payload"], "member", issues);
31199
+ const key = record(member?.key);
31200
+ if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
31201
+ issues.push({
31202
+ path: "member.tool",
31203
+ code: "invalid_fleet_tool",
31204
+ message: "Member tool is required."
31205
+ });
31206
+ }
31207
+ if (!key || key.$fleet !== "template" || !Array.isArray(key.parts) || key.parts.length === 0) {
31208
+ issues.push({
31209
+ path: "member.key",
31210
+ code: "invalid_fleet_key",
31211
+ message: "Member key must be a tagged fleet template."
31212
+ });
31213
+ } else {
31214
+ exactKeys(key, ["$fleet", "parts"], "member.key", issues);
31215
+ for (const [index, part] of key.parts.entries()) {
31216
+ if (typeof part !== "string")
31217
+ validateExpression(part, `member.key.parts.${index}`, issues);
31218
+ }
31219
+ if (sourceKey && !key.parts.some(
31220
+ (part) => record(part)?.$fleet === "column" && record(part)?.name === sourceKey.column
31221
+ )) {
31222
+ issues.push({
31223
+ path: "member.key.parts",
31224
+ code: "fleet_key_missing_source_key",
31225
+ message: "Member key must include the source key column."
31226
+ });
31227
+ }
31228
+ }
31229
+ if (!member || !("payload" in member)) {
31230
+ issues.push({
31231
+ path: "member.payload",
31232
+ code: "invalid_fleet_payload",
31233
+ message: "Member payload is required."
31234
+ });
31235
+ } else {
31236
+ jsonValue(member.payload, "member.payload", issues);
31237
+ }
31238
+ walkPayload(member?.payload, "member.payload", issues);
31239
+ const selection = record(input2.selection);
31240
+ exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
31241
+ if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
31242
+ issues.push({
31243
+ path: "selection.limit",
31244
+ code: "MONITOR_FLEET_LIMIT_EXCEEDED",
31245
+ message: "selection.limit must be between 1 and 1,000."
31246
+ });
31247
+ }
31248
+ if (selection?.membership !== "sticky") {
31249
+ issues.push({
31250
+ path: "selection.membership",
31251
+ code: "invalid_fleet_membership",
31252
+ message: `Fleet membership is fixed to ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.membership}. ${MONITOR_FLEET_DOCUMENTATION.stickyMembership}`
31253
+ });
31254
+ }
31255
+ const orderBy = selection?.orderBy;
31256
+ if (!Array.isArray(orderBy) || orderBy.length === 0) {
31257
+ issues.push({
31258
+ path: "selection.orderBy",
31259
+ code: "invalid_fleet_order",
31260
+ message: "At least one deterministic order field is required."
31261
+ });
31262
+ } else {
31263
+ const orderColumns = /* @__PURE__ */ new Set();
31264
+ for (const [index, order] of orderBy.entries()) {
31265
+ const item = record(order);
31266
+ exactKeys(
31267
+ item,
31268
+ ["column", "direction"],
31269
+ `selection.orderBy.${index}`,
31270
+ issues
31271
+ );
31272
+ if (!item || !identifier(item.column) || !["asc", "desc"].includes(String(item.direction))) {
31273
+ issues.push({
31274
+ path: `selection.orderBy.${index}`,
31275
+ code: "invalid_fleet_order",
31276
+ message: "Order fields need a column and asc/desc direction."
31277
+ });
31278
+ } else if (orderColumns.has(item.column)) {
31279
+ issues.push({
31280
+ path: `selection.orderBy.${index}.column`,
31281
+ code: "duplicate_fleet_order_column",
31282
+ message: "Each selection order column may appear only once."
31283
+ });
31284
+ } else {
31285
+ orderColumns.add(item.column);
31286
+ }
31287
+ }
31288
+ if (sourceKey && record(orderBy.at(-1))?.column !== sourceKey.column) {
31289
+ issues.push({
31290
+ path: "selection.orderBy",
31291
+ code: "fleet_order_missing_key",
31292
+ message: "The final order field must be the source key."
31293
+ });
31294
+ }
31295
+ }
31296
+ for (const removedOption of ["spendLimits", "lifecycle", "reconciliation"]) {
31297
+ if (removedOption in input2) {
31298
+ issues.push({
31299
+ path: removedOption,
31300
+ code: "unsupported_fleet_option",
31301
+ message: `${removedOption} is fixed by Monitor Fleets and must be omitted. Fleets sync ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.cadence} and ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.onRemoved} members after ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.removalGrace} absent from the source.`
31302
+ });
31303
+ }
31304
+ }
31305
+ return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
31306
+ }
31307
+ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHORING_CONTRACT_EDITION) {
31308
+ if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
31309
+ edition
31310
+ )) {
31311
+ return {
31312
+ valid: false,
31313
+ issues: [
31314
+ {
31315
+ path: "authoring_contract_edition",
31316
+ code: "unsupported_fleet_authoring_contract_edition",
31317
+ message: `Monitor Fleet authoring contract edition ${edition} is not supported.`
31318
+ }
31319
+ ]
31320
+ };
31321
+ }
31322
+ const result = validateMonitorFleetDefinition(value);
31323
+ return result.valid && result.definition ? {
31324
+ valid: true,
31325
+ contract: {
31326
+ edition,
31327
+ // JSON cloning prevents later caller mutation from changing the
31328
+ // admitted snapshot.
31329
+ definition: JSON.parse(
31330
+ JSON.stringify(result.definition)
31331
+ )
31332
+ },
31333
+ issues: []
31334
+ } : { valid: false, issues: result.issues };
31335
+ }
31336
+
31337
+ // src/cli/commands/monitors.ts
30910
31338
  var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
30911
31339
  function withJsonOption(command) {
30912
31340
  return command.option("--json", JSON_OPTION_DESCRIPTION);
@@ -30928,6 +31356,7 @@ var MonitorDryRunUnsupportedError = class extends Error {
30928
31356
  };
30929
31357
  function monitorsErrorExitCode(error) {
30930
31358
  if (error instanceof MonitorsUsageError) return 2;
31359
+ if (error instanceof MonitorFleetStateError) return 6;
30931
31360
  if (error instanceof AuthError) return 3;
30932
31361
  if (error instanceof DeeplineError) {
30933
31362
  const status = error.statusCode;
@@ -30938,12 +31367,14 @@ function monitorsErrorExitCode(error) {
30938
31367
  }
30939
31368
  return 5;
30940
31369
  }
30941
- function monitorsFailureNextCommand(error, exitCode) {
31370
+ function monitorsFailureNextCommand(error, exitCode, options) {
31371
+ if (error instanceof MonitorFleetStateError) return error.next;
30942
31372
  if (error instanceof DeeplineError) {
30943
31373
  const response = asRecord2(asRecord2(error.details)?.response);
30944
- const serverNextAction = asString(response?.next_action);
30945
- if (serverNextAction) return serverNextAction;
31374
+ const serverNext = asString(response?.next) ?? asString(response?.next_action);
31375
+ if (serverNext) return serverNext;
30946
31376
  }
31377
+ if (exitCode === 5 && options?.retryCommand) return options.retryCommand;
30947
31378
  if (error instanceof DeeplineError && error.code === "monitor_access_required") {
30948
31379
  return "deepline monitors status";
30949
31380
  }
@@ -30969,9 +31400,10 @@ function readValidationIssues(error) {
30969
31400
  ];
30970
31401
  });
30971
31402
  }
30972
- function reportMonitorsFailure(error) {
31403
+ function reportMonitorsFailure(error, options) {
30973
31404
  const exitCode = monitorsErrorExitCode(error);
30974
- const next = monitorsFailureNextCommand(error, exitCode);
31405
+ const next = monitorsFailureNextCommand(error, exitCode, options);
31406
+ const retrySafe = exitCode === 5 && options?.retryCommand !== void 0;
30975
31407
  const wantsJson = shouldEmitJson(process.argv.includes("--json"));
30976
31408
  if (wantsJson) {
30977
31409
  const payload = errorToJsonPayload(error);
@@ -30979,10 +31411,15 @@ function reportMonitorsFailure(error) {
30979
31411
  ok: false,
30980
31412
  exitCode,
30981
31413
  ...next ? { next } : {},
30982
- error: payload.error
31414
+ ...retrySafe ? { retry_safe: true } : {},
31415
+ error: retrySafe ? {
31416
+ ...payload.error,
31417
+ message: `${payload.error.message} ${FLEET_RETRY_SAFE_NOTE}`
31418
+ } : payload.error
30983
31419
  });
30984
31420
  } else {
30985
- const message = error instanceof Error ? error.message : String(error);
31421
+ const base = error instanceof Error ? error.message : String(error);
31422
+ const message = retrySafe ? `${base} ${FLEET_RETRY_SAFE_NOTE}` : base;
30986
31423
  process.stderr.write(`Error: ${message}
30987
31424
  `);
30988
31425
  for (const issue of readValidationIssues(error)) {
@@ -31533,6 +31970,724 @@ async function handleMonitorsDeploy(definition, options) {
31533
31970
  text: renderMonitorDeployCompletion(payload)
31534
31971
  });
31535
31972
  }
31973
+ function fleetIntegerOption(raw, flag) {
31974
+ if (raw === void 0) return void 0;
31975
+ const value = Number(raw);
31976
+ if (!Number.isSafeInteger(value) || value < 0) {
31977
+ throw new MonitorsUsageError(`${flag} must be a non-negative integer.`);
31978
+ }
31979
+ return value;
31980
+ }
31981
+ function fleetIdempotencyKey(operation, supplied) {
31982
+ const normalized = supplied?.trim();
31983
+ if (supplied !== void 0 && !normalized) {
31984
+ throw new MonitorsUsageError("--idempotency-key must not be empty.");
31985
+ }
31986
+ return normalized ?? `monitor-fleet-${operation}-${randomUUID5()}`;
31987
+ }
31988
+ var FLEET_COUNT_KEYS = [
31989
+ "pending",
31990
+ "submitting",
31991
+ "rate_limited",
31992
+ "settled",
31993
+ "blocked",
31994
+ "failed"
31995
+ ];
31996
+ var FLEET_DEFAULT_WAIT_MS = 10 * 6e4;
31997
+ var FLEET_POLL_INTERVAL_MS = 2e3;
31998
+ var FLEET_PLAIN_PROGRESS_INTERVAL_MS = 15e3;
31999
+ var FLEET_RETRY_SAFE_NOTE = "Safe to retry \u2014 every fleet command is idempotent.";
32000
+ var MONITOR_FLEET_LIFECYCLE = [
32001
+ {
32002
+ step: 1,
32003
+ what: "Write a definition file you can read and edit.",
32004
+ command: "deepline monitors fleets init <fleet-id> --source public.accounts --key account_id --tool <tool> --payload '<json>' --out fleet.json"
32005
+ },
32006
+ {
32007
+ step: 2,
32008
+ what: "See the plan and the credits before anything changes.",
32009
+ command: "deepline monitors fleets sync --file fleet.json --dry-run"
32010
+ },
32011
+ {
32012
+ step: 3,
32013
+ what: "Apply it and wait for the server to call it converged.",
32014
+ command: "deepline monitors fleets sync --file fleet.json --wait"
32015
+ },
32016
+ {
32017
+ step: 4,
32018
+ what: "Read live state; add --drift to see what has not settled.",
32019
+ command: "deepline monitors fleets get <fleet-id>"
32020
+ }
32021
+ ];
32022
+ var MONITOR_FLEET_COMMANDS = [
32023
+ { name: "init", summary: "Write a Fleet definition JSON file." },
32024
+ {
32025
+ name: "sync",
32026
+ summary: "Create or re-plan a fleet from a definition file or its stored config."
32027
+ },
32028
+ {
32029
+ name: "get",
32030
+ summary: "Read one fleet, list every fleet, or inspect drift."
32031
+ },
32032
+ {
32033
+ name: "deactivate",
32034
+ summary: "Deactivate a fleet and the monitors it owns."
32035
+ }
32036
+ ];
32037
+ var MONITOR_FLEET_AGENT_NOTES = [
32038
+ "Add --json for stable output; stdout is always exactly one JSON object.",
32039
+ "Every error includes a runnable `next` command \u2014 run it, do not guess.",
32040
+ "Exit 5 = retry the same command; 6 = inspect counts with `get --drift`; 7 = change the request."
32041
+ ];
32042
+ var MONITOR_FLEET_HELP_EPILOG = `
32043
+ Agent notes:
32044
+ ${MONITOR_FLEET_AGENT_NOTES.join("\n ")}
32045
+ `;
32046
+ var MonitorFleetStateError = class extends Error {
32047
+ code;
32048
+ next;
32049
+ constructor(input2) {
32050
+ super(input2.message);
32051
+ this.name = "MonitorFleetStateError";
32052
+ this.code = input2.code;
32053
+ this.next = input2.next;
32054
+ }
32055
+ };
32056
+ function fleetCounts(payload) {
32057
+ const raw = asRecord2(payload.counts) ?? {};
32058
+ const counts = {};
32059
+ for (const key of FLEET_COUNT_KEYS) {
32060
+ counts[key] = asFiniteNumber(raw[key]) ?? 0;
32061
+ }
32062
+ return counts;
32063
+ }
32064
+ function fleetShellArg(value) {
32065
+ return /^[A-Za-z0-9._/@:=-]+$/.test(value) ? value : `'${value.replaceAll("'", `'\\''`)}'`;
32066
+ }
32067
+ function fleetJsonFlag(options) {
32068
+ return options.json ? ["--json"] : [];
32069
+ }
32070
+ function fleetTimeoutMs(raw) {
32071
+ if (raw === void 0) return FLEET_DEFAULT_WAIT_MS;
32072
+ const match = /^(\d+)(ms|s|m|h)?$/.exec(raw.trim());
32073
+ if (!match) {
32074
+ throw new MonitorsUsageError(
32075
+ "--timeout must be a duration like 500ms, 90s, 10m, or 1h (a bare number is seconds)."
32076
+ );
32077
+ }
32078
+ const value = Number(match[1]);
32079
+ if (!value) {
32080
+ throw new MonitorsUsageError("--timeout must be greater than zero.");
32081
+ }
32082
+ const unit = match[2] ?? "s";
32083
+ const factor = unit === "ms" ? 1 : unit === "s" ? 1e3 : unit === "m" ? 6e4 : 36e5;
32084
+ return value * factor;
32085
+ }
32086
+ function fleetServerNext(payload) {
32087
+ return asString(payload.next) ?? asString(payload.next_action);
32088
+ }
32089
+ function fleetStatus(payload) {
32090
+ return asString(payload.status);
32091
+ }
32092
+ function fleetProgressReporter() {
32093
+ const interactive = process.stderr.isTTY === true;
32094
+ let wrote = false;
32095
+ let lastPlainAt = 0;
32096
+ return {
32097
+ report: (payload) => {
32098
+ const counts = fleetCounts(payload);
32099
+ const expected = asFiniteNumber(payload.expected) ?? FLEET_COUNT_KEYS.reduce((sum, key) => sum + counts[key], 0);
32100
+ const line = `settled ${counts.settled}/${expected} \xB7 rate_limited ${counts.rate_limited} \xB7 blocked ${counts.blocked}`;
32101
+ if (interactive) {
32102
+ process.stderr.write(`\r\x1B[2K${line}`);
32103
+ wrote = true;
32104
+ return;
32105
+ }
32106
+ const now = Date.now();
32107
+ if (wrote && now - lastPlainAt < FLEET_PLAIN_PROGRESS_INTERVAL_MS) return;
32108
+ lastPlainAt = now;
32109
+ wrote = true;
32110
+ process.stderr.write(`${line}
32111
+ `);
32112
+ },
32113
+ finish: () => {
32114
+ if (interactive && wrote) process.stderr.write("\n");
32115
+ }
32116
+ };
32117
+ }
32118
+ function fleetPlanLine(payload) {
32119
+ const plan = asRecord2(payload.plan) ?? {};
32120
+ const blocked = asRecord2(plan.blocked) ?? {};
32121
+ const entries = Object.entries(blocked).flatMap(([limitId, raw]) => {
32122
+ const count = asFiniteNumber(raw);
32123
+ return count === void 0 ? [] : [[limitId, count]];
32124
+ }).sort(([left], [right]) => left.localeCompare(right));
32125
+ const blockedTotal = entries.reduce((sum, [, count]) => sum + count, 0);
32126
+ const detail = entries.length === 0 ? "" : entries.length === 1 ? ` (${entries[0][0]})` : ` (${entries.map(([id, count]) => `${id}: ${count}`).join(", ")})`;
32127
+ return [
32128
+ `creates ${asFiniteNumber(plan.creates) ?? 0}`,
32129
+ `updates ${asFiniteNumber(plan.updates) ?? 0}`,
32130
+ `removes ${asFiniteNumber(plan.removes) ?? 0}`,
32131
+ `blocked ${blockedTotal}${detail}`
32132
+ ].join(" \xB7 ");
32133
+ }
32134
+ function fleetCountsLine(payload) {
32135
+ const counts = fleetCounts(payload);
32136
+ return FLEET_COUNT_KEYS.map((key) => `${key} ${counts[key]}`).join(" \xB7 ");
32137
+ }
32138
+ function renderFleetSync(payload, input2) {
32139
+ const lines = [
32140
+ input2.dryRun ? `Fleet ${input2.fleetId} \u2014 plan only, nothing changed` : `Fleet ${input2.fleetId} \u2014 accepted`,
32141
+ ` plan ${fleetPlanLine(payload)}`
32142
+ ];
32143
+ const credits = asFiniteNumber(payload.credits_due_now);
32144
+ lines.push(` credits due now ${credits ?? 0}`);
32145
+ lines.push(
32146
+ ` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 replayed ${yesNo(
32147
+ payload.replayed
32148
+ )} \xB7 idempotency key ${input2.idempotencyKey}`
32149
+ );
32150
+ const next = fleetServerNext(payload);
32151
+ if (next) lines.push(`Next: ${next}`);
32152
+ return `${lines.join("\n")}
32153
+ `;
32154
+ }
32155
+ function renderFleetGet(payload) {
32156
+ const id = asString(payload.id) ?? "unknown";
32157
+ const status = fleetStatus(payload) ?? "unknown";
32158
+ const lines = [
32159
+ `Fleet ${id} \u2014 ${status}`,
32160
+ ` monitors ${asFiniteNumber(payload.live) ?? 0} live / ${asFiniteNumber(payload.expected) ?? 0} expected`,
32161
+ ` counts ${fleetCountsLine(payload)}`,
32162
+ ` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
32163
+ ];
32164
+ lines.push(...renderFleetDriftRows(payload));
32165
+ const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
32166
+ if (next) lines.push(`Next: ${next}`);
32167
+ return `${lines.join("\n")}
32168
+ `;
32169
+ }
32170
+ function renderFleetDriftRows(payload) {
32171
+ const drift = Array.isArray(payload.drift) ? payload.drift : void 0;
32172
+ if (!drift) return [];
32173
+ const rows = drift.flatMap((raw) => {
32174
+ const row = asRecord2(raw);
32175
+ return row ? [row] : [];
32176
+ }).map((row) => ({
32177
+ monitorKey: asString(row.monitor_key) ?? "-",
32178
+ entityKey: asString(row.entity_key) ?? "-",
32179
+ convergence: asString(row.convergence) ?? "-",
32180
+ since: asString(row.since) ?? "-",
32181
+ detail: asString(row.error) ?? (asString(row.blocked_by) ? `blocked_by ${asString(row.blocked_by)}` : asString(row.next_attempt_at) ? `next_attempt_at ${asString(row.next_attempt_at)}` : "")
32182
+ })).sort(
32183
+ (left, right) => left.monitorKey.localeCompare(right.monitorKey) || left.entityKey.localeCompare(right.entityKey)
32184
+ );
32185
+ if (rows.length === 0) {
32186
+ return [` drift none${payload.truncated === true ? " (truncated)" : ""}`];
32187
+ }
32188
+ const width = (values) => values.reduce((max, value) => Math.max(max, value.length), 0);
32189
+ const monitorWidth = width(rows.map((row) => row.monitorKey));
32190
+ const entityWidth = width(rows.map((row) => row.entityKey));
32191
+ const convergenceWidth = width(rows.map((row) => row.convergence));
32192
+ const lines = [
32193
+ ` drift (${rows.length}${payload.truncated === true ? ", truncated" : ""})`
32194
+ ];
32195
+ for (const row of rows) {
32196
+ lines.push(
32197
+ ` ${row.monitorKey.padEnd(monitorWidth)} ${row.entityKey.padEnd(
32198
+ entityWidth
32199
+ )} ${row.convergence.padEnd(convergenceWidth)} ${row.since}${row.detail ? ` ${row.detail}` : ""}`
32200
+ );
32201
+ }
32202
+ return lines;
32203
+ }
32204
+ function renderFleetList(payload) {
32205
+ const fleets = (Array.isArray(payload.fleets) ? payload.fleets : []).flatMap((raw) => {
32206
+ const fleet = asRecord2(raw);
32207
+ return fleet ? [fleet] : [];
32208
+ }).sort(
32209
+ (left, right) => (asString(left.id) ?? "").localeCompare(asString(right.id) ?? "")
32210
+ );
32211
+ if (fleets.length === 0) {
32212
+ return "No Monitor Fleets in this workspace.\nNext: deepline monitors fleets init <fleet-id> --help\n";
32213
+ }
32214
+ const idWidth = fleets.reduce(
32215
+ (max, fleet) => Math.max(max, (asString(fleet.id) ?? "").length),
32216
+ 0
32217
+ );
32218
+ const statusWidth = fleets.reduce(
32219
+ (max, fleet) => Math.max(max, (fleetStatus(fleet) ?? "unknown").length),
32220
+ 0
32221
+ );
32222
+ const lines = [`Fleets (${fleets.length})`];
32223
+ for (const fleet of fleets) {
32224
+ const counts = fleetCounts(fleet);
32225
+ const trouble = [
32226
+ counts.blocked ? `blocked ${counts.blocked}` : "",
32227
+ counts.failed ? `failed ${counts.failed}` : ""
32228
+ ].filter(Boolean);
32229
+ lines.push(
32230
+ ` ${(asString(fleet.id) ?? "-").padEnd(idWidth)} ${(fleetStatus(fleet) ?? "unknown").padEnd(statusWidth)} ${asFiniteNumber(fleet.live) ?? 0}/${asFiniteNumber(fleet.expected) ?? 0}${trouble.length ? ` ${trouble.join(" \xB7 ")}` : ""}`
32231
+ );
32232
+ }
32233
+ return `${lines.join("\n")}
32234
+ `;
32235
+ }
32236
+ function renderFleetDeactivatePlan(payload, fleetId) {
32237
+ const radius = asRecord2(payload.would_deactivate) ?? {};
32238
+ const lines = [
32239
+ `Deactivate fleet ${fleetId} \u2014 plan only, nothing changed`,
32240
+ ` would deactivate ${asFiniteNumber(radius.monitors) ?? 0} monitors \xB7 ${asFiniteNumber(radius.accounts) ?? 0} accounts`
32241
+ ];
32242
+ const note = asString(payload.note);
32243
+ if (note) lines.push(` ${note}`);
32244
+ lines.push(
32245
+ `Next: ${fleetServerNext(payload) ?? `deepline monitors fleets deactivate ${fleetShellArg(fleetId)} --yes`}`
32246
+ );
32247
+ return `${lines.join("\n")}
32248
+ `;
32249
+ }
32250
+ function reportFleetState(payload, error, options) {
32251
+ printCommandEnvelope(
32252
+ {
32253
+ ...payload,
32254
+ code: error.code,
32255
+ message: error.message,
32256
+ next: error.next
32257
+ },
32258
+ {
32259
+ json: options.json,
32260
+ text: `${options.text}${error.message}
32261
+ Next: ${error.next}
32262
+ `
32263
+ }
32264
+ );
32265
+ process.exitCode = monitorsErrorExitCode(error);
32266
+ }
32267
+ function fleetSourceTable(value) {
32268
+ const [schema, table, extra] = value?.trim().split(".") ?? [];
32269
+ if (!schema || !table || extra || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(schema) || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(table)) {
32270
+ throw new MonitorsUsageError(
32271
+ "--source must be a Customer DB table in schema.table form."
32272
+ );
32273
+ }
32274
+ return { schema, table };
32275
+ }
32276
+ function fleetColumnName(value, flag) {
32277
+ const name = value?.trim();
32278
+ if (!name || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
32279
+ throw new MonitorsUsageError(`${flag} must be a SQL column identifier.`);
32280
+ }
32281
+ return name;
32282
+ }
32283
+ function fleetMemberLimit(value) {
32284
+ if (value === void 0) return 1e3;
32285
+ const limit = fleetIntegerOption(value, "--limit");
32286
+ if (!limit || limit > 1e3) {
32287
+ throw new MonitorsUsageError("--limit must be between 1 and 1,000.");
32288
+ }
32289
+ return limit;
32290
+ }
32291
+ function fleetOrderBy(values, sourceKey) {
32292
+ const parsed = (values ?? []).map((value) => {
32293
+ const match = /^([A-Za-z_][A-Za-z0-9_]*):(asc|desc)$/.exec(value.trim());
32294
+ if (!match) {
32295
+ throw new MonitorsUsageError(
32296
+ "--order-by must use column:asc or column:desc."
32297
+ );
32298
+ }
32299
+ return { column: match[1], direction: match[2] };
32300
+ });
32301
+ const seen = /* @__PURE__ */ new Set();
32302
+ for (const order of parsed) {
32303
+ if (seen.has(order.column)) {
32304
+ throw new MonitorsUsageError(
32305
+ `--order-by repeats '${order.column}'. Each column may appear once.`
32306
+ );
32307
+ }
32308
+ seen.add(order.column);
32309
+ }
32310
+ const sourceOrder = parsed.find((order) => order.column === sourceKey);
32311
+ return [
32312
+ ...parsed.filter((order) => order.column !== sourceKey),
32313
+ sourceOrder ?? { column: sourceKey, direction: "asc" }
32314
+ ];
32315
+ }
32316
+ async function handleMonitorFleetsInit(fleetId, options) {
32317
+ if (!/^[a-z][a-z0-9-]{0,199}$/.test(fleetId)) {
32318
+ throw new MonitorsUsageError("<fleet-id> must be lowercase kebab-case.");
32319
+ }
32320
+ const source = fleetSourceTable(options.source);
32321
+ const key = fleetColumnName(options.key, "--key");
32322
+ const keyType = options.keyType?.trim() ?? "text";
32323
+ if (!["text", "uuid", "int4", "int8"].includes(keyType)) {
32324
+ throw new MonitorsUsageError(
32325
+ "--key-type must be text, uuid, int4, or int8."
32326
+ );
32327
+ }
32328
+ const tool = options.tool?.trim();
32329
+ if (!tool) throw new MonitorsUsageError("--tool is required.");
32330
+ if (!options.payload) {
32331
+ throw new MonitorsUsageError(
32332
+ "--payload is required and must be the monitor payload JSON for --tool."
32333
+ );
32334
+ }
32335
+ const payload = parseJsonObjectArg(options.payload, "--payload");
32336
+ const where = options.where ? parseJsonObjectArg(options.where, "--where") : void 0;
32337
+ const out = options.out?.trim();
32338
+ if (!out) throw new MonitorsUsageError("--out is required.");
32339
+ const authoredDefinition = {
32340
+ id: fleetId,
32341
+ source: {
32342
+ kind: "customer_db_table",
32343
+ schema: source.schema,
32344
+ table: source.table,
32345
+ key: { column: key, type: keyType },
32346
+ ...where ? { where } : {}
32347
+ },
32348
+ member: {
32349
+ tool,
32350
+ key: {
32351
+ $fleet: "template",
32352
+ parts: [`${fleetId}-`, { $fleet: "column", name: key }]
32353
+ },
32354
+ payload
32355
+ },
32356
+ selection: {
32357
+ limit: fleetMemberLimit(options.limit),
32358
+ orderBy: fleetOrderBy(options.orderBy, key),
32359
+ membership: "sticky"
32360
+ }
32361
+ };
32362
+ const definition = requireCompiledFleetDefinition(authoredDefinition);
32363
+ const file = resolve14(out);
32364
+ writeFileSync12(file, `${JSON.stringify(definition, null, 2)}
32365
+ `, "utf8");
32366
+ const next = `deepline monitors fleets sync --file ${fleetShellArg(file)} --dry-run --json`;
32367
+ printCommandEnvelope(
32368
+ { schemaVersion: 1, file, definition, next },
32369
+ {
32370
+ json: options.json,
32371
+ text: `Wrote ${file}
32372
+ Next: ${next}
32373
+ `
32374
+ }
32375
+ );
32376
+ }
32377
+ function requireCompiledFleetDefinition(definition) {
32378
+ const result = admitMonitorFleetAuthoringContract(definition);
32379
+ if (result.valid && result.contract) return result.contract.definition;
32380
+ const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
32381
+ throw new MonitorsUsageError(
32382
+ `Monitor Fleet definition failed local contract check. ${messages}
32383
+ Fix the file, then re-run: deepline monitors fleets sync --file <fleet.json> --dry-run`
32384
+ );
32385
+ }
32386
+ function fleetSyncCommandLine(target, options) {
32387
+ const parts = ["deepline monitors fleets sync"];
32388
+ if (options.file) parts.push(`--file ${fleetShellArg(options.file)}`);
32389
+ else if (target) parts.push(fleetShellArg(target));
32390
+ if (options.dryRun) parts.push("--dry-run");
32391
+ if (options.wait) parts.push("--wait");
32392
+ if (options.timeout)
32393
+ parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
32394
+ if (options.expectedGeneration !== void 0) {
32395
+ parts.push(
32396
+ `--expected-generation ${fleetShellArg(options.expectedGeneration)}`
32397
+ );
32398
+ }
32399
+ if (options.idempotencyKey) {
32400
+ parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
32401
+ }
32402
+ parts.push(...fleetJsonFlag(options));
32403
+ return parts.join(" ");
32404
+ }
32405
+ async function handleMonitorFleetsSync(target, options, idempotencyKey) {
32406
+ const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
32407
+ if (!usesDefinition && !target?.trim()) {
32408
+ throw new MonitorsUsageError(
32409
+ "sync needs a fleet: pass --file fleet.json to apply a definition, or <fleet-id> to re-plan the stored one.\n deepline monitors fleets sync --file fleet.json --dry-run\n deepline monitors fleets sync <fleet-id> --dry-run"
32410
+ );
32411
+ }
32412
+ const definition = usesDefinition ? requireCompiledFleetDefinition(
32413
+ resolveMonitorJsonBody({
32414
+ positional: target,
32415
+ file: options.file,
32416
+ argLabel: "<definition>",
32417
+ command: "deepline monitors fleets sync"
32418
+ })
32419
+ ) : void 0;
32420
+ const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
32421
+ if (!fleetId) {
32422
+ throw new MonitorsUsageError(
32423
+ 'The Fleet definition has no id. Add a top-level "id" and re-run.'
32424
+ );
32425
+ }
32426
+ const client2 = new DeeplineClient();
32427
+ const payload = await client2.monitors.fleets.sync(
32428
+ definition ?? fleetId,
32429
+ {
32430
+ ...options.dryRun ? { dryRun: true } : {},
32431
+ ...options.expectedGeneration !== void 0 ? {
32432
+ expectedGeneration: fleetIntegerOption(
32433
+ options.expectedGeneration,
32434
+ "--expected-generation"
32435
+ )
32436
+ } : {},
32437
+ idempotencyKey
32438
+ }
32439
+ );
32440
+ if (options.dryRun) {
32441
+ assertMonitorDryRunAcknowledged(payload, {
32442
+ command: "deepline monitors fleets sync",
32443
+ mutation: "fleet sync"
32444
+ });
32445
+ }
32446
+ const accepted = { ...payload, idempotency_key: idempotencyKey };
32447
+ if (!options.wait || options.dryRun) {
32448
+ printCommandEnvelope(accepted, {
32449
+ json: options.json,
32450
+ text: renderFleetSync(payload, {
32451
+ fleetId,
32452
+ dryRun: options.dryRun === true,
32453
+ idempotencyKey
32454
+ })
32455
+ });
32456
+ return;
32457
+ }
32458
+ const timeoutMs = fleetTimeoutMs(options.timeout);
32459
+ const progress = fleetProgressReporter();
32460
+ let final;
32461
+ try {
32462
+ final = await client2.monitors.fleets.waitForConvergence(fleetId, {
32463
+ timeoutMs,
32464
+ pollIntervalMs: FLEET_POLL_INTERVAL_MS,
32465
+ onProgress: progress.report
32466
+ });
32467
+ } finally {
32468
+ progress.finish();
32469
+ }
32470
+ const envelope = { ...accepted, ...final };
32471
+ const status = fleetStatus(final);
32472
+ const summary = renderFleetGet(final);
32473
+ if (status === "converged") {
32474
+ printCommandEnvelope(envelope, { json: options.json, text: summary });
32475
+ return;
32476
+ }
32477
+ const driftCommand = `deepline monitors fleets get ${fleetShellArg(fleetId)} --drift --json`;
32478
+ if (status === "degraded") {
32479
+ reportFleetState(
32480
+ envelope,
32481
+ new MonitorFleetStateError({
32482
+ code: "MONITOR_FLEET_DEGRADED",
32483
+ message: `Fleet ${fleetId} is degraded: some members will not converge without a change. Retrying sync will not fix it.`,
32484
+ next: fleetServerNext(final) ?? driftCommand
32485
+ }),
32486
+ { json: options.json, text: summary }
32487
+ );
32488
+ return;
32489
+ }
32490
+ reportFleetState(
32491
+ envelope,
32492
+ new MonitorFleetStateError({
32493
+ code: "MONITOR_FLEET_WAIT_TIMEOUT",
32494
+ message: `Stopped waiting after ${timeoutMs}ms. Nothing is broken and nothing was lost \u2014 fleet ${fleetId} is still ${status ?? "working"} on the server.`,
32495
+ next: fleetServerNext(final) ?? driftCommand
32496
+ }),
32497
+ { json: options.json, text: summary }
32498
+ );
32499
+ }
32500
+ async function handleMonitorFleetsGet(fleetId, options) {
32501
+ if (options.drift && !fleetId) {
32502
+ throw new MonitorsUsageError(
32503
+ "--drift needs a fleet id: deepline monitors fleets get <fleet-id> --drift"
32504
+ );
32505
+ }
32506
+ const limit = options.limit === void 0 ? void 0 : fleetIntegerOption(options.limit, "--limit");
32507
+ const client2 = new DeeplineClient();
32508
+ const payload = await client2.monitors.fleets.get(fleetId, {
32509
+ ...options.drift ? { drift: true } : {},
32510
+ ...limit !== void 0 ? { limit } : {}
32511
+ });
32512
+ const text = fleetId ? renderFleetGet(payload) : renderFleetList(payload);
32513
+ if (!options.check) {
32514
+ printCommandEnvelope(payload, { json: options.json, text });
32515
+ return;
32516
+ }
32517
+ const statuses = fleetId ? [fleetStatus(payload)] : (Array.isArray(payload.fleets) ? payload.fleets : []).map(
32518
+ (raw) => fleetStatus(asRecord2(raw) ?? {})
32519
+ );
32520
+ const unconverged = statuses.filter((status) => status !== "converged");
32521
+ if (unconverged.length === 0) {
32522
+ printCommandEnvelope(payload, { json: options.json, text });
32523
+ return;
32524
+ }
32525
+ const target = fleetId ?? "<fleet-id>";
32526
+ const degraded = unconverged.includes("degraded");
32527
+ reportFleetState(
32528
+ payload,
32529
+ new MonitorFleetStateError({
32530
+ code: degraded ? "MONITOR_FLEET_DEGRADED" : "MONITOR_FLEET_NOT_CONVERGED",
32531
+ message: degraded ? `Fleet ${target} is degraded: members are stuck and retrying will not move them.` : `Fleet ${target} has not converged yet.`,
32532
+ next: fleetServerNext(payload) ?? `deepline monitors fleets get ${fleetShellArg(target)} --drift --json`
32533
+ }),
32534
+ { json: options.json, text }
32535
+ );
32536
+ }
32537
+ function fleetDeactivateCommandLine(fleetId, options) {
32538
+ const parts = [
32539
+ "deepline monitors fleets deactivate",
32540
+ fleetShellArg(fleetId),
32541
+ "--yes"
32542
+ ];
32543
+ if (options.dryRun) parts.push("--dry-run");
32544
+ if (options.wait) parts.push("--wait");
32545
+ if (options.timeout)
32546
+ parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
32547
+ if (options.idempotencyKey) {
32548
+ parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
32549
+ }
32550
+ parts.push(...fleetJsonFlag(options));
32551
+ return parts.join(" ");
32552
+ }
32553
+ async function confirmFleetDeactivate(fleetId, plan) {
32554
+ process.stderr.write(renderFleetDeactivatePlan(plan, fleetId));
32555
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
32556
+ try {
32557
+ const answer = await rl.question(
32558
+ `Deactivate fleet "${fleetId}" and the monitors it owns? [y/N] `
32559
+ );
32560
+ return /^y(es)?$/i.test(answer.trim());
32561
+ } finally {
32562
+ rl.close();
32563
+ }
32564
+ }
32565
+ async function handleMonitorFleetsDeactivate(fleetId, options, idempotencyKey) {
32566
+ const client2 = new DeeplineClient();
32567
+ if (options.dryRun) {
32568
+ const plan = await client2.monitors.fleets.deactivate(fleetId, {
32569
+ dryRun: true,
32570
+ idempotencyKey
32571
+ });
32572
+ assertMonitorDryRunAcknowledged(plan, {
32573
+ command: "deepline monitors fleets deactivate",
32574
+ mutation: "fleet deactivate"
32575
+ });
32576
+ printCommandEnvelope(plan, {
32577
+ json: options.json,
32578
+ text: renderFleetDeactivatePlan(plan, fleetId)
32579
+ });
32580
+ return;
32581
+ }
32582
+ if (!options.yes) {
32583
+ const interactive = process.stdout.isTTY === true && process.stdin.isTTY === true;
32584
+ if (!interactive) {
32585
+ throw new MonitorsUsageError(
32586
+ `deactivate is destructive: it deactivates fleet "${fleetId}" and every monitor it owns. Non-interactive runs must confirm with --yes:
32587
+ ${fleetDeactivateCommandLine(fleetId, options)}
32588
+ Preview the blast radius first:
32589
+ deepline monitors fleets deactivate ${fleetShellArg(fleetId)} --dry-run`
32590
+ );
32591
+ }
32592
+ const plan = await client2.monitors.fleets.deactivate(fleetId, {
32593
+ dryRun: true,
32594
+ idempotencyKey: `${idempotencyKey}-plan`
32595
+ });
32596
+ assertMonitorDryRunAcknowledged(plan, {
32597
+ command: "deepline monitors fleets deactivate",
32598
+ mutation: "fleet deactivate"
32599
+ });
32600
+ if (!await confirmFleetDeactivate(fleetId, plan)) {
32601
+ process.stderr.write(
32602
+ `Aborted. Fleet "${fleetId}" was not deactivated.
32603
+ `
32604
+ );
32605
+ process.exitCode = 2;
32606
+ return;
32607
+ }
32608
+ }
32609
+ const payload = await client2.monitors.fleets.deactivate(fleetId, {
32610
+ idempotencyKey
32611
+ });
32612
+ const accepted = { ...payload, idempotency_key: idempotencyKey };
32613
+ if (payload.already === true) {
32614
+ printCommandEnvelope(accepted, {
32615
+ json: options.json,
32616
+ text: `Fleet ${fleetId} is already deactivated.
32617
+ `
32618
+ });
32619
+ return;
32620
+ }
32621
+ const acceptedText = `Fleet ${fleetId} \u2014 ${asString(payload.status) ?? "deactivating"}
32622
+ idempotency key ${idempotencyKey}
32623
+ ` + (fleetServerNext(payload) ? `Next: ${fleetServerNext(payload)}
32624
+ ` : "");
32625
+ if (!options.wait) {
32626
+ printCommandEnvelope(accepted, {
32627
+ json: options.json,
32628
+ text: acceptedText
32629
+ });
32630
+ return;
32631
+ }
32632
+ const timeoutMs = fleetTimeoutMs(options.timeout);
32633
+ const progress = fleetProgressReporter();
32634
+ let final;
32635
+ try {
32636
+ final = await client2.monitors.fleets.waitForConvergence(fleetId, {
32637
+ timeoutMs,
32638
+ pollIntervalMs: FLEET_POLL_INTERVAL_MS,
32639
+ onProgress: progress.report,
32640
+ until: "deactivated"
32641
+ });
32642
+ } finally {
32643
+ progress.finish();
32644
+ }
32645
+ const envelope = { ...accepted, ...final };
32646
+ const summary = renderFleetGet(final);
32647
+ if (fleetStatus(final) === "deactivated") {
32648
+ printCommandEnvelope(envelope, { json: options.json, text: summary });
32649
+ return;
32650
+ }
32651
+ reportFleetState(
32652
+ envelope,
32653
+ new MonitorFleetStateError({
32654
+ code: "MONITOR_FLEET_WAIT_TIMEOUT",
32655
+ message: `Stopped waiting after ${timeoutMs}ms. Deactivation of fleet ${fleetId} is still in progress on the server; nothing was lost.`,
32656
+ next: fleetServerNext(final) ?? `deepline monitors fleets get ${fleetShellArg(fleetId)} --json`
32657
+ }),
32658
+ { json: options.json, text: summary }
32659
+ );
32660
+ }
32661
+ function handleMonitorFleetsOverview(options) {
32662
+ const lines = [
32663
+ "Monitor Fleets \u2014 one Customer DB table row, one ordinary monitor.",
32664
+ "",
32665
+ "Lifecycle:",
32666
+ ...MONITOR_FLEET_LIFECYCLE.flatMap((entry) => [
32667
+ ` ${entry.step}. ${entry.what}`,
32668
+ ` ${entry.command}`
32669
+ ]),
32670
+ "",
32671
+ "Commands:",
32672
+ ...MONITOR_FLEET_COMMANDS.map(
32673
+ (command) => ` ${command.name.padEnd(12)}${command.summary}`
32674
+ ),
32675
+ "",
32676
+ "Agent notes:",
32677
+ ...MONITOR_FLEET_AGENT_NOTES.map((note) => ` ${note}`)
32678
+ ];
32679
+ printCommandEnvelope(
32680
+ {
32681
+ schemaVersion: 1,
32682
+ lifecycle: MONITOR_FLEET_LIFECYCLE,
32683
+ commands: MONITOR_FLEET_COMMANDS,
32684
+ agent_notes: MONITOR_FLEET_AGENT_NOTES,
32685
+ next: MONITOR_FLEET_LIFECYCLE[0].command
32686
+ },
32687
+ { json: options.json, text: `${lines.join("\n")}
32688
+ ` }
32689
+ );
32690
+ }
31536
32691
  function renderMonitorGet(payload) {
31537
32692
  const key = asString(payload.key);
31538
32693
  const tool = asString(payload.tool);
@@ -31782,7 +32937,9 @@ Notes:
31782
32937
 
31783
32938
  Exit codes:
31784
32939
  0 success; 2 usage/local input; 3 auth or permission; 4 not found;
31785
- 5 server failure; 7 validation failed.
32940
+ 5 server failure (retry the same command); 6 not at the desired state
32941
+ (fleets: degraded, or --wait/--check stopped while healthy \u2014 retrying
32942
+ changes nothing); 7 refused, change the request.
31786
32943
  \`monitors status\` exits 1 when you lack monitor access (documented contract).
31787
32944
 
31788
32945
  Examples:
@@ -32053,6 +33210,181 @@ Examples:
32053
33210
  `
32054
33211
  ).option("--dry-run", "Show the reactivation cost without reactivating")
32055
33212
  ).action(monitorsAction(handleMonitorsReactivate));
33213
+ const fleets = monitors.command("fleets").description("Define and reconcile table-backed Monitor Fleets.").addHelpText(
33214
+ "after",
33215
+ `
33216
+ Notes:
33217
+ A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
33218
+ monitors. Fleet definitions are canonical JSON, and \`sync\` is the only verb
33219
+ that changes one: applying the same definition twice is the same operation,
33220
+ so the server answers \`replayed: true\` instead of building a second fleet.
33221
+ The fleet's status is computed by Deepline; this CLI reports it and never
33222
+ recomputes a verdict from the counts.
33223
+
33224
+ Exit codes:
33225
+ 0 converged or done; 2 usage or local validation; 3 auth; 4 not found;
33226
+ 5 server failure (retry the same command); 6 not at the desired state
33227
+ (degraded, or --wait/--check stopped while healthy); 7 refused (change the
33228
+ request).
33229
+
33230
+ Lifecycle:
33231
+ ${MONITOR_FLEET_LIFECYCLE.map(
33232
+ (entry) => ` ${entry.step}. ${entry.command}`
33233
+ ).join("\n")}
33234
+ ${MONITOR_FLEET_HELP_EPILOG}`
33235
+ ).action(
33236
+ monitorsAction(async (options) => {
33237
+ handleMonitorFleetsOverview(options);
33238
+ })
33239
+ );
33240
+ withJsonOption(fleets);
33241
+ withJsonOption(
33242
+ fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
33243
+ "after",
33244
+ `
33245
+ Creates a ready-to-review JSON definition. Fleets always sync ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.cadence} and retain
33246
+ a missing member for ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.removalGrace} before it is ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.onRemoved}d; those
33247
+ policies are not authored in the file. ${MONITOR_FLEET_DOCUMENTATION.stickyMembership} The payload remains the actual monitor payload for the chosen tool, so use
33248
+ \`deepline monitors available\` to discover a tool first.
33249
+
33250
+ Example:
33251
+ deepline monitors fleets init account-job-openings \\
33252
+ --source public.accounts --key account_id --key-type uuid \\
33253
+ --tool deepline_native.company_radar \\
33254
+ --payload '{"domain":{"$fleet":"column","name":"domain"},"radar_type":"company_job_openings"}' \\
33255
+ --order-by intent_score:desc \\
33256
+ --out fleet.json
33257
+ `
33258
+ ).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(
33259
+ "--payload <json>",
33260
+ "Monitor payload JSON for --tool; use $fleet column tags for row values"
33261
+ ).option(
33262
+ "--where <json>",
33263
+ "Optional source-row equality filter JSON; not arbitrary SQL"
33264
+ ).option(
33265
+ "--order-by <column:direction>",
33266
+ "Rank candidates; repeatable, with the source key appended for stability",
33267
+ (value, previous = []) => [...previous, value],
33268
+ []
33269
+ ).option(
33270
+ "--limit <n>",
33271
+ "Maximum active members; ranking changes do not churn sticky members (default 1,000)"
33272
+ ).requiredOption("--out <path>", "Write the definition JSON to this path")
33273
+ ).action(monitorsAction(handleMonitorFleetsInit));
33274
+ withJsonOption(
33275
+ fleets.command("sync [fleet-id]").description(
33276
+ "Apply a Fleet definition, or re-plan an existing fleet from its stored one."
33277
+ ).addHelpText(
33278
+ "after",
33279
+ `
33280
+ Notes:
33281
+ --file (or an inline definition, or --file - for stdin) is compiled locally
33282
+ BEFORE any network call: a definition that fails the contract exits 2 and
33283
+ never becomes a request. A bare <fleet-id> re-plans the stored definition.
33284
+ The plan always shows blocked members; they are never hidden.
33285
+ --wait polls until Deepline reports a terminal status: converged exits 0,
33286
+ degraded exits 6, and a timeout exits 6 without implying anything broke.
33287
+ Progress goes to stderr, so stdout stays exactly one JSON object.
33288
+
33289
+ Examples:
33290
+ deepline monitors fleets sync --file fleet.json --dry-run
33291
+ deepline monitors fleets sync --file fleet.json --wait --timeout 20m
33292
+ deepline monitors fleets sync account-job-openings --wait --json
33293
+ cat fleet.json | deepline monitors fleets sync --file - --dry-run --json
33294
+ `
33295
+ ).option(
33296
+ "-f, --file <path>",
33297
+ "Apply definition JSON from a file, or - for stdin"
33298
+ ).option(
33299
+ "--dry-run",
33300
+ "Show the plan and the credits due without changing state"
33301
+ ).option("--wait", "Poll until the fleet reaches a terminal status").option(
33302
+ "--timeout <duration>",
33303
+ "How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
33304
+ ).option(
33305
+ "--expected-generation <generation>",
33306
+ "Refuse the write unless the fleet is at this generation"
33307
+ ).option(
33308
+ "--idempotency-key <key>",
33309
+ "Stable retry key (generated and returned when omitted)"
33310
+ )
33311
+ ).action(async (target, options) => {
33312
+ let retryCommand = fleetSyncCommandLine(target, options);
33313
+ try {
33314
+ const idempotencyKey = fleetIdempotencyKey(
33315
+ "sync",
33316
+ options.idempotencyKey
33317
+ );
33318
+ retryCommand = fleetSyncCommandLine(target, {
33319
+ ...options,
33320
+ idempotencyKey
33321
+ });
33322
+ await handleMonitorFleetsSync(target, options, idempotencyKey);
33323
+ } catch (error) {
33324
+ reportMonitorsFailure(error, { retryCommand });
33325
+ }
33326
+ });
33327
+ withJsonOption(
33328
+ fleets.command("get [fleet-id]").description(
33329
+ "Read one fleet, or list every fleet when the id is omitted."
33330
+ ).addHelpText(
33331
+ "after",
33332
+ `
33333
+ Notes:
33334
+ Status is the server's verdict. --check turns it into an exit code so a
33335
+ script can branch without parsing output: 0 converged, 6 anything else.
33336
+ --drift lists the members that have not settled and why.
33337
+
33338
+ Examples:
33339
+ deepline monitors fleets get --json
33340
+ deepline monitors fleets get account-job-openings --json
33341
+ deepline monitors fleets get account-job-openings --drift --limit 50 --json
33342
+ deepline monitors fleets get account-job-openings --check
33343
+ `
33344
+ ).option("--drift", "Include the members that have not settled, and why").option("--limit <n>", "Maximum drift rows to return").option(
33345
+ "--check",
33346
+ "Exit 0 when converged and 6 otherwise, for scripts and agents"
33347
+ )
33348
+ ).action(monitorsAction(handleMonitorFleetsGet));
33349
+ withJsonOption(
33350
+ fleets.command("deactivate <fleet-id>").description("Deactivate a fleet and the monitors it owns.").addHelpText(
33351
+ "after",
33352
+ `
33353
+ Notes:
33354
+ Destructive. --dry-run shows the blast radius without changing anything.
33355
+ An interactive terminal is shown that blast radius and asked to confirm;
33356
+ a non-interactive run must pass --yes. Re-running after a failure is safe.
33357
+
33358
+ Examples:
33359
+ deepline monitors fleets deactivate account-job-openings --dry-run
33360
+ deepline monitors fleets deactivate account-job-openings --yes --wait --json
33361
+ `
33362
+ ).option("--dry-run", "Show the blast radius without deactivating").option("--wait", "Poll until the fleet reports deactivated").option(
33363
+ "--timeout <duration>",
33364
+ "How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
33365
+ ).option(
33366
+ "--yes",
33367
+ "Skip the confirmation prompt (required non-interactively)"
33368
+ ).option(
33369
+ "--idempotency-key <key>",
33370
+ "Stable retry key (generated and returned when omitted)"
33371
+ )
33372
+ ).action(async (fleetId, options) => {
33373
+ let retryCommand = fleetDeactivateCommandLine(fleetId, options);
33374
+ try {
33375
+ const idempotencyKey = fleetIdempotencyKey(
33376
+ "deactivate",
33377
+ options.idempotencyKey
33378
+ );
33379
+ retryCommand = fleetDeactivateCommandLine(fleetId, {
33380
+ ...options,
33381
+ idempotencyKey
33382
+ });
33383
+ await handleMonitorFleetsDeactivate(fleetId, options, idempotencyKey);
33384
+ } catch (error) {
33385
+ reportMonitorsFailure(error, { retryCommand });
33386
+ }
33387
+ });
32056
33388
  const deployed = withJsonOption(
32057
33389
  monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
32058
33390
  "--status <status>",
@@ -32755,7 +34087,7 @@ async function readHiddenLine(prompt, streams = {}) {
32755
34087
  }
32756
34088
  let value = "";
32757
34089
  inputStream.resume();
32758
- return await new Promise((resolve20, reject) => {
34090
+ return await new Promise((resolve21, reject) => {
32759
34091
  let settled = false;
32760
34092
  const cleanup = () => {
32761
34093
  inputStream.off("data", onData);
@@ -32773,7 +34105,7 @@ async function readHiddenLine(prompt, streams = {}) {
32773
34105
  settled = true;
32774
34106
  outputStream.write("\n");
32775
34107
  cleanup();
32776
- resolve20(line);
34108
+ resolve21(line);
32777
34109
  };
32778
34110
  const fail = (error) => {
32779
34111
  if (settled) return;
@@ -32951,10 +34283,10 @@ import {
32951
34283
  mkdirSync as mkdirSync11,
32952
34284
  readFileSync as readFileSync14,
32953
34285
  realpathSync as realpathSync4,
32954
- writeFileSync as writeFileSync14
34286
+ writeFileSync as writeFileSync15
32955
34287
  } from "fs";
32956
34288
  import { homedir as homedir9 } from "os";
32957
- import { dirname as dirname16, join as join16, resolve as resolve15 } from "path";
34289
+ import { dirname as dirname16, join as join16, resolve as resolve16 } from "path";
32958
34290
 
32959
34291
  // src/cli/installation-lifecycle.ts
32960
34292
  import {
@@ -32964,7 +34296,7 @@ import {
32964
34296
  realpathSync as realpathSync3,
32965
34297
  rmSync as rmSync4
32966
34298
  } from "fs";
32967
- import { basename as basename6, dirname as dirname13, join as join13, relative as relative5, resolve as resolve14 } from "path";
34299
+ import { basename as basename6, dirname as dirname13, join as join13, relative as relative5, resolve as resolve15 } from "path";
32968
34300
  var nodeFileSystem = {
32969
34301
  exists: existsSync11,
32970
34302
  isSymbolicLink(path) {
@@ -33079,14 +34411,14 @@ function isOwnedInstallerCommandPath(input2) {
33079
34411
  if (!input2.commandPath || basename6(input2.commandPath) !== "deepline") {
33080
34412
  return false;
33081
34413
  }
33082
- const commandPath = resolve14(input2.commandPath);
33083
- const fromHost = relative5(resolve14(input2.hostDir), commandPath);
34414
+ const commandPath = resolve15(input2.commandPath);
34415
+ const fromHost = relative5(resolve15(input2.hostDir), commandPath);
33084
34416
  return fromHost !== "" && fromHost !== ".." && !fromHost.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`);
33085
34417
  }
33086
34418
 
33087
34419
  // src/cli/commands/skills.ts
33088
34420
  import { spawn as spawn3 } from "child_process";
33089
- import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
34421
+ import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync14 } from "fs";
33090
34422
  import { homedir as homedir8 } from "os";
33091
34423
  import { dirname as dirname15, join as join15 } from "path";
33092
34424
 
@@ -33203,7 +34535,7 @@ import {
33203
34535
  mkdirSync as mkdirSync9,
33204
34536
  readFileSync as readFileSync12,
33205
34537
  unlinkSync,
33206
- writeFileSync as writeFileSync12
34538
+ writeFileSync as writeFileSync13
33207
34539
  } from "fs";
33208
34540
  import { dirname as dirname14, join as join14 } from "path";
33209
34541
 
@@ -33261,7 +34593,7 @@ function readMarkedSkillsSyncVersion(path) {
33261
34593
  function writeMarkedSkillsSyncVersion(path, version) {
33262
34594
  try {
33263
34595
  mkdirSync9(dirname14(path), { recursive: true });
33264
- writeFileSync12(path, `${version}
34596
+ writeFileSync13(path, `${version}
33265
34597
  `, "utf-8");
33266
34598
  } catch {
33267
34599
  }
@@ -33414,7 +34746,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
33414
34746
  return commands;
33415
34747
  }
33416
34748
  function runOneSkillsInstall(install) {
33417
- return new Promise((resolve20) => {
34749
+ return new Promise((resolve21) => {
33418
34750
  const plan = resolveSkillsInstallSpawn(install);
33419
34751
  const child = spawn2(plan.command, plan.args, {
33420
34752
  stdio: ["ignore", "ignore", "pipe"],
@@ -33426,7 +34758,7 @@ function runOneSkillsInstall(install) {
33426
34758
  stderr += chunk.toString("utf-8");
33427
34759
  });
33428
34760
  child.on("error", (error) => {
33429
- resolve20({
34761
+ resolve21({
33430
34762
  ok: false,
33431
34763
  detail: `failed to start ${install.command}: ${error.message}`,
33432
34764
  manualCommand: install.manualCommand
@@ -33434,11 +34766,11 @@ function runOneSkillsInstall(install) {
33434
34766
  });
33435
34767
  child.on("close", (code) => {
33436
34768
  if (code === 0) {
33437
- resolve20({ ok: true, detail: "", manualCommand: install.manualCommand });
34769
+ resolve21({ ok: true, detail: "", manualCommand: install.manualCommand });
33438
34770
  return;
33439
34771
  }
33440
34772
  const detail = stderr.trim();
33441
- resolve20({
34773
+ resolve21({
33442
34774
  ok: false,
33443
34775
  detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
33444
34776
  manualCommand: install.manualCommand
@@ -33720,7 +35052,7 @@ function readSkillsInstallState(path) {
33720
35052
  }
33721
35053
  }
33722
35054
  function runProcess(command, args, cwd) {
33723
- return new Promise((resolve20, reject) => {
35055
+ return new Promise((resolve21, reject) => {
33724
35056
  const plan = resolveShellSpawn(command, args);
33725
35057
  const child = spawn3(plan.command, plan.args, {
33726
35058
  cwd,
@@ -33739,7 +35071,7 @@ function runProcess(command, args, cwd) {
33739
35071
  process.stderr.write(`${SKILLS_NPX_PACKAGE} exited ${code}.
33740
35072
  `);
33741
35073
  }
33742
- resolve20(code ?? 1);
35074
+ resolve21(code ?? 1);
33743
35075
  });
33744
35076
  });
33745
35077
  }
@@ -33867,7 +35199,7 @@ async function runSkillsCommand(options, dependencies = {}) {
33867
35199
  );
33868
35200
  }
33869
35201
  mkdirSync10(dirname15(plan.statePath), { recursive: true });
33870
- writeFileSync13(
35202
+ writeFileSync14(
33871
35203
  plan.statePath,
33872
35204
  `${JSON.stringify(
33873
35205
  {
@@ -33962,26 +35294,26 @@ function parseSetupPhases(value) {
33962
35294
  if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
33963
35295
  return null;
33964
35296
  }
33965
- const record = phase;
33966
- if (!isSetupPhaseStatus(record.status)) return null;
33967
- switch (record.status) {
35297
+ const record2 = phase;
35298
+ if (!isSetupPhaseStatus(record2.status)) return null;
35299
+ switch (record2.status) {
33968
35300
  case "pending":
33969
35301
  case "in_progress":
33970
- phases[name] = { status: record.status };
35302
+ phases[name] = { status: record2.status };
33971
35303
  break;
33972
35304
  case "complete":
33973
35305
  phases[name] = {
33974
35306
  status: "complete",
33975
- ...typeof record.outcome === "string" ? { outcome: record.outcome } : {}
35307
+ ...typeof record2.outcome === "string" ? { outcome: record2.outcome } : {}
33976
35308
  };
33977
35309
  break;
33978
35310
  case "waiting":
33979
- if (typeof record.outcome !== "string") return null;
33980
- phases[name] = { status: "waiting", outcome: record.outcome };
35311
+ if (typeof record2.outcome !== "string") return null;
35312
+ phases[name] = { status: "waiting", outcome: record2.outcome };
33981
35313
  break;
33982
35314
  case "failed":
33983
- if (typeof record.code !== "string") return null;
33984
- phases[name] = { status: "failed", code: record.code };
35315
+ if (typeof record2.code !== "string") return null;
35316
+ phases[name] = { status: "failed", code: record2.code };
33985
35317
  break;
33986
35318
  }
33987
35319
  }
@@ -34129,7 +35461,7 @@ function resolvePathCommands(command) {
34129
35461
  );
34130
35462
  return [
34131
35463
  ...new Set(
34132
- String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => resolve15(path))
35464
+ String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => resolve16(path))
34133
35465
  )
34134
35466
  ];
34135
35467
  }
@@ -34177,11 +35509,11 @@ function pathsResolveToSameFile(left, right) {
34177
35509
  try {
34178
35510
  return realpathSync4(left) === realpathSync4(right);
34179
35511
  } catch {
34180
- return resolve15(left) === resolve15(right);
35512
+ return resolve16(left) === resolve16(right);
34181
35513
  }
34182
35514
  }
34183
35515
  function isKnownDeeplineCommand(path) {
34184
- const entrypoint = process.argv[1] ? resolve15(process.argv[1]) : "";
35516
+ const entrypoint = process.argv[1] ? resolve16(process.argv[1]) : "";
34185
35517
  let resolvedPath = path;
34186
35518
  try {
34187
35519
  resolvedPath = realpathSync4(path);
@@ -34207,7 +35539,7 @@ function inspectPathConflict() {
34207
35539
  function writeSetupState(input2) {
34208
35540
  const path = setupStatePath(input2.baseUrl, input2.scope, input2.root);
34209
35541
  mkdirSync11(dirname16(path), { recursive: true });
34210
- writeFileSync14(
35542
+ writeFileSync15(
34211
35543
  path,
34212
35544
  `${JSON.stringify(
34213
35545
  {
@@ -34334,7 +35666,7 @@ function buildDoctorAssessment(input2) {
34334
35666
  const connected = input2.authStatus.payload?.connected === true;
34335
35667
  const authScopeOk = input2.scope === "local" ? Boolean(projectAuth) : Boolean(apiKey && !projectAuth);
34336
35668
  const skillsOk = skillsState?.scope === input2.scope && typeof skillsState.skillsVersion === "string" && Array.isArray(skillsState.agents) && skillsState.agents.length > 0;
34337
- const runningCliPath = process.argv[1] ? resolve15(process.argv[1]) : null;
35669
+ const runningCliPath = process.argv[1] ? resolve16(process.argv[1]) : null;
34338
35670
  const globalCli = input2.scope === "global" ? inspectGlobalCliAvailability() : null;
34339
35671
  const pathGlobalCli = globalCli?.path ?? null;
34340
35672
  const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
@@ -34877,7 +36209,7 @@ import {
34877
36209
  readFileSync as readFileSync15,
34878
36210
  renameSync,
34879
36211
  rmSync as rmSync5,
34880
- writeFileSync as writeFileSync15
36212
+ writeFileSync as writeFileSync16
34881
36213
  } from "fs";
34882
36214
  import { homedir as homedir10 } from "os";
34883
36215
  import { dirname as dirname17, join as join17 } from "path";
@@ -34939,7 +36271,7 @@ function writeCliUpdatePreferences(preferences, homeDir2 = homedir10()) {
34939
36271
  const tempPath = `${path}.${process.pid}.tmp`;
34940
36272
  mkdirSync12(dirname17(path), { recursive: true });
34941
36273
  try {
34942
- writeFileSync15(tempPath, `${JSON.stringify(preferences, null, 2)}
36274
+ writeFileSync16(tempPath, `${JSON.stringify(preferences, null, 2)}
34943
36275
  `, {
34944
36276
  encoding: "utf8",
34945
36277
  mode: 384
@@ -35004,7 +36336,7 @@ import {
35004
36336
  renameSync as renameSync2,
35005
36337
  rmSync as rmSync6,
35006
36338
  unlinkSync as unlinkSync2,
35007
- writeFileSync as writeFileSync16
36339
+ writeFileSync as writeFileSync17
35008
36340
  } from "fs";
35009
36341
  import { homedir as homedir11 } from "os";
35010
36342
  import {
@@ -35013,13 +36345,13 @@ import {
35013
36345
  isAbsolute as isAbsolute7,
35014
36346
  join as join19,
35015
36347
  relative as relative7,
35016
- resolve as resolve17
36348
+ resolve as resolve18
35017
36349
  } from "path";
35018
36350
 
35019
36351
  // src/cli/install-integrity.ts
35020
36352
  import { createRequire } from "module";
35021
36353
  import { existsSync as existsSync16, readFileSync as readFileSync16, statSync as statSync5 } from "fs";
35022
- import { isAbsolute as isAbsolute6, join as join18, relative as relative6, resolve as resolve16 } from "path";
36354
+ import { isAbsolute as isAbsolute6, join as join18, relative as relative6, resolve as resolve17 } from "path";
35023
36355
  var SDK_SIDECAR_CRITICAL_PACKAGE_FILES = [
35024
36356
  "dist/cli/index.mjs",
35025
36357
  "dist/index.mjs",
@@ -35044,8 +36376,8 @@ function safeRelativePath(value) {
35044
36376
  }
35045
36377
  function resolveContainedPath(root, value) {
35046
36378
  if (!safeRelativePath(value)) return null;
35047
- const target = resolve16(root, value);
35048
- const relativeTarget = relative6(resolve16(root), target);
36379
+ const target = resolve17(root, value);
36380
+ const relativeTarget = relative6(resolve17(root), target);
35049
36381
  if (!relativeTarget || relativeTarget.startsWith("..") || isAbsolute6(relativeTarget)) {
35050
36382
  return null;
35051
36383
  }
@@ -35271,8 +36603,8 @@ function resolvePythonSidecarUpdatePlan(options) {
35271
36603
  const stateDir = sidecarStateDir(options);
35272
36604
  if (!stateDir) return null;
35273
36605
  const relativeEntrypoint = relative7(
35274
- resolve17(stateDir),
35275
- resolve17(options.entrypoint)
36606
+ resolve18(stateDir),
36607
+ resolve18(options.entrypoint)
35276
36608
  );
35277
36609
  if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || isAbsolute7(relativeEntrypoint)) {
35278
36610
  return null;
@@ -35306,7 +36638,7 @@ function resolvePythonSidecarUpdatePlan(options) {
35306
36638
  };
35307
36639
  }
35308
36640
  function findRepoBackedSdkRoot(startPath) {
35309
- let current = resolve17(startPath);
36641
+ let current = resolve18(startPath);
35310
36642
  while (true) {
35311
36643
  if (existsSync17(join19(current, "package.json")) && existsSync17(join19(current, "bin", "deepline-dev.ts"))) {
35312
36644
  const parent2 = dirname18(current);
@@ -35325,7 +36657,7 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
35325
36657
  try {
35326
36658
  return realpathSync5(entrypoint);
35327
36659
  } catch {
35328
- return resolve17(entrypoint);
36660
+ return resolve18(entrypoint);
35329
36661
  }
35330
36662
  })();
35331
36663
  const parts = normalized.split(/[\\/]+/);
@@ -35341,9 +36673,9 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
35341
36673
  const knownWindowsPrefixes = [
35342
36674
  env.npm_config_prefix,
35343
36675
  env.APPDATA ? join19(env.APPDATA, "npm") : void 0
35344
- ].filter((value) => Boolean(value)).map((value) => resolve17(value).replace(/\\/g, "/").toLowerCase());
36676
+ ].filter((value) => Boolean(value)).map((value) => resolve18(value).replace(/\\/g, "/").toLowerCase());
35345
36677
  if (!knownWindowsPrefixes.includes(
35346
- resolve17(directPrefix).replace(/\\/g, "/").toLowerCase()
36678
+ resolve18(directPrefix).replace(/\\/g, "/").toLowerCase()
35347
36679
  )) {
35348
36680
  return null;
35349
36681
  }
@@ -35356,9 +36688,9 @@ function normalizedNpmPrefix(value) {
35356
36688
  if (!trimmed) return null;
35357
36689
  const normalized = (() => {
35358
36690
  try {
35359
- return realpathSync5(resolve17(trimmed));
36691
+ return realpathSync5(resolve18(trimmed));
35360
36692
  } catch {
35361
- return resolve17(trimmed);
36693
+ return resolve18(trimmed);
35362
36694
  }
35363
36695
  })().replace(/\\/g, "/");
35364
36696
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
@@ -35383,7 +36715,7 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
35383
36715
  try {
35384
36716
  return realpathSync5(entrypoint);
35385
36717
  } catch {
35386
- return resolve17(entrypoint);
36718
+ return resolve18(entrypoint);
35387
36719
  }
35388
36720
  })();
35389
36721
  const parts = normalized.split(/[\\/]+/);
@@ -35393,7 +36725,7 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
35393
36725
  function resolveUpdatePlan(options = {}) {
35394
36726
  const env = options.env ?? process.env;
35395
36727
  const homeDir2 = options.homeDir ?? homedir11();
35396
- const entrypoint = options.entrypoint ?? (process.argv[1] ? resolve17(process.argv[1]) : "");
36728
+ const entrypoint = options.entrypoint ?? (process.argv[1] ? resolve18(process.argv[1]) : "");
35397
36729
  const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname18(entrypoint)) : null;
35398
36730
  if (sourceRoot) {
35399
36731
  return {
@@ -35487,7 +36819,7 @@ function writeAutoUpdateFailure(plan, exitCode) {
35487
36819
  };
35488
36820
  try {
35489
36821
  mkdirSync13(dirname18(path), { recursive: true });
35490
- writeFileSync16(path, `${JSON.stringify(marker, null, 2)}
36822
+ writeFileSync17(path, `${JSON.stringify(marker, null, 2)}
35491
36823
  `, "utf8");
35492
36824
  } catch {
35493
36825
  }
@@ -35679,7 +37011,7 @@ function writeSidecarLauncher(input2) {
35679
37011
  )
35680
37012
  ];
35681
37013
  if (process.platform === "win32") {
35682
- writeFileSync16(
37014
+ writeFileSync17(
35683
37015
  input2.path,
35684
37016
  [
35685
37017
  `@set DEEPLINE_HOST_URL=${input2.hostUrl.replace(/\r?\n/g, "")}`,
@@ -35702,7 +37034,7 @@ function writeSidecarLauncher(input2) {
35702
37034
  );
35703
37035
  return;
35704
37036
  }
35705
- writeFileSync16(
37037
+ writeFileSync17(
35706
37038
  input2.path,
35707
37039
  [
35708
37040
  "#!/usr/bin/env sh",
@@ -35736,7 +37068,7 @@ async function runPythonSidecarUpdatePlan(plan) {
35736
37068
  );
35737
37069
  rmSync6(tempDir, { recursive: true, force: true });
35738
37070
  mkdirSync13(tempDir, { recursive: true });
35739
- writeFileSync16(join19(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
37071
+ writeFileSync17(join19(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
35740
37072
  const env = {
35741
37073
  ...process.env,
35742
37074
  PATH: `${dirname18(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
@@ -35859,27 +37191,27 @@ async function runPythonSidecarUpdatePlan(plan) {
35859
37191
  nodeBin: plan.nodeBin,
35860
37192
  entryPath: finalEntryPath
35861
37193
  });
35862
- writeFileSync16(
37194
+ writeFileSync17(
35863
37195
  join19(plan.stateDir, ".version"),
35864
37196
  `${installedVersion}
35865
37197
  `,
35866
37198
  "utf8"
35867
37199
  );
35868
- writeFileSync16(
37200
+ writeFileSync17(
35869
37201
  join19(plan.stateDir, ".install-method"),
35870
37202
  "python-sidecar\n",
35871
37203
  "utf8"
35872
37204
  );
35873
- writeFileSync16(
37205
+ writeFileSync17(
35874
37206
  join19(plan.stateDir, ".command-path"),
35875
37207
  `${plan.sidecarPath}
35876
37208
  `,
35877
37209
  "utf8"
35878
37210
  );
35879
- writeFileSync16(join19(plan.stateDir, ".runner"), "node\n", "utf8");
35880
- writeFileSync16(join19(plan.stateDir, ".node-bin"), `${plan.nodeBin}
37211
+ writeFileSync17(join19(plan.stateDir, ".runner"), "node\n", "utf8");
37212
+ writeFileSync17(join19(plan.stateDir, ".node-bin"), `${plan.nodeBin}
35881
37213
  `, "utf8");
35882
- writeFileSync16(
37214
+ writeFileSync17(
35883
37215
  join19(plan.stateDir, ".entry-path"),
35884
37216
  `${finalEntryPath}
35885
37217
  `,
@@ -36812,17 +38144,17 @@ import {
36812
38144
  existsSync as existsSync18,
36813
38145
  mkdtempSync,
36814
38146
  readFileSync as readFileSync18,
36815
- writeFileSync as writeFileSync18
38147
+ writeFileSync as writeFileSync19
36816
38148
  } from "fs";
36817
38149
  import { tmpdir as tmpdir5 } from "os";
36818
- import { join as join21, resolve as resolve18 } from "path";
38150
+ import { join as join21, resolve as resolve19 } from "path";
36819
38151
 
36820
38152
  // src/tool-output.ts
36821
38153
  import {
36822
38154
  closeSync as closeSync3,
36823
38155
  mkdirSync as mkdirSync14,
36824
38156
  openSync as openSync3,
36825
- writeFileSync as writeFileSync17,
38157
+ writeFileSync as writeFileSync18,
36826
38158
  writeSync
36827
38159
  } from "fs";
36828
38160
  import { homedir as homedir12 } from "os";
@@ -36960,7 +38292,7 @@ function ensureOutputDir() {
36960
38292
  function writeJsonOutputFile(payload, stem) {
36961
38293
  const outputDir = ensureOutputDir();
36962
38294
  const outputPath = join20(outputDir, `${stem}_${Date.now()}.json`);
36963
- writeFileSync17(outputPath, JSON.stringify(payload, null, 2), "utf-8");
38295
+ writeFileSync18(outputPath, JSON.stringify(payload, null, 2), "utf-8");
36964
38296
  return outputPath;
36965
38297
  }
36966
38298
  function writeCsvOutputFile(rows, stem, options) {
@@ -37301,9 +38633,9 @@ function requiredInputIds(tool) {
37301
38633
  return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
37302
38634
  }
37303
38635
  function notConnectedSuffix(tool) {
37304
- const record = tool;
37305
- const status = stringField2(record, "credentialStatus", "credential_status");
37306
- const connected = record.connected;
38636
+ const record2 = tool;
38637
+ const status = stringField2(record2, "credentialStatus", "credential_status");
38638
+ const connected = record2.connected;
37307
38639
  if (status === "requires_connection" || connected === false) {
37308
38640
  return " - \u26A0 requires your credentials \u2014 not connected (connect to use)";
37309
38641
  }
@@ -37678,19 +39010,19 @@ function printPlayAliasToolError(toolId, play) {
37678
39010
  console.error(playAliasToolErrorMessage(toolId, play));
37679
39011
  }
37680
39012
  function isPlayLikeTool(tool) {
37681
- const record = tool;
37682
- if (record.isPlay === true || record.is_play === true) return true;
37683
- const playExpansion = recordField2(record, "playExpansion", "play_expansion");
39013
+ const record2 = tool;
39014
+ if (record2.isPlay === true || record2.is_play === true) return true;
39015
+ const playExpansion = recordField2(record2, "playExpansion", "play_expansion");
37684
39016
  if (Object.keys(playExpansion).length > 0) return true;
37685
- const toolId = typeof record.toolId === "string" ? record.toolId : "";
39017
+ const toolId = typeof record2.toolId === "string" ? record2.toolId : "";
37686
39018
  return toolId.endsWith("_waterfall");
37687
39019
  }
37688
39020
  function isMonitorTypeTool(tool) {
37689
39021
  return stringField2(tool, "kind") === "monitor_type";
37690
39022
  }
37691
39023
  function playReferenceForTool(tool) {
37692
- const record = tool;
37693
- const declared = stringField2(record, "playReference", "play_reference");
39024
+ const record2 = tool;
39025
+ const declared = stringField2(record2, "playReference", "play_reference");
37694
39026
  if (declared.startsWith("prebuilt/")) {
37695
39027
  return declared;
37696
39028
  }
@@ -38648,12 +39980,12 @@ function singleLineText(value, maxLength = 260) {
38648
39980
  return `${text.slice(0, maxLength - 3).trimEnd()}...`;
38649
39981
  }
38650
39982
  function listedToolDescription(tool) {
38651
- const record = tool;
38652
- return singleLineText(record.bestFor ?? record.best_for ?? tool.description);
39983
+ const record2 = tool;
39984
+ return singleLineText(record2.bestFor ?? record2.best_for ?? tool.description);
38653
39985
  }
38654
39986
  function formatListedToolCost(tool) {
38655
- const record = tool;
38656
- const pricing = recordField2(record, "pricing");
39987
+ const record2 = tool;
39988
+ const pricing = recordField2(record2, "pricing");
38657
39989
  const displayText = stringField2(pricing, "displayText", "display_text");
38658
39990
  return displayText ? `Cost: ${displayText}` : "";
38659
39991
  }
@@ -38934,10 +40266,10 @@ function normalizeOutputFormat(raw) {
38934
40266
  }
38935
40267
  function resolveAtFilePath(rawPath) {
38936
40268
  const trimmed = rawPath.trim();
38937
- const resolved = resolve18(trimmed);
40269
+ const resolved = resolve19(trimmed);
38938
40270
  if (existsSync18(resolved)) return resolved;
38939
40271
  if (process.platform !== "win32" && trimmed.includes("\\")) {
38940
- const normalized = resolve18(trimmed.replace(/\\/g, "/"));
40272
+ const normalized = resolve19(trimmed.replace(/\\/g, "/"));
38941
40273
  if (existsSync18(normalized)) return normalized;
38942
40274
  }
38943
40275
  return resolved;
@@ -39026,7 +40358,7 @@ function parseExecuteOptions(args) {
39026
40358
  continue;
39027
40359
  }
39028
40360
  if ((arg === "--out" || arg === "-o") && args[index + 1]) {
39029
- outPath = resolve18(args[++index]);
40361
+ outPath = resolve19(args[++index]);
39030
40362
  continue;
39031
40363
  }
39032
40364
  throw new Error(`Unknown option: ${arg}`);
@@ -39101,7 +40433,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
39101
40433
  description: ${JSON.stringify(`Seed ${input2.toolId} rows into a Deepline workflow-ready dataset.`)},
39102
40434
  });
39103
40435
  `;
39104
- writeFileSync18(scriptPath, script, { encoding: "utf-8", mode: 384 });
40436
+ writeFileSync19(scriptPath, script, { encoding: "utf-8", mode: 384 });
39105
40437
  return {
39106
40438
  path: scriptPath,
39107
40439
  sourceCode: script,
@@ -39527,7 +40859,7 @@ Examples:
39527
40859
 
39528
40860
  // src/cli/commands/workflow.ts
39529
40861
  import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
39530
- import { dirname as dirname20, join as join22, resolve as resolve19 } from "path";
40862
+ import { dirname as dirname20, join as join22, resolve as resolve20 } from "path";
39531
40863
 
39532
40864
  // src/cli/workflow-to-play.ts
39533
40865
  import { createHash as createHash5 } from "crypto";
@@ -39733,9 +41065,9 @@ function clientWithTimeout(timeoutSeconds) {
39733
41065
  }
39734
41066
  function readStatus(payload) {
39735
41067
  if (!payload || typeof payload !== "object") return null;
39736
- const record = payload;
39737
- if (typeof record.status === "string") return record.status;
39738
- const run = record.run;
41068
+ const record2 = payload;
41069
+ if (typeof record2.status === "string") return record2.status;
41070
+ const run = record2.run;
39739
41071
  if (run && typeof run === "object") {
39740
41072
  const status = run.status;
39741
41073
  if (typeof status === "string") return status;
@@ -39744,7 +41076,7 @@ function readStatus(payload) {
39744
41076
  }
39745
41077
  async function readJsonOption(payload, file) {
39746
41078
  if (file) {
39747
- const raw = await readFile4(resolve19(file), "utf8");
41079
+ const raw = await readFile4(resolve20(file), "utf8");
39748
41080
  return JSON.parse(raw);
39749
41081
  }
39750
41082
  if (payload) {
@@ -39778,7 +41110,7 @@ async function transformOne(api, workflowId, outDir, publish) {
39778
41110
  revision.config,
39779
41111
  { workflowName: workflow.name, version: revision.version }
39780
41112
  );
39781
- const file = join22(resolve19(outDir), `${compiled.playName}.play.ts`);
41113
+ const file = join22(resolve20(outDir), `${compiled.playName}.play.ts`);
39782
41114
  await mkdir5(dirname20(file), { recursive: true });
39783
41115
  await writeFile5(file, compiled.sourceCode, "utf8");
39784
41116
  let published = false;
@@ -40158,7 +41490,7 @@ function isDowngradeAutoUpdateResponse(response) {
40158
41490
  return compareSemver(target, current) < 0;
40159
41491
  }
40160
41492
  function relaunchCurrentCommand(plan) {
40161
- return new Promise((resolve20) => {
41493
+ return new Promise((resolve21) => {
40162
41494
  const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
40163
41495
  const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
40164
41496
  const child = spawn5(command, args, {
@@ -40174,9 +41506,9 @@ function relaunchCurrentCommand(plan) {
40174
41506
  `Deepline SDK/CLI updated, but relaunch failed: ${error.message}
40175
41507
  `
40176
41508
  );
40177
- resolve20(1);
41509
+ resolve21(1);
40178
41510
  });
40179
- child.on("close", (code) => resolve20(code ?? 1));
41511
+ child.on("close", (code) => resolve21(code ?? 1));
40180
41512
  });
40181
41513
  }
40182
41514
  async function maybeAutoUpdateAndRelaunch(response, baseUrl) {
@@ -40324,8 +41656,8 @@ function classifyNetworkFailure(error) {
40324
41656
  let current = error;
40325
41657
  while (current && !seen.has(current)) {
40326
41658
  seen.add(current);
40327
- const record = typeof current === "object" && current !== null ? current : {};
40328
- const code = String(record.code ?? "").toLowerCase();
41659
+ const record2 = typeof current === "object" && current !== null ? current : {};
41660
+ const code = String(record2.code ?? "").toLowerCase();
40329
41661
  const name = current instanceof Error ? current.name.toLowerCase() : "";
40330
41662
  const text = String(
40331
41663
  current instanceof Error ? current.message : current
@@ -40352,7 +41684,7 @@ function classifyNetworkFailure(error) {
40352
41684
  if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
40353
41685
  return "network_ssl_error";
40354
41686
  }
40355
- current = record.cause ?? record.context;
41687
+ current = record2.cause ?? record2.context;
40356
41688
  }
40357
41689
  return "network_error";
40358
41690
  }