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.
package/dist/cli/index.js CHANGED
@@ -182,7 +182,7 @@ configureProxyFromEnv();
182
182
 
183
183
  // src/cli/index.ts
184
184
  var import_promises10 = require("fs/promises");
185
- var import_node_path27 = require("path");
185
+ var import_node_path28 = require("path");
186
186
  var import_node_os18 = require("os");
187
187
  var import_commander4 = require("commander");
188
188
 
@@ -1075,7 +1075,7 @@ var SDK_RELEASE = {
1075
1075
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1076
1076
  // getters keep their established compatibility behavior.
1077
1077
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1078
- version: "0.3.55",
1078
+ version: "0.3.57",
1079
1079
  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.",
1080
1080
  packageCapabilities: {
1081
1081
  updatePreferences: 1
@@ -2212,7 +2212,7 @@ function decodeSseFrame(frame) {
2212
2212
  return parsed;
2213
2213
  }
2214
2214
  function sleep(ms) {
2215
- return new Promise((resolve20) => setTimeout(resolve20, ms));
2215
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
2216
2216
  }
2217
2217
  function withCoworkNetworkHint(message) {
2218
2218
  if (!isCoworkLikeSandbox2() || message.includes(COWORK_NETWORK_HINT)) {
@@ -3115,9 +3115,9 @@ function nonEmptyString(value) {
3115
3115
  }
3116
3116
  function normalizeDatasetBornFrom(value) {
3117
3117
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
3118
- const record = value;
3119
- const table = nonEmptyString(record.table);
3120
- const rowCountIn = finiteNonNegativeInteger2(record.rowCountIn);
3118
+ const record2 = value;
3119
+ const table = nonEmptyString(record2.table);
3120
+ const rowCountIn = finiteNonNegativeInteger2(record2.rowCountIn);
3121
3121
  if (!table || rowCountIn === null) return null;
3122
3122
  return { table, rowCountIn };
3123
3123
  }
@@ -3977,14 +3977,14 @@ async function* observeRunEvents(options) {
3977
3977
  try {
3978
3978
  for (; ; ) {
3979
3979
  if (queue.length === 0) {
3980
- const waitForItem = new Promise((resolve20) => {
3981
- wake = resolve20;
3980
+ const waitForItem = new Promise((resolve21) => {
3981
+ wake = resolve21;
3982
3982
  });
3983
3983
  if (!sawFirstSnapshot) {
3984
3984
  const timedOut = await Promise.race([
3985
3985
  waitForItem.then(() => false),
3986
3986
  new Promise(
3987
- (resolve20) => setTimeout(() => resolve20(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
3987
+ (resolve21) => setTimeout(() => resolve21(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
3988
3988
  )
3989
3989
  ]);
3990
3990
  if (timedOut && queue.length === 0) {
@@ -4177,21 +4177,21 @@ function normalizePlayRuntimeNamespace(value) {
4177
4177
  }
4178
4178
  function normalizePlayRuntimeSelection(value) {
4179
4179
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
4180
- const record = value;
4181
- if (Object.keys(record).some(
4180
+ const record2 = value;
4181
+ if (Object.keys(record2).some(
4182
4182
  (key) => key !== "environment" && key !== "namespace" && key !== "backend"
4183
- ) || record.environment !== "preview") {
4183
+ ) || record2.environment !== "preview") {
4184
4184
  return null;
4185
4185
  }
4186
- const namespace = normalizePlayRuntimeNamespace(record.namespace);
4186
+ const namespace = normalizePlayRuntimeNamespace(record2.namespace);
4187
4187
  if (!namespace) return null;
4188
- if (record.backend === void 0) {
4188
+ if (record2.backend === void 0) {
4189
4189
  return { environment: "preview", namespace };
4190
4190
  }
4191
- if (record.backend !== PLAY_RUNTIME_BACKENDS.daytona && record.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4191
+ if (record2.backend !== PLAY_RUNTIME_BACKENDS.daytona && record2.backend !== PLAY_RUNTIME_BACKENDS.modal) {
4192
4192
  return null;
4193
4193
  }
4194
- return { environment: "preview", namespace, backend: record.backend };
4194
+ return { environment: "preview", namespace, backend: record2.backend };
4195
4195
  }
4196
4196
  function normalizePlayRuntimeEnvironment(value) {
4197
4197
  return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
@@ -4343,7 +4343,7 @@ function parseEnvTestPolicyOverrides() {
4343
4343
  return normalizeTestPolicyOverrides(parsed, "DEEPLINE_TEST_POLICY_OVERRIDES");
4344
4344
  }
4345
4345
  function sleep2(ms) {
4346
- return new Promise((resolve20) => setTimeout(resolve20, ms));
4346
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
4347
4347
  }
4348
4348
  function isTransientCompileManifestError(error) {
4349
4349
  if (error instanceof DeeplineError && typeof error.statusCode === "number") {
@@ -4775,7 +4775,14 @@ var DeeplineClient = class {
4775
4775
  dependents: (key) => this.getMonitorDependents(key),
4776
4776
  update: (key, patch) => this.updateMonitor(key, patch),
4777
4777
  delete: (key, options2) => this.deleteMonitor(key, options2),
4778
- reactivate: (key, options2) => this.reactivateMonitor(key, options2)
4778
+ reactivate: (key, options2) => this.reactivateMonitor(key, options2),
4779
+ fleets: {
4780
+ sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
4781
+ get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
4782
+ list: () => this.listMonitorFleets(),
4783
+ deactivate: (fleetId, options2) => this.deactivateMonitorFleet(fleetId, options2),
4784
+ waitForConvergence: (fleetId, options2) => this.waitForMonitorFleetConvergence(fleetId, options2)
4785
+ }
4779
4786
  };
4780
4787
  }
4781
4788
  /** The resolved base URL this client is targeting (e.g. `"http://localhost:3000"`). */
@@ -7083,6 +7090,104 @@ var DeeplineClient = class {
7083
7090
  { method: "POST", body: {} }
7084
7091
  );
7085
7092
  }
7093
+ // ——————————————————————————————————————————————————————————
7094
+ // Monitor Fleets
7095
+ // ——————————————————————————————————————————————————————————
7096
+ monitorFleetIdempotencyKey(operation) {
7097
+ const uuid = globalThis.crypto?.randomUUID?.();
7098
+ return `monitor-fleet-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
7099
+ }
7100
+ monitorFleetHeaders(operation, idempotencyKey) {
7101
+ return {
7102
+ "Idempotency-Key": idempotencyKey?.trim() || this.monitorFleetIdempotencyKey(operation)
7103
+ };
7104
+ }
7105
+ monitorFleetPath(fleetId) {
7106
+ return `/api/v2/monitors/fleets/${encodeURIComponent(fleetId)}`;
7107
+ }
7108
+ /**
7109
+ * Create, update, or re-plan one fleet.
7110
+ *
7111
+ * The fleet id is always the resource path, so the same definition PUT twice
7112
+ * is the same operation and the server can answer `replayed: true` instead of
7113
+ * building a second set of monitors. Re-planning an existing fleet from its
7114
+ * stored definition sends an EMPTY body: there is no second definition to
7115
+ * send, and an empty body cannot be mistaken for "replace the definition with
7116
+ * nothing".
7117
+ */
7118
+ async syncMonitorFleet(definitionOrId, options) {
7119
+ const fleetId = typeof definitionOrId === "string" ? definitionOrId : definitionOrId.id;
7120
+ const body = {
7121
+ ...typeof definitionOrId === "string" ? {} : { definition: definitionOrId },
7122
+ ...options?.dryRun ? { dry_run: true } : {},
7123
+ ...options?.expectedGeneration !== void 0 ? { expected_generation: options.expectedGeneration } : {}
7124
+ };
7125
+ return this.http.request(
7126
+ this.monitorFleetPath(fleetId),
7127
+ {
7128
+ method: "PUT",
7129
+ body,
7130
+ headers: this.monitorFleetHeaders("sync", options?.idempotencyKey),
7131
+ maxRetries: 0,
7132
+ exactUrlOnly: true
7133
+ }
7134
+ );
7135
+ }
7136
+ async listMonitorFleets() {
7137
+ return this.http.request("/api/v2/monitors/fleets", {
7138
+ method: "GET"
7139
+ });
7140
+ }
7141
+ async getMonitorFleet(fleetId, options) {
7142
+ const params = new URLSearchParams();
7143
+ if (options?.drift) params.set("drift", "1");
7144
+ if (options?.limit !== void 0)
7145
+ params.set("limit", String(options.limit));
7146
+ const query = params.toString();
7147
+ return this.http.request(
7148
+ `${this.monitorFleetPath(fleetId)}${query ? `?${query}` : ""}`,
7149
+ { method: "GET" }
7150
+ );
7151
+ }
7152
+ async deactivateMonitorFleet(fleetId, options) {
7153
+ return this.http.request(
7154
+ this.monitorFleetPath(fleetId),
7155
+ {
7156
+ method: "DELETE",
7157
+ body: options?.dryRun ? { dry_run: true } : {},
7158
+ headers: this.monitorFleetHeaders(
7159
+ "deactivate",
7160
+ options?.idempotencyKey
7161
+ ),
7162
+ maxRetries: 0,
7163
+ exactUrlOnly: true
7164
+ }
7165
+ );
7166
+ }
7167
+ /**
7168
+ * Poll one fleet until the server reports a terminal status.
7169
+ *
7170
+ * Convergence is the server's verdict, read from `status`. The timeout is not
7171
+ * a failure and does not throw: a fleet still `converging` after ten minutes
7172
+ * is healthy and slow, not broken, so the caller gets the last snapshot and
7173
+ * decides what that means. Throwing here would have made "still working" look
7174
+ * identical to "the request failed".
7175
+ */
7176
+ async waitForMonitorFleetConvergence(fleetId, options) {
7177
+ const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
7178
+ const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
7179
+ const terminal = options?.until === "deactivated" ? /* @__PURE__ */ new Set(["deactivated", "degraded"]) : /* @__PURE__ */ new Set(["converged", "degraded", "deactivated"]);
7180
+ const startedAt = Date.now();
7181
+ let latest = await this.getMonitorFleet(fleetId);
7182
+ while (true) {
7183
+ options?.onProgress?.(latest);
7184
+ const status = typeof latest.status === "string" ? latest.status : void 0;
7185
+ if (status && terminal.has(status)) return latest;
7186
+ if (Date.now() - startedAt >= timeoutMs) return latest;
7187
+ await sleep2(pollIntervalMs);
7188
+ latest = await this.getMonitorFleet(fleetId);
7189
+ }
7190
+ }
7086
7191
  /**
7087
7192
  * Check API connectivity and server health.
7088
7193
  *
@@ -7749,30 +7854,30 @@ function flattenObjectColumns(row, options = {}) {
7749
7854
  continue;
7750
7855
  }
7751
7856
  if (value && typeof value === "object" && !Array.isArray(value)) {
7752
- const record = value;
7857
+ const record2 = value;
7753
7858
  if (options.objectColumns === "json") {
7754
- flattened[key] = csvSafeJsonString(record);
7859
+ flattened[key] = csvSafeJsonString(record2);
7755
7860
  continue;
7756
7861
  }
7757
- const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record, "matched_result") || Object.prototype.hasOwnProperty.call(record, "matchedResult");
7862
+ const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record2, "matched_result") || Object.prototype.hasOwnProperty.call(record2, "matchedResult");
7758
7863
  if (hasMatchedEnvelope) {
7759
- flattened[key] = csvSafeJsonString(record);
7864
+ flattened[key] = csvSafeJsonString(record2);
7760
7865
  continue;
7761
7866
  }
7762
7867
  if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
7763
7868
  flattened[key] = rawValue;
7764
7869
  continue;
7765
7870
  } else {
7766
- const failureMessage = failureMessageFromRecord(record);
7871
+ const failureMessage = failureMessageFromRecord(record2);
7767
7872
  if (failureMessage) {
7768
7873
  flattened[key] = failureMessage;
7769
7874
  continue;
7770
- } else if (Object.prototype.hasOwnProperty.call(record, "result")) {
7771
- flattened[key] = csvSafeJsonString(record);
7875
+ } else if (Object.prototype.hasOwnProperty.call(record2, "result")) {
7876
+ flattened[key] = csvSafeJsonString(record2);
7772
7877
  continue;
7773
7878
  }
7774
7879
  }
7775
- for (const [nestedKey, nestedValue] of Object.entries(record)) {
7880
+ for (const [nestedKey, nestedValue] of Object.entries(record2)) {
7776
7881
  flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
7777
7882
  }
7778
7883
  continue;
@@ -8161,7 +8266,7 @@ function buildCandidateUrls2(url) {
8161
8266
  }
8162
8267
  }
8163
8268
  function sleep4(ms) {
8164
- return new Promise((resolve20) => setTimeout(resolve20, ms));
8269
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
8165
8270
  }
8166
8271
  function printDeeplineLogo() {
8167
8272
  if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
@@ -10256,9 +10361,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
10256
10361
  }
10257
10362
  if (ancestors.has(value)) return value;
10258
10363
  ancestors.add(value);
10259
- const record = value;
10364
+ const record2 = value;
10260
10365
  const normalized = Object.fromEntries(
10261
- Object.keys(record).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record[key], ancestors)])
10366
+ Object.keys(record2).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record2[key], ancestors)])
10262
10367
  );
10263
10368
  ancestors.delete(value);
10264
10369
  return normalized;
@@ -11425,16 +11530,16 @@ function collectErrorText(value) {
11425
11530
  if (!value || typeof value !== "object" || Array.isArray(value)) {
11426
11531
  return errorMessage(value);
11427
11532
  }
11428
- const record = value;
11533
+ const record2 = value;
11429
11534
  return [
11430
11535
  errorMessage(value),
11431
- typeof record.error === "string" ? record.error : "",
11432
- typeof record.message === "string" ? record.message : "",
11433
- typeof record.detail === "string" ? record.detail : "",
11434
- typeof record.hint === "string" ? record.hint : "",
11435
- typeof record.code === "string" ? record.code : "",
11436
- record.response ? collectErrorText(record.response) : "",
11437
- record.details ? collectErrorText(record.details) : ""
11536
+ typeof record2.error === "string" ? record2.error : "",
11537
+ typeof record2.message === "string" ? record2.message : "",
11538
+ typeof record2.detail === "string" ? record2.detail : "",
11539
+ typeof record2.hint === "string" ? record2.hint : "",
11540
+ typeof record2.code === "string" ? record2.code : "",
11541
+ record2.response ? collectErrorText(record2.response) : "",
11542
+ record2.details ? collectErrorText(record2.details) : ""
11438
11543
  ].filter(Boolean).join("\n");
11439
11544
  }
11440
11545
  function formatDbQueryError(sql, error) {
@@ -12448,8 +12553,8 @@ function getterNamesFromTool(tool, kind) {
12448
12553
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
12449
12554
  }
12450
12555
  function targetGettersFromTool(tool) {
12451
- const record = isRecord9(tool) ? tool : {};
12452
- const raw = record.targetGetters ?? record.target_getters;
12556
+ const record2 = isRecord9(tool) ? tool : {};
12557
+ const raw = record2.targetGetters ?? record2.target_getters;
12453
12558
  if (!isRecord9(raw)) return {};
12454
12559
  const entries = [];
12455
12560
  for (const [target, value] of Object.entries(raw)) {
@@ -15315,11 +15420,11 @@ function staticStringFromExpression(node, context, seen = /* @__PURE__ */ new Se
15315
15420
  if (!value?.trim()) return null;
15316
15421
  return trimResult ? value.trim() : value;
15317
15422
  }
15318
- const identifier = getIdentifierName2(expression);
15319
- if (!identifier || seen.has(identifier)) return null;
15320
- seen.add(identifier);
15423
+ const identifier2 = getIdentifierName2(expression);
15424
+ if (!identifier2 || seen.has(identifier2)) return null;
15425
+ seen.add(identifier2);
15321
15426
  return staticStringFromExpression(
15322
- context.declarations.get(identifier),
15427
+ context.declarations.get(identifier2),
15323
15428
  context,
15324
15429
  seen,
15325
15430
  trimResult
@@ -15343,11 +15448,11 @@ function objectExpressionFromNode(node, context, seen = /* @__PURE__ */ new Set(
15343
15448
  const expression = unwrapStaticExpression2(node);
15344
15449
  if (!expression) return null;
15345
15450
  if (expression.type === "ObjectExpression") return expression;
15346
- const identifier = getIdentifierName2(expression);
15347
- if (!identifier || seen.has(identifier)) return null;
15348
- seen.add(identifier);
15451
+ const identifier2 = getIdentifierName2(expression);
15452
+ if (!identifier2 || seen.has(identifier2)) return null;
15453
+ seen.add(identifier2);
15349
15454
  return objectExpressionFromNode(
15350
- context.declarations.get(identifier),
15455
+ context.declarations.get(identifier2),
15351
15456
  context,
15352
15457
  seen
15353
15458
  );
@@ -15415,11 +15520,11 @@ function staticNumberFromExpression(node, context, seen = /* @__PURE__ */ new Se
15415
15520
  if (expression.type === "Literal" && typeof expression.value === "number") {
15416
15521
  return expression.value;
15417
15522
  }
15418
- const identifier = getIdentifierName2(expression);
15419
- if (!identifier || seen.has(identifier)) return null;
15420
- seen.add(identifier);
15523
+ const identifier2 = getIdentifierName2(expression);
15524
+ if (!identifier2 || seen.has(identifier2)) return null;
15525
+ seen.add(identifier2);
15421
15526
  return staticNumberFromExpression(
15422
- context.declarations.get(identifier),
15527
+ context.declarations.get(identifier2),
15423
15528
  context,
15424
15529
  seen
15425
15530
  );
@@ -16484,13 +16589,13 @@ function validateFixtureBehavior(value) {
16484
16589
  if (!value || typeof value !== "object" || Array.isArray(value)) {
16485
16590
  return { ok: false, error: "fixtureBehavior must be a JSON object." };
16486
16591
  }
16487
- const record = value;
16488
- const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
16592
+ const record2 = value;
16593
+ const supportedKeys = record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
16489
16594
  "version",
16490
16595
  "responseSamples",
16491
- ...record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
16596
+ ...record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
16492
16597
  ]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
16493
- const unknownKeys = Object.keys(record).filter(
16598
+ const unknownKeys = Object.keys(record2).filter(
16494
16599
  (key) => !supportedKeys.has(key)
16495
16600
  );
16496
16601
  if (unknownKeys.length > 0) {
@@ -16499,22 +16604,22 @@ function validateFixtureBehavior(value) {
16499
16604
  error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
16500
16605
  };
16501
16606
  }
16502
- if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16607
+ if (record2.version !== FIXTURE_BEHAVIOR_VERSION && record2.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record2.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16503
16608
  return {
16504
16609
  ok: false,
16505
16610
  error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
16506
16611
  };
16507
16612
  }
16508
- if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16509
- if (!Array.isArray(record.responseSamples) || record.responseSamples.length === 0 || record.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
16613
+ if (record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16614
+ if (!Array.isArray(record2.responseSamples) || record2.responseSamples.length === 0 || record2.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
16510
16615
  return {
16511
16616
  ok: false,
16512
16617
  error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
16513
16618
  };
16514
16619
  }
16515
16620
  const samples2 = [];
16516
- for (let index = 0; index < record.responseSamples.length; index += 1) {
16517
- const value2 = record.responseSamples[index];
16621
+ for (let index = 0; index < record2.responseSamples.length; index += 1) {
16622
+ const value2 = record2.responseSamples[index];
16518
16623
  if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
16519
16624
  return {
16520
16625
  ok: false,
@@ -16613,14 +16718,14 @@ function validateFixtureBehavior(value) {
16613
16718
  });
16614
16719
  }
16615
16720
  let replayBundle;
16616
- if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16617
- if (!record.replayBundle || typeof record.replayBundle !== "object" || Array.isArray(record.replayBundle)) {
16721
+ if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16722
+ if (!record2.replayBundle || typeof record2.replayBundle !== "object" || Array.isArray(record2.replayBundle)) {
16618
16723
  return {
16619
16724
  ok: false,
16620
16725
  error: "fixtureBehavior.replayBundle must be an object."
16621
16726
  };
16622
16727
  }
16623
- const replay = record.replayBundle;
16728
+ const replay = record2.replayBundle;
16624
16729
  const replayUnknownKeys = Object.keys(replay).filter(
16625
16730
  (key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
16626
16731
  );
@@ -16668,7 +16773,7 @@ function validateFixtureBehavior(value) {
16668
16773
  ...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
16669
16774
  };
16670
16775
  }
16671
- if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16776
+ if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
16672
16777
  return {
16673
16778
  ok: true,
16674
16779
  behavior: {
@@ -16686,15 +16791,15 @@ function validateFixtureBehavior(value) {
16686
16791
  }
16687
16792
  };
16688
16793
  }
16689
- if (!Array.isArray(record.responseDelaySamplesMs) || record.responseDelaySamplesMs.length === 0 || record.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
16794
+ if (!Array.isArray(record2.responseDelaySamplesMs) || record2.responseDelaySamplesMs.length === 0 || record2.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
16690
16795
  return {
16691
16796
  ok: false,
16692
16797
  error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
16693
16798
  };
16694
16799
  }
16695
16800
  const samples = [];
16696
- for (let index = 0; index < record.responseDelaySamplesMs.length; index += 1) {
16697
- const value2 = record.responseDelaySamplesMs[index];
16801
+ for (let index = 0; index < record2.responseDelaySamplesMs.length; index += 1) {
16802
+ const value2 = record2.responseDelaySamplesMs[index];
16698
16803
  if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
16699
16804
  return {
16700
16805
  ok: false,
@@ -16903,7 +17008,7 @@ function traceCliSync(phase, fields, run) {
16903
17008
  }
16904
17009
  }
16905
17010
  function sleep5(ms) {
16906
- return new Promise((resolve20) => setTimeout(resolve20, ms));
17011
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
16907
17012
  }
16908
17013
  function parseReferencedPlayTarget2(target) {
16909
17014
  const trimmed = target.trim();
@@ -17436,8 +17541,8 @@ function looksLikeStagedFileRef(value) {
17436
17541
  if (!value || typeof value !== "object" || Array.isArray(value)) {
17437
17542
  return false;
17438
17543
  }
17439
- const record = value;
17440
- return typeof record.contentHash === "string" || typeof record.contentBase64 === "string" || typeof record.logicalPath === "string" && typeof record.bytes === "number";
17544
+ const record2 = value;
17545
+ return typeof record2.contentHash === "string" || typeof record2.contentBase64 === "string" || typeof record2.logicalPath === "string" && typeof record2.bytes === "number";
17441
17546
  }
17442
17547
  var CSV_DATA_INPUT_KEY = "csv";
17443
17548
  function collectLocalFileInputRefs(value, inputPath, key, out) {
@@ -17938,8 +18043,8 @@ function readLiveRunField(event, field) {
17938
18043
  const records = [payload, payload.progress, run, run?.progress].filter(
17939
18044
  (value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
17940
18045
  );
17941
- for (const record of records) {
17942
- if (record[field] !== void 0) return record[field];
18046
+ for (const record2 of records) {
18047
+ if (record2[field] !== void 0) return record2[field];
17943
18048
  }
17944
18049
  return void 0;
17945
18050
  }
@@ -18241,8 +18346,8 @@ function getProgressLinesFromLiveEvent(event) {
18241
18346
  if (!state || typeof state !== "object" || Array.isArray(state)) {
18242
18347
  continue;
18243
18348
  }
18244
- const record = state;
18245
- const progress = record.progress && typeof record.progress === "object" && !Array.isArray(record.progress) ? record.progress : null;
18349
+ const record2 = state;
18350
+ const progress = record2.progress && typeof record2.progress === "object" && !Array.isArray(record2.progress) ? record2.progress : null;
18246
18351
  if (!progress) {
18247
18352
  continue;
18248
18353
  }
@@ -18259,7 +18364,7 @@ function getProgressLinesFromLiveEvent(event) {
18259
18364
  completed: progress.completed
18260
18365
  });
18261
18366
  lines.push(
18262
- `progress ${formatProgressLabel(record.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
18367
+ `progress ${formatProgressLabel(record2.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
18263
18368
  );
18264
18369
  }
18265
18370
  return lines;
@@ -19088,17 +19193,17 @@ function collectDatasetHandleLines(value, path = "result") {
19088
19193
  return [];
19089
19194
  }
19090
19195
  if (isDatasetHandle(value)) {
19091
- const record = value;
19092
- const count = typeof record.count === "number" ? record.count : typeof record.rowCount === "number" ? record.rowCount : null;
19093
- const preview = Array.isArray(record.preview) ? record.preview : [];
19196
+ const record2 = value;
19197
+ const count = typeof record2.count === "number" ? record2.count : typeof record2.rowCount === "number" ? record2.rowCount : null;
19198
+ const preview = Array.isArray(record2.preview) ? record2.preview : [];
19094
19199
  const lines2 = [
19095
- ` dataset ${typeof record.path === "string" ? record.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
19200
+ ` dataset ${typeof record2.path === "string" ? record2.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
19096
19201
  ];
19097
- if (typeof record.queryDatasetCommand === "string") {
19098
- lines2.push(` query dataset: ${record.queryDatasetCommand}`);
19202
+ if (typeof record2.queryDatasetCommand === "string") {
19203
+ lines2.push(` query dataset: ${record2.queryDatasetCommand}`);
19099
19204
  }
19100
- if (typeof record.slowExportAsCsvCommand === "string") {
19101
- lines2.push(` export CSV: ${record.slowExportAsCsvCommand}`);
19205
+ if (typeof record2.slowExportAsCsvCommand === "string") {
19206
+ lines2.push(` export CSV: ${record2.slowExportAsCsvCommand}`);
19102
19207
  }
19103
19208
  return lines2;
19104
19209
  }
@@ -19495,8 +19600,8 @@ function withTerminalPlayIdentity(status, playName) {
19495
19600
  if (!playName.trim() || getPlayRunPackage(status)) {
19496
19601
  return status;
19497
19602
  }
19498
- const record = status;
19499
- 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"));
19603
+ const record2 = status;
19604
+ 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"));
19500
19605
  if (hasIdentity) {
19501
19606
  return status;
19502
19607
  }
@@ -19609,9 +19714,9 @@ function formatSummaryScalar(value) {
19609
19714
  }
19610
19715
  return null;
19611
19716
  }
19612
- function formatSummaryScalarParts(record, skipKeys = /* @__PURE__ */ new Set()) {
19717
+ function formatSummaryScalarParts(record2, skipKeys = /* @__PURE__ */ new Set()) {
19613
19718
  const parts = [];
19614
- for (const [key, value] of Object.entries(record)) {
19719
+ for (const [key, value] of Object.entries(record2)) {
19615
19720
  if (skipKeys.has(key)) {
19616
19721
  continue;
19617
19722
  }
@@ -19638,13 +19743,13 @@ function formatTopValuesPart(value) {
19638
19743
  return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
19639
19744
  }
19640
19745
  function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
19641
- const record = readRecord(summary);
19642
- const columnStats = readRecord(record?.columnStats);
19643
- if (!record || !columnStats) {
19746
+ const record2 = readRecord(summary);
19747
+ const columnStats = readRecord(record2?.columnStats);
19748
+ if (!record2 || !columnStats) {
19644
19749
  return [];
19645
19750
  }
19646
19751
  const lines = [];
19647
- const rowCounts = readRecord(record.rowCounts);
19752
+ const rowCounts = readRecord(record2.rowCounts);
19648
19753
  if (rowCounts) {
19649
19754
  const persisted = readNonNegativeInteger(rowCounts.persisted);
19650
19755
  const succeeded = readNonNegativeInteger(rowCounts.succeeded);
@@ -19660,7 +19765,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
19660
19765
  }
19661
19766
  }
19662
19767
  const parts = formatSummaryScalarParts(
19663
- record,
19768
+ record2,
19664
19769
  /* @__PURE__ */ new Set(["columnStats", "rowCounts"])
19665
19770
  );
19666
19771
  if (parts.length > 0) {
@@ -19690,35 +19795,35 @@ function actionToCommand(action) {
19690
19795
  if (!action || typeof action !== "object" || Array.isArray(action)) {
19691
19796
  return null;
19692
19797
  }
19693
- const record = action;
19694
- if (typeof record.command === "string" && record.command.trim()) {
19695
- return record.command.trim();
19798
+ const record2 = action;
19799
+ if (typeof record2.command === "string" && record2.command.trim()) {
19800
+ return record2.command.trim();
19696
19801
  }
19697
- if (record.kind === "deepline_run_inspect" && typeof record.runId === "string") {
19698
- return `deepline runs get ${record.runId} --json`;
19802
+ if (record2.kind === "deepline_run_inspect" && typeof record2.runId === "string") {
19803
+ return `deepline runs get ${record2.runId} --json`;
19699
19804
  }
19700
- if (record.kind === "deepline_run_full" && typeof record.runId === "string") {
19701
- return `deepline runs get ${record.runId} --full --json`;
19805
+ if (record2.kind === "deepline_run_full" && typeof record2.runId === "string") {
19806
+ return `deepline runs get ${record2.runId} --full --json`;
19702
19807
  }
19703
- if (record.kind === "deepline_run_billing" && typeof record.runId === "string") {
19704
- return `deepline runs get ${record.runId} --full --json | jq '.billing'`;
19808
+ if (record2.kind === "deepline_run_billing" && typeof record2.runId === "string") {
19809
+ return `deepline runs get ${record2.runId} --full --json | jq '.billing'`;
19705
19810
  }
19706
- if (record.kind === "deepline_run_export" && typeof record.runId === "string" && typeof record.datasetPath === "string") {
19707
- return `deepline runs export ${record.runId} --dataset ${shellSingleQuote(
19708
- record.datasetPath
19709
- )} --out ${shellSingleQuote(`${record.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
19811
+ if (record2.kind === "deepline_run_export" && typeof record2.runId === "string" && typeof record2.datasetPath === "string") {
19812
+ return `deepline runs export ${record2.runId} --dataset ${shellSingleQuote(
19813
+ record2.datasetPath
19814
+ )} --out ${shellSingleQuote(`${record2.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
19710
19815
  }
19711
- if (record.kind === "deepline_run_logs") {
19712
- if (typeof record.command === "string" && record.command.trim()) {
19713
- return record.command;
19816
+ if (record2.kind === "deepline_run_logs") {
19817
+ if (typeof record2.command === "string" && record2.command.trim()) {
19818
+ return record2.command;
19714
19819
  }
19715
- if (typeof record.runId === "string") {
19716
- return record.view === "failed" ? `deepline runs get ${record.runId} --log-failed --json` : `deepline runs logs ${record.runId} --json`;
19820
+ if (typeof record2.runId === "string") {
19821
+ return record2.view === "failed" ? `deepline runs get ${record2.runId} --log-failed --json` : `deepline runs logs ${record2.runId} --json`;
19717
19822
  }
19718
19823
  }
19719
- if (record.kind === "deepline_db_query" && typeof record.sql === "string") {
19720
- const maxRows = typeof record.maxRows === "number" && Number.isFinite(record.maxRows) ? Math.trunc(record.maxRows) : 20;
19721
- return `deepline db query --sql ${shellSingleQuote(record.sql)} --max-rows ${maxRows} --json`;
19824
+ if (record2.kind === "deepline_db_query" && typeof record2.sql === "string") {
19825
+ const maxRows = typeof record2.maxRows === "number" && Number.isFinite(record2.maxRows) ? Math.trunc(record2.maxRows) : 20;
19826
+ return `deepline db query --sql ${shellSingleQuote(record2.sql)} --max-rows ${maxRows} --json`;
19722
19827
  }
19723
19828
  return null;
19724
19829
  }
@@ -20123,12 +20228,12 @@ function exportableSheetRow(row) {
20123
20228
  if (!row || typeof row !== "object" || Array.isArray(row)) {
20124
20229
  return null;
20125
20230
  }
20126
- const record = row;
20127
- const data = record.data;
20231
+ const record2 = row;
20232
+ const data = record2.data;
20128
20233
  if (data && typeof data === "object" && !Array.isArray(data)) {
20129
20234
  return data;
20130
20235
  }
20131
- const fallback = { ...record };
20236
+ const fallback = { ...record2 };
20132
20237
  for (const key of [
20133
20238
  "key",
20134
20239
  "status",
@@ -20480,8 +20585,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
20480
20585
  "ctx.map(...) has been replaced by ctx.dataset(...)",
20481
20586
  "Dataset .step(...) has been replaced by .withColumn(...)"
20482
20587
  ];
20483
- function stringArrayField(record, key) {
20484
- const value = record[key];
20588
+ function stringArrayField(record2, key) {
20589
+ const value = record2[key];
20485
20590
  if (!Array.isArray(value)) return [];
20486
20591
  return value.filter((entry) => typeof entry === "string");
20487
20592
  }
@@ -23654,10 +23759,16 @@ Concepts:
23654
23759
  Authoring:
23655
23760
  Use normal TypeScript interpolation for human-facing strings:
23656
23761
  const readyMessage = \`Put \${input.title} through to send-ready.\`;
23657
- An authored diagram is optional. Docflow parses only an explicit
23762
+ An authored diagram is optional but highly recommended for every new or
23763
+ substantially changed Play. Docflow parses only an explicit
23658
23764
  /** @mermaid ... */ block and its // @mermaid-node annotations; ordinary
23659
23765
  prose comments are never Docflow syntax. When Docflow is enabled, plays check
23660
- gives missing diagrams a non-blocking visualization warning.
23766
+ gives missing diagrams a high-priority, non-blocking warning with the exact
23767
+ Mermaid repair steps. Without a diagram, users see only an inferred execution
23768
+ graph rather than a clear business-language map. It is easy to add: write a
23769
+ short top-of-file flowchart, annotate its visible executable steps, then run
23770
+ plays check again. Treat that warning as an authoring task before finishing
23771
+ Play work unless the caller explicitly asks to leave the inferred graph.
23661
23772
 
23662
23773
  Common commands:
23663
23774
  deepline plays search email --json
@@ -26253,7 +26364,7 @@ function emitEnrichDebug(message) {
26253
26364
  );
26254
26365
  }
26255
26366
  function sleep6(ms) {
26256
- return new Promise((resolve20) => setTimeout(resolve20, ms));
26367
+ return new Promise((resolve21) => setTimeout(resolve21, ms));
26257
26368
  }
26258
26369
  function enrichExportBackingRowsWaitMs() {
26259
26370
  const raw = process.env.DEEPLINE_ENRICH_EXPORT_BACKING_ROWS_WAIT_MS?.trim();
@@ -26362,9 +26473,9 @@ async function expandCompiledConfigAtFiles(value) {
26362
26473
  if (!value || typeof value !== "object") {
26363
26474
  return value;
26364
26475
  }
26365
- const record = value;
26476
+ const record2 = value;
26366
26477
  const expanded = {};
26367
- for (const [key, entry] of Object.entries(record)) {
26478
+ for (const [key, entry] of Object.entries(record2)) {
26368
26479
  expanded[key] = await expandCompiledConfigAtFiles(entry);
26369
26480
  }
26370
26481
  for (const field of ["extract_js", "run_if_js"]) {
@@ -27162,26 +27273,26 @@ function readFirstEnrichDatasetActions(value) {
27162
27273
  }
27163
27274
  return null;
27164
27275
  }
27165
- const record = candidate;
27166
- const actions = isRecord11(record.actions) ? record.actions : null;
27276
+ const record2 = candidate;
27277
+ const actions = isRecord11(record2.actions) ? record2.actions : null;
27167
27278
  const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
27168
27279
  const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
27169
27280
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
27170
27281
  if (query?.kind === "deepline_db_query") {
27171
27282
  return {
27172
- dataset: record,
27283
+ dataset: record2,
27173
27284
  query,
27174
27285
  ...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
27175
27286
  };
27176
27287
  }
27177
- if (options.allowLegacy && record.kind === "dataset" && typeof record.queryDatasetCommand === "string" && record.queryDatasetCommand.trim()) {
27288
+ if (options.allowLegacy && record2.kind === "dataset" && typeof record2.queryDatasetCommand === "string" && record2.queryDatasetCommand.trim()) {
27178
27289
  return {
27179
- dataset: record,
27180
- queryDatasetCommand: record.queryDatasetCommand.trim(),
27181
- ...typeof record.slowExportAsCsvCommand === "string" && record.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record.slowExportAsCsvCommand.trim() } : {}
27290
+ dataset: record2,
27291
+ queryDatasetCommand: record2.queryDatasetCommand.trim(),
27292
+ ...typeof record2.slowExportAsCsvCommand === "string" && record2.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record2.slowExportAsCsvCommand.trim() } : {}
27182
27293
  };
27183
27294
  }
27184
- for (const [key, entry] of Object.entries(record)) {
27295
+ for (const [key, entry] of Object.entries(record2)) {
27185
27296
  if (key === "preview") {
27186
27297
  continue;
27187
27298
  }
@@ -27197,8 +27308,8 @@ function readFirstEnrichDatasetActions(value) {
27197
27308
  seen.clear();
27198
27309
  return walk(value, { allowLegacy: true });
27199
27310
  }
27200
- function actionStringField(record, key) {
27201
- const value = record[key];
27311
+ function actionStringField(record2, key) {
27312
+ const value = record2[key];
27202
27313
  return typeof value === "string" && value.trim() ? value.trim() : null;
27203
27314
  }
27204
27315
  function parseSqlFromDbQueryCommand(command) {
@@ -27542,12 +27653,12 @@ function collectStringFields(value, key, output2, depth = 0) {
27542
27653
  }
27543
27654
  return;
27544
27655
  }
27545
- const record = value;
27546
- const direct = record[key];
27656
+ const record2 = value;
27657
+ const direct = record2[key];
27547
27658
  if (typeof direct === "string" && direct.trim()) {
27548
27659
  output2.add(direct.trim());
27549
27660
  }
27550
- for (const child of Object.values(record)) {
27661
+ for (const child of Object.values(record2)) {
27551
27662
  collectStringFields(child, key, output2, depth + 1);
27552
27663
  }
27553
27664
  }
@@ -27733,23 +27844,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
27733
27844
  if (!row || typeof row !== "object" || Array.isArray(row)) {
27734
27845
  return null;
27735
27846
  }
27736
- const record = row;
27737
- const data = record.data;
27847
+ const record2 = row;
27848
+ const data = record2.data;
27738
27849
  if (data && typeof data === "object" && !Array.isArray(data)) {
27739
27850
  const exported = { ...data };
27740
27851
  applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
27741
- rowError: record.error
27852
+ rowError: record2.error
27742
27853
  });
27743
- applyFailureCellMeta(exported, record.cellMeta, { rowError: record.error });
27744
- applyFailureCellMeta(exported, record.cellMetaPatch, {
27745
- rowError: record.error
27854
+ applyFailureCellMeta(exported, record2.cellMeta, { rowError: record2.error });
27855
+ applyFailureCellMeta(exported, record2.cellMetaPatch, {
27856
+ rowError: record2.error
27746
27857
  });
27747
- applyFailureCellMeta(exported, record[ENRICH_CELL_META_PATCH_FIELD], {
27748
- rowError: record.error
27858
+ applyFailureCellMeta(exported, record2[ENRICH_CELL_META_PATCH_FIELD], {
27859
+ rowError: record2.error
27749
27860
  });
27750
27861
  delete exported[ENRICH_CELL_META_FIELD];
27751
27862
  delete exported[ENRICH_CELL_META_PATCH_FIELD];
27752
- const inputIndex = typeof record.inputIndex === "number" ? record.inputIndex : typeof record.inputIndex === "string" && record.inputIndex.trim() ? Number(record.inputIndex) : Number.NaN;
27863
+ const inputIndex = typeof record2.inputIndex === "number" ? record2.inputIndex : typeof record2.inputIndex === "string" && record2.inputIndex.trim() ? Number(record2.inputIndex) : Number.NaN;
27753
27864
  if (Number.isInteger(inputIndex) && inputIndex >= 0) {
27754
27865
  if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
27755
27866
  exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
@@ -27758,18 +27869,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
27758
27869
  }
27759
27870
  return exported;
27760
27871
  }
27761
- const fallback = { ...record };
27872
+ const fallback = { ...record2 };
27762
27873
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
27763
- rowError: record.error
27874
+ rowError: record2.error
27764
27875
  });
27765
- applyFailureCellMeta(fallback, record.cellMeta, {
27766
- rowError: record.error
27876
+ applyFailureCellMeta(fallback, record2.cellMeta, {
27877
+ rowError: record2.error
27767
27878
  });
27768
- applyFailureCellMeta(fallback, record.cellMetaPatch, {
27769
- rowError: record.error
27879
+ applyFailureCellMeta(fallback, record2.cellMetaPatch, {
27880
+ rowError: record2.error
27770
27881
  });
27771
27882
  applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
27772
- rowError: record.error
27883
+ rowError: record2.error
27773
27884
  });
27774
27885
  for (const key of [
27775
27886
  "key",
@@ -27988,16 +28099,16 @@ function isWaterfallResultMeaningful(value) {
27988
28099
  return value.some(isWaterfallResultMeaningful);
27989
28100
  }
27990
28101
  if (value && typeof value === "object") {
27991
- const record = value;
27992
- const status = typeof record.status === "string" ? record.status.trim().toLowerCase() : "";
28102
+ const record2 = value;
28103
+ const status = typeof record2.status === "string" ? record2.status.trim().toLowerCase() : "";
27993
28104
  if (status === "error" || status === "failed") {
27994
28105
  return false;
27995
28106
  }
27996
- if (typeof record.error === "string" && record.error.trim()) {
28107
+ if (typeof record2.error === "string" && record2.error.trim()) {
27997
28108
  return false;
27998
28109
  }
27999
- if (Object.prototype.hasOwnProperty.call(record, "matched_result")) {
28000
- return isWaterfallResultMeaningful(record.matched_result);
28110
+ if (Object.prototype.hasOwnProperty.call(record2, "matched_result")) {
28111
+ return isWaterfallResultMeaningful(record2.matched_result);
28001
28112
  }
28002
28113
  for (const key of [
28003
28114
  "value",
@@ -28012,11 +28123,11 @@ function isWaterfallResultMeaningful(value) {
28012
28123
  "result",
28013
28124
  "data"
28014
28125
  ]) {
28015
- if (isWaterfallResultMeaningful(record[key])) {
28126
+ if (isWaterfallResultMeaningful(record2[key])) {
28016
28127
  return true;
28017
28128
  }
28018
28129
  }
28019
- return Object.entries(record).some(
28130
+ return Object.entries(record2).some(
28020
28131
  ([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
28021
28132
  );
28022
28133
  }
@@ -28032,8 +28143,8 @@ function stableRowSnapshot(value) {
28032
28143
  return `[${value.map(stableRowSnapshot).join(",")}]`;
28033
28144
  }
28034
28145
  if (value && typeof value === "object") {
28035
- const record = value;
28036
- return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record[key])}`).join(",")}}`;
28146
+ const record2 = value;
28147
+ return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record2[key])}`).join(",")}}`;
28037
28148
  }
28038
28149
  return JSON.stringify(value);
28039
28150
  }
@@ -28620,8 +28731,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
28620
28731
  seen.add(normalized);
28621
28732
  commands.push({ ...command, command: normalized });
28622
28733
  }
28623
- function datasetSelectorForEnrichCommand(record, fallbackPath) {
28624
- const candidates = [record.path, record.tableNamespace, fallbackPath];
28734
+ function datasetSelectorForEnrichCommand(record2, fallbackPath) {
28735
+ const candidates = [record2.path, record2.tableNamespace, fallbackPath];
28625
28736
  for (const candidate of candidates) {
28626
28737
  if (typeof candidate === "string" && candidate.trim()) {
28627
28738
  return candidate.trim();
@@ -28683,19 +28794,19 @@ function collectDatasetFollowUpCommands(value, state) {
28683
28794
  );
28684
28795
  return;
28685
28796
  }
28686
- const record = value;
28687
- const isDataset = record.kind === "dataset";
28797
+ const record2 = value;
28798
+ const isDataset = record2.kind === "dataset";
28688
28799
  if (isDataset) {
28689
- const selector = datasetSelectorForEnrichCommand(record, state.path);
28690
- const labelPath = typeof record.path === "string" && record.path.trim() ? record.path.trim() : selector ?? state.path;
28691
- if (typeof record.queryDatasetCommand === "string") {
28800
+ const selector = datasetSelectorForEnrichCommand(record2, state.path);
28801
+ const labelPath = typeof record2.path === "string" && record2.path.trim() ? record2.path.trim() : selector ?? state.path;
28802
+ if (typeof record2.queryDatasetCommand === "string") {
28692
28803
  addEnrichFollowUpCommand(state.commands, state.seen, {
28693
28804
  label: `query ${labelPath}`,
28694
28805
  path: labelPath,
28695
- command: record.queryDatasetCommand
28806
+ command: record2.queryDatasetCommand
28696
28807
  });
28697
28808
  }
28698
- const exportCommand = typeof record.slowExportAsCsvCommand === "string" ? record.slowExportAsCsvCommand : typeof record.fullExportCommand === "string" ? record.fullExportCommand : null;
28809
+ const exportCommand = typeof record2.slowExportAsCsvCommand === "string" ? record2.slowExportAsCsvCommand : typeof record2.fullExportCommand === "string" ? record2.fullExportCommand : null;
28699
28810
  if (exportCommand) {
28700
28811
  addEnrichFollowUpCommand(state.commands, state.seen, {
28701
28812
  label: `export ${labelPath}`,
@@ -28712,7 +28823,7 @@ function collectDatasetFollowUpCommands(value, state) {
28712
28823
  });
28713
28824
  }
28714
28825
  }
28715
- for (const [key, child] of Object.entries(record)) {
28826
+ for (const [key, child] of Object.entries(record2)) {
28716
28827
  if (key === "preview" || key === "access") {
28717
28828
  continue;
28718
28829
  }
@@ -30137,9 +30248,9 @@ function readCodexSessionId(filePath) {
30137
30248
  )) {
30138
30249
  const parsed = parseJsonLine(line);
30139
30250
  if (!parsed || typeof parsed !== "object") continue;
30140
- const record = parsed;
30141
- const payload = record.payload && typeof record.payload === "object" ? record.payload : null;
30142
- const id = record.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
30251
+ const record2 = parsed;
30252
+ const payload = record2.payload && typeof record2.payload === "object" ? record2.payload : null;
30253
+ const id = record2.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
30143
30254
  if (id && UUID_RE.test(id)) return id;
30144
30255
  }
30145
30256
  } catch {
@@ -30238,15 +30349,15 @@ function messageContentKey(value) {
30238
30349
  if (!Array.isArray(content)) return null;
30239
30350
  return content.map((block) => {
30240
30351
  if (!block || typeof block !== "object") return String(block);
30241
- const record = block;
30242
- const type = String(record.type ?? "");
30352
+ const record2 = block;
30353
+ const type = String(record2.type ?? "");
30243
30354
  if (type === "tool_use") {
30244
- return `tool_use:${String(record.name ?? "")}:${String(record.id ?? "")}`;
30355
+ return `tool_use:${String(record2.name ?? "")}:${String(record2.id ?? "")}`;
30245
30356
  }
30246
30357
  if (type === "tool_result") {
30247
- return `tool_result:${String(record.tool_use_id ?? "")}`;
30358
+ return `tool_result:${String(record2.tool_use_id ?? "")}`;
30248
30359
  }
30249
- return String(record.text ?? type);
30360
+ return String(record2.text ?? type);
30250
30361
  }).join("\n");
30251
30362
  }
30252
30363
  function dedupConsecutiveEvents(raw) {
@@ -30261,9 +30372,9 @@ function dedupConsecutiveEvents(raw) {
30261
30372
  index += 1;
30262
30373
  continue;
30263
30374
  }
30264
- const record = event;
30265
- const eventType = String(record.type ?? "");
30266
- const eventKey = messageContentKey(record);
30375
+ const record2 = event;
30376
+ const eventType = String(record2.type ?? "");
30377
+ const eventKey = messageContentKey(record2);
30267
30378
  if (!["user", "assistant"].includes(eventType) || !eventKey) {
30268
30379
  output2.push(rawLines[index] ?? "");
30269
30380
  index += 1;
@@ -30282,9 +30393,9 @@ function dedupConsecutiveEvents(raw) {
30282
30393
  cursor += 1;
30283
30394
  }
30284
30395
  if (runCount > 1) {
30285
- record._repeat_count = runCount;
30286
- record._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
30287
- output2.push(JSON.stringify(record));
30396
+ record2._repeat_count = runCount;
30397
+ record2._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
30398
+ output2.push(JSON.stringify(record2));
30288
30399
  index = cursor;
30289
30400
  continue;
30290
30401
  }
@@ -30329,9 +30440,9 @@ function selectiveCompactToolResults(raw) {
30329
30440
  lines.push(line);
30330
30441
  continue;
30331
30442
  }
30332
- const record = parsed;
30333
- if (record.type === "user") {
30334
- const message = record.message;
30443
+ const record2 = parsed;
30444
+ if (record2.type === "user") {
30445
+ const message = record2.message;
30335
30446
  const content = message && typeof message === "object" ? message.content : null;
30336
30447
  if (Array.isArray(content)) {
30337
30448
  message.content = content.map(
@@ -30339,7 +30450,7 @@ function selectiveCompactToolResults(raw) {
30339
30450
  );
30340
30451
  }
30341
30452
  }
30342
- lines.push(JSON.stringify(record));
30453
+ lines.push(JSON.stringify(record2));
30343
30454
  }
30344
30455
  return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
30345
30456
  ` : "", "utf8");
@@ -30365,15 +30476,15 @@ function compactCodexEvents(raw) {
30365
30476
  lines.push(rawLines[index] ?? "");
30366
30477
  return;
30367
30478
  }
30368
- const record = event;
30369
- if (record.type === "world_state") return;
30370
- const payload = record.payload;
30479
+ const record2 = event;
30480
+ if (record2.type === "world_state") return;
30481
+ const payload = record2.payload;
30371
30482
  const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
30372
30483
  if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
30373
30484
  if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
30374
30485
  const record_payload = payload;
30375
30486
  record_payload.output = compactEventValue(record_payload.output);
30376
- lines.push(JSON.stringify(record));
30487
+ lines.push(JSON.stringify(record2));
30377
30488
  return;
30378
30489
  }
30379
30490
  lines.push(rawLines[index] ?? "");
@@ -30836,8 +30947,325 @@ Examples:
30836
30947
  }
30837
30948
 
30838
30949
  // src/cli/commands/monitors.ts
30950
+ var import_node_crypto8 = require("crypto");
30839
30951
  var import_node_fs14 = require("fs");
30952
+ var import_node_path17 = require("path");
30840
30953
  var import_promises8 = require("readline/promises");
30954
+
30955
+ // src/monitor-fleet-contract.ts
30956
+ var MONITOR_FLEET_MAX_MEMBERS = 1e3;
30957
+ var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
30958
+ var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
30959
+ MONITOR_FLEET_AUTHORING_CONTRACT_EDITION
30960
+ ];
30961
+ var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
30962
+ var MONITOR_FLEET_DOCUMENTATION = {
30963
+ summary: "A Monitor Fleet keeps one bounded, sticky set of ordinary monitors aligned with Customer DB rows.",
30964
+ authoredFields: {
30965
+ id: "Stable lowercase fleet id used by sync, pause, resume, and deactivate.",
30966
+ source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
30967
+ member: "Ordinary monitor tool, stable key template, and payload evaluated for each selected source row.",
30968
+ selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
30969
+ },
30970
+ fixedPolicy: {
30971
+ cadence: "daily",
30972
+ membership: "sticky",
30973
+ removalGrace: "7d",
30974
+ onRemoved: "deactivate",
30975
+ 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.",
30976
+ billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
30977
+ },
30978
+ stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
30979
+ columnExpression: 'Use { "$fleet": "column", "name": "column_name" } in a member key or payload to read a value from each source row.'
30980
+ };
30981
+ function record(value) {
30982
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
30983
+ }
30984
+ function identifier(value) {
30985
+ return typeof value === "string" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value);
30986
+ }
30987
+ function exactKeys(input2, keys, path, issues) {
30988
+ if (!input2) return;
30989
+ for (const key of Object.keys(input2)) {
30990
+ if (keys.includes(key)) continue;
30991
+ issues.push({
30992
+ path: path ? `${path}.${key}` : key,
30993
+ code: "unknown_fleet_field",
30994
+ message: `${path || "Fleet"} does not accept '${key}'.`
30995
+ });
30996
+ }
30997
+ }
30998
+ function jsonValue(value, path, issues) {
30999
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
31000
+ return;
31001
+ }
31002
+ if (Array.isArray(value)) {
31003
+ value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
31004
+ return;
31005
+ }
31006
+ const input2 = record(value);
31007
+ if (!input2) {
31008
+ issues.push({
31009
+ path,
31010
+ code: "invalid_fleet_json_value",
31011
+ message: "Fleet payload values must be JSON values."
31012
+ });
31013
+ return;
31014
+ }
31015
+ for (const [key, item] of Object.entries(input2)) {
31016
+ jsonValue(item, `${path}.${key}`, issues);
31017
+ }
31018
+ }
31019
+ function validateExpression(value, path, issues) {
31020
+ const input2 = record(value);
31021
+ if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
31022
+ issues.push({
31023
+ path,
31024
+ code: "invalid_fleet_expression",
31025
+ message: "Fleet expressions must be an exact tagged column reference."
31026
+ });
31027
+ return;
31028
+ }
31029
+ exactKeys(input2, ["$fleet", "name"], path, issues);
31030
+ }
31031
+ function walkPayload(value, path, issues) {
31032
+ if (Array.isArray(value)) {
31033
+ value.forEach(
31034
+ (item, index) => walkPayload(item, `${path}.${index}`, issues)
31035
+ );
31036
+ return;
31037
+ }
31038
+ const input2 = record(value);
31039
+ if (!input2) return;
31040
+ if ("$fleet" in input2) {
31041
+ validateExpression(input2, path, issues);
31042
+ return;
31043
+ }
31044
+ for (const [key, item] of Object.entries(input2)) {
31045
+ walkPayload(item, `${path}.${key}`, issues);
31046
+ }
31047
+ }
31048
+ function validateMonitorFleetDefinition(value) {
31049
+ const issues = [];
31050
+ const input2 = record(value);
31051
+ if (!input2) {
31052
+ return {
31053
+ valid: false,
31054
+ issues: [
31055
+ {
31056
+ path: "",
31057
+ code: "invalid_fleet",
31058
+ message: "Fleet must be an object."
31059
+ }
31060
+ ]
31061
+ };
31062
+ }
31063
+ exactKeys(input2, ["id", "source", "member", "selection"], "", issues);
31064
+ if (typeof input2.id !== "string" || !/^[a-z][a-z0-9-]{0,199}$/.test(input2.id)) {
31065
+ issues.push({
31066
+ path: "id",
31067
+ code: "invalid_fleet_id",
31068
+ message: "Fleet id must be lowercase kebab-case."
31069
+ });
31070
+ }
31071
+ const source = record(input2.source);
31072
+ exactKeys(
31073
+ source,
31074
+ ["kind", "schema", "table", "key", "where"],
31075
+ "source",
31076
+ issues
31077
+ );
31078
+ if (!source || source.kind !== "customer_db_table") {
31079
+ issues.push({
31080
+ path: "source.kind",
31081
+ code: "invalid_fleet_source",
31082
+ message: "Beta fleets require customer_db_table."
31083
+ });
31084
+ }
31085
+ if (!identifier(source?.schema) || !identifier(source?.table)) {
31086
+ issues.push({
31087
+ path: "source",
31088
+ code: "invalid_fleet_table",
31089
+ message: "Source schema and table must be SQL identifiers."
31090
+ });
31091
+ }
31092
+ const sourceKey = record(source?.key);
31093
+ exactKeys(sourceKey, ["column", "type"], "source.key", issues);
31094
+ if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
31095
+ issues.push({
31096
+ path: "source.key",
31097
+ code: "invalid_fleet_source_key",
31098
+ message: "Source key must name a supported typed column."
31099
+ });
31100
+ }
31101
+ if (source?.where !== void 0) {
31102
+ const where = record(source.where);
31103
+ if (!where) {
31104
+ issues.push({
31105
+ path: "source.where",
31106
+ code: "invalid_fleet_where",
31107
+ message: "source.where must be an object of equality values."
31108
+ });
31109
+ } else {
31110
+ for (const [column, expected] of Object.entries(where)) {
31111
+ if (!identifier(column)) {
31112
+ issues.push({
31113
+ path: `source.where.${column}`,
31114
+ code: "invalid_fleet_where_column",
31115
+ message: "source.where keys must be SQL identifiers."
31116
+ });
31117
+ }
31118
+ if (expected !== null && typeof expected !== "string" && typeof expected !== "boolean" && !(typeof expected === "number" && Number.isFinite(expected))) {
31119
+ issues.push({
31120
+ path: `source.where.${column}`,
31121
+ code: "invalid_fleet_where_value",
31122
+ message: "source.where values must be finite JSON scalars or null."
31123
+ });
31124
+ }
31125
+ }
31126
+ }
31127
+ }
31128
+ const member = record(input2.member);
31129
+ exactKeys(member, ["tool", "key", "payload"], "member", issues);
31130
+ const key = record(member?.key);
31131
+ if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
31132
+ issues.push({
31133
+ path: "member.tool",
31134
+ code: "invalid_fleet_tool",
31135
+ message: "Member tool is required."
31136
+ });
31137
+ }
31138
+ if (!key || key.$fleet !== "template" || !Array.isArray(key.parts) || key.parts.length === 0) {
31139
+ issues.push({
31140
+ path: "member.key",
31141
+ code: "invalid_fleet_key",
31142
+ message: "Member key must be a tagged fleet template."
31143
+ });
31144
+ } else {
31145
+ exactKeys(key, ["$fleet", "parts"], "member.key", issues);
31146
+ for (const [index, part] of key.parts.entries()) {
31147
+ if (typeof part !== "string")
31148
+ validateExpression(part, `member.key.parts.${index}`, issues);
31149
+ }
31150
+ if (sourceKey && !key.parts.some(
31151
+ (part) => record(part)?.$fleet === "column" && record(part)?.name === sourceKey.column
31152
+ )) {
31153
+ issues.push({
31154
+ path: "member.key.parts",
31155
+ code: "fleet_key_missing_source_key",
31156
+ message: "Member key must include the source key column."
31157
+ });
31158
+ }
31159
+ }
31160
+ if (!member || !("payload" in member)) {
31161
+ issues.push({
31162
+ path: "member.payload",
31163
+ code: "invalid_fleet_payload",
31164
+ message: "Member payload is required."
31165
+ });
31166
+ } else {
31167
+ jsonValue(member.payload, "member.payload", issues);
31168
+ }
31169
+ walkPayload(member?.payload, "member.payload", issues);
31170
+ const selection = record(input2.selection);
31171
+ exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
31172
+ if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
31173
+ issues.push({
31174
+ path: "selection.limit",
31175
+ code: "MONITOR_FLEET_LIMIT_EXCEEDED",
31176
+ message: "selection.limit must be between 1 and 1,000."
31177
+ });
31178
+ }
31179
+ if (selection?.membership !== "sticky") {
31180
+ issues.push({
31181
+ path: "selection.membership",
31182
+ code: "invalid_fleet_membership",
31183
+ message: `Fleet membership is fixed to ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.membership}. ${MONITOR_FLEET_DOCUMENTATION.stickyMembership}`
31184
+ });
31185
+ }
31186
+ const orderBy = selection?.orderBy;
31187
+ if (!Array.isArray(orderBy) || orderBy.length === 0) {
31188
+ issues.push({
31189
+ path: "selection.orderBy",
31190
+ code: "invalid_fleet_order",
31191
+ message: "At least one deterministic order field is required."
31192
+ });
31193
+ } else {
31194
+ const orderColumns = /* @__PURE__ */ new Set();
31195
+ for (const [index, order] of orderBy.entries()) {
31196
+ const item = record(order);
31197
+ exactKeys(
31198
+ item,
31199
+ ["column", "direction"],
31200
+ `selection.orderBy.${index}`,
31201
+ issues
31202
+ );
31203
+ if (!item || !identifier(item.column) || !["asc", "desc"].includes(String(item.direction))) {
31204
+ issues.push({
31205
+ path: `selection.orderBy.${index}`,
31206
+ code: "invalid_fleet_order",
31207
+ message: "Order fields need a column and asc/desc direction."
31208
+ });
31209
+ } else if (orderColumns.has(item.column)) {
31210
+ issues.push({
31211
+ path: `selection.orderBy.${index}.column`,
31212
+ code: "duplicate_fleet_order_column",
31213
+ message: "Each selection order column may appear only once."
31214
+ });
31215
+ } else {
31216
+ orderColumns.add(item.column);
31217
+ }
31218
+ }
31219
+ if (sourceKey && record(orderBy.at(-1))?.column !== sourceKey.column) {
31220
+ issues.push({
31221
+ path: "selection.orderBy",
31222
+ code: "fleet_order_missing_key",
31223
+ message: "The final order field must be the source key."
31224
+ });
31225
+ }
31226
+ }
31227
+ for (const removedOption of ["spendLimits", "lifecycle", "reconciliation"]) {
31228
+ if (removedOption in input2) {
31229
+ issues.push({
31230
+ path: removedOption,
31231
+ code: "unsupported_fleet_option",
31232
+ 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.`
31233
+ });
31234
+ }
31235
+ }
31236
+ return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
31237
+ }
31238
+ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHORING_CONTRACT_EDITION) {
31239
+ if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
31240
+ edition
31241
+ )) {
31242
+ return {
31243
+ valid: false,
31244
+ issues: [
31245
+ {
31246
+ path: "authoring_contract_edition",
31247
+ code: "unsupported_fleet_authoring_contract_edition",
31248
+ message: `Monitor Fleet authoring contract edition ${edition} is not supported.`
31249
+ }
31250
+ ]
31251
+ };
31252
+ }
31253
+ const result = validateMonitorFleetDefinition(value);
31254
+ return result.valid && result.definition ? {
31255
+ valid: true,
31256
+ contract: {
31257
+ edition,
31258
+ // JSON cloning prevents later caller mutation from changing the
31259
+ // admitted snapshot.
31260
+ definition: JSON.parse(
31261
+ JSON.stringify(result.definition)
31262
+ )
31263
+ },
31264
+ issues: []
31265
+ } : { valid: false, issues: result.issues };
31266
+ }
31267
+
31268
+ // src/cli/commands/monitors.ts
30841
31269
  var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
30842
31270
  function withJsonOption(command) {
30843
31271
  return command.option("--json", JSON_OPTION_DESCRIPTION);
@@ -30859,6 +31287,7 @@ var MonitorDryRunUnsupportedError = class extends Error {
30859
31287
  };
30860
31288
  function monitorsErrorExitCode(error) {
30861
31289
  if (error instanceof MonitorsUsageError) return 2;
31290
+ if (error instanceof MonitorFleetStateError) return 6;
30862
31291
  if (error instanceof AuthError) return 3;
30863
31292
  if (error instanceof DeeplineError) {
30864
31293
  const status = error.statusCode;
@@ -30869,12 +31298,14 @@ function monitorsErrorExitCode(error) {
30869
31298
  }
30870
31299
  return 5;
30871
31300
  }
30872
- function monitorsFailureNextCommand(error, exitCode) {
31301
+ function monitorsFailureNextCommand(error, exitCode, options) {
31302
+ if (error instanceof MonitorFleetStateError) return error.next;
30873
31303
  if (error instanceof DeeplineError) {
30874
31304
  const response = asRecord2(asRecord2(error.details)?.response);
30875
- const serverNextAction = asString(response?.next_action);
30876
- if (serverNextAction) return serverNextAction;
31305
+ const serverNext = asString(response?.next) ?? asString(response?.next_action);
31306
+ if (serverNext) return serverNext;
30877
31307
  }
31308
+ if (exitCode === 5 && options?.retryCommand) return options.retryCommand;
30878
31309
  if (error instanceof DeeplineError && error.code === "monitor_access_required") {
30879
31310
  return "deepline monitors status";
30880
31311
  }
@@ -30900,9 +31331,10 @@ function readValidationIssues(error) {
30900
31331
  ];
30901
31332
  });
30902
31333
  }
30903
- function reportMonitorsFailure(error) {
31334
+ function reportMonitorsFailure(error, options) {
30904
31335
  const exitCode = monitorsErrorExitCode(error);
30905
- const next = monitorsFailureNextCommand(error, exitCode);
31336
+ const next = monitorsFailureNextCommand(error, exitCode, options);
31337
+ const retrySafe = exitCode === 5 && options?.retryCommand !== void 0;
30906
31338
  const wantsJson = shouldEmitJson(process.argv.includes("--json"));
30907
31339
  if (wantsJson) {
30908
31340
  const payload = errorToJsonPayload(error);
@@ -30910,10 +31342,15 @@ function reportMonitorsFailure(error) {
30910
31342
  ok: false,
30911
31343
  exitCode,
30912
31344
  ...next ? { next } : {},
30913
- error: payload.error
31345
+ ...retrySafe ? { retry_safe: true } : {},
31346
+ error: retrySafe ? {
31347
+ ...payload.error,
31348
+ message: `${payload.error.message} ${FLEET_RETRY_SAFE_NOTE}`
31349
+ } : payload.error
30914
31350
  });
30915
31351
  } else {
30916
- const message = error instanceof Error ? error.message : String(error);
31352
+ const base = error instanceof Error ? error.message : String(error);
31353
+ const message = retrySafe ? `${base} ${FLEET_RETRY_SAFE_NOTE}` : base;
30917
31354
  process.stderr.write(`Error: ${message}
30918
31355
  `);
30919
31356
  for (const issue of readValidationIssues(error)) {
@@ -31464,6 +31901,724 @@ async function handleMonitorsDeploy(definition, options) {
31464
31901
  text: renderMonitorDeployCompletion(payload)
31465
31902
  });
31466
31903
  }
31904
+ function fleetIntegerOption(raw, flag) {
31905
+ if (raw === void 0) return void 0;
31906
+ const value = Number(raw);
31907
+ if (!Number.isSafeInteger(value) || value < 0) {
31908
+ throw new MonitorsUsageError(`${flag} must be a non-negative integer.`);
31909
+ }
31910
+ return value;
31911
+ }
31912
+ function fleetIdempotencyKey(operation, supplied) {
31913
+ const normalized = supplied?.trim();
31914
+ if (supplied !== void 0 && !normalized) {
31915
+ throw new MonitorsUsageError("--idempotency-key must not be empty.");
31916
+ }
31917
+ return normalized ?? `monitor-fleet-${operation}-${(0, import_node_crypto8.randomUUID)()}`;
31918
+ }
31919
+ var FLEET_COUNT_KEYS = [
31920
+ "pending",
31921
+ "submitting",
31922
+ "rate_limited",
31923
+ "settled",
31924
+ "blocked",
31925
+ "failed"
31926
+ ];
31927
+ var FLEET_DEFAULT_WAIT_MS = 10 * 6e4;
31928
+ var FLEET_POLL_INTERVAL_MS = 2e3;
31929
+ var FLEET_PLAIN_PROGRESS_INTERVAL_MS = 15e3;
31930
+ var FLEET_RETRY_SAFE_NOTE = "Safe to retry \u2014 every fleet command is idempotent.";
31931
+ var MONITOR_FLEET_LIFECYCLE = [
31932
+ {
31933
+ step: 1,
31934
+ what: "Write a definition file you can read and edit.",
31935
+ command: "deepline monitors fleets init <fleet-id> --source public.accounts --key account_id --tool <tool> --payload '<json>' --out fleet.json"
31936
+ },
31937
+ {
31938
+ step: 2,
31939
+ what: "See the plan and the credits before anything changes.",
31940
+ command: "deepline monitors fleets sync --file fleet.json --dry-run"
31941
+ },
31942
+ {
31943
+ step: 3,
31944
+ what: "Apply it and wait for the server to call it converged.",
31945
+ command: "deepline monitors fleets sync --file fleet.json --wait"
31946
+ },
31947
+ {
31948
+ step: 4,
31949
+ what: "Read live state; add --drift to see what has not settled.",
31950
+ command: "deepline monitors fleets get <fleet-id>"
31951
+ }
31952
+ ];
31953
+ var MONITOR_FLEET_COMMANDS = [
31954
+ { name: "init", summary: "Write a Fleet definition JSON file." },
31955
+ {
31956
+ name: "sync",
31957
+ summary: "Create or re-plan a fleet from a definition file or its stored config."
31958
+ },
31959
+ {
31960
+ name: "get",
31961
+ summary: "Read one fleet, list every fleet, or inspect drift."
31962
+ },
31963
+ {
31964
+ name: "deactivate",
31965
+ summary: "Deactivate a fleet and the monitors it owns."
31966
+ }
31967
+ ];
31968
+ var MONITOR_FLEET_AGENT_NOTES = [
31969
+ "Add --json for stable output; stdout is always exactly one JSON object.",
31970
+ "Every error includes a runnable `next` command \u2014 run it, do not guess.",
31971
+ "Exit 5 = retry the same command; 6 = inspect counts with `get --drift`; 7 = change the request."
31972
+ ];
31973
+ var MONITOR_FLEET_HELP_EPILOG = `
31974
+ Agent notes:
31975
+ ${MONITOR_FLEET_AGENT_NOTES.join("\n ")}
31976
+ `;
31977
+ var MonitorFleetStateError = class extends Error {
31978
+ code;
31979
+ next;
31980
+ constructor(input2) {
31981
+ super(input2.message);
31982
+ this.name = "MonitorFleetStateError";
31983
+ this.code = input2.code;
31984
+ this.next = input2.next;
31985
+ }
31986
+ };
31987
+ function fleetCounts(payload) {
31988
+ const raw = asRecord2(payload.counts) ?? {};
31989
+ const counts = {};
31990
+ for (const key of FLEET_COUNT_KEYS) {
31991
+ counts[key] = asFiniteNumber(raw[key]) ?? 0;
31992
+ }
31993
+ return counts;
31994
+ }
31995
+ function fleetShellArg(value) {
31996
+ return /^[A-Za-z0-9._/@:=-]+$/.test(value) ? value : `'${value.replaceAll("'", `'\\''`)}'`;
31997
+ }
31998
+ function fleetJsonFlag(options) {
31999
+ return options.json ? ["--json"] : [];
32000
+ }
32001
+ function fleetTimeoutMs(raw) {
32002
+ if (raw === void 0) return FLEET_DEFAULT_WAIT_MS;
32003
+ const match = /^(\d+)(ms|s|m|h)?$/.exec(raw.trim());
32004
+ if (!match) {
32005
+ throw new MonitorsUsageError(
32006
+ "--timeout must be a duration like 500ms, 90s, 10m, or 1h (a bare number is seconds)."
32007
+ );
32008
+ }
32009
+ const value = Number(match[1]);
32010
+ if (!value) {
32011
+ throw new MonitorsUsageError("--timeout must be greater than zero.");
32012
+ }
32013
+ const unit = match[2] ?? "s";
32014
+ const factor = unit === "ms" ? 1 : unit === "s" ? 1e3 : unit === "m" ? 6e4 : 36e5;
32015
+ return value * factor;
32016
+ }
32017
+ function fleetServerNext(payload) {
32018
+ return asString(payload.next) ?? asString(payload.next_action);
32019
+ }
32020
+ function fleetStatus(payload) {
32021
+ return asString(payload.status);
32022
+ }
32023
+ function fleetProgressReporter() {
32024
+ const interactive = process.stderr.isTTY === true;
32025
+ let wrote = false;
32026
+ let lastPlainAt = 0;
32027
+ return {
32028
+ report: (payload) => {
32029
+ const counts = fleetCounts(payload);
32030
+ const expected = asFiniteNumber(payload.expected) ?? FLEET_COUNT_KEYS.reduce((sum, key) => sum + counts[key], 0);
32031
+ const line = `settled ${counts.settled}/${expected} \xB7 rate_limited ${counts.rate_limited} \xB7 blocked ${counts.blocked}`;
32032
+ if (interactive) {
32033
+ process.stderr.write(`\r\x1B[2K${line}`);
32034
+ wrote = true;
32035
+ return;
32036
+ }
32037
+ const now = Date.now();
32038
+ if (wrote && now - lastPlainAt < FLEET_PLAIN_PROGRESS_INTERVAL_MS) return;
32039
+ lastPlainAt = now;
32040
+ wrote = true;
32041
+ process.stderr.write(`${line}
32042
+ `);
32043
+ },
32044
+ finish: () => {
32045
+ if (interactive && wrote) process.stderr.write("\n");
32046
+ }
32047
+ };
32048
+ }
32049
+ function fleetPlanLine(payload) {
32050
+ const plan = asRecord2(payload.plan) ?? {};
32051
+ const blocked = asRecord2(plan.blocked) ?? {};
32052
+ const entries = Object.entries(blocked).flatMap(([limitId, raw]) => {
32053
+ const count = asFiniteNumber(raw);
32054
+ return count === void 0 ? [] : [[limitId, count]];
32055
+ }).sort(([left], [right]) => left.localeCompare(right));
32056
+ const blockedTotal = entries.reduce((sum, [, count]) => sum + count, 0);
32057
+ const detail = entries.length === 0 ? "" : entries.length === 1 ? ` (${entries[0][0]})` : ` (${entries.map(([id, count]) => `${id}: ${count}`).join(", ")})`;
32058
+ return [
32059
+ `creates ${asFiniteNumber(plan.creates) ?? 0}`,
32060
+ `updates ${asFiniteNumber(plan.updates) ?? 0}`,
32061
+ `removes ${asFiniteNumber(plan.removes) ?? 0}`,
32062
+ `blocked ${blockedTotal}${detail}`
32063
+ ].join(" \xB7 ");
32064
+ }
32065
+ function fleetCountsLine(payload) {
32066
+ const counts = fleetCounts(payload);
32067
+ return FLEET_COUNT_KEYS.map((key) => `${key} ${counts[key]}`).join(" \xB7 ");
32068
+ }
32069
+ function renderFleetSync(payload, input2) {
32070
+ const lines = [
32071
+ input2.dryRun ? `Fleet ${input2.fleetId} \u2014 plan only, nothing changed` : `Fleet ${input2.fleetId} \u2014 accepted`,
32072
+ ` plan ${fleetPlanLine(payload)}`
32073
+ ];
32074
+ const credits = asFiniteNumber(payload.credits_due_now);
32075
+ lines.push(` credits due now ${credits ?? 0}`);
32076
+ lines.push(
32077
+ ` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 replayed ${yesNo(
32078
+ payload.replayed
32079
+ )} \xB7 idempotency key ${input2.idempotencyKey}`
32080
+ );
32081
+ const next = fleetServerNext(payload);
32082
+ if (next) lines.push(`Next: ${next}`);
32083
+ return `${lines.join("\n")}
32084
+ `;
32085
+ }
32086
+ function renderFleetGet(payload) {
32087
+ const id = asString(payload.id) ?? "unknown";
32088
+ const status = fleetStatus(payload) ?? "unknown";
32089
+ const lines = [
32090
+ `Fleet ${id} \u2014 ${status}`,
32091
+ ` monitors ${asFiniteNumber(payload.live) ?? 0} live / ${asFiniteNumber(payload.expected) ?? 0} expected`,
32092
+ ` counts ${fleetCountsLine(payload)}`,
32093
+ ` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
32094
+ ];
32095
+ lines.push(...renderFleetDriftRows(payload));
32096
+ const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
32097
+ if (next) lines.push(`Next: ${next}`);
32098
+ return `${lines.join("\n")}
32099
+ `;
32100
+ }
32101
+ function renderFleetDriftRows(payload) {
32102
+ const drift = Array.isArray(payload.drift) ? payload.drift : void 0;
32103
+ if (!drift) return [];
32104
+ const rows = drift.flatMap((raw) => {
32105
+ const row = asRecord2(raw);
32106
+ return row ? [row] : [];
32107
+ }).map((row) => ({
32108
+ monitorKey: asString(row.monitor_key) ?? "-",
32109
+ entityKey: asString(row.entity_key) ?? "-",
32110
+ convergence: asString(row.convergence) ?? "-",
32111
+ since: asString(row.since) ?? "-",
32112
+ 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)}` : "")
32113
+ })).sort(
32114
+ (left, right) => left.monitorKey.localeCompare(right.monitorKey) || left.entityKey.localeCompare(right.entityKey)
32115
+ );
32116
+ if (rows.length === 0) {
32117
+ return [` drift none${payload.truncated === true ? " (truncated)" : ""}`];
32118
+ }
32119
+ const width = (values) => values.reduce((max, value) => Math.max(max, value.length), 0);
32120
+ const monitorWidth = width(rows.map((row) => row.monitorKey));
32121
+ const entityWidth = width(rows.map((row) => row.entityKey));
32122
+ const convergenceWidth = width(rows.map((row) => row.convergence));
32123
+ const lines = [
32124
+ ` drift (${rows.length}${payload.truncated === true ? ", truncated" : ""})`
32125
+ ];
32126
+ for (const row of rows) {
32127
+ lines.push(
32128
+ ` ${row.monitorKey.padEnd(monitorWidth)} ${row.entityKey.padEnd(
32129
+ entityWidth
32130
+ )} ${row.convergence.padEnd(convergenceWidth)} ${row.since}${row.detail ? ` ${row.detail}` : ""}`
32131
+ );
32132
+ }
32133
+ return lines;
32134
+ }
32135
+ function renderFleetList(payload) {
32136
+ const fleets = (Array.isArray(payload.fleets) ? payload.fleets : []).flatMap((raw) => {
32137
+ const fleet = asRecord2(raw);
32138
+ return fleet ? [fleet] : [];
32139
+ }).sort(
32140
+ (left, right) => (asString(left.id) ?? "").localeCompare(asString(right.id) ?? "")
32141
+ );
32142
+ if (fleets.length === 0) {
32143
+ return "No Monitor Fleets in this workspace.\nNext: deepline monitors fleets init <fleet-id> --help\n";
32144
+ }
32145
+ const idWidth = fleets.reduce(
32146
+ (max, fleet) => Math.max(max, (asString(fleet.id) ?? "").length),
32147
+ 0
32148
+ );
32149
+ const statusWidth = fleets.reduce(
32150
+ (max, fleet) => Math.max(max, (fleetStatus(fleet) ?? "unknown").length),
32151
+ 0
32152
+ );
32153
+ const lines = [`Fleets (${fleets.length})`];
32154
+ for (const fleet of fleets) {
32155
+ const counts = fleetCounts(fleet);
32156
+ const trouble = [
32157
+ counts.blocked ? `blocked ${counts.blocked}` : "",
32158
+ counts.failed ? `failed ${counts.failed}` : ""
32159
+ ].filter(Boolean);
32160
+ lines.push(
32161
+ ` ${(asString(fleet.id) ?? "-").padEnd(idWidth)} ${(fleetStatus(fleet) ?? "unknown").padEnd(statusWidth)} ${asFiniteNumber(fleet.live) ?? 0}/${asFiniteNumber(fleet.expected) ?? 0}${trouble.length ? ` ${trouble.join(" \xB7 ")}` : ""}`
32162
+ );
32163
+ }
32164
+ return `${lines.join("\n")}
32165
+ `;
32166
+ }
32167
+ function renderFleetDeactivatePlan(payload, fleetId) {
32168
+ const radius = asRecord2(payload.would_deactivate) ?? {};
32169
+ const lines = [
32170
+ `Deactivate fleet ${fleetId} \u2014 plan only, nothing changed`,
32171
+ ` would deactivate ${asFiniteNumber(radius.monitors) ?? 0} monitors \xB7 ${asFiniteNumber(radius.accounts) ?? 0} accounts`
32172
+ ];
32173
+ const note = asString(payload.note);
32174
+ if (note) lines.push(` ${note}`);
32175
+ lines.push(
32176
+ `Next: ${fleetServerNext(payload) ?? `deepline monitors fleets deactivate ${fleetShellArg(fleetId)} --yes`}`
32177
+ );
32178
+ return `${lines.join("\n")}
32179
+ `;
32180
+ }
32181
+ function reportFleetState(payload, error, options) {
32182
+ printCommandEnvelope(
32183
+ {
32184
+ ...payload,
32185
+ code: error.code,
32186
+ message: error.message,
32187
+ next: error.next
32188
+ },
32189
+ {
32190
+ json: options.json,
32191
+ text: `${options.text}${error.message}
32192
+ Next: ${error.next}
32193
+ `
32194
+ }
32195
+ );
32196
+ process.exitCode = monitorsErrorExitCode(error);
32197
+ }
32198
+ function fleetSourceTable(value) {
32199
+ const [schema, table, extra] = value?.trim().split(".") ?? [];
32200
+ if (!schema || !table || extra || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(schema) || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(table)) {
32201
+ throw new MonitorsUsageError(
32202
+ "--source must be a Customer DB table in schema.table form."
32203
+ );
32204
+ }
32205
+ return { schema, table };
32206
+ }
32207
+ function fleetColumnName(value, flag) {
32208
+ const name = value?.trim();
32209
+ if (!name || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
32210
+ throw new MonitorsUsageError(`${flag} must be a SQL column identifier.`);
32211
+ }
32212
+ return name;
32213
+ }
32214
+ function fleetMemberLimit(value) {
32215
+ if (value === void 0) return 1e3;
32216
+ const limit = fleetIntegerOption(value, "--limit");
32217
+ if (!limit || limit > 1e3) {
32218
+ throw new MonitorsUsageError("--limit must be between 1 and 1,000.");
32219
+ }
32220
+ return limit;
32221
+ }
32222
+ function fleetOrderBy(values, sourceKey) {
32223
+ const parsed = (values ?? []).map((value) => {
32224
+ const match = /^([A-Za-z_][A-Za-z0-9_]*):(asc|desc)$/.exec(value.trim());
32225
+ if (!match) {
32226
+ throw new MonitorsUsageError(
32227
+ "--order-by must use column:asc or column:desc."
32228
+ );
32229
+ }
32230
+ return { column: match[1], direction: match[2] };
32231
+ });
32232
+ const seen = /* @__PURE__ */ new Set();
32233
+ for (const order of parsed) {
32234
+ if (seen.has(order.column)) {
32235
+ throw new MonitorsUsageError(
32236
+ `--order-by repeats '${order.column}'. Each column may appear once.`
32237
+ );
32238
+ }
32239
+ seen.add(order.column);
32240
+ }
32241
+ const sourceOrder = parsed.find((order) => order.column === sourceKey);
32242
+ return [
32243
+ ...parsed.filter((order) => order.column !== sourceKey),
32244
+ sourceOrder ?? { column: sourceKey, direction: "asc" }
32245
+ ];
32246
+ }
32247
+ async function handleMonitorFleetsInit(fleetId, options) {
32248
+ if (!/^[a-z][a-z0-9-]{0,199}$/.test(fleetId)) {
32249
+ throw new MonitorsUsageError("<fleet-id> must be lowercase kebab-case.");
32250
+ }
32251
+ const source = fleetSourceTable(options.source);
32252
+ const key = fleetColumnName(options.key, "--key");
32253
+ const keyType = options.keyType?.trim() ?? "text";
32254
+ if (!["text", "uuid", "int4", "int8"].includes(keyType)) {
32255
+ throw new MonitorsUsageError(
32256
+ "--key-type must be text, uuid, int4, or int8."
32257
+ );
32258
+ }
32259
+ const tool = options.tool?.trim();
32260
+ if (!tool) throw new MonitorsUsageError("--tool is required.");
32261
+ if (!options.payload) {
32262
+ throw new MonitorsUsageError(
32263
+ "--payload is required and must be the monitor payload JSON for --tool."
32264
+ );
32265
+ }
32266
+ const payload = parseJsonObjectArg(options.payload, "--payload");
32267
+ const where = options.where ? parseJsonObjectArg(options.where, "--where") : void 0;
32268
+ const out = options.out?.trim();
32269
+ if (!out) throw new MonitorsUsageError("--out is required.");
32270
+ const authoredDefinition = {
32271
+ id: fleetId,
32272
+ source: {
32273
+ kind: "customer_db_table",
32274
+ schema: source.schema,
32275
+ table: source.table,
32276
+ key: { column: key, type: keyType },
32277
+ ...where ? { where } : {}
32278
+ },
32279
+ member: {
32280
+ tool,
32281
+ key: {
32282
+ $fleet: "template",
32283
+ parts: [`${fleetId}-`, { $fleet: "column", name: key }]
32284
+ },
32285
+ payload
32286
+ },
32287
+ selection: {
32288
+ limit: fleetMemberLimit(options.limit),
32289
+ orderBy: fleetOrderBy(options.orderBy, key),
32290
+ membership: "sticky"
32291
+ }
32292
+ };
32293
+ const definition = requireCompiledFleetDefinition(authoredDefinition);
32294
+ const file = (0, import_node_path17.resolve)(out);
32295
+ (0, import_node_fs14.writeFileSync)(file, `${JSON.stringify(definition, null, 2)}
32296
+ `, "utf8");
32297
+ const next = `deepline monitors fleets sync --file ${fleetShellArg(file)} --dry-run --json`;
32298
+ printCommandEnvelope(
32299
+ { schemaVersion: 1, file, definition, next },
32300
+ {
32301
+ json: options.json,
32302
+ text: `Wrote ${file}
32303
+ Next: ${next}
32304
+ `
32305
+ }
32306
+ );
32307
+ }
32308
+ function requireCompiledFleetDefinition(definition) {
32309
+ const result = admitMonitorFleetAuthoringContract(definition);
32310
+ if (result.valid && result.contract) return result.contract.definition;
32311
+ const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
32312
+ throw new MonitorsUsageError(
32313
+ `Monitor Fleet definition failed local contract check. ${messages}
32314
+ Fix the file, then re-run: deepline monitors fleets sync --file <fleet.json> --dry-run`
32315
+ );
32316
+ }
32317
+ function fleetSyncCommandLine(target, options) {
32318
+ const parts = ["deepline monitors fleets sync"];
32319
+ if (options.file) parts.push(`--file ${fleetShellArg(options.file)}`);
32320
+ else if (target) parts.push(fleetShellArg(target));
32321
+ if (options.dryRun) parts.push("--dry-run");
32322
+ if (options.wait) parts.push("--wait");
32323
+ if (options.timeout)
32324
+ parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
32325
+ if (options.expectedGeneration !== void 0) {
32326
+ parts.push(
32327
+ `--expected-generation ${fleetShellArg(options.expectedGeneration)}`
32328
+ );
32329
+ }
32330
+ if (options.idempotencyKey) {
32331
+ parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
32332
+ }
32333
+ parts.push(...fleetJsonFlag(options));
32334
+ return parts.join(" ");
32335
+ }
32336
+ async function handleMonitorFleetsSync(target, options, idempotencyKey) {
32337
+ const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
32338
+ if (!usesDefinition && !target?.trim()) {
32339
+ throw new MonitorsUsageError(
32340
+ "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"
32341
+ );
32342
+ }
32343
+ const definition = usesDefinition ? requireCompiledFleetDefinition(
32344
+ resolveMonitorJsonBody({
32345
+ positional: target,
32346
+ file: options.file,
32347
+ argLabel: "<definition>",
32348
+ command: "deepline monitors fleets sync"
32349
+ })
32350
+ ) : void 0;
32351
+ const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
32352
+ if (!fleetId) {
32353
+ throw new MonitorsUsageError(
32354
+ 'The Fleet definition has no id. Add a top-level "id" and re-run.'
32355
+ );
32356
+ }
32357
+ const client2 = new DeeplineClient();
32358
+ const payload = await client2.monitors.fleets.sync(
32359
+ definition ?? fleetId,
32360
+ {
32361
+ ...options.dryRun ? { dryRun: true } : {},
32362
+ ...options.expectedGeneration !== void 0 ? {
32363
+ expectedGeneration: fleetIntegerOption(
32364
+ options.expectedGeneration,
32365
+ "--expected-generation"
32366
+ )
32367
+ } : {},
32368
+ idempotencyKey
32369
+ }
32370
+ );
32371
+ if (options.dryRun) {
32372
+ assertMonitorDryRunAcknowledged(payload, {
32373
+ command: "deepline monitors fleets sync",
32374
+ mutation: "fleet sync"
32375
+ });
32376
+ }
32377
+ const accepted = { ...payload, idempotency_key: idempotencyKey };
32378
+ if (!options.wait || options.dryRun) {
32379
+ printCommandEnvelope(accepted, {
32380
+ json: options.json,
32381
+ text: renderFleetSync(payload, {
32382
+ fleetId,
32383
+ dryRun: options.dryRun === true,
32384
+ idempotencyKey
32385
+ })
32386
+ });
32387
+ return;
32388
+ }
32389
+ const timeoutMs = fleetTimeoutMs(options.timeout);
32390
+ const progress = fleetProgressReporter();
32391
+ let final;
32392
+ try {
32393
+ final = await client2.monitors.fleets.waitForConvergence(fleetId, {
32394
+ timeoutMs,
32395
+ pollIntervalMs: FLEET_POLL_INTERVAL_MS,
32396
+ onProgress: progress.report
32397
+ });
32398
+ } finally {
32399
+ progress.finish();
32400
+ }
32401
+ const envelope = { ...accepted, ...final };
32402
+ const status = fleetStatus(final);
32403
+ const summary = renderFleetGet(final);
32404
+ if (status === "converged") {
32405
+ printCommandEnvelope(envelope, { json: options.json, text: summary });
32406
+ return;
32407
+ }
32408
+ const driftCommand = `deepline monitors fleets get ${fleetShellArg(fleetId)} --drift --json`;
32409
+ if (status === "degraded") {
32410
+ reportFleetState(
32411
+ envelope,
32412
+ new MonitorFleetStateError({
32413
+ code: "MONITOR_FLEET_DEGRADED",
32414
+ message: `Fleet ${fleetId} is degraded: some members will not converge without a change. Retrying sync will not fix it.`,
32415
+ next: fleetServerNext(final) ?? driftCommand
32416
+ }),
32417
+ { json: options.json, text: summary }
32418
+ );
32419
+ return;
32420
+ }
32421
+ reportFleetState(
32422
+ envelope,
32423
+ new MonitorFleetStateError({
32424
+ code: "MONITOR_FLEET_WAIT_TIMEOUT",
32425
+ message: `Stopped waiting after ${timeoutMs}ms. Nothing is broken and nothing was lost \u2014 fleet ${fleetId} is still ${status ?? "working"} on the server.`,
32426
+ next: fleetServerNext(final) ?? driftCommand
32427
+ }),
32428
+ { json: options.json, text: summary }
32429
+ );
32430
+ }
32431
+ async function handleMonitorFleetsGet(fleetId, options) {
32432
+ if (options.drift && !fleetId) {
32433
+ throw new MonitorsUsageError(
32434
+ "--drift needs a fleet id: deepline monitors fleets get <fleet-id> --drift"
32435
+ );
32436
+ }
32437
+ const limit = options.limit === void 0 ? void 0 : fleetIntegerOption(options.limit, "--limit");
32438
+ const client2 = new DeeplineClient();
32439
+ const payload = await client2.monitors.fleets.get(fleetId, {
32440
+ ...options.drift ? { drift: true } : {},
32441
+ ...limit !== void 0 ? { limit } : {}
32442
+ });
32443
+ const text = fleetId ? renderFleetGet(payload) : renderFleetList(payload);
32444
+ if (!options.check) {
32445
+ printCommandEnvelope(payload, { json: options.json, text });
32446
+ return;
32447
+ }
32448
+ const statuses = fleetId ? [fleetStatus(payload)] : (Array.isArray(payload.fleets) ? payload.fleets : []).map(
32449
+ (raw) => fleetStatus(asRecord2(raw) ?? {})
32450
+ );
32451
+ const unconverged = statuses.filter((status) => status !== "converged");
32452
+ if (unconverged.length === 0) {
32453
+ printCommandEnvelope(payload, { json: options.json, text });
32454
+ return;
32455
+ }
32456
+ const target = fleetId ?? "<fleet-id>";
32457
+ const degraded = unconverged.includes("degraded");
32458
+ reportFleetState(
32459
+ payload,
32460
+ new MonitorFleetStateError({
32461
+ code: degraded ? "MONITOR_FLEET_DEGRADED" : "MONITOR_FLEET_NOT_CONVERGED",
32462
+ message: degraded ? `Fleet ${target} is degraded: members are stuck and retrying will not move them.` : `Fleet ${target} has not converged yet.`,
32463
+ next: fleetServerNext(payload) ?? `deepline monitors fleets get ${fleetShellArg(target)} --drift --json`
32464
+ }),
32465
+ { json: options.json, text }
32466
+ );
32467
+ }
32468
+ function fleetDeactivateCommandLine(fleetId, options) {
32469
+ const parts = [
32470
+ "deepline monitors fleets deactivate",
32471
+ fleetShellArg(fleetId),
32472
+ "--yes"
32473
+ ];
32474
+ if (options.dryRun) parts.push("--dry-run");
32475
+ if (options.wait) parts.push("--wait");
32476
+ if (options.timeout)
32477
+ parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
32478
+ if (options.idempotencyKey) {
32479
+ parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
32480
+ }
32481
+ parts.push(...fleetJsonFlag(options));
32482
+ return parts.join(" ");
32483
+ }
32484
+ async function confirmFleetDeactivate(fleetId, plan) {
32485
+ process.stderr.write(renderFleetDeactivatePlan(plan, fleetId));
32486
+ const rl = (0, import_promises8.createInterface)({ input: process.stdin, output: process.stderr });
32487
+ try {
32488
+ const answer = await rl.question(
32489
+ `Deactivate fleet "${fleetId}" and the monitors it owns? [y/N] `
32490
+ );
32491
+ return /^y(es)?$/i.test(answer.trim());
32492
+ } finally {
32493
+ rl.close();
32494
+ }
32495
+ }
32496
+ async function handleMonitorFleetsDeactivate(fleetId, options, idempotencyKey) {
32497
+ const client2 = new DeeplineClient();
32498
+ if (options.dryRun) {
32499
+ const plan = await client2.monitors.fleets.deactivate(fleetId, {
32500
+ dryRun: true,
32501
+ idempotencyKey
32502
+ });
32503
+ assertMonitorDryRunAcknowledged(plan, {
32504
+ command: "deepline monitors fleets deactivate",
32505
+ mutation: "fleet deactivate"
32506
+ });
32507
+ printCommandEnvelope(plan, {
32508
+ json: options.json,
32509
+ text: renderFleetDeactivatePlan(plan, fleetId)
32510
+ });
32511
+ return;
32512
+ }
32513
+ if (!options.yes) {
32514
+ const interactive = process.stdout.isTTY === true && process.stdin.isTTY === true;
32515
+ if (!interactive) {
32516
+ throw new MonitorsUsageError(
32517
+ `deactivate is destructive: it deactivates fleet "${fleetId}" and every monitor it owns. Non-interactive runs must confirm with --yes:
32518
+ ${fleetDeactivateCommandLine(fleetId, options)}
32519
+ Preview the blast radius first:
32520
+ deepline monitors fleets deactivate ${fleetShellArg(fleetId)} --dry-run`
32521
+ );
32522
+ }
32523
+ const plan = await client2.monitors.fleets.deactivate(fleetId, {
32524
+ dryRun: true,
32525
+ idempotencyKey: `${idempotencyKey}-plan`
32526
+ });
32527
+ assertMonitorDryRunAcknowledged(plan, {
32528
+ command: "deepline monitors fleets deactivate",
32529
+ mutation: "fleet deactivate"
32530
+ });
32531
+ if (!await confirmFleetDeactivate(fleetId, plan)) {
32532
+ process.stderr.write(
32533
+ `Aborted. Fleet "${fleetId}" was not deactivated.
32534
+ `
32535
+ );
32536
+ process.exitCode = 2;
32537
+ return;
32538
+ }
32539
+ }
32540
+ const payload = await client2.monitors.fleets.deactivate(fleetId, {
32541
+ idempotencyKey
32542
+ });
32543
+ const accepted = { ...payload, idempotency_key: idempotencyKey };
32544
+ if (payload.already === true) {
32545
+ printCommandEnvelope(accepted, {
32546
+ json: options.json,
32547
+ text: `Fleet ${fleetId} is already deactivated.
32548
+ `
32549
+ });
32550
+ return;
32551
+ }
32552
+ const acceptedText = `Fleet ${fleetId} \u2014 ${asString(payload.status) ?? "deactivating"}
32553
+ idempotency key ${idempotencyKey}
32554
+ ` + (fleetServerNext(payload) ? `Next: ${fleetServerNext(payload)}
32555
+ ` : "");
32556
+ if (!options.wait) {
32557
+ printCommandEnvelope(accepted, {
32558
+ json: options.json,
32559
+ text: acceptedText
32560
+ });
32561
+ return;
32562
+ }
32563
+ const timeoutMs = fleetTimeoutMs(options.timeout);
32564
+ const progress = fleetProgressReporter();
32565
+ let final;
32566
+ try {
32567
+ final = await client2.monitors.fleets.waitForConvergence(fleetId, {
32568
+ timeoutMs,
32569
+ pollIntervalMs: FLEET_POLL_INTERVAL_MS,
32570
+ onProgress: progress.report,
32571
+ until: "deactivated"
32572
+ });
32573
+ } finally {
32574
+ progress.finish();
32575
+ }
32576
+ const envelope = { ...accepted, ...final };
32577
+ const summary = renderFleetGet(final);
32578
+ if (fleetStatus(final) === "deactivated") {
32579
+ printCommandEnvelope(envelope, { json: options.json, text: summary });
32580
+ return;
32581
+ }
32582
+ reportFleetState(
32583
+ envelope,
32584
+ new MonitorFleetStateError({
32585
+ code: "MONITOR_FLEET_WAIT_TIMEOUT",
32586
+ message: `Stopped waiting after ${timeoutMs}ms. Deactivation of fleet ${fleetId} is still in progress on the server; nothing was lost.`,
32587
+ next: fleetServerNext(final) ?? `deepline monitors fleets get ${fleetShellArg(fleetId)} --json`
32588
+ }),
32589
+ { json: options.json, text: summary }
32590
+ );
32591
+ }
32592
+ function handleMonitorFleetsOverview(options) {
32593
+ const lines = [
32594
+ "Monitor Fleets \u2014 one Customer DB table row, one ordinary monitor.",
32595
+ "",
32596
+ "Lifecycle:",
32597
+ ...MONITOR_FLEET_LIFECYCLE.flatMap((entry) => [
32598
+ ` ${entry.step}. ${entry.what}`,
32599
+ ` ${entry.command}`
32600
+ ]),
32601
+ "",
32602
+ "Commands:",
32603
+ ...MONITOR_FLEET_COMMANDS.map(
32604
+ (command) => ` ${command.name.padEnd(12)}${command.summary}`
32605
+ ),
32606
+ "",
32607
+ "Agent notes:",
32608
+ ...MONITOR_FLEET_AGENT_NOTES.map((note) => ` ${note}`)
32609
+ ];
32610
+ printCommandEnvelope(
32611
+ {
32612
+ schemaVersion: 1,
32613
+ lifecycle: MONITOR_FLEET_LIFECYCLE,
32614
+ commands: MONITOR_FLEET_COMMANDS,
32615
+ agent_notes: MONITOR_FLEET_AGENT_NOTES,
32616
+ next: MONITOR_FLEET_LIFECYCLE[0].command
32617
+ },
32618
+ { json: options.json, text: `${lines.join("\n")}
32619
+ ` }
32620
+ );
32621
+ }
31467
32622
  function renderMonitorGet(payload) {
31468
32623
  const key = asString(payload.key);
31469
32624
  const tool = asString(payload.tool);
@@ -31713,7 +32868,9 @@ Notes:
31713
32868
 
31714
32869
  Exit codes:
31715
32870
  0 success; 2 usage/local input; 3 auth or permission; 4 not found;
31716
- 5 server failure; 7 validation failed.
32871
+ 5 server failure (retry the same command); 6 not at the desired state
32872
+ (fleets: degraded, or --wait/--check stopped while healthy \u2014 retrying
32873
+ changes nothing); 7 refused, change the request.
31717
32874
  \`monitors status\` exits 1 when you lack monitor access (documented contract).
31718
32875
 
31719
32876
  Examples:
@@ -31984,6 +33141,181 @@ Examples:
31984
33141
  `
31985
33142
  ).option("--dry-run", "Show the reactivation cost without reactivating")
31986
33143
  ).action(monitorsAction(handleMonitorsReactivate));
33144
+ const fleets = monitors.command("fleets").description("Define and reconcile table-backed Monitor Fleets.").addHelpText(
33145
+ "after",
33146
+ `
33147
+ Notes:
33148
+ A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
33149
+ monitors. Fleet definitions are canonical JSON, and \`sync\` is the only verb
33150
+ that changes one: applying the same definition twice is the same operation,
33151
+ so the server answers \`replayed: true\` instead of building a second fleet.
33152
+ The fleet's status is computed by Deepline; this CLI reports it and never
33153
+ recomputes a verdict from the counts.
33154
+
33155
+ Exit codes:
33156
+ 0 converged or done; 2 usage or local validation; 3 auth; 4 not found;
33157
+ 5 server failure (retry the same command); 6 not at the desired state
33158
+ (degraded, or --wait/--check stopped while healthy); 7 refused (change the
33159
+ request).
33160
+
33161
+ Lifecycle:
33162
+ ${MONITOR_FLEET_LIFECYCLE.map(
33163
+ (entry) => ` ${entry.step}. ${entry.command}`
33164
+ ).join("\n")}
33165
+ ${MONITOR_FLEET_HELP_EPILOG}`
33166
+ ).action(
33167
+ monitorsAction(async (options) => {
33168
+ handleMonitorFleetsOverview(options);
33169
+ })
33170
+ );
33171
+ withJsonOption(fleets);
33172
+ withJsonOption(
33173
+ fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
33174
+ "after",
33175
+ `
33176
+ Creates a ready-to-review JSON definition. Fleets always sync ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.cadence} and retain
33177
+ a missing member for ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.removalGrace} before it is ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.onRemoved}d; those
33178
+ policies are not authored in the file. ${MONITOR_FLEET_DOCUMENTATION.stickyMembership} The payload remains the actual monitor payload for the chosen tool, so use
33179
+ \`deepline monitors available\` to discover a tool first.
33180
+
33181
+ Example:
33182
+ deepline monitors fleets init account-job-openings \\
33183
+ --source public.accounts --key account_id --key-type uuid \\
33184
+ --tool deepline_native.company_radar \\
33185
+ --payload '{"domain":{"$fleet":"column","name":"domain"},"radar_type":"company_job_openings"}' \\
33186
+ --order-by intent_score:desc \\
33187
+ --out fleet.json
33188
+ `
33189
+ ).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(
33190
+ "--payload <json>",
33191
+ "Monitor payload JSON for --tool; use $fleet column tags for row values"
33192
+ ).option(
33193
+ "--where <json>",
33194
+ "Optional source-row equality filter JSON; not arbitrary SQL"
33195
+ ).option(
33196
+ "--order-by <column:direction>",
33197
+ "Rank candidates; repeatable, with the source key appended for stability",
33198
+ (value, previous = []) => [...previous, value],
33199
+ []
33200
+ ).option(
33201
+ "--limit <n>",
33202
+ "Maximum active members; ranking changes do not churn sticky members (default 1,000)"
33203
+ ).requiredOption("--out <path>", "Write the definition JSON to this path")
33204
+ ).action(monitorsAction(handleMonitorFleetsInit));
33205
+ withJsonOption(
33206
+ fleets.command("sync [fleet-id]").description(
33207
+ "Apply a Fleet definition, or re-plan an existing fleet from its stored one."
33208
+ ).addHelpText(
33209
+ "after",
33210
+ `
33211
+ Notes:
33212
+ --file (or an inline definition, or --file - for stdin) is compiled locally
33213
+ BEFORE any network call: a definition that fails the contract exits 2 and
33214
+ never becomes a request. A bare <fleet-id> re-plans the stored definition.
33215
+ The plan always shows blocked members; they are never hidden.
33216
+ --wait polls until Deepline reports a terminal status: converged exits 0,
33217
+ degraded exits 6, and a timeout exits 6 without implying anything broke.
33218
+ Progress goes to stderr, so stdout stays exactly one JSON object.
33219
+
33220
+ Examples:
33221
+ deepline monitors fleets sync --file fleet.json --dry-run
33222
+ deepline monitors fleets sync --file fleet.json --wait --timeout 20m
33223
+ deepline monitors fleets sync account-job-openings --wait --json
33224
+ cat fleet.json | deepline monitors fleets sync --file - --dry-run --json
33225
+ `
33226
+ ).option(
33227
+ "-f, --file <path>",
33228
+ "Apply definition JSON from a file, or - for stdin"
33229
+ ).option(
33230
+ "--dry-run",
33231
+ "Show the plan and the credits due without changing state"
33232
+ ).option("--wait", "Poll until the fleet reaches a terminal status").option(
33233
+ "--timeout <duration>",
33234
+ "How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
33235
+ ).option(
33236
+ "--expected-generation <generation>",
33237
+ "Refuse the write unless the fleet is at this generation"
33238
+ ).option(
33239
+ "--idempotency-key <key>",
33240
+ "Stable retry key (generated and returned when omitted)"
33241
+ )
33242
+ ).action(async (target, options) => {
33243
+ let retryCommand = fleetSyncCommandLine(target, options);
33244
+ try {
33245
+ const idempotencyKey = fleetIdempotencyKey(
33246
+ "sync",
33247
+ options.idempotencyKey
33248
+ );
33249
+ retryCommand = fleetSyncCommandLine(target, {
33250
+ ...options,
33251
+ idempotencyKey
33252
+ });
33253
+ await handleMonitorFleetsSync(target, options, idempotencyKey);
33254
+ } catch (error) {
33255
+ reportMonitorsFailure(error, { retryCommand });
33256
+ }
33257
+ });
33258
+ withJsonOption(
33259
+ fleets.command("get [fleet-id]").description(
33260
+ "Read one fleet, or list every fleet when the id is omitted."
33261
+ ).addHelpText(
33262
+ "after",
33263
+ `
33264
+ Notes:
33265
+ Status is the server's verdict. --check turns it into an exit code so a
33266
+ script can branch without parsing output: 0 converged, 6 anything else.
33267
+ --drift lists the members that have not settled and why.
33268
+
33269
+ Examples:
33270
+ deepline monitors fleets get --json
33271
+ deepline monitors fleets get account-job-openings --json
33272
+ deepline monitors fleets get account-job-openings --drift --limit 50 --json
33273
+ deepline monitors fleets get account-job-openings --check
33274
+ `
33275
+ ).option("--drift", "Include the members that have not settled, and why").option("--limit <n>", "Maximum drift rows to return").option(
33276
+ "--check",
33277
+ "Exit 0 when converged and 6 otherwise, for scripts and agents"
33278
+ )
33279
+ ).action(monitorsAction(handleMonitorFleetsGet));
33280
+ withJsonOption(
33281
+ fleets.command("deactivate <fleet-id>").description("Deactivate a fleet and the monitors it owns.").addHelpText(
33282
+ "after",
33283
+ `
33284
+ Notes:
33285
+ Destructive. --dry-run shows the blast radius without changing anything.
33286
+ An interactive terminal is shown that blast radius and asked to confirm;
33287
+ a non-interactive run must pass --yes. Re-running after a failure is safe.
33288
+
33289
+ Examples:
33290
+ deepline monitors fleets deactivate account-job-openings --dry-run
33291
+ deepline monitors fleets deactivate account-job-openings --yes --wait --json
33292
+ `
33293
+ ).option("--dry-run", "Show the blast radius without deactivating").option("--wait", "Poll until the fleet reports deactivated").option(
33294
+ "--timeout <duration>",
33295
+ "How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
33296
+ ).option(
33297
+ "--yes",
33298
+ "Skip the confirmation prompt (required non-interactively)"
33299
+ ).option(
33300
+ "--idempotency-key <key>",
33301
+ "Stable retry key (generated and returned when omitted)"
33302
+ )
33303
+ ).action(async (fleetId, options) => {
33304
+ let retryCommand = fleetDeactivateCommandLine(fleetId, options);
33305
+ try {
33306
+ const idempotencyKey = fleetIdempotencyKey(
33307
+ "deactivate",
33308
+ options.idempotencyKey
33309
+ );
33310
+ retryCommand = fleetDeactivateCommandLine(fleetId, {
33311
+ ...options,
33312
+ idempotencyKey
33313
+ });
33314
+ await handleMonitorFleetsDeactivate(fleetId, options, idempotencyKey);
33315
+ } catch (error) {
33316
+ reportMonitorsFailure(error, { retryCommand });
33317
+ }
33318
+ });
31987
33319
  const deployed = withJsonOption(
31988
33320
  monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
31989
33321
  "--status <status>",
@@ -32686,7 +34018,7 @@ async function readHiddenLine(prompt, streams = {}) {
32686
34018
  }
32687
34019
  let value = "";
32688
34020
  inputStream.resume();
32689
- return await new Promise((resolve20, reject) => {
34021
+ return await new Promise((resolve21, reject) => {
32690
34022
  let settled = false;
32691
34023
  const cleanup = () => {
32692
34024
  inputStream.off("data", onData);
@@ -32704,7 +34036,7 @@ async function readHiddenLine(prompt, streams = {}) {
32704
34036
  settled = true;
32705
34037
  outputStream.write("\n");
32706
34038
  cleanup();
32707
- resolve20(line);
34039
+ resolve21(line);
32708
34040
  };
32709
34041
  const fail = (error) => {
32710
34042
  if (settled) return;
@@ -32878,11 +34210,11 @@ Examples:
32878
34210
  var import_node_child_process4 = require("child_process");
32879
34211
  var import_node_fs18 = require("fs");
32880
34212
  var import_node_os12 = require("os");
32881
- var import_node_path20 = require("path");
34213
+ var import_node_path21 = require("path");
32882
34214
 
32883
34215
  // src/cli/installation-lifecycle.ts
32884
34216
  var import_node_fs15 = require("fs");
32885
- var import_node_path17 = require("path");
34217
+ var import_node_path18 = require("path");
32886
34218
  var nodeFileSystem = {
32887
34219
  exists: import_node_fs15.existsSync,
32888
34220
  isSymbolicLink(path) {
@@ -32938,25 +34270,25 @@ var CliInstallation = class _CliInstallation {
32938
34270
  });
32939
34271
  }
32940
34272
  static isNpmPackagePath(path) {
32941
- return path?.includes(`${(0, import_node_path17.join)("node_modules", "deepline")}`) ?? false;
34273
+ return path?.includes(`${(0, import_node_path18.join)("node_modules", "deepline")}`) ?? false;
32942
34274
  }
32943
34275
  launcher(path) {
32944
34276
  return inspectLauncher(path, this.input.fileSystem);
32945
34277
  }
32946
34278
  retiredArtifacts() {
32947
- const hostDir = (0, import_node_path17.join)(
34279
+ const hostDir = (0, import_node_path18.join)(
32948
34280
  this.input.home,
32949
34281
  ".local",
32950
34282
  "deepline",
32951
34283
  this.input.baseUrlSlug
32952
34284
  );
32953
- const legacyLauncherPath = (0, import_node_path17.join)(
34285
+ const legacyLauncherPath = (0, import_node_path18.join)(
32954
34286
  this.input.home,
32955
34287
  ".local",
32956
34288
  "bin",
32957
34289
  "deepline"
32958
34290
  );
32959
- const installerCommandPath = this.input.fileSystem.read((0, import_node_path17.join)(hostDir, "sdk", ".command-path")).trim();
34291
+ const installerCommandPath = this.input.fileSystem.read((0, import_node_path18.join)(hostDir, "sdk", ".command-path")).trim();
32960
34292
  const ownedInstallerCommand = isOwnedInstallerCommandPath({
32961
34293
  hostDir,
32962
34294
  commandPath: installerCommandPath
@@ -32964,16 +34296,16 @@ var CliInstallation = class _CliInstallation {
32964
34296
  const legacyLauncher = this.launcher(legacyLauncherPath);
32965
34297
  const candidates = [
32966
34298
  ...legacyLauncher.ownership === "installer_legacy" ? [legacyLauncherPath] : [],
32967
- (0, import_node_path17.join)(this.input.home, ".local", "bin", "deepline-real"),
32968
- (0, import_node_path17.join)(hostDir, "bin", "deepline"),
32969
- (0, import_node_path17.join)(hostDir, "bin", "deepline-real"),
32970
- (0, import_node_path17.join)(hostDir, "cli", ".install-method"),
32971
- (0, import_node_path17.join)(hostDir, "cli", ".version"),
32972
- (0, import_node_path17.join)(hostDir, "sdk", ".install-method"),
32973
- (0, import_node_path17.join)(hostDir, "sdk", ".command-path"),
34299
+ (0, import_node_path18.join)(this.input.home, ".local", "bin", "deepline-real"),
34300
+ (0, import_node_path18.join)(hostDir, "bin", "deepline"),
34301
+ (0, import_node_path18.join)(hostDir, "bin", "deepline-real"),
34302
+ (0, import_node_path18.join)(hostDir, "cli", ".install-method"),
34303
+ (0, import_node_path18.join)(hostDir, "cli", ".version"),
34304
+ (0, import_node_path18.join)(hostDir, "sdk", ".install-method"),
34305
+ (0, import_node_path18.join)(hostDir, "sdk", ".command-path"),
32974
34306
  ...ownedInstallerCommand ? [
32975
34307
  installerCommandPath,
32976
- (0, import_node_path17.join)((0, import_node_path17.dirname)(installerCommandPath), "deepline-sdk")
34308
+ (0, import_node_path18.join)((0, import_node_path18.dirname)(installerCommandPath), "deepline-sdk")
32977
34309
  ] : []
32978
34310
  ];
32979
34311
  return {
@@ -32994,11 +34326,11 @@ function removeArtifacts(plan, fileSystem) {
32994
34326
  return plan.paths;
32995
34327
  }
32996
34328
  function isOwnedInstallerCommandPath(input2) {
32997
- if (!input2.commandPath || (0, import_node_path17.basename)(input2.commandPath) !== "deepline") {
34329
+ if (!input2.commandPath || (0, import_node_path18.basename)(input2.commandPath) !== "deepline") {
32998
34330
  return false;
32999
34331
  }
33000
- const commandPath = (0, import_node_path17.resolve)(input2.commandPath);
33001
- const fromHost = (0, import_node_path17.relative)((0, import_node_path17.resolve)(input2.hostDir), commandPath);
34332
+ const commandPath = (0, import_node_path18.resolve)(input2.commandPath);
34333
+ const fromHost = (0, import_node_path18.relative)((0, import_node_path18.resolve)(input2.hostDir), commandPath);
33002
34334
  return fromHost !== "" && fromHost !== ".." && !fromHost.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`);
33003
34335
  }
33004
34336
 
@@ -33006,7 +34338,7 @@ function isOwnedInstallerCommandPath(input2) {
33006
34338
  var import_node_child_process3 = require("child_process");
33007
34339
  var import_node_fs17 = require("fs");
33008
34340
  var import_node_os11 = require("os");
33009
- var import_node_path19 = require("path");
34341
+ var import_node_path20 = require("path");
33010
34342
 
33011
34343
  // ../../shared_libs/cli/install-commands.json
33012
34344
  var install_commands_default = {
@@ -33117,7 +34449,7 @@ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
33117
34449
  // src/cli/skills-sync.ts
33118
34450
  var import_node_child_process2 = require("child_process");
33119
34451
  var import_node_fs16 = require("fs");
33120
- var import_node_path18 = require("path");
34452
+ var import_node_path19 = require("path");
33121
34453
 
33122
34454
  // src/cli/windows-arg-escape.ts
33123
34455
  var CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
@@ -33152,10 +34484,10 @@ function shouldSkipSkillsSync() {
33152
34484
  return value === "1" || value === "true" || value === "yes" || value === "on";
33153
34485
  }
33154
34486
  function unavailableSkillsNoticePath(baseUrl) {
33155
- return (0, import_node_path18.join)(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
34487
+ return (0, import_node_path19.join)(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
33156
34488
  }
33157
34489
  function failedSkillsSyncPath(baseUrl, agents) {
33158
- return (0, import_node_path18.join)(
34490
+ return (0, import_node_path19.join)(
33159
34491
  sdkCliStateDirPath(baseUrl),
33160
34492
  `skills-sync-failed-${agents.join("-")}-version`
33161
34493
  );
@@ -33172,7 +34504,7 @@ function readMarkedSkillsSyncVersion(path) {
33172
34504
  }
33173
34505
  function writeMarkedSkillsSyncVersion(path, version) {
33174
34506
  try {
33175
- (0, import_node_fs16.mkdirSync)((0, import_node_path18.dirname)(path), { recursive: true });
34507
+ (0, import_node_fs16.mkdirSync)((0, import_node_path19.dirname)(path), { recursive: true });
33176
34508
  (0, import_node_fs16.writeFileSync)(path, `${version}
33177
34509
  `, "utf-8");
33178
34510
  } catch {
@@ -33326,7 +34658,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
33326
34658
  return commands;
33327
34659
  }
33328
34660
  function runOneSkillsInstall(install) {
33329
- return new Promise((resolve20) => {
34661
+ return new Promise((resolve21) => {
33330
34662
  const plan = resolveSkillsInstallSpawn(install);
33331
34663
  const child = (0, import_node_child_process2.spawn)(plan.command, plan.args, {
33332
34664
  stdio: ["ignore", "ignore", "pipe"],
@@ -33338,7 +34670,7 @@ function runOneSkillsInstall(install) {
33338
34670
  stderr += chunk.toString("utf-8");
33339
34671
  });
33340
34672
  child.on("error", (error) => {
33341
- resolve20({
34673
+ resolve21({
33342
34674
  ok: false,
33343
34675
  detail: `failed to start ${install.command}: ${error.message}`,
33344
34676
  manualCommand: install.manualCommand
@@ -33346,11 +34678,11 @@ function runOneSkillsInstall(install) {
33346
34678
  });
33347
34679
  child.on("close", (code) => {
33348
34680
  if (code === 0) {
33349
- resolve20({ ok: true, detail: "", manualCommand: install.manualCommand });
34681
+ resolve21({ ok: true, detail: "", manualCommand: install.manualCommand });
33350
34682
  return;
33351
34683
  }
33352
34684
  const detail = stderr.trim();
33353
- resolve20({
34685
+ resolve21({
33354
34686
  ok: false,
33355
34687
  detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
33356
34688
  manualCommand: install.manualCommand
@@ -33552,13 +34884,13 @@ function detectSkillsAgents(input2) {
33552
34884
  ];
33553
34885
  const detected = AGENT_MARKERS.filter(
33554
34886
  (marker) => roots.some(
33555
- (root) => marker.paths.some((path) => (0, import_node_fs17.existsSync)((0, import_node_path19.join)(root, path)))
34887
+ (root) => marker.paths.some((path) => (0, import_node_fs17.existsSync)((0, import_node_path20.join)(root, path)))
33556
34888
  )
33557
34889
  ).map((marker) => marker.agent);
33558
34890
  return detected.length > 0 ? detected : ["*"];
33559
34891
  }
33560
34892
  function skillsStatePathForScope(baseUrl, scope, root) {
33561
- return scope === "local" && root ? (0, import_node_path19.join)(root, ".deepline", "setup", "skills.json") : (0, import_node_path19.join)(sdkCliStateDirPath(baseUrl), "skills-install.json");
34893
+ return scope === "local" && root ? (0, import_node_path20.join)(root, ".deepline", "setup", "skills.json") : (0, import_node_path20.join)(sdkCliStateDirPath(baseUrl), "skills-install.json");
33562
34894
  }
33563
34895
  function buildSkillsPlan(input2) {
33564
34896
  const scopeArgs = input2.scope === "global" ? ["--global"] : [];
@@ -33632,7 +34964,7 @@ function readSkillsInstallState(path) {
33632
34964
  }
33633
34965
  }
33634
34966
  function runProcess(command, args, cwd) {
33635
- return new Promise((resolve20, reject) => {
34967
+ return new Promise((resolve21, reject) => {
33636
34968
  const plan = resolveShellSpawn(command, args);
33637
34969
  const child = (0, import_node_child_process3.spawn)(plan.command, plan.args, {
33638
34970
  cwd,
@@ -33651,7 +34983,7 @@ function runProcess(command, args, cwd) {
33651
34983
  process.stderr.write(`${SKILLS_NPX_PACKAGE} exited ${code}.
33652
34984
  `);
33653
34985
  }
33654
- resolve20(code ?? 1);
34986
+ resolve21(code ?? 1);
33655
34987
  });
33656
34988
  });
33657
34989
  }
@@ -33778,7 +35110,7 @@ async function runSkillsCommand(options, dependencies = {}) {
33778
35110
  `
33779
35111
  );
33780
35112
  }
33781
- (0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(plan.statePath), { recursive: true });
35113
+ (0, import_node_fs17.mkdirSync)((0, import_node_path20.dirname)(plan.statePath), { recursive: true });
33782
35114
  (0, import_node_fs17.writeFileSync)(
33783
35115
  plan.statePath,
33784
35116
  `${JSON.stringify(
@@ -33874,26 +35206,26 @@ function parseSetupPhases(value) {
33874
35206
  if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
33875
35207
  return null;
33876
35208
  }
33877
- const record = phase;
33878
- if (!isSetupPhaseStatus(record.status)) return null;
33879
- switch (record.status) {
35209
+ const record2 = phase;
35210
+ if (!isSetupPhaseStatus(record2.status)) return null;
35211
+ switch (record2.status) {
33880
35212
  case "pending":
33881
35213
  case "in_progress":
33882
- phases[name] = { status: record.status };
35214
+ phases[name] = { status: record2.status };
33883
35215
  break;
33884
35216
  case "complete":
33885
35217
  phases[name] = {
33886
35218
  status: "complete",
33887
- ...typeof record.outcome === "string" ? { outcome: record.outcome } : {}
35219
+ ...typeof record2.outcome === "string" ? { outcome: record2.outcome } : {}
33888
35220
  };
33889
35221
  break;
33890
35222
  case "waiting":
33891
- if (typeof record.outcome !== "string") return null;
33892
- phases[name] = { status: "waiting", outcome: record.outcome };
35223
+ if (typeof record2.outcome !== "string") return null;
35224
+ phases[name] = { status: "waiting", outcome: record2.outcome };
33893
35225
  break;
33894
35226
  case "failed":
33895
- if (typeof record.code !== "string") return null;
33896
- phases[name] = { status: "failed", code: record.code };
35227
+ if (typeof record2.code !== "string") return null;
35228
+ phases[name] = { status: "failed", code: record2.code };
33897
35229
  break;
33898
35230
  }
33899
35231
  }
@@ -33993,7 +35325,7 @@ function buildPendingAuthorizationOutput(input2) {
33993
35325
  };
33994
35326
  }
33995
35327
  function setupStatePath(baseUrl, scope, root) {
33996
- return scope === "local" && root ? (0, import_node_path20.join)(root, ".deepline", "setup", "state.json") : (0, import_node_path20.join)(sdkCliStateDirPath(baseUrl), "setup.json");
35328
+ return scope === "local" && root ? (0, import_node_path21.join)(root, ".deepline", "setup", "state.json") : (0, import_node_path21.join)(sdkCliStateDirPath(baseUrl), "setup.json");
33997
35329
  }
33998
35330
  async function captureStdout2(run) {
33999
35331
  let stdout = "";
@@ -34041,7 +35373,7 @@ function resolvePathCommands(command) {
34041
35373
  );
34042
35374
  return [
34043
35375
  ...new Set(
34044
- String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => (0, import_node_path20.resolve)(path))
35376
+ String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => (0, import_node_path21.resolve)(path))
34045
35377
  )
34046
35378
  ];
34047
35379
  }
@@ -34074,7 +35406,7 @@ function resolvePersistentGlobalCommand(dependencies = {}) {
34074
35406
  if (prefix.status !== 0) return null;
34075
35407
  const root = String(prefix.stdout ?? "").trim();
34076
35408
  if (!root) return null;
34077
- const candidates = platform3 === "win32" ? [(0, import_node_path20.join)(root, "deepline.cmd"), (0, import_node_path20.join)(root, "deepline")] : [(0, import_node_path20.join)(root, "bin", "deepline")];
35409
+ const candidates = platform3 === "win32" ? [(0, import_node_path21.join)(root, "deepline.cmd"), (0, import_node_path21.join)(root, "deepline")] : [(0, import_node_path21.join)(root, "bin", "deepline")];
34078
35410
  return candidates.find((candidate) => pathExists(candidate)) ?? null;
34079
35411
  }
34080
35412
  function inspectGlobalCliAvailability(input2) {
@@ -34089,18 +35421,18 @@ function pathsResolveToSameFile(left, right) {
34089
35421
  try {
34090
35422
  return (0, import_node_fs18.realpathSync)(left) === (0, import_node_fs18.realpathSync)(right);
34091
35423
  } catch {
34092
- return (0, import_node_path20.resolve)(left) === (0, import_node_path20.resolve)(right);
35424
+ return (0, import_node_path21.resolve)(left) === (0, import_node_path21.resolve)(right);
34093
35425
  }
34094
35426
  }
34095
35427
  function isKnownDeeplineCommand(path) {
34096
- const entrypoint = process.argv[1] ? (0, import_node_path20.resolve)(process.argv[1]) : "";
35428
+ const entrypoint = process.argv[1] ? (0, import_node_path21.resolve)(process.argv[1]) : "";
34097
35429
  let resolvedPath = path;
34098
35430
  try {
34099
35431
  resolvedPath = (0, import_node_fs18.realpathSync)(path);
34100
35432
  } catch {
34101
35433
  }
34102
35434
  if (entrypoint && resolvedPath === entrypoint) return true;
34103
- if (resolvedPath.includes(`${(0, import_node_path20.join)("node_modules", "deepline")}`)) return true;
35435
+ if (resolvedPath.includes(`${(0, import_node_path21.join)("node_modules", "deepline")}`)) return true;
34104
35436
  const content = safeRead(path);
34105
35437
  return content.includes("node_modules/deepline") || content.includes("node_modules\\deepline") || content.includes("DEEPLINE_CONFIG_SCOPE") || content.includes("deepline-real");
34106
35438
  }
@@ -34110,7 +35442,7 @@ function inspectPathConflict() {
34110
35442
  try {
34111
35443
  if ((0, import_node_fs18.lstatSync)(commandPath).isSymbolicLink()) {
34112
35444
  const target = (0, import_node_fs18.realpathSync)(commandPath);
34113
- if (target.includes(`${(0, import_node_path20.join)("node_modules", "deepline")}`)) return null;
35445
+ if (target.includes(`${(0, import_node_path21.join)("node_modules", "deepline")}`)) return null;
34114
35446
  }
34115
35447
  } catch {
34116
35448
  }
@@ -34118,7 +35450,7 @@ function inspectPathConflict() {
34118
35450
  }
34119
35451
  function writeSetupState(input2) {
34120
35452
  const path = setupStatePath(input2.baseUrl, input2.scope, input2.root);
34121
- (0, import_node_fs18.mkdirSync)((0, import_node_path20.dirname)(path), { recursive: true });
35453
+ (0, import_node_fs18.mkdirSync)((0, import_node_path21.dirname)(path), { recursive: true });
34122
35454
  (0, import_node_fs18.writeFileSync)(
34123
35455
  path,
34124
35456
  `${JSON.stringify(
@@ -34159,7 +35491,7 @@ function failSetupPhase(phases, phase, code) {
34159
35491
  phases[phase] = { status: "failed", code };
34160
35492
  }
34161
35493
  function rollbackCommand(scope, root) {
34162
- const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify((0, import_node_path20.join)(root, ".deepline", "runtime"))}` : "";
35494
+ const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify((0, import_node_path21.join)(root, ".deepline", "runtime"))}` : "";
34163
35495
  return `npm install -g${prefix} --no-audit --no-fund --include=optional --allow-scripts=esbuild deepline@${SDK_VERSION}`;
34164
35496
  }
34165
35497
  function setupResumeCommand(baseUrl, scope) {
@@ -34246,12 +35578,12 @@ function buildDoctorAssessment(input2) {
34246
35578
  const connected = input2.authStatus.payload?.connected === true;
34247
35579
  const authScopeOk = input2.scope === "local" ? Boolean(projectAuth) : Boolean(apiKey && !projectAuth);
34248
35580
  const skillsOk = skillsState?.scope === input2.scope && typeof skillsState.skillsVersion === "string" && Array.isArray(skillsState.agents) && skillsState.agents.length > 0;
34249
- const runningCliPath = process.argv[1] ? (0, import_node_path20.resolve)(process.argv[1]) : null;
35581
+ const runningCliPath = process.argv[1] ? (0, import_node_path21.resolve)(process.argv[1]) : null;
34250
35582
  const globalCli = input2.scope === "global" ? inspectGlobalCliAvailability() : null;
34251
35583
  const pathGlobalCli = globalCli?.path ?? null;
34252
35584
  const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
34253
35585
  const cliScopeOk = input2.scope === "global" ? Boolean(pathGlobalCli) : Boolean(
34254
- input2.root && runningCliPath?.includes((0, import_node_path20.join)(input2.root, ".deepline", "runtime"))
35586
+ input2.root && runningCliPath?.includes((0, import_node_path21.join)(input2.root, ".deepline", "runtime"))
34255
35587
  );
34256
35588
  const checks = {
34257
35589
  cli: {
@@ -34785,7 +36117,7 @@ Examples:
34785
36117
  // src/cli/update-preferences.ts
34786
36118
  var import_node_fs19 = require("fs");
34787
36119
  var import_node_os13 = require("os");
34788
- var import_node_path21 = require("path");
36120
+ var import_node_path22 = require("path");
34789
36121
  var UPDATE_PREFERENCES_SCHEMA_VERSION = 1;
34790
36122
  var CLI_UPDATE_MESSAGES = [
34791
36123
  {
@@ -34814,7 +36146,7 @@ function unreadablePreferences(path, error) {
34814
36146
  };
34815
36147
  }
34816
36148
  function cliUpdatePreferencesPath(homeDir2 = (0, import_node_os13.homedir)()) {
34817
- return (0, import_node_path21.join)(
36149
+ return (0, import_node_path22.join)(
34818
36150
  homeDir2,
34819
36151
  ".local",
34820
36152
  "deepline",
@@ -34842,7 +36174,7 @@ function readCliUpdatePreferences(homeDir2 = (0, import_node_os13.homedir)()) {
34842
36174
  function writeCliUpdatePreferences(preferences, homeDir2 = (0, import_node_os13.homedir)()) {
34843
36175
  const path = cliUpdatePreferencesPath(homeDir2);
34844
36176
  const tempPath = `${path}.${process.pid}.tmp`;
34845
- (0, import_node_fs19.mkdirSync)((0, import_node_path21.dirname)(path), { recursive: true });
36177
+ (0, import_node_fs19.mkdirSync)((0, import_node_path22.dirname)(path), { recursive: true });
34846
36178
  try {
34847
36179
  (0, import_node_fs19.writeFileSync)(tempPath, `${JSON.stringify(preferences, null, 2)}
34848
36180
  `, {
@@ -34903,12 +36235,12 @@ function consumePendingCliUpdateMessages(homeDir2 = (0, import_node_os13.homedir
34903
36235
  var import_node_child_process5 = require("child_process");
34904
36236
  var import_node_fs21 = require("fs");
34905
36237
  var import_node_os14 = require("os");
34906
- var import_node_path23 = require("path");
36238
+ var import_node_path24 = require("path");
34907
36239
 
34908
36240
  // src/cli/install-integrity.ts
34909
36241
  var import_node_module2 = require("module");
34910
36242
  var import_node_fs20 = require("fs");
34911
- var import_node_path22 = require("path");
36243
+ var import_node_path23 = require("path");
34912
36244
  var SDK_SIDECAR_CRITICAL_PACKAGE_FILES = [
34913
36245
  "dist/cli/index.mjs",
34914
36246
  "dist/index.mjs",
@@ -34925,7 +36257,7 @@ var SDK_SIDECAR_CRITICAL_DEPENDENCY_FILES = [
34925
36257
  "esbuild/lib/main.js"
34926
36258
  ];
34927
36259
  function safeRelativePath(value) {
34928
- if (typeof value !== "string" || !value || (0, import_node_path22.isAbsolute)(value)) return false;
36260
+ if (typeof value !== "string" || !value || (0, import_node_path23.isAbsolute)(value)) return false;
34929
36261
  const segments = value.split(/[\\/]+/);
34930
36262
  return segments.every(
34931
36263
  (segment) => Boolean(segment) && segment !== "." && segment !== ".."
@@ -34933,9 +36265,9 @@ function safeRelativePath(value) {
34933
36265
  }
34934
36266
  function resolveContainedPath(root, value) {
34935
36267
  if (!safeRelativePath(value)) return null;
34936
- const target = (0, import_node_path22.resolve)(root, value);
34937
- const relativeTarget = (0, import_node_path22.relative)((0, import_node_path22.resolve)(root), target);
34938
- if (!relativeTarget || relativeTarget.startsWith("..") || (0, import_node_path22.isAbsolute)(relativeTarget)) {
36268
+ const target = (0, import_node_path23.resolve)(root, value);
36269
+ const relativeTarget = (0, import_node_path23.relative)((0, import_node_path23.resolve)(root), target);
36270
+ if (!relativeTarget || relativeTarget.startsWith("..") || (0, import_node_path23.isAbsolute)(relativeTarget)) {
34939
36271
  return null;
34940
36272
  }
34941
36273
  return target;
@@ -34951,7 +36283,7 @@ function isFile(path) {
34951
36283
  }
34952
36284
  }
34953
36285
  function readManifest(packageRoot) {
34954
- const packageJsonPath = (0, import_node_path22.join)(packageRoot, "package.json");
36286
+ const packageJsonPath = (0, import_node_path23.join)(packageRoot, "package.json");
34955
36287
  let packageJson;
34956
36288
  try {
34957
36289
  packageJson = parseJson(packageJsonPath);
@@ -35025,8 +36357,8 @@ function readManifest(packageRoot) {
35025
36357
  return { mode: "manifest", manifest };
35026
36358
  }
35027
36359
  function inspectSdkSidecarInstall(versionDir) {
35028
- const nodeModulesRoot = (0, import_node_path22.join)(versionDir, "node_modules");
35029
- const packageRoot = (0, import_node_path22.join)(nodeModulesRoot, "deepline");
36360
+ const nodeModulesRoot = (0, import_node_path23.join)(versionDir, "node_modules");
36361
+ const packageRoot = (0, import_node_path23.join)(nodeModulesRoot, "deepline");
35030
36362
  const manifestResult = readManifest(packageRoot);
35031
36363
  if ("invalidReason" in manifestResult) {
35032
36364
  return {
@@ -35037,8 +36369,8 @@ function inspectSdkSidecarInstall(versionDir) {
35037
36369
  };
35038
36370
  }
35039
36371
  const missing = [
35040
- ...manifestResult.manifest.packageFiles.filter((path) => !isFile((0, import_node_path22.join)(packageRoot, path))).map((path) => `deepline/${path}`),
35041
- ...manifestResult.manifest.dependencyFiles.filter((path) => !isFile((0, import_node_path22.join)(nodeModulesRoot, path))).map((path) => `node_modules/${path}`)
36372
+ ...manifestResult.manifest.packageFiles.filter((path) => !isFile((0, import_node_path23.join)(packageRoot, path))).map((path) => `deepline/${path}`),
36373
+ ...manifestResult.manifest.dependencyFiles.filter((path) => !isFile((0, import_node_path23.join)(nodeModulesRoot, path))).map((path) => `node_modules/${path}`)
35042
36374
  ];
35043
36375
  return {
35044
36376
  ok: missing.length === 0,
@@ -35049,7 +36381,7 @@ function inspectSdkSidecarInstall(versionDir) {
35049
36381
  }
35050
36382
  function probeSdkSidecarEsbuild(versionDir) {
35051
36383
  try {
35052
- const requireFromInstall = (0, import_node_module2.createRequire)((0, import_node_path22.join)(versionDir, "package.json"));
36384
+ const requireFromInstall = (0, import_node_module2.createRequire)((0, import_node_path23.join)(versionDir, "package.json"));
35053
36385
  const esbuild = requireFromInstall("esbuild");
35054
36386
  if (typeof esbuild.transformSync !== "function") {
35055
36387
  return "esbuild does not export transformSync";
@@ -35124,7 +36456,7 @@ function sidecarStateDir(input2) {
35124
36456
  if (!scope || scope.includes("/") || scope.includes("\\")) {
35125
36457
  return null;
35126
36458
  }
35127
- return (0, import_node_path23.join)(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
36459
+ return (0, import_node_path24.join)(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
35128
36460
  }
35129
36461
  function sidecarRegistryUrl(hostUrl) {
35130
36462
  let url;
@@ -35159,19 +36491,19 @@ function readOptionalText(path) {
35159
36491
  function resolvePythonSidecarUpdatePlan(options) {
35160
36492
  const stateDir = sidecarStateDir(options);
35161
36493
  if (!stateDir) return null;
35162
- const relativeEntrypoint = (0, import_node_path23.relative)(
35163
- (0, import_node_path23.resolve)(stateDir),
35164
- (0, import_node_path23.resolve)(options.entrypoint)
36494
+ const relativeEntrypoint = (0, import_node_path24.relative)(
36495
+ (0, import_node_path24.resolve)(stateDir),
36496
+ (0, import_node_path24.resolve)(options.entrypoint)
35165
36497
  );
35166
- if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || (0, import_node_path23.isAbsolute)(relativeEntrypoint)) {
36498
+ if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || (0, import_node_path24.isAbsolute)(relativeEntrypoint)) {
35167
36499
  return null;
35168
36500
  }
35169
- const installMethod = readOptionalText((0, import_node_path23.join)(stateDir, ".install-method"));
36501
+ const installMethod = readOptionalText((0, import_node_path24.join)(stateDir, ".install-method"));
35170
36502
  if (installMethod !== "python-sidecar") return null;
35171
36503
  const scope = options.env.DEEPLINE_CONFIG_SCOPE?.trim() || "";
35172
36504
  const hostUrl = options.env.DEEPLINE_HOST_URL?.trim() || "";
35173
- const nodeBin = readOptionalText((0, import_node_path23.join)(stateDir, ".node-bin")) || process.execPath;
35174
- const sidecarPath = readOptionalText((0, import_node_path23.join)(stateDir, ".command-path")) || (0, import_node_path23.join)(
36505
+ const nodeBin = readOptionalText((0, import_node_path24.join)(stateDir, ".node-bin")) || process.execPath;
36506
+ const sidecarPath = readOptionalText((0, import_node_path24.join)(stateDir, ".command-path")) || (0, import_node_path24.join)(
35175
36507
  stateDir,
35176
36508
  "bin",
35177
36509
  process.platform === "win32" ? "deepline-sdk.cmd" : "deepline-sdk"
@@ -35179,7 +36511,7 @@ function resolvePythonSidecarUpdatePlan(options) {
35179
36511
  const packageSpec = options.packageSpec || "deepline@latest";
35180
36512
  const npmCommand = "npm";
35181
36513
  const registryUrl = sidecarRegistryUrl(hostUrl);
35182
- const versionDir = (0, import_node_path23.join)(stateDir, "versions", "<version>");
36514
+ const versionDir = (0, import_node_path24.join)(stateDir, "versions", "<version>");
35183
36515
  const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote4(versionDir)} --registry ${shellQuote4(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote4).join(" ")} ${shellQuote4(packageSpec)}`;
35184
36516
  return {
35185
36517
  kind: "python-sidecar",
@@ -35195,16 +36527,16 @@ function resolvePythonSidecarUpdatePlan(options) {
35195
36527
  };
35196
36528
  }
35197
36529
  function findRepoBackedSdkRoot(startPath) {
35198
- let current = (0, import_node_path23.resolve)(startPath);
36530
+ let current = (0, import_node_path24.resolve)(startPath);
35199
36531
  while (true) {
35200
- if ((0, import_node_fs21.existsSync)((0, import_node_path23.join)(current, "package.json")) && (0, import_node_fs21.existsSync)((0, import_node_path23.join)(current, "bin", "deepline-dev.ts"))) {
35201
- const parent2 = (0, import_node_path23.dirname)(current);
35202
- return (0, import_node_path23.basename)(parent2) === "packages" && (0, import_node_path23.basename)(current) === "sdk" ? (0, import_node_path23.dirname)(parent2) : parent2;
36532
+ if ((0, import_node_fs21.existsSync)((0, import_node_path24.join)(current, "package.json")) && (0, import_node_fs21.existsSync)((0, import_node_path24.join)(current, "bin", "deepline-dev.ts"))) {
36533
+ const parent2 = (0, import_node_path24.dirname)(current);
36534
+ return (0, import_node_path24.basename)(parent2) === "packages" && (0, import_node_path24.basename)(current) === "sdk" ? (0, import_node_path24.dirname)(parent2) : parent2;
35203
36535
  }
35204
- if ((0, import_node_fs21.existsSync)((0, import_node_path23.join)(current, "sdk", "package.json")) && (0, import_node_fs21.existsSync)((0, import_node_path23.join)(current, "sdk", "bin", "deepline-dev.ts"))) {
36536
+ if ((0, import_node_fs21.existsSync)((0, import_node_path24.join)(current, "sdk", "package.json")) && (0, import_node_fs21.existsSync)((0, import_node_path24.join)(current, "sdk", "bin", "deepline-dev.ts"))) {
35205
36537
  return current;
35206
36538
  }
35207
- const parent = (0, import_node_path23.dirname)(current);
36539
+ const parent = (0, import_node_path24.dirname)(current);
35208
36540
  if (parent === current) return null;
35209
36541
  current = parent;
35210
36542
  }
@@ -35214,7 +36546,7 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
35214
36546
  try {
35215
36547
  return (0, import_node_fs21.realpathSync)(entrypoint);
35216
36548
  } catch {
35217
- return (0, import_node_path23.resolve)(entrypoint);
36549
+ return (0, import_node_path24.resolve)(entrypoint);
35218
36550
  }
35219
36551
  })();
35220
36552
  const parts = normalized.split(/[\\/]+/);
@@ -35229,10 +36561,10 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
35229
36561
  const directPrefix = prefixParts.join("/").toLowerCase();
35230
36562
  const knownWindowsPrefixes = [
35231
36563
  env.npm_config_prefix,
35232
- env.APPDATA ? (0, import_node_path23.join)(env.APPDATA, "npm") : void 0
35233
- ].filter((value) => Boolean(value)).map((value) => (0, import_node_path23.resolve)(value).replace(/\\/g, "/").toLowerCase());
36564
+ env.APPDATA ? (0, import_node_path24.join)(env.APPDATA, "npm") : void 0
36565
+ ].filter((value) => Boolean(value)).map((value) => (0, import_node_path24.resolve)(value).replace(/\\/g, "/").toLowerCase());
35234
36566
  if (!knownWindowsPrefixes.includes(
35235
- (0, import_node_path23.resolve)(directPrefix).replace(/\\/g, "/").toLowerCase()
36567
+ (0, import_node_path24.resolve)(directPrefix).replace(/\\/g, "/").toLowerCase()
35236
36568
  )) {
35237
36569
  return null;
35238
36570
  }
@@ -35245,9 +36577,9 @@ function normalizedNpmPrefix(value) {
35245
36577
  if (!trimmed) return null;
35246
36578
  const normalized = (() => {
35247
36579
  try {
35248
- return (0, import_node_fs21.realpathSync)((0, import_node_path23.resolve)(trimmed));
36580
+ return (0, import_node_fs21.realpathSync)((0, import_node_path24.resolve)(trimmed));
35249
36581
  } catch {
35250
- return (0, import_node_path23.resolve)(trimmed);
36582
+ return (0, import_node_path24.resolve)(trimmed);
35251
36583
  }
35252
36584
  })().replace(/\\/g, "/");
35253
36585
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
@@ -35272,7 +36604,7 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
35272
36604
  try {
35273
36605
  return (0, import_node_fs21.realpathSync)(entrypoint);
35274
36606
  } catch {
35275
- return (0, import_node_path23.resolve)(entrypoint);
36607
+ return (0, import_node_path24.resolve)(entrypoint);
35276
36608
  }
35277
36609
  })();
35278
36610
  const parts = normalized.split(/[\\/]+/);
@@ -35282,8 +36614,8 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
35282
36614
  function resolveUpdatePlan(options = {}) {
35283
36615
  const env = options.env ?? process.env;
35284
36616
  const homeDir2 = options.homeDir ?? (0, import_node_os14.homedir)();
35285
- const entrypoint = options.entrypoint ?? (process.argv[1] ? (0, import_node_path23.resolve)(process.argv[1]) : "");
35286
- const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0, import_node_path23.dirname)(entrypoint)) : null;
36617
+ const entrypoint = options.entrypoint ?? (process.argv[1] ? (0, import_node_path24.resolve)(process.argv[1]) : "");
36618
+ const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0, import_node_path24.dirname)(entrypoint)) : null;
35287
36619
  if (sourceRoot) {
35288
36620
  return {
35289
36621
  kind: "source",
@@ -35334,9 +36666,9 @@ var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
35334
36666
  function autoUpdateFailurePath(plan) {
35335
36667
  if (plan.kind === "source" || plan.kind === "homebrew") return null;
35336
36668
  if (plan.kind === "python-sidecar") {
35337
- return (0, import_node_path23.join)(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
36669
+ return (0, import_node_path24.join)(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
35338
36670
  }
35339
- return (0, import_node_path23.join)(
36671
+ return (0, import_node_path24.join)(
35340
36672
  (0, import_node_os14.homedir)(),
35341
36673
  ".local",
35342
36674
  "deepline",
@@ -35375,7 +36707,7 @@ function writeAutoUpdateFailure(plan, exitCode) {
35375
36707
  manualCommand: plan.manualCommand
35376
36708
  };
35377
36709
  try {
35378
- (0, import_node_fs21.mkdirSync)((0, import_node_path23.dirname)(path), { recursive: true });
36710
+ (0, import_node_fs21.mkdirSync)((0, import_node_path24.dirname)(path), { recursive: true });
35379
36711
  (0, import_node_fs21.writeFileSync)(path, `${JSON.stringify(marker, null, 2)}
35380
36712
  `, "utf8");
35381
36713
  } catch {
@@ -35423,7 +36755,7 @@ function safeVersionSegment(value) {
35423
36755
  return /^[0-9A-Za-z._-]+$/.test(normalized) ? normalized : "";
35424
36756
  }
35425
36757
  function entryPathInVersionDir(versionDir) {
35426
- return (0, import_node_path23.join)(
36758
+ return (0, import_node_path24.join)(
35427
36759
  versionDir,
35428
36760
  "node_modules",
35429
36761
  "deepline",
@@ -35433,7 +36765,7 @@ function entryPathInVersionDir(versionDir) {
35433
36765
  );
35434
36766
  }
35435
36767
  function installedPackageVersion(versionDir) {
35436
- const packageJsonPath = (0, import_node_path23.join)(
36768
+ const packageJsonPath = (0, import_node_path24.join)(
35437
36769
  versionDir,
35438
36770
  "node_modules",
35439
36771
  "deepline",
@@ -35555,16 +36887,16 @@ async function runNpmInstallWithRegistryFallback(input2) {
35555
36887
  return first.exitCode;
35556
36888
  }
35557
36889
  function writeSidecarLauncher(input2) {
35558
- (0, import_node_fs21.mkdirSync)((0, import_node_path23.dirname)(input2.path), { recursive: true });
35559
- const packageRoot = (0, import_node_path23.dirname)((0, import_node_path23.dirname)((0, import_node_path23.dirname)(input2.entryPath)));
35560
- const versionDir = (0, import_node_path23.dirname)((0, import_node_path23.dirname)(packageRoot));
36890
+ (0, import_node_fs21.mkdirSync)((0, import_node_path24.dirname)(input2.path), { recursive: true });
36891
+ const packageRoot = (0, import_node_path24.dirname)((0, import_node_path24.dirname)((0, import_node_path24.dirname)(input2.entryPath)));
36892
+ const versionDir = (0, import_node_path24.dirname)((0, import_node_path24.dirname)(packageRoot));
35561
36893
  const esbuildProbe = "const {createRequire}=require('node:module');const path=require('node:path');const req=createRequire(path.join(process.argv[1],'package.json'));const result=req('esbuild').transformSync('const value: number = 1;',{loader:'ts'});if(!result||typeof result.code!=='string')process.exit(3);";
35562
36894
  const criticalPaths = [
35563
36895
  ...SDK_SIDECAR_CRITICAL_PACKAGE_FILES.map(
35564
- (path) => (0, import_node_path23.join)(packageRoot, path)
36896
+ (path) => (0, import_node_path24.join)(packageRoot, path)
35565
36897
  ),
35566
36898
  ...SDK_SIDECAR_CRITICAL_DEPENDENCY_FILES.map(
35567
- (path) => (0, import_node_path23.join)(versionDir, "node_modules", path)
36899
+ (path) => (0, import_node_path24.join)(versionDir, "node_modules", path)
35568
36900
  )
35569
36901
  ];
35570
36902
  if (process.platform === "win32") {
@@ -35618,17 +36950,17 @@ function writeSidecarLauncher(input2) {
35618
36950
  );
35619
36951
  }
35620
36952
  async function runPythonSidecarUpdatePlan(plan) {
35621
- const versionsDir = (0, import_node_path23.join)(plan.stateDir, "versions");
35622
- const tempDir = (0, import_node_path23.join)(
36953
+ const versionsDir = (0, import_node_path24.join)(plan.stateDir, "versions");
36954
+ const tempDir = (0, import_node_path24.join)(
35623
36955
  versionsDir,
35624
36956
  `.tmp-sdk-update-${process.pid}-${Date.now()}`
35625
36957
  );
35626
36958
  (0, import_node_fs21.rmSync)(tempDir, { recursive: true, force: true });
35627
36959
  (0, import_node_fs21.mkdirSync)(tempDir, { recursive: true });
35628
- (0, import_node_fs21.writeFileSync)((0, import_node_path23.join)(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
36960
+ (0, import_node_fs21.writeFileSync)((0, import_node_path24.join)(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
35629
36961
  const env = {
35630
36962
  ...process.env,
35631
- PATH: `${(0, import_node_path23.dirname)(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
36963
+ PATH: `${(0, import_node_path24.dirname)(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
35632
36964
  };
35633
36965
  const installResult = await runCommand(
35634
36966
  plan.npmCommand,
@@ -35665,7 +36997,7 @@ async function runPythonSidecarUpdatePlan(plan) {
35665
36997
  (0, import_node_fs21.rmSync)(tempDir, { recursive: true, force: true });
35666
36998
  return 1;
35667
36999
  }
35668
- const finalDir = (0, import_node_path23.join)(versionsDir, installedVersion);
37000
+ const finalDir = (0, import_node_path24.join)(versionsDir, installedVersion);
35669
37001
  const finalEntryPath = entryPathInVersionDir(finalDir);
35670
37002
  const finalFailure = sidecarInstallFailure(finalDir);
35671
37003
  let backupDir = null;
@@ -35674,7 +37006,7 @@ async function runPythonSidecarUpdatePlan(plan) {
35674
37006
  } else {
35675
37007
  let shouldPublishTemp = true;
35676
37008
  if ((0, import_node_fs21.existsSync)(finalDir)) {
35677
- backupDir = (0, import_node_path23.join)(
37009
+ backupDir = (0, import_node_path24.join)(
35678
37010
  versionsDir,
35679
37011
  `.backup-${installedVersion}-${process.pid}-${Date.now()}`
35680
37012
  );
@@ -35749,27 +37081,27 @@ async function runPythonSidecarUpdatePlan(plan) {
35749
37081
  entryPath: finalEntryPath
35750
37082
  });
35751
37083
  (0, import_node_fs21.writeFileSync)(
35752
- (0, import_node_path23.join)(plan.stateDir, ".version"),
37084
+ (0, import_node_path24.join)(plan.stateDir, ".version"),
35753
37085
  `${installedVersion}
35754
37086
  `,
35755
37087
  "utf8"
35756
37088
  );
35757
37089
  (0, import_node_fs21.writeFileSync)(
35758
- (0, import_node_path23.join)(plan.stateDir, ".install-method"),
37090
+ (0, import_node_path24.join)(plan.stateDir, ".install-method"),
35759
37091
  "python-sidecar\n",
35760
37092
  "utf8"
35761
37093
  );
35762
37094
  (0, import_node_fs21.writeFileSync)(
35763
- (0, import_node_path23.join)(plan.stateDir, ".command-path"),
37095
+ (0, import_node_path24.join)(plan.stateDir, ".command-path"),
35764
37096
  `${plan.sidecarPath}
35765
37097
  `,
35766
37098
  "utf8"
35767
37099
  );
35768
- (0, import_node_fs21.writeFileSync)((0, import_node_path23.join)(plan.stateDir, ".runner"), "node\n", "utf8");
35769
- (0, import_node_fs21.writeFileSync)((0, import_node_path23.join)(plan.stateDir, ".node-bin"), `${plan.nodeBin}
37100
+ (0, import_node_fs21.writeFileSync)((0, import_node_path24.join)(plan.stateDir, ".runner"), "node\n", "utf8");
37101
+ (0, import_node_fs21.writeFileSync)((0, import_node_path24.join)(plan.stateDir, ".node-bin"), `${plan.nodeBin}
35770
37102
  `, "utf8");
35771
37103
  (0, import_node_fs21.writeFileSync)(
35772
- (0, import_node_path23.join)(plan.stateDir, ".entry-path"),
37104
+ (0, import_node_path24.join)(plan.stateDir, ".entry-path"),
35773
37105
  `${finalEntryPath}
35774
37106
  `,
35775
37107
  "utf8"
@@ -36698,12 +38030,12 @@ chooses the connected Slack channel or member and the events it receives.
36698
38030
  var import_commander3 = require("commander");
36699
38031
  var import_node_fs23 = require("fs");
36700
38032
  var import_node_os16 = require("os");
36701
- var import_node_path25 = require("path");
38033
+ var import_node_path26 = require("path");
36702
38034
 
36703
38035
  // src/tool-output.ts
36704
38036
  var import_node_fs22 = require("fs");
36705
38037
  var import_node_os15 = require("os");
36706
- var import_node_path24 = require("path");
38038
+ var import_node_path25 = require("path");
36707
38039
  function isPlainObject(value) {
36708
38040
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
36709
38041
  }
@@ -36830,19 +38162,19 @@ function projectRowOutput(conversion) {
36830
38162
  };
36831
38163
  }
36832
38164
  function ensureOutputDir() {
36833
- const outputDir = (0, import_node_path24.join)((0, import_node_os15.homedir)(), ".local", "share", "deepline", "data");
38165
+ const outputDir = (0, import_node_path25.join)((0, import_node_os15.homedir)(), ".local", "share", "deepline", "data");
36834
38166
  (0, import_node_fs22.mkdirSync)(outputDir, { recursive: true });
36835
38167
  return outputDir;
36836
38168
  }
36837
38169
  function writeJsonOutputFile(payload, stem) {
36838
38170
  const outputDir = ensureOutputDir();
36839
- const outputPath = (0, import_node_path24.join)(outputDir, `${stem}_${Date.now()}.json`);
38171
+ const outputPath = (0, import_node_path25.join)(outputDir, `${stem}_${Date.now()}.json`);
36840
38172
  (0, import_node_fs22.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
36841
38173
  return outputPath;
36842
38174
  }
36843
38175
  function writeCsvOutputFile(rows, stem, options) {
36844
- const outputPath = options?.outPath ? options.outPath : (0, import_node_path24.join)(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
36845
- (0, import_node_fs22.mkdirSync)((0, import_node_path24.dirname)(outputPath), { recursive: true });
38176
+ const outputPath = options?.outPath ? options.outPath : (0, import_node_path25.join)(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
38177
+ (0, import_node_fs22.mkdirSync)((0, import_node_path25.dirname)(outputPath), { recursive: true });
36846
38178
  const columns = columnsForRows(rows);
36847
38179
  const escapeCell = (value) => {
36848
38180
  const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
@@ -37178,9 +38510,9 @@ function requiredInputIds(tool) {
37178
38510
  return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
37179
38511
  }
37180
38512
  function notConnectedSuffix(tool) {
37181
- const record = tool;
37182
- const status = stringField2(record, "credentialStatus", "credential_status");
37183
- const connected = record.connected;
38513
+ const record2 = tool;
38514
+ const status = stringField2(record2, "credentialStatus", "credential_status");
38515
+ const connected = record2.connected;
37184
38516
  if (status === "requires_connection" || connected === false) {
37185
38517
  return " - \u26A0 requires your credentials \u2014 not connected (connect to use)";
37186
38518
  }
@@ -37555,19 +38887,19 @@ function printPlayAliasToolError(toolId, play) {
37555
38887
  console.error(playAliasToolErrorMessage(toolId, play));
37556
38888
  }
37557
38889
  function isPlayLikeTool(tool) {
37558
- const record = tool;
37559
- if (record.isPlay === true || record.is_play === true) return true;
37560
- const playExpansion = recordField2(record, "playExpansion", "play_expansion");
38890
+ const record2 = tool;
38891
+ if (record2.isPlay === true || record2.is_play === true) return true;
38892
+ const playExpansion = recordField2(record2, "playExpansion", "play_expansion");
37561
38893
  if (Object.keys(playExpansion).length > 0) return true;
37562
- const toolId = typeof record.toolId === "string" ? record.toolId : "";
38894
+ const toolId = typeof record2.toolId === "string" ? record2.toolId : "";
37563
38895
  return toolId.endsWith("_waterfall");
37564
38896
  }
37565
38897
  function isMonitorTypeTool(tool) {
37566
38898
  return stringField2(tool, "kind") === "monitor_type";
37567
38899
  }
37568
38900
  function playReferenceForTool(tool) {
37569
- const record = tool;
37570
- const declared = stringField2(record, "playReference", "play_reference");
38901
+ const record2 = tool;
38902
+ const declared = stringField2(record2, "playReference", "play_reference");
37571
38903
  if (declared.startsWith("prebuilt/")) {
37572
38904
  return declared;
37573
38905
  }
@@ -38525,12 +39857,12 @@ function singleLineText(value, maxLength = 260) {
38525
39857
  return `${text.slice(0, maxLength - 3).trimEnd()}...`;
38526
39858
  }
38527
39859
  function listedToolDescription(tool) {
38528
- const record = tool;
38529
- return singleLineText(record.bestFor ?? record.best_for ?? tool.description);
39860
+ const record2 = tool;
39861
+ return singleLineText(record2.bestFor ?? record2.best_for ?? tool.description);
38530
39862
  }
38531
39863
  function formatListedToolCost(tool) {
38532
- const record = tool;
38533
- const pricing = recordField2(record, "pricing");
39864
+ const record2 = tool;
39865
+ const pricing = recordField2(record2, "pricing");
38534
39866
  const displayText = stringField2(pricing, "displayText", "display_text");
38535
39867
  return displayText ? `Cost: ${displayText}` : "";
38536
39868
  }
@@ -38811,10 +40143,10 @@ function normalizeOutputFormat(raw) {
38811
40143
  }
38812
40144
  function resolveAtFilePath(rawPath) {
38813
40145
  const trimmed = rawPath.trim();
38814
- const resolved = (0, import_node_path25.resolve)(trimmed);
40146
+ const resolved = (0, import_node_path26.resolve)(trimmed);
38815
40147
  if ((0, import_node_fs23.existsSync)(resolved)) return resolved;
38816
40148
  if (process.platform !== "win32" && trimmed.includes("\\")) {
38817
- const normalized = (0, import_node_path25.resolve)(trimmed.replace(/\\/g, "/"));
40149
+ const normalized = (0, import_node_path26.resolve)(trimmed.replace(/\\/g, "/"));
38818
40150
  if ((0, import_node_fs23.existsSync)(normalized)) return normalized;
38819
40151
  }
38820
40152
  return resolved;
@@ -38903,7 +40235,7 @@ function parseExecuteOptions(args) {
38903
40235
  continue;
38904
40236
  }
38905
40237
  if ((arg === "--out" || arg === "-o") && args[index + 1]) {
38906
- outPath = (0, import_node_path25.resolve)(args[++index]);
40238
+ outPath = (0, import_node_path26.resolve)(args[++index]);
38907
40239
  continue;
38908
40240
  }
38909
40241
  throw new Error(`Unknown option: ${arg}`);
@@ -38933,9 +40265,9 @@ function starterScriptJson(script) {
38933
40265
  function seedToolListScript(input2) {
38934
40266
  const stem = safeFileStem(input2.toolId);
38935
40267
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
38936
- const scriptDir = (0, import_node_fs23.mkdtempSync)((0, import_node_path25.join)((0, import_node_os16.tmpdir)(), "deepline-workflow-seed-"));
40268
+ const scriptDir = (0, import_node_fs23.mkdtempSync)((0, import_node_path26.join)((0, import_node_os16.tmpdir)(), "deepline-workflow-seed-"));
38937
40269
  (0, import_node_fs23.chmodSync)(scriptDir, 448);
38938
- const scriptPath = (0, import_node_path25.join)(scriptDir, fileName);
40270
+ const scriptPath = (0, import_node_path26.join)(scriptDir, fileName);
38939
40271
  const projectDir = `deepline/projects/${stem}-workflow`;
38940
40272
  const playName = `${stem}-workflow`;
38941
40273
  const sampleRows = input2.rows.length > 0 ? `${JSON.stringify(input2.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
@@ -39404,10 +40736,10 @@ Examples:
39404
40736
 
39405
40737
  // src/cli/commands/workflow.ts
39406
40738
  var import_promises9 = require("fs/promises");
39407
- var import_node_path26 = require("path");
40739
+ var import_node_path27 = require("path");
39408
40740
 
39409
40741
  // src/cli/workflow-to-play.ts
39410
- var import_node_crypto8 = require("crypto");
40742
+ var import_node_crypto9 = require("crypto");
39411
40743
  var HITL_WAIT_FOR_SIGNAL_TOOL = "deepline_workflow_wait_for_signal";
39412
40744
  var HITL_SLACK_TOOL = "slack_message_with_hitl";
39413
40745
  var SUB_WORKFLOW_TOOL_PREFIX = "deepline_workflow_";
@@ -39513,7 +40845,7 @@ function sanitizePlayNameSegment(value) {
39513
40845
  }
39514
40846
  function deriveWorkflowPlayName(workflowName) {
39515
40847
  const base = sanitizePlayNameSegment(workflowName) || "workflow";
39516
- const suffix = (0, import_node_crypto8.createHash)("sha256").update(workflowName).digest("hex").slice(0, 8);
40848
+ const suffix = (0, import_node_crypto9.createHash)("sha256").update(workflowName).digest("hex").slice(0, 8);
39517
40849
  const reserved = suffix.length + 1;
39518
40850
  const allowedBase = Math.max(1, MAX_PLAY_NAME_LENGTH - reserved);
39519
40851
  let name = `${base.slice(0, allowedBase)}_${suffix}`;
@@ -39610,9 +40942,9 @@ function clientWithTimeout(timeoutSeconds) {
39610
40942
  }
39611
40943
  function readStatus(payload) {
39612
40944
  if (!payload || typeof payload !== "object") return null;
39613
- const record = payload;
39614
- if (typeof record.status === "string") return record.status;
39615
- const run = record.run;
40945
+ const record2 = payload;
40946
+ if (typeof record2.status === "string") return record2.status;
40947
+ const run = record2.run;
39616
40948
  if (run && typeof run === "object") {
39617
40949
  const status = run.status;
39618
40950
  if (typeof status === "string") return status;
@@ -39621,7 +40953,7 @@ function readStatus(payload) {
39621
40953
  }
39622
40954
  async function readJsonOption(payload, file) {
39623
40955
  if (file) {
39624
- const raw = await (0, import_promises9.readFile)((0, import_node_path26.resolve)(file), "utf8");
40956
+ const raw = await (0, import_promises9.readFile)((0, import_node_path27.resolve)(file), "utf8");
39625
40957
  return JSON.parse(raw);
39626
40958
  }
39627
40959
  if (payload) {
@@ -39655,8 +40987,8 @@ async function transformOne(api, workflowId, outDir, publish) {
39655
40987
  revision.config,
39656
40988
  { workflowName: workflow.name, version: revision.version }
39657
40989
  );
39658
- const file = (0, import_node_path26.join)((0, import_node_path26.resolve)(outDir), `${compiled.playName}.play.ts`);
39659
- await (0, import_promises9.mkdir)((0, import_node_path26.dirname)(file), { recursive: true });
40990
+ const file = (0, import_node_path27.join)((0, import_node_path27.resolve)(outDir), `${compiled.playName}.play.ts`);
40991
+ await (0, import_promises9.mkdir)((0, import_node_path27.dirname)(file), { recursive: true });
39660
40992
  await (0, import_promises9.writeFile)(file, compiled.sourceCode, "utf8");
39661
40993
  let published = false;
39662
40994
  if (publish) {
@@ -40035,7 +41367,7 @@ function isDowngradeAutoUpdateResponse(response) {
40035
41367
  return compareSemver(target, current) < 0;
40036
41368
  }
40037
41369
  function relaunchCurrentCommand(plan) {
40038
- return new Promise((resolve20) => {
41370
+ return new Promise((resolve21) => {
40039
41371
  const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
40040
41372
  const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
40041
41373
  const child = (0, import_node_child_process6.spawn)(command, args, {
@@ -40051,9 +41383,9 @@ function relaunchCurrentCommand(plan) {
40051
41383
  `Deepline SDK/CLI updated, but relaunch failed: ${error.message}
40052
41384
  `
40053
41385
  );
40054
- resolve20(1);
41386
+ resolve21(1);
40055
41387
  });
40056
- child.on("close", (code) => resolve20(code ?? 1));
41388
+ child.on("close", (code) => resolve21(code ?? 1));
40057
41389
  });
40058
41390
  }
40059
41391
  async function maybeAutoUpdateAndRelaunch(response, baseUrl) {
@@ -40201,8 +41533,8 @@ function classifyNetworkFailure(error) {
40201
41533
  let current = error;
40202
41534
  while (current && !seen.has(current)) {
40203
41535
  seen.add(current);
40204
- const record = typeof current === "object" && current !== null ? current : {};
40205
- const code = String(record.code ?? "").toLowerCase();
41536
+ const record2 = typeof current === "object" && current !== null ? current : {};
41537
+ const code = String(record2.code ?? "").toLowerCase();
40206
41538
  const name = current instanceof Error ? current.name.toLowerCase() : "";
40207
41539
  const text = String(
40208
41540
  current instanceof Error ? current.message : current
@@ -40229,7 +41561,7 @@ function classifyNetworkFailure(error) {
40229
41561
  if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
40230
41562
  return "network_ssl_error";
40231
41563
  }
40232
- current = record.cause ?? record.context;
41564
+ current = record2.cause ?? record2.context;
40233
41565
  }
40234
41566
  return "network_error";
40235
41567
  }
@@ -40444,8 +41776,8 @@ function topLevelCommandKnown(program, commandName) {
40444
41776
  );
40445
41777
  }
40446
41778
  async function runPlayRunnerHealthCheck() {
40447
- const dir = await (0, import_promises10.mkdtemp)((0, import_node_path27.join)((0, import_node_os18.tmpdir)(), "deepline-health-play-"));
40448
- const file = (0, import_node_path27.join)(dir, "health-check.play.ts");
41779
+ const dir = await (0, import_promises10.mkdtemp)((0, import_node_path28.join)((0, import_node_os18.tmpdir)(), "deepline-health-play-"));
41780
+ const file = (0, import_node_path28.join)(dir, "health-check.play.ts");
40449
41781
  try {
40450
41782
  await (0, import_promises10.writeFile)(
40451
41783
  file,