deepline 0.3.54 → 0.3.56
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/bundling-sources/sdk/src/client.ts +232 -0
- package/dist/bundling-sources/sdk/src/index.ts +29 -0
- package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +556 -0
- package/dist/bundling-sources/sdk/src/monitor-fleets.ts +31 -0
- package/dist/bundling-sources/sdk/src/play.ts +2 -8
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/monitor-fleet-limits.ts +14 -0
- package/dist/bundling-sources/shared_libs/monitors/org-monitor-limits.ts +102 -0
- package/dist/bundling-sources/shared_libs/monitors/validation.ts +244 -0
- package/dist/cli/index.js +1718 -376
- package/dist/cli/index.mjs +1654 -312
- package/dist/index.d.mts +220 -9
- package/dist/index.d.ts +220 -9
- package/dist/index.js +474 -14
- package/dist/index.mjs +464 -14
- package/dist/install-integrity.json +5 -0
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -1060,7 +1060,7 @@ var SDK_RELEASE = {
|
|
|
1060
1060
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1061
1061
|
// getters keep their established compatibility behavior.
|
|
1062
1062
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1063
|
-
version: "0.3.
|
|
1063
|
+
version: "0.3.56",
|
|
1064
1064
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
1065
1065
|
packageCapabilities: {
|
|
1066
1066
|
updatePreferences: 1
|
|
@@ -2197,7 +2197,7 @@ function decodeSseFrame(frame) {
|
|
|
2197
2197
|
return parsed;
|
|
2198
2198
|
}
|
|
2199
2199
|
function sleep(ms) {
|
|
2200
|
-
return new Promise((
|
|
2200
|
+
return new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
2201
2201
|
}
|
|
2202
2202
|
function withCoworkNetworkHint(message) {
|
|
2203
2203
|
if (!isCoworkLikeSandbox2() || message.includes(COWORK_NETWORK_HINT)) {
|
|
@@ -3100,9 +3100,9 @@ function nonEmptyString(value) {
|
|
|
3100
3100
|
}
|
|
3101
3101
|
function normalizeDatasetBornFrom(value) {
|
|
3102
3102
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
3103
|
-
const
|
|
3104
|
-
const table = nonEmptyString(
|
|
3105
|
-
const rowCountIn = finiteNonNegativeInteger2(
|
|
3103
|
+
const record2 = value;
|
|
3104
|
+
const table = nonEmptyString(record2.table);
|
|
3105
|
+
const rowCountIn = finiteNonNegativeInteger2(record2.rowCountIn);
|
|
3106
3106
|
if (!table || rowCountIn === null) return null;
|
|
3107
3107
|
return { table, rowCountIn };
|
|
3108
3108
|
}
|
|
@@ -3962,14 +3962,14 @@ async function* observeRunEvents(options) {
|
|
|
3962
3962
|
try {
|
|
3963
3963
|
for (; ; ) {
|
|
3964
3964
|
if (queue.length === 0) {
|
|
3965
|
-
const waitForItem = new Promise((
|
|
3966
|
-
wake =
|
|
3965
|
+
const waitForItem = new Promise((resolve21) => {
|
|
3966
|
+
wake = resolve21;
|
|
3967
3967
|
});
|
|
3968
3968
|
if (!sawFirstSnapshot) {
|
|
3969
3969
|
const timedOut = await Promise.race([
|
|
3970
3970
|
waitForItem.then(() => false),
|
|
3971
3971
|
new Promise(
|
|
3972
|
-
(
|
|
3972
|
+
(resolve21) => setTimeout(() => resolve21(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
|
|
3973
3973
|
)
|
|
3974
3974
|
]);
|
|
3975
3975
|
if (timedOut && queue.length === 0) {
|
|
@@ -4162,21 +4162,21 @@ function normalizePlayRuntimeNamespace(value) {
|
|
|
4162
4162
|
}
|
|
4163
4163
|
function normalizePlayRuntimeSelection(value) {
|
|
4164
4164
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
4165
|
-
const
|
|
4166
|
-
if (Object.keys(
|
|
4165
|
+
const record2 = value;
|
|
4166
|
+
if (Object.keys(record2).some(
|
|
4167
4167
|
(key) => key !== "environment" && key !== "namespace" && key !== "backend"
|
|
4168
|
-
) ||
|
|
4168
|
+
) || record2.environment !== "preview") {
|
|
4169
4169
|
return null;
|
|
4170
4170
|
}
|
|
4171
|
-
const namespace = normalizePlayRuntimeNamespace(
|
|
4171
|
+
const namespace = normalizePlayRuntimeNamespace(record2.namespace);
|
|
4172
4172
|
if (!namespace) return null;
|
|
4173
|
-
if (
|
|
4173
|
+
if (record2.backend === void 0) {
|
|
4174
4174
|
return { environment: "preview", namespace };
|
|
4175
4175
|
}
|
|
4176
|
-
if (
|
|
4176
|
+
if (record2.backend !== PLAY_RUNTIME_BACKENDS.daytona && record2.backend !== PLAY_RUNTIME_BACKENDS.modal) {
|
|
4177
4177
|
return null;
|
|
4178
4178
|
}
|
|
4179
|
-
return { environment: "preview", namespace, backend:
|
|
4179
|
+
return { environment: "preview", namespace, backend: record2.backend };
|
|
4180
4180
|
}
|
|
4181
4181
|
function normalizePlayRuntimeEnvironment(value) {
|
|
4182
4182
|
return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
|
|
@@ -4328,7 +4328,7 @@ function parseEnvTestPolicyOverrides() {
|
|
|
4328
4328
|
return normalizeTestPolicyOverrides(parsed, "DEEPLINE_TEST_POLICY_OVERRIDES");
|
|
4329
4329
|
}
|
|
4330
4330
|
function sleep2(ms) {
|
|
4331
|
-
return new Promise((
|
|
4331
|
+
return new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
4332
4332
|
}
|
|
4333
4333
|
function isTransientCompileManifestError(error) {
|
|
4334
4334
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
@@ -4760,7 +4760,14 @@ var DeeplineClient = class {
|
|
|
4760
4760
|
dependents: (key) => this.getMonitorDependents(key),
|
|
4761
4761
|
update: (key, patch) => this.updateMonitor(key, patch),
|
|
4762
4762
|
delete: (key, options2) => this.deleteMonitor(key, options2),
|
|
4763
|
-
reactivate: (key, options2) => this.reactivateMonitor(key, options2)
|
|
4763
|
+
reactivate: (key, options2) => this.reactivateMonitor(key, options2),
|
|
4764
|
+
fleets: {
|
|
4765
|
+
sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
4766
|
+
get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
|
|
4767
|
+
list: () => this.listMonitorFleets(),
|
|
4768
|
+
deactivate: (fleetId, options2) => this.deactivateMonitorFleet(fleetId, options2),
|
|
4769
|
+
waitForConvergence: (fleetId, options2) => this.waitForMonitorFleetConvergence(fleetId, options2)
|
|
4770
|
+
}
|
|
4764
4771
|
};
|
|
4765
4772
|
}
|
|
4766
4773
|
/** The resolved base URL this client is targeting (e.g. `"http://localhost:3000"`). */
|
|
@@ -7068,6 +7075,104 @@ var DeeplineClient = class {
|
|
|
7068
7075
|
{ method: "POST", body: {} }
|
|
7069
7076
|
);
|
|
7070
7077
|
}
|
|
7078
|
+
// ——————————————————————————————————————————————————————————
|
|
7079
|
+
// Monitor Fleets
|
|
7080
|
+
// ——————————————————————————————————————————————————————————
|
|
7081
|
+
monitorFleetIdempotencyKey(operation) {
|
|
7082
|
+
const uuid = globalThis.crypto?.randomUUID?.();
|
|
7083
|
+
return `monitor-fleet-${operation}-${uuid ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`}`;
|
|
7084
|
+
}
|
|
7085
|
+
monitorFleetHeaders(operation, idempotencyKey) {
|
|
7086
|
+
return {
|
|
7087
|
+
"Idempotency-Key": idempotencyKey?.trim() || this.monitorFleetIdempotencyKey(operation)
|
|
7088
|
+
};
|
|
7089
|
+
}
|
|
7090
|
+
monitorFleetPath(fleetId) {
|
|
7091
|
+
return `/api/v2/monitors/fleets/${encodeURIComponent(fleetId)}`;
|
|
7092
|
+
}
|
|
7093
|
+
/**
|
|
7094
|
+
* Create, update, or re-plan one fleet.
|
|
7095
|
+
*
|
|
7096
|
+
* The fleet id is always the resource path, so the same definition PUT twice
|
|
7097
|
+
* is the same operation and the server can answer `replayed: true` instead of
|
|
7098
|
+
* building a second set of monitors. Re-planning an existing fleet from its
|
|
7099
|
+
* stored definition sends an EMPTY body: there is no second definition to
|
|
7100
|
+
* send, and an empty body cannot be mistaken for "replace the definition with
|
|
7101
|
+
* nothing".
|
|
7102
|
+
*/
|
|
7103
|
+
async syncMonitorFleet(definitionOrId, options) {
|
|
7104
|
+
const fleetId = typeof definitionOrId === "string" ? definitionOrId : definitionOrId.id;
|
|
7105
|
+
const body = {
|
|
7106
|
+
...typeof definitionOrId === "string" ? {} : { definition: definitionOrId },
|
|
7107
|
+
...options?.dryRun ? { dry_run: true } : {},
|
|
7108
|
+
...options?.expectedGeneration !== void 0 ? { expected_generation: options.expectedGeneration } : {}
|
|
7109
|
+
};
|
|
7110
|
+
return this.http.request(
|
|
7111
|
+
this.monitorFleetPath(fleetId),
|
|
7112
|
+
{
|
|
7113
|
+
method: "PUT",
|
|
7114
|
+
body,
|
|
7115
|
+
headers: this.monitorFleetHeaders("sync", options?.idempotencyKey),
|
|
7116
|
+
maxRetries: 0,
|
|
7117
|
+
exactUrlOnly: true
|
|
7118
|
+
}
|
|
7119
|
+
);
|
|
7120
|
+
}
|
|
7121
|
+
async listMonitorFleets() {
|
|
7122
|
+
return this.http.request("/api/v2/monitors/fleets", {
|
|
7123
|
+
method: "GET"
|
|
7124
|
+
});
|
|
7125
|
+
}
|
|
7126
|
+
async getMonitorFleet(fleetId, options) {
|
|
7127
|
+
const params = new URLSearchParams();
|
|
7128
|
+
if (options?.drift) params.set("drift", "1");
|
|
7129
|
+
if (options?.limit !== void 0)
|
|
7130
|
+
params.set("limit", String(options.limit));
|
|
7131
|
+
const query = params.toString();
|
|
7132
|
+
return this.http.request(
|
|
7133
|
+
`${this.monitorFleetPath(fleetId)}${query ? `?${query}` : ""}`,
|
|
7134
|
+
{ method: "GET" }
|
|
7135
|
+
);
|
|
7136
|
+
}
|
|
7137
|
+
async deactivateMonitorFleet(fleetId, options) {
|
|
7138
|
+
return this.http.request(
|
|
7139
|
+
this.monitorFleetPath(fleetId),
|
|
7140
|
+
{
|
|
7141
|
+
method: "DELETE",
|
|
7142
|
+
body: options?.dryRun ? { dry_run: true } : {},
|
|
7143
|
+
headers: this.monitorFleetHeaders(
|
|
7144
|
+
"deactivate",
|
|
7145
|
+
options?.idempotencyKey
|
|
7146
|
+
),
|
|
7147
|
+
maxRetries: 0,
|
|
7148
|
+
exactUrlOnly: true
|
|
7149
|
+
}
|
|
7150
|
+
);
|
|
7151
|
+
}
|
|
7152
|
+
/**
|
|
7153
|
+
* Poll one fleet until the server reports a terminal status.
|
|
7154
|
+
*
|
|
7155
|
+
* Convergence is the server's verdict, read from `status`. The timeout is not
|
|
7156
|
+
* a failure and does not throw: a fleet still `converging` after ten minutes
|
|
7157
|
+
* is healthy and slow, not broken, so the caller gets the last snapshot and
|
|
7158
|
+
* decides what that means. Throwing here would have made "still working" look
|
|
7159
|
+
* identical to "the request failed".
|
|
7160
|
+
*/
|
|
7161
|
+
async waitForMonitorFleetConvergence(fleetId, options) {
|
|
7162
|
+
const timeoutMs = Math.max(1, options?.timeoutMs ?? 10 * 6e4);
|
|
7163
|
+
const pollIntervalMs = Math.max(1, options?.pollIntervalMs ?? 2e3);
|
|
7164
|
+
const terminal = options?.until === "deactivated" ? /* @__PURE__ */ new Set(["deactivated", "degraded"]) : /* @__PURE__ */ new Set(["converged", "degraded", "deactivated"]);
|
|
7165
|
+
const startedAt = Date.now();
|
|
7166
|
+
let latest = await this.getMonitorFleet(fleetId);
|
|
7167
|
+
while (true) {
|
|
7168
|
+
options?.onProgress?.(latest);
|
|
7169
|
+
const status = typeof latest.status === "string" ? latest.status : void 0;
|
|
7170
|
+
if (status && terminal.has(status)) return latest;
|
|
7171
|
+
if (Date.now() - startedAt >= timeoutMs) return latest;
|
|
7172
|
+
await sleep2(pollIntervalMs);
|
|
7173
|
+
latest = await this.getMonitorFleet(fleetId);
|
|
7174
|
+
}
|
|
7175
|
+
}
|
|
7071
7176
|
/**
|
|
7072
7177
|
* Check API connectivity and server health.
|
|
7073
7178
|
*
|
|
@@ -7746,30 +7851,30 @@ function flattenObjectColumns(row, options = {}) {
|
|
|
7746
7851
|
continue;
|
|
7747
7852
|
}
|
|
7748
7853
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7749
|
-
const
|
|
7854
|
+
const record2 = value;
|
|
7750
7855
|
if (options.objectColumns === "json") {
|
|
7751
|
-
flattened[key] = csvSafeJsonString(
|
|
7856
|
+
flattened[key] = csvSafeJsonString(record2);
|
|
7752
7857
|
continue;
|
|
7753
7858
|
}
|
|
7754
|
-
const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(
|
|
7859
|
+
const hasMatchedEnvelope = Object.prototype.hasOwnProperty.call(record2, "matched_result") || Object.prototype.hasOwnProperty.call(record2, "matchedResult");
|
|
7755
7860
|
if (hasMatchedEnvelope) {
|
|
7756
|
-
flattened[key] = csvSafeJsonString(
|
|
7861
|
+
flattened[key] = csvSafeJsonString(record2);
|
|
7757
7862
|
continue;
|
|
7758
7863
|
}
|
|
7759
7864
|
if (parsedFromString && shouldPreserveJsonStringColumn(options.preserveJsonStringColumns, key)) {
|
|
7760
7865
|
flattened[key] = rawValue;
|
|
7761
7866
|
continue;
|
|
7762
7867
|
} else {
|
|
7763
|
-
const failureMessage = failureMessageFromRecord(
|
|
7868
|
+
const failureMessage = failureMessageFromRecord(record2);
|
|
7764
7869
|
if (failureMessage) {
|
|
7765
7870
|
flattened[key] = failureMessage;
|
|
7766
7871
|
continue;
|
|
7767
|
-
} else if (Object.prototype.hasOwnProperty.call(
|
|
7768
|
-
flattened[key] = csvSafeJsonString(
|
|
7872
|
+
} else if (Object.prototype.hasOwnProperty.call(record2, "result")) {
|
|
7873
|
+
flattened[key] = csvSafeJsonString(record2);
|
|
7769
7874
|
continue;
|
|
7770
7875
|
}
|
|
7771
7876
|
}
|
|
7772
|
-
for (const [nestedKey, nestedValue] of Object.entries(
|
|
7877
|
+
for (const [nestedKey, nestedValue] of Object.entries(record2)) {
|
|
7773
7878
|
flattened[`${key}.${nestedKey}`] = nestedValue && typeof nestedValue === "object" ? csvSafeJsonString(nestedValue) : nestedValue;
|
|
7774
7879
|
}
|
|
7775
7880
|
continue;
|
|
@@ -8158,7 +8263,7 @@ function buildCandidateUrls2(url) {
|
|
|
8158
8263
|
}
|
|
8159
8264
|
}
|
|
8160
8265
|
function sleep4(ms) {
|
|
8161
|
-
return new Promise((
|
|
8266
|
+
return new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
8162
8267
|
}
|
|
8163
8268
|
function printDeeplineLogo() {
|
|
8164
8269
|
if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
|
|
@@ -10261,9 +10366,9 @@ function canonicalDatasetJsonValue(value, ancestors) {
|
|
|
10261
10366
|
}
|
|
10262
10367
|
if (ancestors.has(value)) return value;
|
|
10263
10368
|
ancestors.add(value);
|
|
10264
|
-
const
|
|
10369
|
+
const record2 = value;
|
|
10265
10370
|
const normalized = Object.fromEntries(
|
|
10266
|
-
Object.keys(
|
|
10371
|
+
Object.keys(record2).sort((left, right) => left.localeCompare(right)).map((key) => [key, canonicalDatasetJsonValue(record2[key], ancestors)])
|
|
10267
10372
|
);
|
|
10268
10373
|
ancestors.delete(value);
|
|
10269
10374
|
return normalized;
|
|
@@ -11430,16 +11535,16 @@ function collectErrorText(value) {
|
|
|
11430
11535
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
11431
11536
|
return errorMessage(value);
|
|
11432
11537
|
}
|
|
11433
|
-
const
|
|
11538
|
+
const record2 = value;
|
|
11434
11539
|
return [
|
|
11435
11540
|
errorMessage(value),
|
|
11436
|
-
typeof
|
|
11437
|
-
typeof
|
|
11438
|
-
typeof
|
|
11439
|
-
typeof
|
|
11440
|
-
typeof
|
|
11441
|
-
|
|
11442
|
-
|
|
11541
|
+
typeof record2.error === "string" ? record2.error : "",
|
|
11542
|
+
typeof record2.message === "string" ? record2.message : "",
|
|
11543
|
+
typeof record2.detail === "string" ? record2.detail : "",
|
|
11544
|
+
typeof record2.hint === "string" ? record2.hint : "",
|
|
11545
|
+
typeof record2.code === "string" ? record2.code : "",
|
|
11546
|
+
record2.response ? collectErrorText(record2.response) : "",
|
|
11547
|
+
record2.details ? collectErrorText(record2.details) : ""
|
|
11443
11548
|
].filter(Boolean).join("\n");
|
|
11444
11549
|
}
|
|
11445
11550
|
function formatDbQueryError(sql, error) {
|
|
@@ -12491,8 +12596,8 @@ function getterNamesFromTool(tool, kind) {
|
|
|
12491
12596
|
return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
|
|
12492
12597
|
}
|
|
12493
12598
|
function targetGettersFromTool(tool) {
|
|
12494
|
-
const
|
|
12495
|
-
const raw =
|
|
12599
|
+
const record2 = isRecord9(tool) ? tool : {};
|
|
12600
|
+
const raw = record2.targetGetters ?? record2.target_getters;
|
|
12496
12601
|
if (!isRecord9(raw)) return {};
|
|
12497
12602
|
const entries = [];
|
|
12498
12603
|
for (const [target, value] of Object.entries(raw)) {
|
|
@@ -15370,11 +15475,11 @@ function staticStringFromExpression(node, context, seen = /* @__PURE__ */ new Se
|
|
|
15370
15475
|
if (!value?.trim()) return null;
|
|
15371
15476
|
return trimResult ? value.trim() : value;
|
|
15372
15477
|
}
|
|
15373
|
-
const
|
|
15374
|
-
if (!
|
|
15375
|
-
seen.add(
|
|
15478
|
+
const identifier2 = getIdentifierName2(expression);
|
|
15479
|
+
if (!identifier2 || seen.has(identifier2)) return null;
|
|
15480
|
+
seen.add(identifier2);
|
|
15376
15481
|
return staticStringFromExpression(
|
|
15377
|
-
context.declarations.get(
|
|
15482
|
+
context.declarations.get(identifier2),
|
|
15378
15483
|
context,
|
|
15379
15484
|
seen,
|
|
15380
15485
|
trimResult
|
|
@@ -15398,11 +15503,11 @@ function objectExpressionFromNode(node, context, seen = /* @__PURE__ */ new Set(
|
|
|
15398
15503
|
const expression = unwrapStaticExpression2(node);
|
|
15399
15504
|
if (!expression) return null;
|
|
15400
15505
|
if (expression.type === "ObjectExpression") return expression;
|
|
15401
|
-
const
|
|
15402
|
-
if (!
|
|
15403
|
-
seen.add(
|
|
15506
|
+
const identifier2 = getIdentifierName2(expression);
|
|
15507
|
+
if (!identifier2 || seen.has(identifier2)) return null;
|
|
15508
|
+
seen.add(identifier2);
|
|
15404
15509
|
return objectExpressionFromNode(
|
|
15405
|
-
context.declarations.get(
|
|
15510
|
+
context.declarations.get(identifier2),
|
|
15406
15511
|
context,
|
|
15407
15512
|
seen
|
|
15408
15513
|
);
|
|
@@ -15470,11 +15575,11 @@ function staticNumberFromExpression(node, context, seen = /* @__PURE__ */ new Se
|
|
|
15470
15575
|
if (expression.type === "Literal" && typeof expression.value === "number") {
|
|
15471
15576
|
return expression.value;
|
|
15472
15577
|
}
|
|
15473
|
-
const
|
|
15474
|
-
if (!
|
|
15475
|
-
seen.add(
|
|
15578
|
+
const identifier2 = getIdentifierName2(expression);
|
|
15579
|
+
if (!identifier2 || seen.has(identifier2)) return null;
|
|
15580
|
+
seen.add(identifier2);
|
|
15476
15581
|
return staticNumberFromExpression(
|
|
15477
|
-
context.declarations.get(
|
|
15582
|
+
context.declarations.get(identifier2),
|
|
15478
15583
|
context,
|
|
15479
15584
|
seen
|
|
15480
15585
|
);
|
|
@@ -16546,13 +16651,13 @@ function validateFixtureBehavior(value) {
|
|
|
16546
16651
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
16547
16652
|
return { ok: false, error: "fixtureBehavior must be a JSON object." };
|
|
16548
16653
|
}
|
|
16549
|
-
const
|
|
16550
|
-
const supportedKeys =
|
|
16654
|
+
const record2 = value;
|
|
16655
|
+
const supportedKeys = record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
|
|
16551
16656
|
"version",
|
|
16552
16657
|
"responseSamples",
|
|
16553
|
-
...
|
|
16658
|
+
...record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
|
|
16554
16659
|
]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
|
|
16555
|
-
const unknownKeys = Object.keys(
|
|
16660
|
+
const unknownKeys = Object.keys(record2).filter(
|
|
16556
16661
|
(key) => !supportedKeys.has(key)
|
|
16557
16662
|
);
|
|
16558
16663
|
if (unknownKeys.length > 0) {
|
|
@@ -16561,22 +16666,22 @@ function validateFixtureBehavior(value) {
|
|
|
16561
16666
|
error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
|
|
16562
16667
|
};
|
|
16563
16668
|
}
|
|
16564
|
-
if (
|
|
16669
|
+
if (record2.version !== FIXTURE_BEHAVIOR_VERSION && record2.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record2.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
16565
16670
|
return {
|
|
16566
16671
|
ok: false,
|
|
16567
16672
|
error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
|
|
16568
16673
|
};
|
|
16569
16674
|
}
|
|
16570
|
-
if (
|
|
16571
|
-
if (!Array.isArray(
|
|
16675
|
+
if (record2.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
16676
|
+
if (!Array.isArray(record2.responseSamples) || record2.responseSamples.length === 0 || record2.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
16572
16677
|
return {
|
|
16573
16678
|
ok: false,
|
|
16574
16679
|
error: `fixtureBehavior.responseSamples must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
|
|
16575
16680
|
};
|
|
16576
16681
|
}
|
|
16577
16682
|
const samples2 = [];
|
|
16578
|
-
for (let index = 0; index <
|
|
16579
|
-
const value2 =
|
|
16683
|
+
for (let index = 0; index < record2.responseSamples.length; index += 1) {
|
|
16684
|
+
const value2 = record2.responseSamples[index];
|
|
16580
16685
|
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
|
|
16581
16686
|
return {
|
|
16582
16687
|
ok: false,
|
|
@@ -16675,14 +16780,14 @@ function validateFixtureBehavior(value) {
|
|
|
16675
16780
|
});
|
|
16676
16781
|
}
|
|
16677
16782
|
let replayBundle;
|
|
16678
|
-
if (
|
|
16679
|
-
if (!
|
|
16783
|
+
if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
16784
|
+
if (!record2.replayBundle || typeof record2.replayBundle !== "object" || Array.isArray(record2.replayBundle)) {
|
|
16680
16785
|
return {
|
|
16681
16786
|
ok: false,
|
|
16682
16787
|
error: "fixtureBehavior.replayBundle must be an object."
|
|
16683
16788
|
};
|
|
16684
16789
|
}
|
|
16685
|
-
const replay =
|
|
16790
|
+
const replay = record2.replayBundle;
|
|
16686
16791
|
const replayUnknownKeys = Object.keys(replay).filter(
|
|
16687
16792
|
(key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
|
|
16688
16793
|
);
|
|
@@ -16730,7 +16835,7 @@ function validateFixtureBehavior(value) {
|
|
|
16730
16835
|
...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
|
|
16731
16836
|
};
|
|
16732
16837
|
}
|
|
16733
|
-
if (
|
|
16838
|
+
if (record2.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
|
|
16734
16839
|
return {
|
|
16735
16840
|
ok: true,
|
|
16736
16841
|
behavior: {
|
|
@@ -16748,15 +16853,15 @@ function validateFixtureBehavior(value) {
|
|
|
16748
16853
|
}
|
|
16749
16854
|
};
|
|
16750
16855
|
}
|
|
16751
|
-
if (!Array.isArray(
|
|
16856
|
+
if (!Array.isArray(record2.responseDelaySamplesMs) || record2.responseDelaySamplesMs.length === 0 || record2.responseDelaySamplesMs.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
|
|
16752
16857
|
return {
|
|
16753
16858
|
ok: false,
|
|
16754
16859
|
error: `fixtureBehavior.responseDelaySamplesMs must contain between 1 and ${MAX_FIXTURE_RESPONSE_DELAY_SAMPLES} values.`
|
|
16755
16860
|
};
|
|
16756
16861
|
}
|
|
16757
16862
|
const samples = [];
|
|
16758
|
-
for (let index = 0; index <
|
|
16759
|
-
const value2 =
|
|
16863
|
+
for (let index = 0; index < record2.responseDelaySamplesMs.length; index += 1) {
|
|
16864
|
+
const value2 = record2.responseDelaySamplesMs[index];
|
|
16760
16865
|
if (typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < 0 || value2 > MAX_FIXTURE_RESPONSE_DELAY_MS) {
|
|
16761
16866
|
return {
|
|
16762
16867
|
ok: false,
|
|
@@ -16965,7 +17070,7 @@ function traceCliSync(phase, fields, run) {
|
|
|
16965
17070
|
}
|
|
16966
17071
|
}
|
|
16967
17072
|
function sleep5(ms) {
|
|
16968
|
-
return new Promise((
|
|
17073
|
+
return new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
16969
17074
|
}
|
|
16970
17075
|
function parseReferencedPlayTarget2(target) {
|
|
16971
17076
|
const trimmed = target.trim();
|
|
@@ -17498,8 +17603,8 @@ function looksLikeStagedFileRef(value) {
|
|
|
17498
17603
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17499
17604
|
return false;
|
|
17500
17605
|
}
|
|
17501
|
-
const
|
|
17502
|
-
return typeof
|
|
17606
|
+
const record2 = value;
|
|
17607
|
+
return typeof record2.contentHash === "string" || typeof record2.contentBase64 === "string" || typeof record2.logicalPath === "string" && typeof record2.bytes === "number";
|
|
17503
17608
|
}
|
|
17504
17609
|
var CSV_DATA_INPUT_KEY = "csv";
|
|
17505
17610
|
function collectLocalFileInputRefs(value, inputPath, key, out) {
|
|
@@ -18000,8 +18105,8 @@ function readLiveRunField(event, field) {
|
|
|
18000
18105
|
const records = [payload, payload.progress, run, run?.progress].filter(
|
|
18001
18106
|
(value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
|
|
18002
18107
|
);
|
|
18003
|
-
for (const
|
|
18004
|
-
if (
|
|
18108
|
+
for (const record2 of records) {
|
|
18109
|
+
if (record2[field] !== void 0) return record2[field];
|
|
18005
18110
|
}
|
|
18006
18111
|
return void 0;
|
|
18007
18112
|
}
|
|
@@ -18303,8 +18408,8 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
18303
18408
|
if (!state || typeof state !== "object" || Array.isArray(state)) {
|
|
18304
18409
|
continue;
|
|
18305
18410
|
}
|
|
18306
|
-
const
|
|
18307
|
-
const progress =
|
|
18411
|
+
const record2 = state;
|
|
18412
|
+
const progress = record2.progress && typeof record2.progress === "object" && !Array.isArray(record2.progress) ? record2.progress : null;
|
|
18308
18413
|
if (!progress) {
|
|
18309
18414
|
continue;
|
|
18310
18415
|
}
|
|
@@ -18321,7 +18426,7 @@ function getProgressLinesFromLiveEvent(event) {
|
|
|
18321
18426
|
completed: progress.completed
|
|
18322
18427
|
});
|
|
18323
18428
|
lines.push(
|
|
18324
|
-
`progress ${formatProgressLabel(
|
|
18429
|
+
`progress ${formatProgressLabel(record2.nodeId ?? progress.artifactTableNamespace)}: ${counts}${messageSuffix}`
|
|
18325
18430
|
);
|
|
18326
18431
|
}
|
|
18327
18432
|
return lines;
|
|
@@ -19150,17 +19255,17 @@ function collectDatasetHandleLines(value, path = "result") {
|
|
|
19150
19255
|
return [];
|
|
19151
19256
|
}
|
|
19152
19257
|
if (isDatasetHandle(value)) {
|
|
19153
|
-
const
|
|
19154
|
-
const count = typeof
|
|
19155
|
-
const preview = Array.isArray(
|
|
19258
|
+
const record2 = value;
|
|
19259
|
+
const count = typeof record2.count === "number" ? record2.count : typeof record2.rowCount === "number" ? record2.rowCount : null;
|
|
19260
|
+
const preview = Array.isArray(record2.preview) ? record2.preview : [];
|
|
19156
19261
|
const lines2 = [
|
|
19157
|
-
` dataset ${typeof
|
|
19262
|
+
` dataset ${typeof record2.path === "string" ? record2.path : path}: rows=${count === null ? "-" : formatInteger(count)} preview=${formatInteger(preview.length)}`
|
|
19158
19263
|
];
|
|
19159
|
-
if (typeof
|
|
19160
|
-
lines2.push(` query dataset: ${
|
|
19264
|
+
if (typeof record2.queryDatasetCommand === "string") {
|
|
19265
|
+
lines2.push(` query dataset: ${record2.queryDatasetCommand}`);
|
|
19161
19266
|
}
|
|
19162
|
-
if (typeof
|
|
19163
|
-
lines2.push(` export CSV: ${
|
|
19267
|
+
if (typeof record2.slowExportAsCsvCommand === "string") {
|
|
19268
|
+
lines2.push(` export CSV: ${record2.slowExportAsCsvCommand}`);
|
|
19164
19269
|
}
|
|
19165
19270
|
return lines2;
|
|
19166
19271
|
}
|
|
@@ -19557,8 +19662,8 @@ function withTerminalPlayIdentity(status, playName) {
|
|
|
19557
19662
|
if (!playName.trim() || getPlayRunPackage(status)) {
|
|
19558
19663
|
return status;
|
|
19559
19664
|
}
|
|
19560
|
-
const
|
|
19561
|
-
const hasIdentity = typeof
|
|
19665
|
+
const record2 = status;
|
|
19666
|
+
const hasIdentity = typeof record2.playName === "string" && record2.playName.trim().length > 0 || typeof record2.name === "string" && record2.name.trim().length > 0 || Boolean(getStringField(record2.run, "playName"));
|
|
19562
19667
|
if (hasIdentity) {
|
|
19563
19668
|
return status;
|
|
19564
19669
|
}
|
|
@@ -19671,9 +19776,9 @@ function formatSummaryScalar(value) {
|
|
|
19671
19776
|
}
|
|
19672
19777
|
return null;
|
|
19673
19778
|
}
|
|
19674
|
-
function formatSummaryScalarParts(
|
|
19779
|
+
function formatSummaryScalarParts(record2, skipKeys = /* @__PURE__ */ new Set()) {
|
|
19675
19780
|
const parts = [];
|
|
19676
|
-
for (const [key, value] of Object.entries(
|
|
19781
|
+
for (const [key, value] of Object.entries(record2)) {
|
|
19677
19782
|
if (skipKeys.has(key)) {
|
|
19678
19783
|
continue;
|
|
19679
19784
|
}
|
|
@@ -19700,13 +19805,13 @@ function formatTopValuesPart(value) {
|
|
|
19700
19805
|
return `top_values=${entries.map(([topValue, count]) => `${topValue}=${String(count)}`).join(", ")}`;
|
|
19701
19806
|
}
|
|
19702
19807
|
function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
|
|
19703
|
-
const
|
|
19704
|
-
const columnStats = readRecord(
|
|
19705
|
-
if (!
|
|
19808
|
+
const record2 = readRecord(summary);
|
|
19809
|
+
const columnStats = readRecord(record2?.columnStats);
|
|
19810
|
+
if (!record2 || !columnStats) {
|
|
19706
19811
|
return [];
|
|
19707
19812
|
}
|
|
19708
19813
|
const lines = [];
|
|
19709
|
-
const rowCounts = readRecord(
|
|
19814
|
+
const rowCounts = readRecord(record2.rowCounts);
|
|
19710
19815
|
if (rowCounts) {
|
|
19711
19816
|
const persisted = readNonNegativeInteger(rowCounts.persisted);
|
|
19712
19817
|
const succeeded = readNonNegativeInteger(rowCounts.succeeded);
|
|
@@ -19722,7 +19827,7 @@ function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
|
|
|
19722
19827
|
}
|
|
19723
19828
|
}
|
|
19724
19829
|
const parts = formatSummaryScalarParts(
|
|
19725
|
-
|
|
19830
|
+
record2,
|
|
19726
19831
|
/* @__PURE__ */ new Set(["columnStats", "rowCounts"])
|
|
19727
19832
|
);
|
|
19728
19833
|
if (parts.length > 0) {
|
|
@@ -19752,35 +19857,35 @@ function actionToCommand(action) {
|
|
|
19752
19857
|
if (!action || typeof action !== "object" || Array.isArray(action)) {
|
|
19753
19858
|
return null;
|
|
19754
19859
|
}
|
|
19755
|
-
const
|
|
19756
|
-
if (typeof
|
|
19757
|
-
return
|
|
19860
|
+
const record2 = action;
|
|
19861
|
+
if (typeof record2.command === "string" && record2.command.trim()) {
|
|
19862
|
+
return record2.command.trim();
|
|
19758
19863
|
}
|
|
19759
|
-
if (
|
|
19760
|
-
return `deepline runs get ${
|
|
19864
|
+
if (record2.kind === "deepline_run_inspect" && typeof record2.runId === "string") {
|
|
19865
|
+
return `deepline runs get ${record2.runId} --json`;
|
|
19761
19866
|
}
|
|
19762
|
-
if (
|
|
19763
|
-
return `deepline runs get ${
|
|
19867
|
+
if (record2.kind === "deepline_run_full" && typeof record2.runId === "string") {
|
|
19868
|
+
return `deepline runs get ${record2.runId} --full --json`;
|
|
19764
19869
|
}
|
|
19765
|
-
if (
|
|
19766
|
-
return `deepline runs get ${
|
|
19870
|
+
if (record2.kind === "deepline_run_billing" && typeof record2.runId === "string") {
|
|
19871
|
+
return `deepline runs get ${record2.runId} --full --json | jq '.billing'`;
|
|
19767
19872
|
}
|
|
19768
|
-
if (
|
|
19769
|
-
return `deepline runs export ${
|
|
19770
|
-
|
|
19771
|
-
)} --out ${shellSingleQuote(`${
|
|
19873
|
+
if (record2.kind === "deepline_run_export" && typeof record2.runId === "string" && typeof record2.datasetPath === "string") {
|
|
19874
|
+
return `deepline runs export ${record2.runId} --dataset ${shellSingleQuote(
|
|
19875
|
+
record2.datasetPath
|
|
19876
|
+
)} --out ${shellSingleQuote(`${record2.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
|
|
19772
19877
|
}
|
|
19773
|
-
if (
|
|
19774
|
-
if (typeof
|
|
19775
|
-
return
|
|
19878
|
+
if (record2.kind === "deepline_run_logs") {
|
|
19879
|
+
if (typeof record2.command === "string" && record2.command.trim()) {
|
|
19880
|
+
return record2.command;
|
|
19776
19881
|
}
|
|
19777
|
-
if (typeof
|
|
19778
|
-
return
|
|
19882
|
+
if (typeof record2.runId === "string") {
|
|
19883
|
+
return record2.view === "failed" ? `deepline runs get ${record2.runId} --log-failed --json` : `deepline runs logs ${record2.runId} --json`;
|
|
19779
19884
|
}
|
|
19780
19885
|
}
|
|
19781
|
-
if (
|
|
19782
|
-
const maxRows = typeof
|
|
19783
|
-
return `deepline db query --sql ${shellSingleQuote(
|
|
19886
|
+
if (record2.kind === "deepline_db_query" && typeof record2.sql === "string") {
|
|
19887
|
+
const maxRows = typeof record2.maxRows === "number" && Number.isFinite(record2.maxRows) ? Math.trunc(record2.maxRows) : 20;
|
|
19888
|
+
return `deepline db query --sql ${shellSingleQuote(record2.sql)} --max-rows ${maxRows} --json`;
|
|
19784
19889
|
}
|
|
19785
19890
|
return null;
|
|
19786
19891
|
}
|
|
@@ -20185,12 +20290,12 @@ function exportableSheetRow(row) {
|
|
|
20185
20290
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
20186
20291
|
return null;
|
|
20187
20292
|
}
|
|
20188
|
-
const
|
|
20189
|
-
const data =
|
|
20293
|
+
const record2 = row;
|
|
20294
|
+
const data = record2.data;
|
|
20190
20295
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
20191
20296
|
return data;
|
|
20192
20297
|
}
|
|
20193
|
-
const fallback = { ...
|
|
20298
|
+
const fallback = { ...record2 };
|
|
20194
20299
|
for (const key of [
|
|
20195
20300
|
"key",
|
|
20196
20301
|
"status",
|
|
@@ -20542,8 +20647,8 @@ var PLAY_SYNTAX_MIGRATION_ERROR_MARKERS = [
|
|
|
20542
20647
|
"ctx.map(...) has been replaced by ctx.dataset(...)",
|
|
20543
20648
|
"Dataset .step(...) has been replaced by .withColumn(...)"
|
|
20544
20649
|
];
|
|
20545
|
-
function stringArrayField(
|
|
20546
|
-
const value =
|
|
20650
|
+
function stringArrayField(record2, key) {
|
|
20651
|
+
const value = record2[key];
|
|
20547
20652
|
if (!Array.isArray(value)) return [];
|
|
20548
20653
|
return value.filter((entry) => typeof entry === "string");
|
|
20549
20654
|
}
|
|
@@ -26315,7 +26420,7 @@ function emitEnrichDebug(message) {
|
|
|
26315
26420
|
);
|
|
26316
26421
|
}
|
|
26317
26422
|
function sleep6(ms) {
|
|
26318
|
-
return new Promise((
|
|
26423
|
+
return new Promise((resolve21) => setTimeout(resolve21, ms));
|
|
26319
26424
|
}
|
|
26320
26425
|
function enrichExportBackingRowsWaitMs() {
|
|
26321
26426
|
const raw = process.env.DEEPLINE_ENRICH_EXPORT_BACKING_ROWS_WAIT_MS?.trim();
|
|
@@ -26424,9 +26529,9 @@ async function expandCompiledConfigAtFiles(value) {
|
|
|
26424
26529
|
if (!value || typeof value !== "object") {
|
|
26425
26530
|
return value;
|
|
26426
26531
|
}
|
|
26427
|
-
const
|
|
26532
|
+
const record2 = value;
|
|
26428
26533
|
const expanded = {};
|
|
26429
|
-
for (const [key, entry] of Object.entries(
|
|
26534
|
+
for (const [key, entry] of Object.entries(record2)) {
|
|
26430
26535
|
expanded[key] = await expandCompiledConfigAtFiles(entry);
|
|
26431
26536
|
}
|
|
26432
26537
|
for (const field of ["extract_js", "run_if_js"]) {
|
|
@@ -27224,26 +27329,26 @@ function readFirstEnrichDatasetActions(value) {
|
|
|
27224
27329
|
}
|
|
27225
27330
|
return null;
|
|
27226
27331
|
}
|
|
27227
|
-
const
|
|
27228
|
-
const actions = isRecord11(
|
|
27332
|
+
const record2 = candidate;
|
|
27333
|
+
const actions = isRecord11(record2.actions) ? record2.actions : null;
|
|
27229
27334
|
const currentQuery = isRecord11(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
|
|
27230
27335
|
const legacyQuery = isRecord11(actions?.query) ? actions.query : null;
|
|
27231
27336
|
const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
|
|
27232
27337
|
if (query?.kind === "deepline_db_query") {
|
|
27233
27338
|
return {
|
|
27234
|
-
dataset:
|
|
27339
|
+
dataset: record2,
|
|
27235
27340
|
query,
|
|
27236
27341
|
...isRecord11(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
|
|
27237
27342
|
};
|
|
27238
27343
|
}
|
|
27239
|
-
if (options.allowLegacy &&
|
|
27344
|
+
if (options.allowLegacy && record2.kind === "dataset" && typeof record2.queryDatasetCommand === "string" && record2.queryDatasetCommand.trim()) {
|
|
27240
27345
|
return {
|
|
27241
|
-
dataset:
|
|
27242
|
-
queryDatasetCommand:
|
|
27243
|
-
...typeof
|
|
27346
|
+
dataset: record2,
|
|
27347
|
+
queryDatasetCommand: record2.queryDatasetCommand.trim(),
|
|
27348
|
+
...typeof record2.slowExportAsCsvCommand === "string" && record2.slowExportAsCsvCommand.trim() ? { slowExportAsCsvCommand: record2.slowExportAsCsvCommand.trim() } : {}
|
|
27244
27349
|
};
|
|
27245
27350
|
}
|
|
27246
|
-
for (const [key, entry] of Object.entries(
|
|
27351
|
+
for (const [key, entry] of Object.entries(record2)) {
|
|
27247
27352
|
if (key === "preview") {
|
|
27248
27353
|
continue;
|
|
27249
27354
|
}
|
|
@@ -27259,8 +27364,8 @@ function readFirstEnrichDatasetActions(value) {
|
|
|
27259
27364
|
seen.clear();
|
|
27260
27365
|
return walk(value, { allowLegacy: true });
|
|
27261
27366
|
}
|
|
27262
|
-
function actionStringField(
|
|
27263
|
-
const value =
|
|
27367
|
+
function actionStringField(record2, key) {
|
|
27368
|
+
const value = record2[key];
|
|
27264
27369
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
27265
27370
|
}
|
|
27266
27371
|
function parseSqlFromDbQueryCommand(command) {
|
|
@@ -27604,12 +27709,12 @@ function collectStringFields(value, key, output2, depth = 0) {
|
|
|
27604
27709
|
}
|
|
27605
27710
|
return;
|
|
27606
27711
|
}
|
|
27607
|
-
const
|
|
27608
|
-
const direct =
|
|
27712
|
+
const record2 = value;
|
|
27713
|
+
const direct = record2[key];
|
|
27609
27714
|
if (typeof direct === "string" && direct.trim()) {
|
|
27610
27715
|
output2.add(direct.trim());
|
|
27611
27716
|
}
|
|
27612
|
-
for (const child of Object.values(
|
|
27717
|
+
for (const child of Object.values(record2)) {
|
|
27613
27718
|
collectStringFields(child, key, output2, depth + 1);
|
|
27614
27719
|
}
|
|
27615
27720
|
}
|
|
@@ -27795,23 +27900,23 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
|
|
|
27795
27900
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
27796
27901
|
return null;
|
|
27797
27902
|
}
|
|
27798
|
-
const
|
|
27799
|
-
const data =
|
|
27903
|
+
const record2 = row;
|
|
27904
|
+
const data = record2.data;
|
|
27800
27905
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
27801
27906
|
const exported = { ...data };
|
|
27802
27907
|
applyFailureCellMeta(exported, exported[ENRICH_CELL_META_FIELD], {
|
|
27803
|
-
rowError:
|
|
27908
|
+
rowError: record2.error
|
|
27804
27909
|
});
|
|
27805
|
-
applyFailureCellMeta(exported,
|
|
27806
|
-
applyFailureCellMeta(exported,
|
|
27807
|
-
rowError:
|
|
27910
|
+
applyFailureCellMeta(exported, record2.cellMeta, { rowError: record2.error });
|
|
27911
|
+
applyFailureCellMeta(exported, record2.cellMetaPatch, {
|
|
27912
|
+
rowError: record2.error
|
|
27808
27913
|
});
|
|
27809
|
-
applyFailureCellMeta(exported,
|
|
27810
|
-
rowError:
|
|
27914
|
+
applyFailureCellMeta(exported, record2[ENRICH_CELL_META_PATCH_FIELD], {
|
|
27915
|
+
rowError: record2.error
|
|
27811
27916
|
});
|
|
27812
27917
|
delete exported[ENRICH_CELL_META_FIELD];
|
|
27813
27918
|
delete exported[ENRICH_CELL_META_PATCH_FIELD];
|
|
27814
|
-
const inputIndex = typeof
|
|
27919
|
+
const inputIndex = typeof record2.inputIndex === "number" ? record2.inputIndex : typeof record2.inputIndex === "string" && record2.inputIndex.trim() ? Number(record2.inputIndex) : Number.NaN;
|
|
27815
27920
|
if (Number.isInteger(inputIndex) && inputIndex >= 0) {
|
|
27816
27921
|
if (ENRICH_SOURCE_ROW_INDEX_COLUMN in exported) {
|
|
27817
27922
|
exported[ENRICH_ORIGINAL_SOURCE_ROW_INDEX_COLUMN] = exported[ENRICH_SOURCE_ROW_INDEX_COLUMN];
|
|
@@ -27820,18 +27925,18 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
|
|
|
27820
27925
|
}
|
|
27821
27926
|
return exported;
|
|
27822
27927
|
}
|
|
27823
|
-
const fallback = { ...
|
|
27928
|
+
const fallback = { ...record2 };
|
|
27824
27929
|
applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_FIELD], {
|
|
27825
|
-
rowError:
|
|
27930
|
+
rowError: record2.error
|
|
27826
27931
|
});
|
|
27827
|
-
applyFailureCellMeta(fallback,
|
|
27828
|
-
rowError:
|
|
27932
|
+
applyFailureCellMeta(fallback, record2.cellMeta, {
|
|
27933
|
+
rowError: record2.error
|
|
27829
27934
|
});
|
|
27830
|
-
applyFailureCellMeta(fallback,
|
|
27831
|
-
rowError:
|
|
27935
|
+
applyFailureCellMeta(fallback, record2.cellMetaPatch, {
|
|
27936
|
+
rowError: record2.error
|
|
27832
27937
|
});
|
|
27833
27938
|
applyFailureCellMeta(fallback, fallback[ENRICH_CELL_META_PATCH_FIELD], {
|
|
27834
|
-
rowError:
|
|
27939
|
+
rowError: record2.error
|
|
27835
27940
|
});
|
|
27836
27941
|
for (const key of [
|
|
27837
27942
|
"key",
|
|
@@ -28050,16 +28155,16 @@ function isWaterfallResultMeaningful(value) {
|
|
|
28050
28155
|
return value.some(isWaterfallResultMeaningful);
|
|
28051
28156
|
}
|
|
28052
28157
|
if (value && typeof value === "object") {
|
|
28053
|
-
const
|
|
28054
|
-
const status = typeof
|
|
28158
|
+
const record2 = value;
|
|
28159
|
+
const status = typeof record2.status === "string" ? record2.status.trim().toLowerCase() : "";
|
|
28055
28160
|
if (status === "error" || status === "failed") {
|
|
28056
28161
|
return false;
|
|
28057
28162
|
}
|
|
28058
|
-
if (typeof
|
|
28163
|
+
if (typeof record2.error === "string" && record2.error.trim()) {
|
|
28059
28164
|
return false;
|
|
28060
28165
|
}
|
|
28061
|
-
if (Object.prototype.hasOwnProperty.call(
|
|
28062
|
-
return isWaterfallResultMeaningful(
|
|
28166
|
+
if (Object.prototype.hasOwnProperty.call(record2, "matched_result")) {
|
|
28167
|
+
return isWaterfallResultMeaningful(record2.matched_result);
|
|
28063
28168
|
}
|
|
28064
28169
|
for (const key of [
|
|
28065
28170
|
"value",
|
|
@@ -28074,11 +28179,11 @@ function isWaterfallResultMeaningful(value) {
|
|
|
28074
28179
|
"result",
|
|
28075
28180
|
"data"
|
|
28076
28181
|
]) {
|
|
28077
|
-
if (isWaterfallResultMeaningful(
|
|
28182
|
+
if (isWaterfallResultMeaningful(record2[key])) {
|
|
28078
28183
|
return true;
|
|
28079
28184
|
}
|
|
28080
28185
|
}
|
|
28081
|
-
return Object.entries(
|
|
28186
|
+
return Object.entries(record2).some(
|
|
28082
28187
|
([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
|
|
28083
28188
|
);
|
|
28084
28189
|
}
|
|
@@ -28094,8 +28199,8 @@ function stableRowSnapshot(value) {
|
|
|
28094
28199
|
return `[${value.map(stableRowSnapshot).join(",")}]`;
|
|
28095
28200
|
}
|
|
28096
28201
|
if (value && typeof value === "object") {
|
|
28097
|
-
const
|
|
28098
|
-
return `{${Object.keys(
|
|
28202
|
+
const record2 = value;
|
|
28203
|
+
return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record2[key])}`).join(",")}}`;
|
|
28099
28204
|
}
|
|
28100
28205
|
return JSON.stringify(value);
|
|
28101
28206
|
}
|
|
@@ -28682,8 +28787,8 @@ function addEnrichFollowUpCommand(commands, seen, command) {
|
|
|
28682
28787
|
seen.add(normalized);
|
|
28683
28788
|
commands.push({ ...command, command: normalized });
|
|
28684
28789
|
}
|
|
28685
|
-
function datasetSelectorForEnrichCommand(
|
|
28686
|
-
const candidates = [
|
|
28790
|
+
function datasetSelectorForEnrichCommand(record2, fallbackPath) {
|
|
28791
|
+
const candidates = [record2.path, record2.tableNamespace, fallbackPath];
|
|
28687
28792
|
for (const candidate of candidates) {
|
|
28688
28793
|
if (typeof candidate === "string" && candidate.trim()) {
|
|
28689
28794
|
return candidate.trim();
|
|
@@ -28745,19 +28850,19 @@ function collectDatasetFollowUpCommands(value, state) {
|
|
|
28745
28850
|
);
|
|
28746
28851
|
return;
|
|
28747
28852
|
}
|
|
28748
|
-
const
|
|
28749
|
-
const isDataset =
|
|
28853
|
+
const record2 = value;
|
|
28854
|
+
const isDataset = record2.kind === "dataset";
|
|
28750
28855
|
if (isDataset) {
|
|
28751
|
-
const selector = datasetSelectorForEnrichCommand(
|
|
28752
|
-
const labelPath = typeof
|
|
28753
|
-
if (typeof
|
|
28856
|
+
const selector = datasetSelectorForEnrichCommand(record2, state.path);
|
|
28857
|
+
const labelPath = typeof record2.path === "string" && record2.path.trim() ? record2.path.trim() : selector ?? state.path;
|
|
28858
|
+
if (typeof record2.queryDatasetCommand === "string") {
|
|
28754
28859
|
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
28755
28860
|
label: `query ${labelPath}`,
|
|
28756
28861
|
path: labelPath,
|
|
28757
|
-
command:
|
|
28862
|
+
command: record2.queryDatasetCommand
|
|
28758
28863
|
});
|
|
28759
28864
|
}
|
|
28760
|
-
const exportCommand = typeof
|
|
28865
|
+
const exportCommand = typeof record2.slowExportAsCsvCommand === "string" ? record2.slowExportAsCsvCommand : typeof record2.fullExportCommand === "string" ? record2.fullExportCommand : null;
|
|
28761
28866
|
if (exportCommand) {
|
|
28762
28867
|
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
28763
28868
|
label: `export ${labelPath}`,
|
|
@@ -28774,7 +28879,7 @@ function collectDatasetFollowUpCommands(value, state) {
|
|
|
28774
28879
|
});
|
|
28775
28880
|
}
|
|
28776
28881
|
}
|
|
28777
|
-
for (const [key, child] of Object.entries(
|
|
28882
|
+
for (const [key, child] of Object.entries(record2)) {
|
|
28778
28883
|
if (key === "preview" || key === "access") {
|
|
28779
28884
|
continue;
|
|
28780
28885
|
}
|
|
@@ -30206,9 +30311,9 @@ function readCodexSessionId(filePath) {
|
|
|
30206
30311
|
)) {
|
|
30207
30312
|
const parsed = parseJsonLine(line);
|
|
30208
30313
|
if (!parsed || typeof parsed !== "object") continue;
|
|
30209
|
-
const
|
|
30210
|
-
const payload =
|
|
30211
|
-
const id =
|
|
30314
|
+
const record2 = parsed;
|
|
30315
|
+
const payload = record2.payload && typeof record2.payload === "object" ? record2.payload : null;
|
|
30316
|
+
const id = record2.type === "session_meta" && typeof payload?.id === "string" ? payload.id : null;
|
|
30212
30317
|
if (id && UUID_RE.test(id)) return id;
|
|
30213
30318
|
}
|
|
30214
30319
|
} catch {
|
|
@@ -30307,15 +30412,15 @@ function messageContentKey(value) {
|
|
|
30307
30412
|
if (!Array.isArray(content)) return null;
|
|
30308
30413
|
return content.map((block) => {
|
|
30309
30414
|
if (!block || typeof block !== "object") return String(block);
|
|
30310
|
-
const
|
|
30311
|
-
const type = String(
|
|
30415
|
+
const record2 = block;
|
|
30416
|
+
const type = String(record2.type ?? "");
|
|
30312
30417
|
if (type === "tool_use") {
|
|
30313
|
-
return `tool_use:${String(
|
|
30418
|
+
return `tool_use:${String(record2.name ?? "")}:${String(record2.id ?? "")}`;
|
|
30314
30419
|
}
|
|
30315
30420
|
if (type === "tool_result") {
|
|
30316
|
-
return `tool_result:${String(
|
|
30421
|
+
return `tool_result:${String(record2.tool_use_id ?? "")}`;
|
|
30317
30422
|
}
|
|
30318
|
-
return String(
|
|
30423
|
+
return String(record2.text ?? type);
|
|
30319
30424
|
}).join("\n");
|
|
30320
30425
|
}
|
|
30321
30426
|
function dedupConsecutiveEvents(raw) {
|
|
@@ -30330,9 +30435,9 @@ function dedupConsecutiveEvents(raw) {
|
|
|
30330
30435
|
index += 1;
|
|
30331
30436
|
continue;
|
|
30332
30437
|
}
|
|
30333
|
-
const
|
|
30334
|
-
const eventType = String(
|
|
30335
|
-
const eventKey = messageContentKey(
|
|
30438
|
+
const record2 = event;
|
|
30439
|
+
const eventType = String(record2.type ?? "");
|
|
30440
|
+
const eventKey = messageContentKey(record2);
|
|
30336
30441
|
if (!["user", "assistant"].includes(eventType) || !eventKey) {
|
|
30337
30442
|
output2.push(rawLines[index] ?? "");
|
|
30338
30443
|
index += 1;
|
|
@@ -30351,9 +30456,9 @@ function dedupConsecutiveEvents(raw) {
|
|
|
30351
30456
|
cursor += 1;
|
|
30352
30457
|
}
|
|
30353
30458
|
if (runCount > 1) {
|
|
30354
|
-
|
|
30355
|
-
|
|
30356
|
-
output2.push(JSON.stringify(
|
|
30459
|
+
record2._repeat_count = runCount;
|
|
30460
|
+
record2._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
|
|
30461
|
+
output2.push(JSON.stringify(record2));
|
|
30357
30462
|
index = cursor;
|
|
30358
30463
|
continue;
|
|
30359
30464
|
}
|
|
@@ -30398,9 +30503,9 @@ function selectiveCompactToolResults(raw) {
|
|
|
30398
30503
|
lines.push(line);
|
|
30399
30504
|
continue;
|
|
30400
30505
|
}
|
|
30401
|
-
const
|
|
30402
|
-
if (
|
|
30403
|
-
const message =
|
|
30506
|
+
const record2 = parsed;
|
|
30507
|
+
if (record2.type === "user") {
|
|
30508
|
+
const message = record2.message;
|
|
30404
30509
|
const content = message && typeof message === "object" ? message.content : null;
|
|
30405
30510
|
if (Array.isArray(content)) {
|
|
30406
30511
|
message.content = content.map(
|
|
@@ -30408,7 +30513,7 @@ function selectiveCompactToolResults(raw) {
|
|
|
30408
30513
|
);
|
|
30409
30514
|
}
|
|
30410
30515
|
}
|
|
30411
|
-
lines.push(JSON.stringify(
|
|
30516
|
+
lines.push(JSON.stringify(record2));
|
|
30412
30517
|
}
|
|
30413
30518
|
return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
|
|
30414
30519
|
` : "", "utf8");
|
|
@@ -30434,15 +30539,15 @@ function compactCodexEvents(raw) {
|
|
|
30434
30539
|
lines.push(rawLines[index] ?? "");
|
|
30435
30540
|
return;
|
|
30436
30541
|
}
|
|
30437
|
-
const
|
|
30438
|
-
if (
|
|
30439
|
-
const payload =
|
|
30542
|
+
const record2 = event;
|
|
30543
|
+
if (record2.type === "world_state") return;
|
|
30544
|
+
const payload = record2.payload;
|
|
30440
30545
|
const payloadType = payload && typeof payload === "object" ? String(payload.type ?? "") : "";
|
|
30441
30546
|
if (payloadType === "token_count" && index !== lastTokenCountIndex) return;
|
|
30442
30547
|
if (payloadType === "custom_tool_call_output" || payloadType === "function_call_output" || payloadType === "tool_search_output") {
|
|
30443
30548
|
const record_payload = payload;
|
|
30444
30549
|
record_payload.output = compactEventValue(record_payload.output);
|
|
30445
|
-
lines.push(JSON.stringify(
|
|
30550
|
+
lines.push(JSON.stringify(record2));
|
|
30446
30551
|
return;
|
|
30447
30552
|
}
|
|
30448
30553
|
lines.push(rawLines[index] ?? "");
|
|
@@ -30905,8 +31010,325 @@ Examples:
|
|
|
30905
31010
|
}
|
|
30906
31011
|
|
|
30907
31012
|
// src/cli/commands/monitors.ts
|
|
30908
|
-
import {
|
|
31013
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
31014
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync12 } from "fs";
|
|
31015
|
+
import { resolve as resolve14 } from "path";
|
|
30909
31016
|
import { createInterface } from "readline/promises";
|
|
31017
|
+
|
|
31018
|
+
// src/monitor-fleet-contract.ts
|
|
31019
|
+
var MONITOR_FLEET_MAX_MEMBERS = 1e3;
|
|
31020
|
+
var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
|
|
31021
|
+
var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
|
|
31022
|
+
MONITOR_FLEET_AUTHORING_CONTRACT_EDITION
|
|
31023
|
+
];
|
|
31024
|
+
var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
|
|
31025
|
+
var MONITOR_FLEET_DOCUMENTATION = {
|
|
31026
|
+
summary: "A Monitor Fleet keeps one bounded, sticky set of ordinary monitors aligned with Customer DB rows.",
|
|
31027
|
+
authoredFields: {
|
|
31028
|
+
id: "Stable lowercase fleet id used by sync, pause, resume, and deactivate.",
|
|
31029
|
+
source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
|
|
31030
|
+
member: "Ordinary monitor tool, stable key template, and payload evaluated for each selected source row.",
|
|
31031
|
+
selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
|
|
31032
|
+
},
|
|
31033
|
+
fixedPolicy: {
|
|
31034
|
+
cadence: "daily",
|
|
31035
|
+
membership: "sticky",
|
|
31036
|
+
removalGrace: "7d",
|
|
31037
|
+
onRemoved: "deactivate",
|
|
31038
|
+
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.",
|
|
31039
|
+
billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
|
|
31040
|
+
},
|
|
31041
|
+
stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
|
|
31042
|
+
columnExpression: 'Use { "$fleet": "column", "name": "column_name" } in a member key or payload to read a value from each source row.'
|
|
31043
|
+
};
|
|
31044
|
+
function record(value) {
|
|
31045
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
31046
|
+
}
|
|
31047
|
+
function identifier(value) {
|
|
31048
|
+
return typeof value === "string" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value);
|
|
31049
|
+
}
|
|
31050
|
+
function exactKeys(input2, keys, path, issues) {
|
|
31051
|
+
if (!input2) return;
|
|
31052
|
+
for (const key of Object.keys(input2)) {
|
|
31053
|
+
if (keys.includes(key)) continue;
|
|
31054
|
+
issues.push({
|
|
31055
|
+
path: path ? `${path}.${key}` : key,
|
|
31056
|
+
code: "unknown_fleet_field",
|
|
31057
|
+
message: `${path || "Fleet"} does not accept '${key}'.`
|
|
31058
|
+
});
|
|
31059
|
+
}
|
|
31060
|
+
}
|
|
31061
|
+
function jsonValue(value, path, issues) {
|
|
31062
|
+
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
|
|
31063
|
+
return;
|
|
31064
|
+
}
|
|
31065
|
+
if (Array.isArray(value)) {
|
|
31066
|
+
value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
|
|
31067
|
+
return;
|
|
31068
|
+
}
|
|
31069
|
+
const input2 = record(value);
|
|
31070
|
+
if (!input2) {
|
|
31071
|
+
issues.push({
|
|
31072
|
+
path,
|
|
31073
|
+
code: "invalid_fleet_json_value",
|
|
31074
|
+
message: "Fleet payload values must be JSON values."
|
|
31075
|
+
});
|
|
31076
|
+
return;
|
|
31077
|
+
}
|
|
31078
|
+
for (const [key, item] of Object.entries(input2)) {
|
|
31079
|
+
jsonValue(item, `${path}.${key}`, issues);
|
|
31080
|
+
}
|
|
31081
|
+
}
|
|
31082
|
+
function validateExpression(value, path, issues) {
|
|
31083
|
+
const input2 = record(value);
|
|
31084
|
+
if (!input2 || input2.$fleet !== "column" || !identifier(input2.name)) {
|
|
31085
|
+
issues.push({
|
|
31086
|
+
path,
|
|
31087
|
+
code: "invalid_fleet_expression",
|
|
31088
|
+
message: "Fleet expressions must be an exact tagged column reference."
|
|
31089
|
+
});
|
|
31090
|
+
return;
|
|
31091
|
+
}
|
|
31092
|
+
exactKeys(input2, ["$fleet", "name"], path, issues);
|
|
31093
|
+
}
|
|
31094
|
+
function walkPayload(value, path, issues) {
|
|
31095
|
+
if (Array.isArray(value)) {
|
|
31096
|
+
value.forEach(
|
|
31097
|
+
(item, index) => walkPayload(item, `${path}.${index}`, issues)
|
|
31098
|
+
);
|
|
31099
|
+
return;
|
|
31100
|
+
}
|
|
31101
|
+
const input2 = record(value);
|
|
31102
|
+
if (!input2) return;
|
|
31103
|
+
if ("$fleet" in input2) {
|
|
31104
|
+
validateExpression(input2, path, issues);
|
|
31105
|
+
return;
|
|
31106
|
+
}
|
|
31107
|
+
for (const [key, item] of Object.entries(input2)) {
|
|
31108
|
+
walkPayload(item, `${path}.${key}`, issues);
|
|
31109
|
+
}
|
|
31110
|
+
}
|
|
31111
|
+
function validateMonitorFleetDefinition(value) {
|
|
31112
|
+
const issues = [];
|
|
31113
|
+
const input2 = record(value);
|
|
31114
|
+
if (!input2) {
|
|
31115
|
+
return {
|
|
31116
|
+
valid: false,
|
|
31117
|
+
issues: [
|
|
31118
|
+
{
|
|
31119
|
+
path: "",
|
|
31120
|
+
code: "invalid_fleet",
|
|
31121
|
+
message: "Fleet must be an object."
|
|
31122
|
+
}
|
|
31123
|
+
]
|
|
31124
|
+
};
|
|
31125
|
+
}
|
|
31126
|
+
exactKeys(input2, ["id", "source", "member", "selection"], "", issues);
|
|
31127
|
+
if (typeof input2.id !== "string" || !/^[a-z][a-z0-9-]{0,199}$/.test(input2.id)) {
|
|
31128
|
+
issues.push({
|
|
31129
|
+
path: "id",
|
|
31130
|
+
code: "invalid_fleet_id",
|
|
31131
|
+
message: "Fleet id must be lowercase kebab-case."
|
|
31132
|
+
});
|
|
31133
|
+
}
|
|
31134
|
+
const source = record(input2.source);
|
|
31135
|
+
exactKeys(
|
|
31136
|
+
source,
|
|
31137
|
+
["kind", "schema", "table", "key", "where"],
|
|
31138
|
+
"source",
|
|
31139
|
+
issues
|
|
31140
|
+
);
|
|
31141
|
+
if (!source || source.kind !== "customer_db_table") {
|
|
31142
|
+
issues.push({
|
|
31143
|
+
path: "source.kind",
|
|
31144
|
+
code: "invalid_fleet_source",
|
|
31145
|
+
message: "Beta fleets require customer_db_table."
|
|
31146
|
+
});
|
|
31147
|
+
}
|
|
31148
|
+
if (!identifier(source?.schema) || !identifier(source?.table)) {
|
|
31149
|
+
issues.push({
|
|
31150
|
+
path: "source",
|
|
31151
|
+
code: "invalid_fleet_table",
|
|
31152
|
+
message: "Source schema and table must be SQL identifiers."
|
|
31153
|
+
});
|
|
31154
|
+
}
|
|
31155
|
+
const sourceKey = record(source?.key);
|
|
31156
|
+
exactKeys(sourceKey, ["column", "type"], "source.key", issues);
|
|
31157
|
+
if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
|
|
31158
|
+
issues.push({
|
|
31159
|
+
path: "source.key",
|
|
31160
|
+
code: "invalid_fleet_source_key",
|
|
31161
|
+
message: "Source key must name a supported typed column."
|
|
31162
|
+
});
|
|
31163
|
+
}
|
|
31164
|
+
if (source?.where !== void 0) {
|
|
31165
|
+
const where = record(source.where);
|
|
31166
|
+
if (!where) {
|
|
31167
|
+
issues.push({
|
|
31168
|
+
path: "source.where",
|
|
31169
|
+
code: "invalid_fleet_where",
|
|
31170
|
+
message: "source.where must be an object of equality values."
|
|
31171
|
+
});
|
|
31172
|
+
} else {
|
|
31173
|
+
for (const [column, expected] of Object.entries(where)) {
|
|
31174
|
+
if (!identifier(column)) {
|
|
31175
|
+
issues.push({
|
|
31176
|
+
path: `source.where.${column}`,
|
|
31177
|
+
code: "invalid_fleet_where_column",
|
|
31178
|
+
message: "source.where keys must be SQL identifiers."
|
|
31179
|
+
});
|
|
31180
|
+
}
|
|
31181
|
+
if (expected !== null && typeof expected !== "string" && typeof expected !== "boolean" && !(typeof expected === "number" && Number.isFinite(expected))) {
|
|
31182
|
+
issues.push({
|
|
31183
|
+
path: `source.where.${column}`,
|
|
31184
|
+
code: "invalid_fleet_where_value",
|
|
31185
|
+
message: "source.where values must be finite JSON scalars or null."
|
|
31186
|
+
});
|
|
31187
|
+
}
|
|
31188
|
+
}
|
|
31189
|
+
}
|
|
31190
|
+
}
|
|
31191
|
+
const member = record(input2.member);
|
|
31192
|
+
exactKeys(member, ["tool", "key", "payload"], "member", issues);
|
|
31193
|
+
const key = record(member?.key);
|
|
31194
|
+
if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
|
|
31195
|
+
issues.push({
|
|
31196
|
+
path: "member.tool",
|
|
31197
|
+
code: "invalid_fleet_tool",
|
|
31198
|
+
message: "Member tool is required."
|
|
31199
|
+
});
|
|
31200
|
+
}
|
|
31201
|
+
if (!key || key.$fleet !== "template" || !Array.isArray(key.parts) || key.parts.length === 0) {
|
|
31202
|
+
issues.push({
|
|
31203
|
+
path: "member.key",
|
|
31204
|
+
code: "invalid_fleet_key",
|
|
31205
|
+
message: "Member key must be a tagged fleet template."
|
|
31206
|
+
});
|
|
31207
|
+
} else {
|
|
31208
|
+
exactKeys(key, ["$fleet", "parts"], "member.key", issues);
|
|
31209
|
+
for (const [index, part] of key.parts.entries()) {
|
|
31210
|
+
if (typeof part !== "string")
|
|
31211
|
+
validateExpression(part, `member.key.parts.${index}`, issues);
|
|
31212
|
+
}
|
|
31213
|
+
if (sourceKey && !key.parts.some(
|
|
31214
|
+
(part) => record(part)?.$fleet === "column" && record(part)?.name === sourceKey.column
|
|
31215
|
+
)) {
|
|
31216
|
+
issues.push({
|
|
31217
|
+
path: "member.key.parts",
|
|
31218
|
+
code: "fleet_key_missing_source_key",
|
|
31219
|
+
message: "Member key must include the source key column."
|
|
31220
|
+
});
|
|
31221
|
+
}
|
|
31222
|
+
}
|
|
31223
|
+
if (!member || !("payload" in member)) {
|
|
31224
|
+
issues.push({
|
|
31225
|
+
path: "member.payload",
|
|
31226
|
+
code: "invalid_fleet_payload",
|
|
31227
|
+
message: "Member payload is required."
|
|
31228
|
+
});
|
|
31229
|
+
} else {
|
|
31230
|
+
jsonValue(member.payload, "member.payload", issues);
|
|
31231
|
+
}
|
|
31232
|
+
walkPayload(member?.payload, "member.payload", issues);
|
|
31233
|
+
const selection = record(input2.selection);
|
|
31234
|
+
exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
|
|
31235
|
+
if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
|
|
31236
|
+
issues.push({
|
|
31237
|
+
path: "selection.limit",
|
|
31238
|
+
code: "MONITOR_FLEET_LIMIT_EXCEEDED",
|
|
31239
|
+
message: "selection.limit must be between 1 and 1,000."
|
|
31240
|
+
});
|
|
31241
|
+
}
|
|
31242
|
+
if (selection?.membership !== "sticky") {
|
|
31243
|
+
issues.push({
|
|
31244
|
+
path: "selection.membership",
|
|
31245
|
+
code: "invalid_fleet_membership",
|
|
31246
|
+
message: `Fleet membership is fixed to ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.membership}. ${MONITOR_FLEET_DOCUMENTATION.stickyMembership}`
|
|
31247
|
+
});
|
|
31248
|
+
}
|
|
31249
|
+
const orderBy = selection?.orderBy;
|
|
31250
|
+
if (!Array.isArray(orderBy) || orderBy.length === 0) {
|
|
31251
|
+
issues.push({
|
|
31252
|
+
path: "selection.orderBy",
|
|
31253
|
+
code: "invalid_fleet_order",
|
|
31254
|
+
message: "At least one deterministic order field is required."
|
|
31255
|
+
});
|
|
31256
|
+
} else {
|
|
31257
|
+
const orderColumns = /* @__PURE__ */ new Set();
|
|
31258
|
+
for (const [index, order] of orderBy.entries()) {
|
|
31259
|
+
const item = record(order);
|
|
31260
|
+
exactKeys(
|
|
31261
|
+
item,
|
|
31262
|
+
["column", "direction"],
|
|
31263
|
+
`selection.orderBy.${index}`,
|
|
31264
|
+
issues
|
|
31265
|
+
);
|
|
31266
|
+
if (!item || !identifier(item.column) || !["asc", "desc"].includes(String(item.direction))) {
|
|
31267
|
+
issues.push({
|
|
31268
|
+
path: `selection.orderBy.${index}`,
|
|
31269
|
+
code: "invalid_fleet_order",
|
|
31270
|
+
message: "Order fields need a column and asc/desc direction."
|
|
31271
|
+
});
|
|
31272
|
+
} else if (orderColumns.has(item.column)) {
|
|
31273
|
+
issues.push({
|
|
31274
|
+
path: `selection.orderBy.${index}.column`,
|
|
31275
|
+
code: "duplicate_fleet_order_column",
|
|
31276
|
+
message: "Each selection order column may appear only once."
|
|
31277
|
+
});
|
|
31278
|
+
} else {
|
|
31279
|
+
orderColumns.add(item.column);
|
|
31280
|
+
}
|
|
31281
|
+
}
|
|
31282
|
+
if (sourceKey && record(orderBy.at(-1))?.column !== sourceKey.column) {
|
|
31283
|
+
issues.push({
|
|
31284
|
+
path: "selection.orderBy",
|
|
31285
|
+
code: "fleet_order_missing_key",
|
|
31286
|
+
message: "The final order field must be the source key."
|
|
31287
|
+
});
|
|
31288
|
+
}
|
|
31289
|
+
}
|
|
31290
|
+
for (const removedOption of ["spendLimits", "lifecycle", "reconciliation"]) {
|
|
31291
|
+
if (removedOption in input2) {
|
|
31292
|
+
issues.push({
|
|
31293
|
+
path: removedOption,
|
|
31294
|
+
code: "unsupported_fleet_option",
|
|
31295
|
+
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.`
|
|
31296
|
+
});
|
|
31297
|
+
}
|
|
31298
|
+
}
|
|
31299
|
+
return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
|
|
31300
|
+
}
|
|
31301
|
+
function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHORING_CONTRACT_EDITION) {
|
|
31302
|
+
if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
|
|
31303
|
+
edition
|
|
31304
|
+
)) {
|
|
31305
|
+
return {
|
|
31306
|
+
valid: false,
|
|
31307
|
+
issues: [
|
|
31308
|
+
{
|
|
31309
|
+
path: "authoring_contract_edition",
|
|
31310
|
+
code: "unsupported_fleet_authoring_contract_edition",
|
|
31311
|
+
message: `Monitor Fleet authoring contract edition ${edition} is not supported.`
|
|
31312
|
+
}
|
|
31313
|
+
]
|
|
31314
|
+
};
|
|
31315
|
+
}
|
|
31316
|
+
const result = validateMonitorFleetDefinition(value);
|
|
31317
|
+
return result.valid && result.definition ? {
|
|
31318
|
+
valid: true,
|
|
31319
|
+
contract: {
|
|
31320
|
+
edition,
|
|
31321
|
+
// JSON cloning prevents later caller mutation from changing the
|
|
31322
|
+
// admitted snapshot.
|
|
31323
|
+
definition: JSON.parse(
|
|
31324
|
+
JSON.stringify(result.definition)
|
|
31325
|
+
)
|
|
31326
|
+
},
|
|
31327
|
+
issues: []
|
|
31328
|
+
} : { valid: false, issues: result.issues };
|
|
31329
|
+
}
|
|
31330
|
+
|
|
31331
|
+
// src/cli/commands/monitors.ts
|
|
30910
31332
|
var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
|
|
30911
31333
|
function withJsonOption(command) {
|
|
30912
31334
|
return command.option("--json", JSON_OPTION_DESCRIPTION);
|
|
@@ -30928,6 +31350,7 @@ var MonitorDryRunUnsupportedError = class extends Error {
|
|
|
30928
31350
|
};
|
|
30929
31351
|
function monitorsErrorExitCode(error) {
|
|
30930
31352
|
if (error instanceof MonitorsUsageError) return 2;
|
|
31353
|
+
if (error instanceof MonitorFleetStateError) return 6;
|
|
30931
31354
|
if (error instanceof AuthError) return 3;
|
|
30932
31355
|
if (error instanceof DeeplineError) {
|
|
30933
31356
|
const status = error.statusCode;
|
|
@@ -30938,12 +31361,14 @@ function monitorsErrorExitCode(error) {
|
|
|
30938
31361
|
}
|
|
30939
31362
|
return 5;
|
|
30940
31363
|
}
|
|
30941
|
-
function monitorsFailureNextCommand(error, exitCode) {
|
|
31364
|
+
function monitorsFailureNextCommand(error, exitCode, options) {
|
|
31365
|
+
if (error instanceof MonitorFleetStateError) return error.next;
|
|
30942
31366
|
if (error instanceof DeeplineError) {
|
|
30943
31367
|
const response = asRecord2(asRecord2(error.details)?.response);
|
|
30944
|
-
const
|
|
30945
|
-
if (
|
|
31368
|
+
const serverNext = asString(response?.next) ?? asString(response?.next_action);
|
|
31369
|
+
if (serverNext) return serverNext;
|
|
30946
31370
|
}
|
|
31371
|
+
if (exitCode === 5 && options?.retryCommand) return options.retryCommand;
|
|
30947
31372
|
if (error instanceof DeeplineError && error.code === "monitor_access_required") {
|
|
30948
31373
|
return "deepline monitors status";
|
|
30949
31374
|
}
|
|
@@ -30969,9 +31394,10 @@ function readValidationIssues(error) {
|
|
|
30969
31394
|
];
|
|
30970
31395
|
});
|
|
30971
31396
|
}
|
|
30972
|
-
function reportMonitorsFailure(error) {
|
|
31397
|
+
function reportMonitorsFailure(error, options) {
|
|
30973
31398
|
const exitCode = monitorsErrorExitCode(error);
|
|
30974
|
-
const next = monitorsFailureNextCommand(error, exitCode);
|
|
31399
|
+
const next = monitorsFailureNextCommand(error, exitCode, options);
|
|
31400
|
+
const retrySafe = exitCode === 5 && options?.retryCommand !== void 0;
|
|
30975
31401
|
const wantsJson = shouldEmitJson(process.argv.includes("--json"));
|
|
30976
31402
|
if (wantsJson) {
|
|
30977
31403
|
const payload = errorToJsonPayload(error);
|
|
@@ -30979,10 +31405,15 @@ function reportMonitorsFailure(error) {
|
|
|
30979
31405
|
ok: false,
|
|
30980
31406
|
exitCode,
|
|
30981
31407
|
...next ? { next } : {},
|
|
30982
|
-
|
|
31408
|
+
...retrySafe ? { retry_safe: true } : {},
|
|
31409
|
+
error: retrySafe ? {
|
|
31410
|
+
...payload.error,
|
|
31411
|
+
message: `${payload.error.message} ${FLEET_RETRY_SAFE_NOTE}`
|
|
31412
|
+
} : payload.error
|
|
30983
31413
|
});
|
|
30984
31414
|
} else {
|
|
30985
|
-
const
|
|
31415
|
+
const base = error instanceof Error ? error.message : String(error);
|
|
31416
|
+
const message = retrySafe ? `${base} ${FLEET_RETRY_SAFE_NOTE}` : base;
|
|
30986
31417
|
process.stderr.write(`Error: ${message}
|
|
30987
31418
|
`);
|
|
30988
31419
|
for (const issue of readValidationIssues(error)) {
|
|
@@ -31533,6 +31964,724 @@ async function handleMonitorsDeploy(definition, options) {
|
|
|
31533
31964
|
text: renderMonitorDeployCompletion(payload)
|
|
31534
31965
|
});
|
|
31535
31966
|
}
|
|
31967
|
+
function fleetIntegerOption(raw, flag) {
|
|
31968
|
+
if (raw === void 0) return void 0;
|
|
31969
|
+
const value = Number(raw);
|
|
31970
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
31971
|
+
throw new MonitorsUsageError(`${flag} must be a non-negative integer.`);
|
|
31972
|
+
}
|
|
31973
|
+
return value;
|
|
31974
|
+
}
|
|
31975
|
+
function fleetIdempotencyKey(operation, supplied) {
|
|
31976
|
+
const normalized = supplied?.trim();
|
|
31977
|
+
if (supplied !== void 0 && !normalized) {
|
|
31978
|
+
throw new MonitorsUsageError("--idempotency-key must not be empty.");
|
|
31979
|
+
}
|
|
31980
|
+
return normalized ?? `monitor-fleet-${operation}-${randomUUID5()}`;
|
|
31981
|
+
}
|
|
31982
|
+
var FLEET_COUNT_KEYS = [
|
|
31983
|
+
"pending",
|
|
31984
|
+
"submitting",
|
|
31985
|
+
"rate_limited",
|
|
31986
|
+
"settled",
|
|
31987
|
+
"blocked",
|
|
31988
|
+
"failed"
|
|
31989
|
+
];
|
|
31990
|
+
var FLEET_DEFAULT_WAIT_MS = 10 * 6e4;
|
|
31991
|
+
var FLEET_POLL_INTERVAL_MS = 2e3;
|
|
31992
|
+
var FLEET_PLAIN_PROGRESS_INTERVAL_MS = 15e3;
|
|
31993
|
+
var FLEET_RETRY_SAFE_NOTE = "Safe to retry \u2014 every fleet command is idempotent.";
|
|
31994
|
+
var MONITOR_FLEET_LIFECYCLE = [
|
|
31995
|
+
{
|
|
31996
|
+
step: 1,
|
|
31997
|
+
what: "Write a definition file you can read and edit.",
|
|
31998
|
+
command: "deepline monitors fleets init <fleet-id> --source public.accounts --key account_id --tool <tool> --payload '<json>' --out fleet.json"
|
|
31999
|
+
},
|
|
32000
|
+
{
|
|
32001
|
+
step: 2,
|
|
32002
|
+
what: "See the plan and the credits before anything changes.",
|
|
32003
|
+
command: "deepline monitors fleets sync --file fleet.json --dry-run"
|
|
32004
|
+
},
|
|
32005
|
+
{
|
|
32006
|
+
step: 3,
|
|
32007
|
+
what: "Apply it and wait for the server to call it converged.",
|
|
32008
|
+
command: "deepline monitors fleets sync --file fleet.json --wait"
|
|
32009
|
+
},
|
|
32010
|
+
{
|
|
32011
|
+
step: 4,
|
|
32012
|
+
what: "Read live state; add --drift to see what has not settled.",
|
|
32013
|
+
command: "deepline monitors fleets get <fleet-id>"
|
|
32014
|
+
}
|
|
32015
|
+
];
|
|
32016
|
+
var MONITOR_FLEET_COMMANDS = [
|
|
32017
|
+
{ name: "init", summary: "Write a Fleet definition JSON file." },
|
|
32018
|
+
{
|
|
32019
|
+
name: "sync",
|
|
32020
|
+
summary: "Create or re-plan a fleet from a definition file or its stored config."
|
|
32021
|
+
},
|
|
32022
|
+
{
|
|
32023
|
+
name: "get",
|
|
32024
|
+
summary: "Read one fleet, list every fleet, or inspect drift."
|
|
32025
|
+
},
|
|
32026
|
+
{
|
|
32027
|
+
name: "deactivate",
|
|
32028
|
+
summary: "Deactivate a fleet and the monitors it owns."
|
|
32029
|
+
}
|
|
32030
|
+
];
|
|
32031
|
+
var MONITOR_FLEET_AGENT_NOTES = [
|
|
32032
|
+
"Add --json for stable output; stdout is always exactly one JSON object.",
|
|
32033
|
+
"Every error includes a runnable `next` command \u2014 run it, do not guess.",
|
|
32034
|
+
"Exit 5 = retry the same command; 6 = inspect counts with `get --drift`; 7 = change the request."
|
|
32035
|
+
];
|
|
32036
|
+
var MONITOR_FLEET_HELP_EPILOG = `
|
|
32037
|
+
Agent notes:
|
|
32038
|
+
${MONITOR_FLEET_AGENT_NOTES.join("\n ")}
|
|
32039
|
+
`;
|
|
32040
|
+
var MonitorFleetStateError = class extends Error {
|
|
32041
|
+
code;
|
|
32042
|
+
next;
|
|
32043
|
+
constructor(input2) {
|
|
32044
|
+
super(input2.message);
|
|
32045
|
+
this.name = "MonitorFleetStateError";
|
|
32046
|
+
this.code = input2.code;
|
|
32047
|
+
this.next = input2.next;
|
|
32048
|
+
}
|
|
32049
|
+
};
|
|
32050
|
+
function fleetCounts(payload) {
|
|
32051
|
+
const raw = asRecord2(payload.counts) ?? {};
|
|
32052
|
+
const counts = {};
|
|
32053
|
+
for (const key of FLEET_COUNT_KEYS) {
|
|
32054
|
+
counts[key] = asFiniteNumber(raw[key]) ?? 0;
|
|
32055
|
+
}
|
|
32056
|
+
return counts;
|
|
32057
|
+
}
|
|
32058
|
+
function fleetShellArg(value) {
|
|
32059
|
+
return /^[A-Za-z0-9._/@:=-]+$/.test(value) ? value : `'${value.replaceAll("'", `'\\''`)}'`;
|
|
32060
|
+
}
|
|
32061
|
+
function fleetJsonFlag(options) {
|
|
32062
|
+
return options.json ? ["--json"] : [];
|
|
32063
|
+
}
|
|
32064
|
+
function fleetTimeoutMs(raw) {
|
|
32065
|
+
if (raw === void 0) return FLEET_DEFAULT_WAIT_MS;
|
|
32066
|
+
const match = /^(\d+)(ms|s|m|h)?$/.exec(raw.trim());
|
|
32067
|
+
if (!match) {
|
|
32068
|
+
throw new MonitorsUsageError(
|
|
32069
|
+
"--timeout must be a duration like 500ms, 90s, 10m, or 1h (a bare number is seconds)."
|
|
32070
|
+
);
|
|
32071
|
+
}
|
|
32072
|
+
const value = Number(match[1]);
|
|
32073
|
+
if (!value) {
|
|
32074
|
+
throw new MonitorsUsageError("--timeout must be greater than zero.");
|
|
32075
|
+
}
|
|
32076
|
+
const unit = match[2] ?? "s";
|
|
32077
|
+
const factor = unit === "ms" ? 1 : unit === "s" ? 1e3 : unit === "m" ? 6e4 : 36e5;
|
|
32078
|
+
return value * factor;
|
|
32079
|
+
}
|
|
32080
|
+
function fleetServerNext(payload) {
|
|
32081
|
+
return asString(payload.next) ?? asString(payload.next_action);
|
|
32082
|
+
}
|
|
32083
|
+
function fleetStatus(payload) {
|
|
32084
|
+
return asString(payload.status);
|
|
32085
|
+
}
|
|
32086
|
+
function fleetProgressReporter() {
|
|
32087
|
+
const interactive = process.stderr.isTTY === true;
|
|
32088
|
+
let wrote = false;
|
|
32089
|
+
let lastPlainAt = 0;
|
|
32090
|
+
return {
|
|
32091
|
+
report: (payload) => {
|
|
32092
|
+
const counts = fleetCounts(payload);
|
|
32093
|
+
const expected = asFiniteNumber(payload.expected) ?? FLEET_COUNT_KEYS.reduce((sum, key) => sum + counts[key], 0);
|
|
32094
|
+
const line = `settled ${counts.settled}/${expected} \xB7 rate_limited ${counts.rate_limited} \xB7 blocked ${counts.blocked}`;
|
|
32095
|
+
if (interactive) {
|
|
32096
|
+
process.stderr.write(`\r\x1B[2K${line}`);
|
|
32097
|
+
wrote = true;
|
|
32098
|
+
return;
|
|
32099
|
+
}
|
|
32100
|
+
const now = Date.now();
|
|
32101
|
+
if (wrote && now - lastPlainAt < FLEET_PLAIN_PROGRESS_INTERVAL_MS) return;
|
|
32102
|
+
lastPlainAt = now;
|
|
32103
|
+
wrote = true;
|
|
32104
|
+
process.stderr.write(`${line}
|
|
32105
|
+
`);
|
|
32106
|
+
},
|
|
32107
|
+
finish: () => {
|
|
32108
|
+
if (interactive && wrote) process.stderr.write("\n");
|
|
32109
|
+
}
|
|
32110
|
+
};
|
|
32111
|
+
}
|
|
32112
|
+
function fleetPlanLine(payload) {
|
|
32113
|
+
const plan = asRecord2(payload.plan) ?? {};
|
|
32114
|
+
const blocked = asRecord2(plan.blocked) ?? {};
|
|
32115
|
+
const entries = Object.entries(blocked).flatMap(([limitId, raw]) => {
|
|
32116
|
+
const count = asFiniteNumber(raw);
|
|
32117
|
+
return count === void 0 ? [] : [[limitId, count]];
|
|
32118
|
+
}).sort(([left], [right]) => left.localeCompare(right));
|
|
32119
|
+
const blockedTotal = entries.reduce((sum, [, count]) => sum + count, 0);
|
|
32120
|
+
const detail = entries.length === 0 ? "" : entries.length === 1 ? ` (${entries[0][0]})` : ` (${entries.map(([id, count]) => `${id}: ${count}`).join(", ")})`;
|
|
32121
|
+
return [
|
|
32122
|
+
`creates ${asFiniteNumber(plan.creates) ?? 0}`,
|
|
32123
|
+
`updates ${asFiniteNumber(plan.updates) ?? 0}`,
|
|
32124
|
+
`removes ${asFiniteNumber(plan.removes) ?? 0}`,
|
|
32125
|
+
`blocked ${blockedTotal}${detail}`
|
|
32126
|
+
].join(" \xB7 ");
|
|
32127
|
+
}
|
|
32128
|
+
function fleetCountsLine(payload) {
|
|
32129
|
+
const counts = fleetCounts(payload);
|
|
32130
|
+
return FLEET_COUNT_KEYS.map((key) => `${key} ${counts[key]}`).join(" \xB7 ");
|
|
32131
|
+
}
|
|
32132
|
+
function renderFleetSync(payload, input2) {
|
|
32133
|
+
const lines = [
|
|
32134
|
+
input2.dryRun ? `Fleet ${input2.fleetId} \u2014 plan only, nothing changed` : `Fleet ${input2.fleetId} \u2014 accepted`,
|
|
32135
|
+
` plan ${fleetPlanLine(payload)}`
|
|
32136
|
+
];
|
|
32137
|
+
const credits = asFiniteNumber(payload.credits_due_now);
|
|
32138
|
+
lines.push(` credits due now ${credits ?? 0}`);
|
|
32139
|
+
lines.push(
|
|
32140
|
+
` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 replayed ${yesNo(
|
|
32141
|
+
payload.replayed
|
|
32142
|
+
)} \xB7 idempotency key ${input2.idempotencyKey}`
|
|
32143
|
+
);
|
|
32144
|
+
const next = fleetServerNext(payload);
|
|
32145
|
+
if (next) lines.push(`Next: ${next}`);
|
|
32146
|
+
return `${lines.join("\n")}
|
|
32147
|
+
`;
|
|
32148
|
+
}
|
|
32149
|
+
function renderFleetGet(payload) {
|
|
32150
|
+
const id = asString(payload.id) ?? "unknown";
|
|
32151
|
+
const status = fleetStatus(payload) ?? "unknown";
|
|
32152
|
+
const lines = [
|
|
32153
|
+
`Fleet ${id} \u2014 ${status}`,
|
|
32154
|
+
` monitors ${asFiniteNumber(payload.live) ?? 0} live / ${asFiniteNumber(payload.expected) ?? 0} expected`,
|
|
32155
|
+
` counts ${fleetCountsLine(payload)}`,
|
|
32156
|
+
` generation ${asFiniteNumber(payload.generation) ?? "unknown"} \xB7 converged generation ${asFiniteNumber(payload.converged_generation) ?? "none"}`
|
|
32157
|
+
];
|
|
32158
|
+
lines.push(...renderFleetDriftRows(payload));
|
|
32159
|
+
const next = fleetServerNext(payload) ?? (status === "degraded" ? `deepline monitors fleets get ${fleetShellArg(id)} --drift` : void 0);
|
|
32160
|
+
if (next) lines.push(`Next: ${next}`);
|
|
32161
|
+
return `${lines.join("\n")}
|
|
32162
|
+
`;
|
|
32163
|
+
}
|
|
32164
|
+
function renderFleetDriftRows(payload) {
|
|
32165
|
+
const drift = Array.isArray(payload.drift) ? payload.drift : void 0;
|
|
32166
|
+
if (!drift) return [];
|
|
32167
|
+
const rows = drift.flatMap((raw) => {
|
|
32168
|
+
const row = asRecord2(raw);
|
|
32169
|
+
return row ? [row] : [];
|
|
32170
|
+
}).map((row) => ({
|
|
32171
|
+
monitorKey: asString(row.monitor_key) ?? "-",
|
|
32172
|
+
entityKey: asString(row.entity_key) ?? "-",
|
|
32173
|
+
convergence: asString(row.convergence) ?? "-",
|
|
32174
|
+
since: asString(row.since) ?? "-",
|
|
32175
|
+
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)}` : "")
|
|
32176
|
+
})).sort(
|
|
32177
|
+
(left, right) => left.monitorKey.localeCompare(right.monitorKey) || left.entityKey.localeCompare(right.entityKey)
|
|
32178
|
+
);
|
|
32179
|
+
if (rows.length === 0) {
|
|
32180
|
+
return [` drift none${payload.truncated === true ? " (truncated)" : ""}`];
|
|
32181
|
+
}
|
|
32182
|
+
const width = (values) => values.reduce((max, value) => Math.max(max, value.length), 0);
|
|
32183
|
+
const monitorWidth = width(rows.map((row) => row.monitorKey));
|
|
32184
|
+
const entityWidth = width(rows.map((row) => row.entityKey));
|
|
32185
|
+
const convergenceWidth = width(rows.map((row) => row.convergence));
|
|
32186
|
+
const lines = [
|
|
32187
|
+
` drift (${rows.length}${payload.truncated === true ? ", truncated" : ""})`
|
|
32188
|
+
];
|
|
32189
|
+
for (const row of rows) {
|
|
32190
|
+
lines.push(
|
|
32191
|
+
` ${row.monitorKey.padEnd(monitorWidth)} ${row.entityKey.padEnd(
|
|
32192
|
+
entityWidth
|
|
32193
|
+
)} ${row.convergence.padEnd(convergenceWidth)} ${row.since}${row.detail ? ` ${row.detail}` : ""}`
|
|
32194
|
+
);
|
|
32195
|
+
}
|
|
32196
|
+
return lines;
|
|
32197
|
+
}
|
|
32198
|
+
function renderFleetList(payload) {
|
|
32199
|
+
const fleets = (Array.isArray(payload.fleets) ? payload.fleets : []).flatMap((raw) => {
|
|
32200
|
+
const fleet = asRecord2(raw);
|
|
32201
|
+
return fleet ? [fleet] : [];
|
|
32202
|
+
}).sort(
|
|
32203
|
+
(left, right) => (asString(left.id) ?? "").localeCompare(asString(right.id) ?? "")
|
|
32204
|
+
);
|
|
32205
|
+
if (fleets.length === 0) {
|
|
32206
|
+
return "No Monitor Fleets in this workspace.\nNext: deepline monitors fleets init <fleet-id> --help\n";
|
|
32207
|
+
}
|
|
32208
|
+
const idWidth = fleets.reduce(
|
|
32209
|
+
(max, fleet) => Math.max(max, (asString(fleet.id) ?? "").length),
|
|
32210
|
+
0
|
|
32211
|
+
);
|
|
32212
|
+
const statusWidth = fleets.reduce(
|
|
32213
|
+
(max, fleet) => Math.max(max, (fleetStatus(fleet) ?? "unknown").length),
|
|
32214
|
+
0
|
|
32215
|
+
);
|
|
32216
|
+
const lines = [`Fleets (${fleets.length})`];
|
|
32217
|
+
for (const fleet of fleets) {
|
|
32218
|
+
const counts = fleetCounts(fleet);
|
|
32219
|
+
const trouble = [
|
|
32220
|
+
counts.blocked ? `blocked ${counts.blocked}` : "",
|
|
32221
|
+
counts.failed ? `failed ${counts.failed}` : ""
|
|
32222
|
+
].filter(Boolean);
|
|
32223
|
+
lines.push(
|
|
32224
|
+
` ${(asString(fleet.id) ?? "-").padEnd(idWidth)} ${(fleetStatus(fleet) ?? "unknown").padEnd(statusWidth)} ${asFiniteNumber(fleet.live) ?? 0}/${asFiniteNumber(fleet.expected) ?? 0}${trouble.length ? ` ${trouble.join(" \xB7 ")}` : ""}`
|
|
32225
|
+
);
|
|
32226
|
+
}
|
|
32227
|
+
return `${lines.join("\n")}
|
|
32228
|
+
`;
|
|
32229
|
+
}
|
|
32230
|
+
function renderFleetDeactivatePlan(payload, fleetId) {
|
|
32231
|
+
const radius = asRecord2(payload.would_deactivate) ?? {};
|
|
32232
|
+
const lines = [
|
|
32233
|
+
`Deactivate fleet ${fleetId} \u2014 plan only, nothing changed`,
|
|
32234
|
+
` would deactivate ${asFiniteNumber(radius.monitors) ?? 0} monitors \xB7 ${asFiniteNumber(radius.accounts) ?? 0} accounts`
|
|
32235
|
+
];
|
|
32236
|
+
const note = asString(payload.note);
|
|
32237
|
+
if (note) lines.push(` ${note}`);
|
|
32238
|
+
lines.push(
|
|
32239
|
+
`Next: ${fleetServerNext(payload) ?? `deepline monitors fleets deactivate ${fleetShellArg(fleetId)} --yes`}`
|
|
32240
|
+
);
|
|
32241
|
+
return `${lines.join("\n")}
|
|
32242
|
+
`;
|
|
32243
|
+
}
|
|
32244
|
+
function reportFleetState(payload, error, options) {
|
|
32245
|
+
printCommandEnvelope(
|
|
32246
|
+
{
|
|
32247
|
+
...payload,
|
|
32248
|
+
code: error.code,
|
|
32249
|
+
message: error.message,
|
|
32250
|
+
next: error.next
|
|
32251
|
+
},
|
|
32252
|
+
{
|
|
32253
|
+
json: options.json,
|
|
32254
|
+
text: `${options.text}${error.message}
|
|
32255
|
+
Next: ${error.next}
|
|
32256
|
+
`
|
|
32257
|
+
}
|
|
32258
|
+
);
|
|
32259
|
+
process.exitCode = monitorsErrorExitCode(error);
|
|
32260
|
+
}
|
|
32261
|
+
function fleetSourceTable(value) {
|
|
32262
|
+
const [schema, table, extra] = value?.trim().split(".") ?? [];
|
|
32263
|
+
if (!schema || !table || extra || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(schema) || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(table)) {
|
|
32264
|
+
throw new MonitorsUsageError(
|
|
32265
|
+
"--source must be a Customer DB table in schema.table form."
|
|
32266
|
+
);
|
|
32267
|
+
}
|
|
32268
|
+
return { schema, table };
|
|
32269
|
+
}
|
|
32270
|
+
function fleetColumnName(value, flag) {
|
|
32271
|
+
const name = value?.trim();
|
|
32272
|
+
if (!name || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
|
|
32273
|
+
throw new MonitorsUsageError(`${flag} must be a SQL column identifier.`);
|
|
32274
|
+
}
|
|
32275
|
+
return name;
|
|
32276
|
+
}
|
|
32277
|
+
function fleetMemberLimit(value) {
|
|
32278
|
+
if (value === void 0) return 1e3;
|
|
32279
|
+
const limit = fleetIntegerOption(value, "--limit");
|
|
32280
|
+
if (!limit || limit > 1e3) {
|
|
32281
|
+
throw new MonitorsUsageError("--limit must be between 1 and 1,000.");
|
|
32282
|
+
}
|
|
32283
|
+
return limit;
|
|
32284
|
+
}
|
|
32285
|
+
function fleetOrderBy(values, sourceKey) {
|
|
32286
|
+
const parsed = (values ?? []).map((value) => {
|
|
32287
|
+
const match = /^([A-Za-z_][A-Za-z0-9_]*):(asc|desc)$/.exec(value.trim());
|
|
32288
|
+
if (!match) {
|
|
32289
|
+
throw new MonitorsUsageError(
|
|
32290
|
+
"--order-by must use column:asc or column:desc."
|
|
32291
|
+
);
|
|
32292
|
+
}
|
|
32293
|
+
return { column: match[1], direction: match[2] };
|
|
32294
|
+
});
|
|
32295
|
+
const seen = /* @__PURE__ */ new Set();
|
|
32296
|
+
for (const order of parsed) {
|
|
32297
|
+
if (seen.has(order.column)) {
|
|
32298
|
+
throw new MonitorsUsageError(
|
|
32299
|
+
`--order-by repeats '${order.column}'. Each column may appear once.`
|
|
32300
|
+
);
|
|
32301
|
+
}
|
|
32302
|
+
seen.add(order.column);
|
|
32303
|
+
}
|
|
32304
|
+
const sourceOrder = parsed.find((order) => order.column === sourceKey);
|
|
32305
|
+
return [
|
|
32306
|
+
...parsed.filter((order) => order.column !== sourceKey),
|
|
32307
|
+
sourceOrder ?? { column: sourceKey, direction: "asc" }
|
|
32308
|
+
];
|
|
32309
|
+
}
|
|
32310
|
+
async function handleMonitorFleetsInit(fleetId, options) {
|
|
32311
|
+
if (!/^[a-z][a-z0-9-]{0,199}$/.test(fleetId)) {
|
|
32312
|
+
throw new MonitorsUsageError("<fleet-id> must be lowercase kebab-case.");
|
|
32313
|
+
}
|
|
32314
|
+
const source = fleetSourceTable(options.source);
|
|
32315
|
+
const key = fleetColumnName(options.key, "--key");
|
|
32316
|
+
const keyType = options.keyType?.trim() ?? "text";
|
|
32317
|
+
if (!["text", "uuid", "int4", "int8"].includes(keyType)) {
|
|
32318
|
+
throw new MonitorsUsageError(
|
|
32319
|
+
"--key-type must be text, uuid, int4, or int8."
|
|
32320
|
+
);
|
|
32321
|
+
}
|
|
32322
|
+
const tool = options.tool?.trim();
|
|
32323
|
+
if (!tool) throw new MonitorsUsageError("--tool is required.");
|
|
32324
|
+
if (!options.payload) {
|
|
32325
|
+
throw new MonitorsUsageError(
|
|
32326
|
+
"--payload is required and must be the monitor payload JSON for --tool."
|
|
32327
|
+
);
|
|
32328
|
+
}
|
|
32329
|
+
const payload = parseJsonObjectArg(options.payload, "--payload");
|
|
32330
|
+
const where = options.where ? parseJsonObjectArg(options.where, "--where") : void 0;
|
|
32331
|
+
const out = options.out?.trim();
|
|
32332
|
+
if (!out) throw new MonitorsUsageError("--out is required.");
|
|
32333
|
+
const authoredDefinition = {
|
|
32334
|
+
id: fleetId,
|
|
32335
|
+
source: {
|
|
32336
|
+
kind: "customer_db_table",
|
|
32337
|
+
schema: source.schema,
|
|
32338
|
+
table: source.table,
|
|
32339
|
+
key: { column: key, type: keyType },
|
|
32340
|
+
...where ? { where } : {}
|
|
32341
|
+
},
|
|
32342
|
+
member: {
|
|
32343
|
+
tool,
|
|
32344
|
+
key: {
|
|
32345
|
+
$fleet: "template",
|
|
32346
|
+
parts: [`${fleetId}-`, { $fleet: "column", name: key }]
|
|
32347
|
+
},
|
|
32348
|
+
payload
|
|
32349
|
+
},
|
|
32350
|
+
selection: {
|
|
32351
|
+
limit: fleetMemberLimit(options.limit),
|
|
32352
|
+
orderBy: fleetOrderBy(options.orderBy, key),
|
|
32353
|
+
membership: "sticky"
|
|
32354
|
+
}
|
|
32355
|
+
};
|
|
32356
|
+
const definition = requireCompiledFleetDefinition(authoredDefinition);
|
|
32357
|
+
const file = resolve14(out);
|
|
32358
|
+
writeFileSync12(file, `${JSON.stringify(definition, null, 2)}
|
|
32359
|
+
`, "utf8");
|
|
32360
|
+
const next = `deepline monitors fleets sync --file ${fleetShellArg(file)} --dry-run --json`;
|
|
32361
|
+
printCommandEnvelope(
|
|
32362
|
+
{ schemaVersion: 1, file, definition, next },
|
|
32363
|
+
{
|
|
32364
|
+
json: options.json,
|
|
32365
|
+
text: `Wrote ${file}
|
|
32366
|
+
Next: ${next}
|
|
32367
|
+
`
|
|
32368
|
+
}
|
|
32369
|
+
);
|
|
32370
|
+
}
|
|
32371
|
+
function requireCompiledFleetDefinition(definition) {
|
|
32372
|
+
const result = admitMonitorFleetAuthoringContract(definition);
|
|
32373
|
+
if (result.valid && result.contract) return result.contract.definition;
|
|
32374
|
+
const messages = result.issues.map((issue) => `${issue.path || "definition"}: ${issue.message}`).join("; ");
|
|
32375
|
+
throw new MonitorsUsageError(
|
|
32376
|
+
`Monitor Fleet definition failed local contract check. ${messages}
|
|
32377
|
+
Fix the file, then re-run: deepline monitors fleets sync --file <fleet.json> --dry-run`
|
|
32378
|
+
);
|
|
32379
|
+
}
|
|
32380
|
+
function fleetSyncCommandLine(target, options) {
|
|
32381
|
+
const parts = ["deepline monitors fleets sync"];
|
|
32382
|
+
if (options.file) parts.push(`--file ${fleetShellArg(options.file)}`);
|
|
32383
|
+
else if (target) parts.push(fleetShellArg(target));
|
|
32384
|
+
if (options.dryRun) parts.push("--dry-run");
|
|
32385
|
+
if (options.wait) parts.push("--wait");
|
|
32386
|
+
if (options.timeout)
|
|
32387
|
+
parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
|
|
32388
|
+
if (options.expectedGeneration !== void 0) {
|
|
32389
|
+
parts.push(
|
|
32390
|
+
`--expected-generation ${fleetShellArg(options.expectedGeneration)}`
|
|
32391
|
+
);
|
|
32392
|
+
}
|
|
32393
|
+
if (options.idempotencyKey) {
|
|
32394
|
+
parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
|
|
32395
|
+
}
|
|
32396
|
+
parts.push(...fleetJsonFlag(options));
|
|
32397
|
+
return parts.join(" ");
|
|
32398
|
+
}
|
|
32399
|
+
async function handleMonitorFleetsSync(target, options, idempotencyKey) {
|
|
32400
|
+
const usesDefinition = options.file !== void 0 || target?.trim().startsWith("{") === true;
|
|
32401
|
+
if (!usesDefinition && !target?.trim()) {
|
|
32402
|
+
throw new MonitorsUsageError(
|
|
32403
|
+
"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"
|
|
32404
|
+
);
|
|
32405
|
+
}
|
|
32406
|
+
const definition = usesDefinition ? requireCompiledFleetDefinition(
|
|
32407
|
+
resolveMonitorJsonBody({
|
|
32408
|
+
positional: target,
|
|
32409
|
+
file: options.file,
|
|
32410
|
+
argLabel: "<definition>",
|
|
32411
|
+
command: "deepline monitors fleets sync"
|
|
32412
|
+
})
|
|
32413
|
+
) : void 0;
|
|
32414
|
+
const fleetId = definition ? asString(definition.id) ?? "" : target.trim();
|
|
32415
|
+
if (!fleetId) {
|
|
32416
|
+
throw new MonitorsUsageError(
|
|
32417
|
+
'The Fleet definition has no id. Add a top-level "id" and re-run.'
|
|
32418
|
+
);
|
|
32419
|
+
}
|
|
32420
|
+
const client2 = new DeeplineClient();
|
|
32421
|
+
const payload = await client2.monitors.fleets.sync(
|
|
32422
|
+
definition ?? fleetId,
|
|
32423
|
+
{
|
|
32424
|
+
...options.dryRun ? { dryRun: true } : {},
|
|
32425
|
+
...options.expectedGeneration !== void 0 ? {
|
|
32426
|
+
expectedGeneration: fleetIntegerOption(
|
|
32427
|
+
options.expectedGeneration,
|
|
32428
|
+
"--expected-generation"
|
|
32429
|
+
)
|
|
32430
|
+
} : {},
|
|
32431
|
+
idempotencyKey
|
|
32432
|
+
}
|
|
32433
|
+
);
|
|
32434
|
+
if (options.dryRun) {
|
|
32435
|
+
assertMonitorDryRunAcknowledged(payload, {
|
|
32436
|
+
command: "deepline monitors fleets sync",
|
|
32437
|
+
mutation: "fleet sync"
|
|
32438
|
+
});
|
|
32439
|
+
}
|
|
32440
|
+
const accepted = { ...payload, idempotency_key: idempotencyKey };
|
|
32441
|
+
if (!options.wait || options.dryRun) {
|
|
32442
|
+
printCommandEnvelope(accepted, {
|
|
32443
|
+
json: options.json,
|
|
32444
|
+
text: renderFleetSync(payload, {
|
|
32445
|
+
fleetId,
|
|
32446
|
+
dryRun: options.dryRun === true,
|
|
32447
|
+
idempotencyKey
|
|
32448
|
+
})
|
|
32449
|
+
});
|
|
32450
|
+
return;
|
|
32451
|
+
}
|
|
32452
|
+
const timeoutMs = fleetTimeoutMs(options.timeout);
|
|
32453
|
+
const progress = fleetProgressReporter();
|
|
32454
|
+
let final;
|
|
32455
|
+
try {
|
|
32456
|
+
final = await client2.monitors.fleets.waitForConvergence(fleetId, {
|
|
32457
|
+
timeoutMs,
|
|
32458
|
+
pollIntervalMs: FLEET_POLL_INTERVAL_MS,
|
|
32459
|
+
onProgress: progress.report
|
|
32460
|
+
});
|
|
32461
|
+
} finally {
|
|
32462
|
+
progress.finish();
|
|
32463
|
+
}
|
|
32464
|
+
const envelope = { ...accepted, ...final };
|
|
32465
|
+
const status = fleetStatus(final);
|
|
32466
|
+
const summary = renderFleetGet(final);
|
|
32467
|
+
if (status === "converged") {
|
|
32468
|
+
printCommandEnvelope(envelope, { json: options.json, text: summary });
|
|
32469
|
+
return;
|
|
32470
|
+
}
|
|
32471
|
+
const driftCommand = `deepline monitors fleets get ${fleetShellArg(fleetId)} --drift --json`;
|
|
32472
|
+
if (status === "degraded") {
|
|
32473
|
+
reportFleetState(
|
|
32474
|
+
envelope,
|
|
32475
|
+
new MonitorFleetStateError({
|
|
32476
|
+
code: "MONITOR_FLEET_DEGRADED",
|
|
32477
|
+
message: `Fleet ${fleetId} is degraded: some members will not converge without a change. Retrying sync will not fix it.`,
|
|
32478
|
+
next: fleetServerNext(final) ?? driftCommand
|
|
32479
|
+
}),
|
|
32480
|
+
{ json: options.json, text: summary }
|
|
32481
|
+
);
|
|
32482
|
+
return;
|
|
32483
|
+
}
|
|
32484
|
+
reportFleetState(
|
|
32485
|
+
envelope,
|
|
32486
|
+
new MonitorFleetStateError({
|
|
32487
|
+
code: "MONITOR_FLEET_WAIT_TIMEOUT",
|
|
32488
|
+
message: `Stopped waiting after ${timeoutMs}ms. Nothing is broken and nothing was lost \u2014 fleet ${fleetId} is still ${status ?? "working"} on the server.`,
|
|
32489
|
+
next: fleetServerNext(final) ?? driftCommand
|
|
32490
|
+
}),
|
|
32491
|
+
{ json: options.json, text: summary }
|
|
32492
|
+
);
|
|
32493
|
+
}
|
|
32494
|
+
async function handleMonitorFleetsGet(fleetId, options) {
|
|
32495
|
+
if (options.drift && !fleetId) {
|
|
32496
|
+
throw new MonitorsUsageError(
|
|
32497
|
+
"--drift needs a fleet id: deepline monitors fleets get <fleet-id> --drift"
|
|
32498
|
+
);
|
|
32499
|
+
}
|
|
32500
|
+
const limit = options.limit === void 0 ? void 0 : fleetIntegerOption(options.limit, "--limit");
|
|
32501
|
+
const client2 = new DeeplineClient();
|
|
32502
|
+
const payload = await client2.monitors.fleets.get(fleetId, {
|
|
32503
|
+
...options.drift ? { drift: true } : {},
|
|
32504
|
+
...limit !== void 0 ? { limit } : {}
|
|
32505
|
+
});
|
|
32506
|
+
const text = fleetId ? renderFleetGet(payload) : renderFleetList(payload);
|
|
32507
|
+
if (!options.check) {
|
|
32508
|
+
printCommandEnvelope(payload, { json: options.json, text });
|
|
32509
|
+
return;
|
|
32510
|
+
}
|
|
32511
|
+
const statuses = fleetId ? [fleetStatus(payload)] : (Array.isArray(payload.fleets) ? payload.fleets : []).map(
|
|
32512
|
+
(raw) => fleetStatus(asRecord2(raw) ?? {})
|
|
32513
|
+
);
|
|
32514
|
+
const unconverged = statuses.filter((status) => status !== "converged");
|
|
32515
|
+
if (unconverged.length === 0) {
|
|
32516
|
+
printCommandEnvelope(payload, { json: options.json, text });
|
|
32517
|
+
return;
|
|
32518
|
+
}
|
|
32519
|
+
const target = fleetId ?? "<fleet-id>";
|
|
32520
|
+
const degraded = unconverged.includes("degraded");
|
|
32521
|
+
reportFleetState(
|
|
32522
|
+
payload,
|
|
32523
|
+
new MonitorFleetStateError({
|
|
32524
|
+
code: degraded ? "MONITOR_FLEET_DEGRADED" : "MONITOR_FLEET_NOT_CONVERGED",
|
|
32525
|
+
message: degraded ? `Fleet ${target} is degraded: members are stuck and retrying will not move them.` : `Fleet ${target} has not converged yet.`,
|
|
32526
|
+
next: fleetServerNext(payload) ?? `deepline monitors fleets get ${fleetShellArg(target)} --drift --json`
|
|
32527
|
+
}),
|
|
32528
|
+
{ json: options.json, text }
|
|
32529
|
+
);
|
|
32530
|
+
}
|
|
32531
|
+
function fleetDeactivateCommandLine(fleetId, options) {
|
|
32532
|
+
const parts = [
|
|
32533
|
+
"deepline monitors fleets deactivate",
|
|
32534
|
+
fleetShellArg(fleetId),
|
|
32535
|
+
"--yes"
|
|
32536
|
+
];
|
|
32537
|
+
if (options.dryRun) parts.push("--dry-run");
|
|
32538
|
+
if (options.wait) parts.push("--wait");
|
|
32539
|
+
if (options.timeout)
|
|
32540
|
+
parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
|
|
32541
|
+
if (options.idempotencyKey) {
|
|
32542
|
+
parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
|
|
32543
|
+
}
|
|
32544
|
+
parts.push(...fleetJsonFlag(options));
|
|
32545
|
+
return parts.join(" ");
|
|
32546
|
+
}
|
|
32547
|
+
async function confirmFleetDeactivate(fleetId, plan) {
|
|
32548
|
+
process.stderr.write(renderFleetDeactivatePlan(plan, fleetId));
|
|
32549
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
32550
|
+
try {
|
|
32551
|
+
const answer = await rl.question(
|
|
32552
|
+
`Deactivate fleet "${fleetId}" and the monitors it owns? [y/N] `
|
|
32553
|
+
);
|
|
32554
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
32555
|
+
} finally {
|
|
32556
|
+
rl.close();
|
|
32557
|
+
}
|
|
32558
|
+
}
|
|
32559
|
+
async function handleMonitorFleetsDeactivate(fleetId, options, idempotencyKey) {
|
|
32560
|
+
const client2 = new DeeplineClient();
|
|
32561
|
+
if (options.dryRun) {
|
|
32562
|
+
const plan = await client2.monitors.fleets.deactivate(fleetId, {
|
|
32563
|
+
dryRun: true,
|
|
32564
|
+
idempotencyKey
|
|
32565
|
+
});
|
|
32566
|
+
assertMonitorDryRunAcknowledged(plan, {
|
|
32567
|
+
command: "deepline monitors fleets deactivate",
|
|
32568
|
+
mutation: "fleet deactivate"
|
|
32569
|
+
});
|
|
32570
|
+
printCommandEnvelope(plan, {
|
|
32571
|
+
json: options.json,
|
|
32572
|
+
text: renderFleetDeactivatePlan(plan, fleetId)
|
|
32573
|
+
});
|
|
32574
|
+
return;
|
|
32575
|
+
}
|
|
32576
|
+
if (!options.yes) {
|
|
32577
|
+
const interactive = process.stdout.isTTY === true && process.stdin.isTTY === true;
|
|
32578
|
+
if (!interactive) {
|
|
32579
|
+
throw new MonitorsUsageError(
|
|
32580
|
+
`deactivate is destructive: it deactivates fleet "${fleetId}" and every monitor it owns. Non-interactive runs must confirm with --yes:
|
|
32581
|
+
${fleetDeactivateCommandLine(fleetId, options)}
|
|
32582
|
+
Preview the blast radius first:
|
|
32583
|
+
deepline monitors fleets deactivate ${fleetShellArg(fleetId)} --dry-run`
|
|
32584
|
+
);
|
|
32585
|
+
}
|
|
32586
|
+
const plan = await client2.monitors.fleets.deactivate(fleetId, {
|
|
32587
|
+
dryRun: true,
|
|
32588
|
+
idempotencyKey: `${idempotencyKey}-plan`
|
|
32589
|
+
});
|
|
32590
|
+
assertMonitorDryRunAcknowledged(plan, {
|
|
32591
|
+
command: "deepline monitors fleets deactivate",
|
|
32592
|
+
mutation: "fleet deactivate"
|
|
32593
|
+
});
|
|
32594
|
+
if (!await confirmFleetDeactivate(fleetId, plan)) {
|
|
32595
|
+
process.stderr.write(
|
|
32596
|
+
`Aborted. Fleet "${fleetId}" was not deactivated.
|
|
32597
|
+
`
|
|
32598
|
+
);
|
|
32599
|
+
process.exitCode = 2;
|
|
32600
|
+
return;
|
|
32601
|
+
}
|
|
32602
|
+
}
|
|
32603
|
+
const payload = await client2.monitors.fleets.deactivate(fleetId, {
|
|
32604
|
+
idempotencyKey
|
|
32605
|
+
});
|
|
32606
|
+
const accepted = { ...payload, idempotency_key: idempotencyKey };
|
|
32607
|
+
if (payload.already === true) {
|
|
32608
|
+
printCommandEnvelope(accepted, {
|
|
32609
|
+
json: options.json,
|
|
32610
|
+
text: `Fleet ${fleetId} is already deactivated.
|
|
32611
|
+
`
|
|
32612
|
+
});
|
|
32613
|
+
return;
|
|
32614
|
+
}
|
|
32615
|
+
const acceptedText = `Fleet ${fleetId} \u2014 ${asString(payload.status) ?? "deactivating"}
|
|
32616
|
+
idempotency key ${idempotencyKey}
|
|
32617
|
+
` + (fleetServerNext(payload) ? `Next: ${fleetServerNext(payload)}
|
|
32618
|
+
` : "");
|
|
32619
|
+
if (!options.wait) {
|
|
32620
|
+
printCommandEnvelope(accepted, {
|
|
32621
|
+
json: options.json,
|
|
32622
|
+
text: acceptedText
|
|
32623
|
+
});
|
|
32624
|
+
return;
|
|
32625
|
+
}
|
|
32626
|
+
const timeoutMs = fleetTimeoutMs(options.timeout);
|
|
32627
|
+
const progress = fleetProgressReporter();
|
|
32628
|
+
let final;
|
|
32629
|
+
try {
|
|
32630
|
+
final = await client2.monitors.fleets.waitForConvergence(fleetId, {
|
|
32631
|
+
timeoutMs,
|
|
32632
|
+
pollIntervalMs: FLEET_POLL_INTERVAL_MS,
|
|
32633
|
+
onProgress: progress.report,
|
|
32634
|
+
until: "deactivated"
|
|
32635
|
+
});
|
|
32636
|
+
} finally {
|
|
32637
|
+
progress.finish();
|
|
32638
|
+
}
|
|
32639
|
+
const envelope = { ...accepted, ...final };
|
|
32640
|
+
const summary = renderFleetGet(final);
|
|
32641
|
+
if (fleetStatus(final) === "deactivated") {
|
|
32642
|
+
printCommandEnvelope(envelope, { json: options.json, text: summary });
|
|
32643
|
+
return;
|
|
32644
|
+
}
|
|
32645
|
+
reportFleetState(
|
|
32646
|
+
envelope,
|
|
32647
|
+
new MonitorFleetStateError({
|
|
32648
|
+
code: "MONITOR_FLEET_WAIT_TIMEOUT",
|
|
32649
|
+
message: `Stopped waiting after ${timeoutMs}ms. Deactivation of fleet ${fleetId} is still in progress on the server; nothing was lost.`,
|
|
32650
|
+
next: fleetServerNext(final) ?? `deepline monitors fleets get ${fleetShellArg(fleetId)} --json`
|
|
32651
|
+
}),
|
|
32652
|
+
{ json: options.json, text: summary }
|
|
32653
|
+
);
|
|
32654
|
+
}
|
|
32655
|
+
function handleMonitorFleetsOverview(options) {
|
|
32656
|
+
const lines = [
|
|
32657
|
+
"Monitor Fleets \u2014 one Customer DB table row, one ordinary monitor.",
|
|
32658
|
+
"",
|
|
32659
|
+
"Lifecycle:",
|
|
32660
|
+
...MONITOR_FLEET_LIFECYCLE.flatMap((entry) => [
|
|
32661
|
+
` ${entry.step}. ${entry.what}`,
|
|
32662
|
+
` ${entry.command}`
|
|
32663
|
+
]),
|
|
32664
|
+
"",
|
|
32665
|
+
"Commands:",
|
|
32666
|
+
...MONITOR_FLEET_COMMANDS.map(
|
|
32667
|
+
(command) => ` ${command.name.padEnd(12)}${command.summary}`
|
|
32668
|
+
),
|
|
32669
|
+
"",
|
|
32670
|
+
"Agent notes:",
|
|
32671
|
+
...MONITOR_FLEET_AGENT_NOTES.map((note) => ` ${note}`)
|
|
32672
|
+
];
|
|
32673
|
+
printCommandEnvelope(
|
|
32674
|
+
{
|
|
32675
|
+
schemaVersion: 1,
|
|
32676
|
+
lifecycle: MONITOR_FLEET_LIFECYCLE,
|
|
32677
|
+
commands: MONITOR_FLEET_COMMANDS,
|
|
32678
|
+
agent_notes: MONITOR_FLEET_AGENT_NOTES,
|
|
32679
|
+
next: MONITOR_FLEET_LIFECYCLE[0].command
|
|
32680
|
+
},
|
|
32681
|
+
{ json: options.json, text: `${lines.join("\n")}
|
|
32682
|
+
` }
|
|
32683
|
+
);
|
|
32684
|
+
}
|
|
31536
32685
|
function renderMonitorGet(payload) {
|
|
31537
32686
|
const key = asString(payload.key);
|
|
31538
32687
|
const tool = asString(payload.tool);
|
|
@@ -31782,7 +32931,9 @@ Notes:
|
|
|
31782
32931
|
|
|
31783
32932
|
Exit codes:
|
|
31784
32933
|
0 success; 2 usage/local input; 3 auth or permission; 4 not found;
|
|
31785
|
-
5 server failure;
|
|
32934
|
+
5 server failure (retry the same command); 6 not at the desired state
|
|
32935
|
+
(fleets: degraded, or --wait/--check stopped while healthy \u2014 retrying
|
|
32936
|
+
changes nothing); 7 refused, change the request.
|
|
31786
32937
|
\`monitors status\` exits 1 when you lack monitor access (documented contract).
|
|
31787
32938
|
|
|
31788
32939
|
Examples:
|
|
@@ -32053,6 +33204,181 @@ Examples:
|
|
|
32053
33204
|
`
|
|
32054
33205
|
).option("--dry-run", "Show the reactivation cost without reactivating")
|
|
32055
33206
|
).action(monitorsAction(handleMonitorsReactivate));
|
|
33207
|
+
const fleets = monitors.command("fleets").description("Define and reconcile table-backed Monitor Fleets.").addHelpText(
|
|
33208
|
+
"after",
|
|
33209
|
+
`
|
|
33210
|
+
Notes:
|
|
33211
|
+
A Monitor Fleet maps eligible rows in one Customer DB table to ordinary
|
|
33212
|
+
monitors. Fleet definitions are canonical JSON, and \`sync\` is the only verb
|
|
33213
|
+
that changes one: applying the same definition twice is the same operation,
|
|
33214
|
+
so the server answers \`replayed: true\` instead of building a second fleet.
|
|
33215
|
+
The fleet's status is computed by Deepline; this CLI reports it and never
|
|
33216
|
+
recomputes a verdict from the counts.
|
|
33217
|
+
|
|
33218
|
+
Exit codes:
|
|
33219
|
+
0 converged or done; 2 usage or local validation; 3 auth; 4 not found;
|
|
33220
|
+
5 server failure (retry the same command); 6 not at the desired state
|
|
33221
|
+
(degraded, or --wait/--check stopped while healthy); 7 refused (change the
|
|
33222
|
+
request).
|
|
33223
|
+
|
|
33224
|
+
Lifecycle:
|
|
33225
|
+
${MONITOR_FLEET_LIFECYCLE.map(
|
|
33226
|
+
(entry) => ` ${entry.step}. ${entry.command}`
|
|
33227
|
+
).join("\n")}
|
|
33228
|
+
${MONITOR_FLEET_HELP_EPILOG}`
|
|
33229
|
+
).action(
|
|
33230
|
+
monitorsAction(async (options) => {
|
|
33231
|
+
handleMonitorFleetsOverview(options);
|
|
33232
|
+
})
|
|
33233
|
+
);
|
|
33234
|
+
withJsonOption(fleets);
|
|
33235
|
+
withJsonOption(
|
|
33236
|
+
fleets.command("init <fleet-id>").description("Write an opinionated Fleet definition JSON file.").addHelpText(
|
|
33237
|
+
"after",
|
|
33238
|
+
`
|
|
33239
|
+
Creates a ready-to-review JSON definition. Fleets always sync ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.cadence} and retain
|
|
33240
|
+
a missing member for ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.removalGrace} before it is ${MONITOR_FLEET_DOCUMENTATION.fixedPolicy.onRemoved}d; those
|
|
33241
|
+
policies are not authored in the file. ${MONITOR_FLEET_DOCUMENTATION.stickyMembership} The payload remains the actual monitor payload for the chosen tool, so use
|
|
33242
|
+
\`deepline monitors available\` to discover a tool first.
|
|
33243
|
+
|
|
33244
|
+
Example:
|
|
33245
|
+
deepline monitors fleets init account-job-openings \\
|
|
33246
|
+
--source public.accounts --key account_id --key-type uuid \\
|
|
33247
|
+
--tool deepline_native.company_radar \\
|
|
33248
|
+
--payload '{"domain":{"$fleet":"column","name":"domain"},"radar_type":"company_job_openings"}' \\
|
|
33249
|
+
--order-by intent_score:desc \\
|
|
33250
|
+
--out fleet.json
|
|
33251
|
+
`
|
|
33252
|
+
).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(
|
|
33253
|
+
"--payload <json>",
|
|
33254
|
+
"Monitor payload JSON for --tool; use $fleet column tags for row values"
|
|
33255
|
+
).option(
|
|
33256
|
+
"--where <json>",
|
|
33257
|
+
"Optional source-row equality filter JSON; not arbitrary SQL"
|
|
33258
|
+
).option(
|
|
33259
|
+
"--order-by <column:direction>",
|
|
33260
|
+
"Rank candidates; repeatable, with the source key appended for stability",
|
|
33261
|
+
(value, previous = []) => [...previous, value],
|
|
33262
|
+
[]
|
|
33263
|
+
).option(
|
|
33264
|
+
"--limit <n>",
|
|
33265
|
+
"Maximum active members; ranking changes do not churn sticky members (default 1,000)"
|
|
33266
|
+
).requiredOption("--out <path>", "Write the definition JSON to this path")
|
|
33267
|
+
).action(monitorsAction(handleMonitorFleetsInit));
|
|
33268
|
+
withJsonOption(
|
|
33269
|
+
fleets.command("sync [fleet-id]").description(
|
|
33270
|
+
"Apply a Fleet definition, or re-plan an existing fleet from its stored one."
|
|
33271
|
+
).addHelpText(
|
|
33272
|
+
"after",
|
|
33273
|
+
`
|
|
33274
|
+
Notes:
|
|
33275
|
+
--file (or an inline definition, or --file - for stdin) is compiled locally
|
|
33276
|
+
BEFORE any network call: a definition that fails the contract exits 2 and
|
|
33277
|
+
never becomes a request. A bare <fleet-id> re-plans the stored definition.
|
|
33278
|
+
The plan always shows blocked members; they are never hidden.
|
|
33279
|
+
--wait polls until Deepline reports a terminal status: converged exits 0,
|
|
33280
|
+
degraded exits 6, and a timeout exits 6 without implying anything broke.
|
|
33281
|
+
Progress goes to stderr, so stdout stays exactly one JSON object.
|
|
33282
|
+
|
|
33283
|
+
Examples:
|
|
33284
|
+
deepline monitors fleets sync --file fleet.json --dry-run
|
|
33285
|
+
deepline monitors fleets sync --file fleet.json --wait --timeout 20m
|
|
33286
|
+
deepline monitors fleets sync account-job-openings --wait --json
|
|
33287
|
+
cat fleet.json | deepline monitors fleets sync --file - --dry-run --json
|
|
33288
|
+
`
|
|
33289
|
+
).option(
|
|
33290
|
+
"-f, --file <path>",
|
|
33291
|
+
"Apply definition JSON from a file, or - for stdin"
|
|
33292
|
+
).option(
|
|
33293
|
+
"--dry-run",
|
|
33294
|
+
"Show the plan and the credits due without changing state"
|
|
33295
|
+
).option("--wait", "Poll until the fleet reaches a terminal status").option(
|
|
33296
|
+
"--timeout <duration>",
|
|
33297
|
+
"How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
|
|
33298
|
+
).option(
|
|
33299
|
+
"--expected-generation <generation>",
|
|
33300
|
+
"Refuse the write unless the fleet is at this generation"
|
|
33301
|
+
).option(
|
|
33302
|
+
"--idempotency-key <key>",
|
|
33303
|
+
"Stable retry key (generated and returned when omitted)"
|
|
33304
|
+
)
|
|
33305
|
+
).action(async (target, options) => {
|
|
33306
|
+
let retryCommand = fleetSyncCommandLine(target, options);
|
|
33307
|
+
try {
|
|
33308
|
+
const idempotencyKey = fleetIdempotencyKey(
|
|
33309
|
+
"sync",
|
|
33310
|
+
options.idempotencyKey
|
|
33311
|
+
);
|
|
33312
|
+
retryCommand = fleetSyncCommandLine(target, {
|
|
33313
|
+
...options,
|
|
33314
|
+
idempotencyKey
|
|
33315
|
+
});
|
|
33316
|
+
await handleMonitorFleetsSync(target, options, idempotencyKey);
|
|
33317
|
+
} catch (error) {
|
|
33318
|
+
reportMonitorsFailure(error, { retryCommand });
|
|
33319
|
+
}
|
|
33320
|
+
});
|
|
33321
|
+
withJsonOption(
|
|
33322
|
+
fleets.command("get [fleet-id]").description(
|
|
33323
|
+
"Read one fleet, or list every fleet when the id is omitted."
|
|
33324
|
+
).addHelpText(
|
|
33325
|
+
"after",
|
|
33326
|
+
`
|
|
33327
|
+
Notes:
|
|
33328
|
+
Status is the server's verdict. --check turns it into an exit code so a
|
|
33329
|
+
script can branch without parsing output: 0 converged, 6 anything else.
|
|
33330
|
+
--drift lists the members that have not settled and why.
|
|
33331
|
+
|
|
33332
|
+
Examples:
|
|
33333
|
+
deepline monitors fleets get --json
|
|
33334
|
+
deepline monitors fleets get account-job-openings --json
|
|
33335
|
+
deepline monitors fleets get account-job-openings --drift --limit 50 --json
|
|
33336
|
+
deepline monitors fleets get account-job-openings --check
|
|
33337
|
+
`
|
|
33338
|
+
).option("--drift", "Include the members that have not settled, and why").option("--limit <n>", "Maximum drift rows to return").option(
|
|
33339
|
+
"--check",
|
|
33340
|
+
"Exit 0 when converged and 6 otherwise, for scripts and agents"
|
|
33341
|
+
)
|
|
33342
|
+
).action(monitorsAction(handleMonitorFleetsGet));
|
|
33343
|
+
withJsonOption(
|
|
33344
|
+
fleets.command("deactivate <fleet-id>").description("Deactivate a fleet and the monitors it owns.").addHelpText(
|
|
33345
|
+
"after",
|
|
33346
|
+
`
|
|
33347
|
+
Notes:
|
|
33348
|
+
Destructive. --dry-run shows the blast radius without changing anything.
|
|
33349
|
+
An interactive terminal is shown that blast radius and asked to confirm;
|
|
33350
|
+
a non-interactive run must pass --yes. Re-running after a failure is safe.
|
|
33351
|
+
|
|
33352
|
+
Examples:
|
|
33353
|
+
deepline monitors fleets deactivate account-job-openings --dry-run
|
|
33354
|
+
deepline monitors fleets deactivate account-job-openings --yes --wait --json
|
|
33355
|
+
`
|
|
33356
|
+
).option("--dry-run", "Show the blast radius without deactivating").option("--wait", "Poll until the fleet reports deactivated").option(
|
|
33357
|
+
"--timeout <duration>",
|
|
33358
|
+
"How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
|
|
33359
|
+
).option(
|
|
33360
|
+
"--yes",
|
|
33361
|
+
"Skip the confirmation prompt (required non-interactively)"
|
|
33362
|
+
).option(
|
|
33363
|
+
"--idempotency-key <key>",
|
|
33364
|
+
"Stable retry key (generated and returned when omitted)"
|
|
33365
|
+
)
|
|
33366
|
+
).action(async (fleetId, options) => {
|
|
33367
|
+
let retryCommand = fleetDeactivateCommandLine(fleetId, options);
|
|
33368
|
+
try {
|
|
33369
|
+
const idempotencyKey = fleetIdempotencyKey(
|
|
33370
|
+
"deactivate",
|
|
33371
|
+
options.idempotencyKey
|
|
33372
|
+
);
|
|
33373
|
+
retryCommand = fleetDeactivateCommandLine(fleetId, {
|
|
33374
|
+
...options,
|
|
33375
|
+
idempotencyKey
|
|
33376
|
+
});
|
|
33377
|
+
await handleMonitorFleetsDeactivate(fleetId, options, idempotencyKey);
|
|
33378
|
+
} catch (error) {
|
|
33379
|
+
reportMonitorsFailure(error, { retryCommand });
|
|
33380
|
+
}
|
|
33381
|
+
});
|
|
32056
33382
|
const deployed = withJsonOption(
|
|
32057
33383
|
monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
|
|
32058
33384
|
"--status <status>",
|
|
@@ -32755,7 +34081,7 @@ async function readHiddenLine(prompt, streams = {}) {
|
|
|
32755
34081
|
}
|
|
32756
34082
|
let value = "";
|
|
32757
34083
|
inputStream.resume();
|
|
32758
|
-
return await new Promise((
|
|
34084
|
+
return await new Promise((resolve21, reject) => {
|
|
32759
34085
|
let settled = false;
|
|
32760
34086
|
const cleanup = () => {
|
|
32761
34087
|
inputStream.off("data", onData);
|
|
@@ -32773,7 +34099,7 @@ async function readHiddenLine(prompt, streams = {}) {
|
|
|
32773
34099
|
settled = true;
|
|
32774
34100
|
outputStream.write("\n");
|
|
32775
34101
|
cleanup();
|
|
32776
|
-
|
|
34102
|
+
resolve21(line);
|
|
32777
34103
|
};
|
|
32778
34104
|
const fail = (error) => {
|
|
32779
34105
|
if (settled) return;
|
|
@@ -32951,10 +34277,10 @@ import {
|
|
|
32951
34277
|
mkdirSync as mkdirSync11,
|
|
32952
34278
|
readFileSync as readFileSync14,
|
|
32953
34279
|
realpathSync as realpathSync4,
|
|
32954
|
-
writeFileSync as
|
|
34280
|
+
writeFileSync as writeFileSync15
|
|
32955
34281
|
} from "fs";
|
|
32956
34282
|
import { homedir as homedir9 } from "os";
|
|
32957
|
-
import { dirname as dirname16, join as join16, resolve as
|
|
34283
|
+
import { dirname as dirname16, join as join16, resolve as resolve16 } from "path";
|
|
32958
34284
|
|
|
32959
34285
|
// src/cli/installation-lifecycle.ts
|
|
32960
34286
|
import {
|
|
@@ -32964,7 +34290,7 @@ import {
|
|
|
32964
34290
|
realpathSync as realpathSync3,
|
|
32965
34291
|
rmSync as rmSync4
|
|
32966
34292
|
} from "fs";
|
|
32967
|
-
import { basename as basename6, dirname as dirname13, join as join13, relative as relative5, resolve as
|
|
34293
|
+
import { basename as basename6, dirname as dirname13, join as join13, relative as relative5, resolve as resolve15 } from "path";
|
|
32968
34294
|
var nodeFileSystem = {
|
|
32969
34295
|
exists: existsSync11,
|
|
32970
34296
|
isSymbolicLink(path) {
|
|
@@ -33079,14 +34405,14 @@ function isOwnedInstallerCommandPath(input2) {
|
|
|
33079
34405
|
if (!input2.commandPath || basename6(input2.commandPath) !== "deepline") {
|
|
33080
34406
|
return false;
|
|
33081
34407
|
}
|
|
33082
|
-
const commandPath =
|
|
33083
|
-
const fromHost = relative5(
|
|
34408
|
+
const commandPath = resolve15(input2.commandPath);
|
|
34409
|
+
const fromHost = relative5(resolve15(input2.hostDir), commandPath);
|
|
33084
34410
|
return fromHost !== "" && fromHost !== ".." && !fromHost.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`);
|
|
33085
34411
|
}
|
|
33086
34412
|
|
|
33087
34413
|
// src/cli/commands/skills.ts
|
|
33088
34414
|
import { spawn as spawn3 } from "child_process";
|
|
33089
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as
|
|
34415
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync14 } from "fs";
|
|
33090
34416
|
import { homedir as homedir8 } from "os";
|
|
33091
34417
|
import { dirname as dirname15, join as join15 } from "path";
|
|
33092
34418
|
|
|
@@ -33104,7 +34430,7 @@ var install_commands_default = {
|
|
|
33104
34430
|
npx_binary: "npx",
|
|
33105
34431
|
npx_add_args_template: [
|
|
33106
34432
|
"--yes",
|
|
33107
|
-
"skills@1.5.
|
|
34433
|
+
"skills@1.5.15",
|
|
33108
34434
|
"add",
|
|
33109
34435
|
"{skills_source_url}",
|
|
33110
34436
|
"--agent",
|
|
@@ -33124,9 +34450,15 @@ var install_commands_default = {
|
|
|
33124
34450
|
// src/cli/install-commands.ts
|
|
33125
34451
|
var INSTALL_COMMANDS = install_commands_default;
|
|
33126
34452
|
var DEFAULT_SKILL_AGENTS = INSTALL_COMMANDS.skills.default_agents;
|
|
33127
|
-
var
|
|
33128
|
-
(arg) => arg
|
|
33129
|
-
)
|
|
34453
|
+
var skillsNpxPackage = INSTALL_COMMANDS.skills.npx_add_args_template.find(
|
|
34454
|
+
(arg) => /^skills@\d+\.\d+\.\d+$/.test(arg)
|
|
34455
|
+
);
|
|
34456
|
+
if (!skillsNpxPackage) {
|
|
34457
|
+
throw new Error(
|
|
34458
|
+
"shared_libs/cli/install-commands.json must pin an exact skills package version."
|
|
34459
|
+
);
|
|
34460
|
+
}
|
|
34461
|
+
var SKILLS_NPX_PACKAGE = skillsNpxPackage;
|
|
33130
34462
|
var DEFAULT_V1_SKILL_NAMES = [
|
|
33131
34463
|
"build-tam",
|
|
33132
34464
|
"clay-to-deepline",
|
|
@@ -33197,7 +34529,7 @@ import {
|
|
|
33197
34529
|
mkdirSync as mkdirSync9,
|
|
33198
34530
|
readFileSync as readFileSync12,
|
|
33199
34531
|
unlinkSync,
|
|
33200
|
-
writeFileSync as
|
|
34532
|
+
writeFileSync as writeFileSync13
|
|
33201
34533
|
} from "fs";
|
|
33202
34534
|
import { dirname as dirname14, join as join14 } from "path";
|
|
33203
34535
|
|
|
@@ -33255,7 +34587,7 @@ function readMarkedSkillsSyncVersion(path) {
|
|
|
33255
34587
|
function writeMarkedSkillsSyncVersion(path, version) {
|
|
33256
34588
|
try {
|
|
33257
34589
|
mkdirSync9(dirname14(path), { recursive: true });
|
|
33258
|
-
|
|
34590
|
+
writeFileSync13(path, `${version}
|
|
33259
34591
|
`, "utf-8");
|
|
33260
34592
|
} catch {
|
|
33261
34593
|
}
|
|
@@ -33408,7 +34740,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
|
|
|
33408
34740
|
return commands;
|
|
33409
34741
|
}
|
|
33410
34742
|
function runOneSkillsInstall(install) {
|
|
33411
|
-
return new Promise((
|
|
34743
|
+
return new Promise((resolve21) => {
|
|
33412
34744
|
const plan = resolveSkillsInstallSpawn(install);
|
|
33413
34745
|
const child = spawn2(plan.command, plan.args, {
|
|
33414
34746
|
stdio: ["ignore", "ignore", "pipe"],
|
|
@@ -33420,7 +34752,7 @@ function runOneSkillsInstall(install) {
|
|
|
33420
34752
|
stderr += chunk.toString("utf-8");
|
|
33421
34753
|
});
|
|
33422
34754
|
child.on("error", (error) => {
|
|
33423
|
-
|
|
34755
|
+
resolve21({
|
|
33424
34756
|
ok: false,
|
|
33425
34757
|
detail: `failed to start ${install.command}: ${error.message}`,
|
|
33426
34758
|
manualCommand: install.manualCommand
|
|
@@ -33428,11 +34760,11 @@ function runOneSkillsInstall(install) {
|
|
|
33428
34760
|
});
|
|
33429
34761
|
child.on("close", (code) => {
|
|
33430
34762
|
if (code === 0) {
|
|
33431
|
-
|
|
34763
|
+
resolve21({ ok: true, detail: "", manualCommand: install.manualCommand });
|
|
33432
34764
|
return;
|
|
33433
34765
|
}
|
|
33434
34766
|
const detail = stderr.trim();
|
|
33435
|
-
|
|
34767
|
+
resolve21({
|
|
33436
34768
|
ok: false,
|
|
33437
34769
|
detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
|
|
33438
34770
|
manualCommand: install.manualCommand
|
|
@@ -33468,7 +34800,7 @@ function runLegacySkillsCleanup(agents) {
|
|
|
33468
34800
|
command: "bunx",
|
|
33469
34801
|
args: [
|
|
33470
34802
|
"--bun",
|
|
33471
|
-
|
|
34803
|
+
SKILLS_NPX_PACKAGE,
|
|
33472
34804
|
"remove",
|
|
33473
34805
|
"--global",
|
|
33474
34806
|
"--agent",
|
|
@@ -33481,7 +34813,7 @@ function runLegacySkillsCleanup(agents) {
|
|
|
33481
34813
|
command: "npx",
|
|
33482
34814
|
args: [
|
|
33483
34815
|
"--yes",
|
|
33484
|
-
|
|
34816
|
+
SKILLS_NPX_PACKAGE,
|
|
33485
34817
|
"remove",
|
|
33486
34818
|
"--global",
|
|
33487
34819
|
"--agent",
|
|
@@ -33495,7 +34827,7 @@ function runLegacySkillsCleanup(agents) {
|
|
|
33495
34827
|
command: "npx",
|
|
33496
34828
|
args: [
|
|
33497
34829
|
"--yes",
|
|
33498
|
-
|
|
34830
|
+
SKILLS_NPX_PACKAGE,
|
|
33499
34831
|
"remove",
|
|
33500
34832
|
"--global",
|
|
33501
34833
|
"--agent",
|
|
@@ -33644,9 +34976,9 @@ function skillsStatePathForScope(baseUrl, scope, root) {
|
|
|
33644
34976
|
}
|
|
33645
34977
|
function buildSkillsPlan(input2) {
|
|
33646
34978
|
const scopeArgs = input2.scope === "global" ? ["--global"] : [];
|
|
33647
|
-
const
|
|
33648
|
-
|
|
33649
|
-
|
|
34979
|
+
const legacyNames = [...LEGACY_SKILL_NAMES_TO_REMOVE].sort(
|
|
34980
|
+
(a, b) => a.localeCompare(b)
|
|
34981
|
+
);
|
|
33650
34982
|
return {
|
|
33651
34983
|
scope: input2.scope,
|
|
33652
34984
|
root: input2.root,
|
|
@@ -33666,7 +34998,7 @@ function buildSkillsPlan(input2) {
|
|
|
33666
34998
|
"--agent",
|
|
33667
34999
|
...input2.agents,
|
|
33668
35000
|
"-y",
|
|
33669
|
-
...
|
|
35001
|
+
...legacyNames
|
|
33670
35002
|
]
|
|
33671
35003
|
},
|
|
33672
35004
|
install: {
|
|
@@ -33714,7 +35046,7 @@ function readSkillsInstallState(path) {
|
|
|
33714
35046
|
}
|
|
33715
35047
|
}
|
|
33716
35048
|
function runProcess(command, args, cwd) {
|
|
33717
|
-
return new Promise((
|
|
35049
|
+
return new Promise((resolve21, reject) => {
|
|
33718
35050
|
const plan = resolveShellSpawn(command, args);
|
|
33719
35051
|
const child = spawn3(plan.command, plan.args, {
|
|
33720
35052
|
cwd,
|
|
@@ -33733,7 +35065,7 @@ function runProcess(command, args, cwd) {
|
|
|
33733
35065
|
process.stderr.write(`${SKILLS_NPX_PACKAGE} exited ${code}.
|
|
33734
35066
|
`);
|
|
33735
35067
|
}
|
|
33736
|
-
|
|
35068
|
+
resolve21(code ?? 1);
|
|
33737
35069
|
});
|
|
33738
35070
|
});
|
|
33739
35071
|
}
|
|
@@ -33817,16 +35149,8 @@ async function runSkillsCommand(options, dependencies = {}) {
|
|
|
33817
35149
|
`Replacing Deepline skills for ${agents.join(", ")} (${scope})...
|
|
33818
35150
|
`
|
|
33819
35151
|
);
|
|
35152
|
+
const execute = dependencies.runProcess ?? runProcess;
|
|
33820
35153
|
try {
|
|
33821
|
-
const execute = dependencies.runProcess ?? runProcess;
|
|
33822
|
-
const removeCode = await execute(
|
|
33823
|
-
plan.remove.command,
|
|
33824
|
-
plan.remove.args,
|
|
33825
|
-
root ?? void 0
|
|
33826
|
-
);
|
|
33827
|
-
if (removeCode !== 0) {
|
|
33828
|
-
throw new Error("Could not remove the existing Deepline skills.");
|
|
33829
|
-
}
|
|
33830
35154
|
const installCode = await execute(
|
|
33831
35155
|
plan.install.command,
|
|
33832
35156
|
plan.install.args,
|
|
@@ -33851,8 +35175,25 @@ async function runSkillsCommand(options, dependencies = {}) {
|
|
|
33851
35175
|
);
|
|
33852
35176
|
return 5;
|
|
33853
35177
|
}
|
|
35178
|
+
try {
|
|
35179
|
+
const removeCode = await execute(
|
|
35180
|
+
plan.remove.command,
|
|
35181
|
+
plan.remove.args,
|
|
35182
|
+
root ?? void 0
|
|
35183
|
+
);
|
|
35184
|
+
if (removeCode !== 0) {
|
|
35185
|
+
process.stderr.write(
|
|
35186
|
+
"Current Deepline skills installed, but legacy skill cleanup failed. The installed skills remain usable.\n"
|
|
35187
|
+
);
|
|
35188
|
+
}
|
|
35189
|
+
} catch (error) {
|
|
35190
|
+
process.stderr.write(
|
|
35191
|
+
`Current Deepline skills installed, but legacy skill cleanup failed: ${error instanceof Error ? error.message : String(error)}. The installed skills remain usable.
|
|
35192
|
+
`
|
|
35193
|
+
);
|
|
35194
|
+
}
|
|
33854
35195
|
mkdirSync10(dirname15(plan.statePath), { recursive: true });
|
|
33855
|
-
|
|
35196
|
+
writeFileSync14(
|
|
33856
35197
|
plan.statePath,
|
|
33857
35198
|
`${JSON.stringify(
|
|
33858
35199
|
{
|
|
@@ -33904,8 +35245,9 @@ function registerSkillsCommand(program) {
|
|
|
33904
35245
|
"after",
|
|
33905
35246
|
`
|
|
33906
35247
|
Notes:
|
|
33907
|
-
This command
|
|
33908
|
-
|
|
35248
|
+
This command reinstalls current Deepline-managed skills using ${SKILLS_NPX_PACKAGE},
|
|
35249
|
+
then removes legacy Deepline skill names. Local scope writes into the resolved
|
|
35250
|
+
persistent project.
|
|
33909
35251
|
|
|
33910
35252
|
Examples:
|
|
33911
35253
|
deepline skills --json
|
|
@@ -33946,26 +35288,26 @@ function parseSetupPhases(value) {
|
|
|
33946
35288
|
if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
|
|
33947
35289
|
return null;
|
|
33948
35290
|
}
|
|
33949
|
-
const
|
|
33950
|
-
if (!isSetupPhaseStatus(
|
|
33951
|
-
switch (
|
|
35291
|
+
const record2 = phase;
|
|
35292
|
+
if (!isSetupPhaseStatus(record2.status)) return null;
|
|
35293
|
+
switch (record2.status) {
|
|
33952
35294
|
case "pending":
|
|
33953
35295
|
case "in_progress":
|
|
33954
|
-
phases[name] = { status:
|
|
35296
|
+
phases[name] = { status: record2.status };
|
|
33955
35297
|
break;
|
|
33956
35298
|
case "complete":
|
|
33957
35299
|
phases[name] = {
|
|
33958
35300
|
status: "complete",
|
|
33959
|
-
...typeof
|
|
35301
|
+
...typeof record2.outcome === "string" ? { outcome: record2.outcome } : {}
|
|
33960
35302
|
};
|
|
33961
35303
|
break;
|
|
33962
35304
|
case "waiting":
|
|
33963
|
-
if (typeof
|
|
33964
|
-
phases[name] = { status: "waiting", outcome:
|
|
35305
|
+
if (typeof record2.outcome !== "string") return null;
|
|
35306
|
+
phases[name] = { status: "waiting", outcome: record2.outcome };
|
|
33965
35307
|
break;
|
|
33966
35308
|
case "failed":
|
|
33967
|
-
if (typeof
|
|
33968
|
-
phases[name] = { status: "failed", code:
|
|
35309
|
+
if (typeof record2.code !== "string") return null;
|
|
35310
|
+
phases[name] = { status: "failed", code: record2.code };
|
|
33969
35311
|
break;
|
|
33970
35312
|
}
|
|
33971
35313
|
}
|
|
@@ -34113,7 +35455,7 @@ function resolvePathCommands(command) {
|
|
|
34113
35455
|
);
|
|
34114
35456
|
return [
|
|
34115
35457
|
...new Set(
|
|
34116
|
-
String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) =>
|
|
35458
|
+
String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => resolve16(path))
|
|
34117
35459
|
)
|
|
34118
35460
|
];
|
|
34119
35461
|
}
|
|
@@ -34161,11 +35503,11 @@ function pathsResolveToSameFile(left, right) {
|
|
|
34161
35503
|
try {
|
|
34162
35504
|
return realpathSync4(left) === realpathSync4(right);
|
|
34163
35505
|
} catch {
|
|
34164
|
-
return
|
|
35506
|
+
return resolve16(left) === resolve16(right);
|
|
34165
35507
|
}
|
|
34166
35508
|
}
|
|
34167
35509
|
function isKnownDeeplineCommand(path) {
|
|
34168
|
-
const entrypoint = process.argv[1] ?
|
|
35510
|
+
const entrypoint = process.argv[1] ? resolve16(process.argv[1]) : "";
|
|
34169
35511
|
let resolvedPath = path;
|
|
34170
35512
|
try {
|
|
34171
35513
|
resolvedPath = realpathSync4(path);
|
|
@@ -34191,7 +35533,7 @@ function inspectPathConflict() {
|
|
|
34191
35533
|
function writeSetupState(input2) {
|
|
34192
35534
|
const path = setupStatePath(input2.baseUrl, input2.scope, input2.root);
|
|
34193
35535
|
mkdirSync11(dirname16(path), { recursive: true });
|
|
34194
|
-
|
|
35536
|
+
writeFileSync15(
|
|
34195
35537
|
path,
|
|
34196
35538
|
`${JSON.stringify(
|
|
34197
35539
|
{
|
|
@@ -34318,7 +35660,7 @@ function buildDoctorAssessment(input2) {
|
|
|
34318
35660
|
const connected = input2.authStatus.payload?.connected === true;
|
|
34319
35661
|
const authScopeOk = input2.scope === "local" ? Boolean(projectAuth) : Boolean(apiKey && !projectAuth);
|
|
34320
35662
|
const skillsOk = skillsState?.scope === input2.scope && typeof skillsState.skillsVersion === "string" && Array.isArray(skillsState.agents) && skillsState.agents.length > 0;
|
|
34321
|
-
const runningCliPath = process.argv[1] ?
|
|
35663
|
+
const runningCliPath = process.argv[1] ? resolve16(process.argv[1]) : null;
|
|
34322
35664
|
const globalCli = input2.scope === "global" ? inspectGlobalCliAvailability() : null;
|
|
34323
35665
|
const pathGlobalCli = globalCli?.path ?? null;
|
|
34324
35666
|
const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
|
|
@@ -34861,7 +36203,7 @@ import {
|
|
|
34861
36203
|
readFileSync as readFileSync15,
|
|
34862
36204
|
renameSync,
|
|
34863
36205
|
rmSync as rmSync5,
|
|
34864
|
-
writeFileSync as
|
|
36206
|
+
writeFileSync as writeFileSync16
|
|
34865
36207
|
} from "fs";
|
|
34866
36208
|
import { homedir as homedir10 } from "os";
|
|
34867
36209
|
import { dirname as dirname17, join as join17 } from "path";
|
|
@@ -34923,7 +36265,7 @@ function writeCliUpdatePreferences(preferences, homeDir2 = homedir10()) {
|
|
|
34923
36265
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
34924
36266
|
mkdirSync12(dirname17(path), { recursive: true });
|
|
34925
36267
|
try {
|
|
34926
|
-
|
|
36268
|
+
writeFileSync16(tempPath, `${JSON.stringify(preferences, null, 2)}
|
|
34927
36269
|
`, {
|
|
34928
36270
|
encoding: "utf8",
|
|
34929
36271
|
mode: 384
|
|
@@ -34988,7 +36330,7 @@ import {
|
|
|
34988
36330
|
renameSync as renameSync2,
|
|
34989
36331
|
rmSync as rmSync6,
|
|
34990
36332
|
unlinkSync as unlinkSync2,
|
|
34991
|
-
writeFileSync as
|
|
36333
|
+
writeFileSync as writeFileSync17
|
|
34992
36334
|
} from "fs";
|
|
34993
36335
|
import { homedir as homedir11 } from "os";
|
|
34994
36336
|
import {
|
|
@@ -34997,13 +36339,13 @@ import {
|
|
|
34997
36339
|
isAbsolute as isAbsolute7,
|
|
34998
36340
|
join as join19,
|
|
34999
36341
|
relative as relative7,
|
|
35000
|
-
resolve as
|
|
36342
|
+
resolve as resolve18
|
|
35001
36343
|
} from "path";
|
|
35002
36344
|
|
|
35003
36345
|
// src/cli/install-integrity.ts
|
|
35004
36346
|
import { createRequire } from "module";
|
|
35005
36347
|
import { existsSync as existsSync16, readFileSync as readFileSync16, statSync as statSync5 } from "fs";
|
|
35006
|
-
import { isAbsolute as isAbsolute6, join as join18, relative as relative6, resolve as
|
|
36348
|
+
import { isAbsolute as isAbsolute6, join as join18, relative as relative6, resolve as resolve17 } from "path";
|
|
35007
36349
|
var SDK_SIDECAR_CRITICAL_PACKAGE_FILES = [
|
|
35008
36350
|
"dist/cli/index.mjs",
|
|
35009
36351
|
"dist/index.mjs",
|
|
@@ -35028,8 +36370,8 @@ function safeRelativePath(value) {
|
|
|
35028
36370
|
}
|
|
35029
36371
|
function resolveContainedPath(root, value) {
|
|
35030
36372
|
if (!safeRelativePath(value)) return null;
|
|
35031
|
-
const target =
|
|
35032
|
-
const relativeTarget = relative6(
|
|
36373
|
+
const target = resolve17(root, value);
|
|
36374
|
+
const relativeTarget = relative6(resolve17(root), target);
|
|
35033
36375
|
if (!relativeTarget || relativeTarget.startsWith("..") || isAbsolute6(relativeTarget)) {
|
|
35034
36376
|
return null;
|
|
35035
36377
|
}
|
|
@@ -35255,8 +36597,8 @@ function resolvePythonSidecarUpdatePlan(options) {
|
|
|
35255
36597
|
const stateDir = sidecarStateDir(options);
|
|
35256
36598
|
if (!stateDir) return null;
|
|
35257
36599
|
const relativeEntrypoint = relative7(
|
|
35258
|
-
|
|
35259
|
-
|
|
36600
|
+
resolve18(stateDir),
|
|
36601
|
+
resolve18(options.entrypoint)
|
|
35260
36602
|
);
|
|
35261
36603
|
if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || isAbsolute7(relativeEntrypoint)) {
|
|
35262
36604
|
return null;
|
|
@@ -35290,7 +36632,7 @@ function resolvePythonSidecarUpdatePlan(options) {
|
|
|
35290
36632
|
};
|
|
35291
36633
|
}
|
|
35292
36634
|
function findRepoBackedSdkRoot(startPath) {
|
|
35293
|
-
let current =
|
|
36635
|
+
let current = resolve18(startPath);
|
|
35294
36636
|
while (true) {
|
|
35295
36637
|
if (existsSync17(join19(current, "package.json")) && existsSync17(join19(current, "bin", "deepline-dev.ts"))) {
|
|
35296
36638
|
const parent2 = dirname18(current);
|
|
@@ -35309,7 +36651,7 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
|
|
|
35309
36651
|
try {
|
|
35310
36652
|
return realpathSync5(entrypoint);
|
|
35311
36653
|
} catch {
|
|
35312
|
-
return
|
|
36654
|
+
return resolve18(entrypoint);
|
|
35313
36655
|
}
|
|
35314
36656
|
})();
|
|
35315
36657
|
const parts = normalized.split(/[\\/]+/);
|
|
@@ -35325,9 +36667,9 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
|
|
|
35325
36667
|
const knownWindowsPrefixes = [
|
|
35326
36668
|
env.npm_config_prefix,
|
|
35327
36669
|
env.APPDATA ? join19(env.APPDATA, "npm") : void 0
|
|
35328
|
-
].filter((value) => Boolean(value)).map((value) =>
|
|
36670
|
+
].filter((value) => Boolean(value)).map((value) => resolve18(value).replace(/\\/g, "/").toLowerCase());
|
|
35329
36671
|
if (!knownWindowsPrefixes.includes(
|
|
35330
|
-
|
|
36672
|
+
resolve18(directPrefix).replace(/\\/g, "/").toLowerCase()
|
|
35331
36673
|
)) {
|
|
35332
36674
|
return null;
|
|
35333
36675
|
}
|
|
@@ -35340,9 +36682,9 @@ function normalizedNpmPrefix(value) {
|
|
|
35340
36682
|
if (!trimmed) return null;
|
|
35341
36683
|
const normalized = (() => {
|
|
35342
36684
|
try {
|
|
35343
|
-
return realpathSync5(
|
|
36685
|
+
return realpathSync5(resolve18(trimmed));
|
|
35344
36686
|
} catch {
|
|
35345
|
-
return
|
|
36687
|
+
return resolve18(trimmed);
|
|
35346
36688
|
}
|
|
35347
36689
|
})().replace(/\\/g, "/");
|
|
35348
36690
|
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
@@ -35367,7 +36709,7 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
|
|
|
35367
36709
|
try {
|
|
35368
36710
|
return realpathSync5(entrypoint);
|
|
35369
36711
|
} catch {
|
|
35370
|
-
return
|
|
36712
|
+
return resolve18(entrypoint);
|
|
35371
36713
|
}
|
|
35372
36714
|
})();
|
|
35373
36715
|
const parts = normalized.split(/[\\/]+/);
|
|
@@ -35377,7 +36719,7 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
|
|
|
35377
36719
|
function resolveUpdatePlan(options = {}) {
|
|
35378
36720
|
const env = options.env ?? process.env;
|
|
35379
36721
|
const homeDir2 = options.homeDir ?? homedir11();
|
|
35380
|
-
const entrypoint = options.entrypoint ?? (process.argv[1] ?
|
|
36722
|
+
const entrypoint = options.entrypoint ?? (process.argv[1] ? resolve18(process.argv[1]) : "");
|
|
35381
36723
|
const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname18(entrypoint)) : null;
|
|
35382
36724
|
if (sourceRoot) {
|
|
35383
36725
|
return {
|
|
@@ -35471,7 +36813,7 @@ function writeAutoUpdateFailure(plan, exitCode) {
|
|
|
35471
36813
|
};
|
|
35472
36814
|
try {
|
|
35473
36815
|
mkdirSync13(dirname18(path), { recursive: true });
|
|
35474
|
-
|
|
36816
|
+
writeFileSync17(path, `${JSON.stringify(marker, null, 2)}
|
|
35475
36817
|
`, "utf8");
|
|
35476
36818
|
} catch {
|
|
35477
36819
|
}
|
|
@@ -35663,7 +37005,7 @@ function writeSidecarLauncher(input2) {
|
|
|
35663
37005
|
)
|
|
35664
37006
|
];
|
|
35665
37007
|
if (process.platform === "win32") {
|
|
35666
|
-
|
|
37008
|
+
writeFileSync17(
|
|
35667
37009
|
input2.path,
|
|
35668
37010
|
[
|
|
35669
37011
|
`@set DEEPLINE_HOST_URL=${input2.hostUrl.replace(/\r?\n/g, "")}`,
|
|
@@ -35686,7 +37028,7 @@ function writeSidecarLauncher(input2) {
|
|
|
35686
37028
|
);
|
|
35687
37029
|
return;
|
|
35688
37030
|
}
|
|
35689
|
-
|
|
37031
|
+
writeFileSync17(
|
|
35690
37032
|
input2.path,
|
|
35691
37033
|
[
|
|
35692
37034
|
"#!/usr/bin/env sh",
|
|
@@ -35720,7 +37062,7 @@ async function runPythonSidecarUpdatePlan(plan) {
|
|
|
35720
37062
|
);
|
|
35721
37063
|
rmSync6(tempDir, { recursive: true, force: true });
|
|
35722
37064
|
mkdirSync13(tempDir, { recursive: true });
|
|
35723
|
-
|
|
37065
|
+
writeFileSync17(join19(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
|
|
35724
37066
|
const env = {
|
|
35725
37067
|
...process.env,
|
|
35726
37068
|
PATH: `${dirname18(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
|
|
@@ -35843,27 +37185,27 @@ async function runPythonSidecarUpdatePlan(plan) {
|
|
|
35843
37185
|
nodeBin: plan.nodeBin,
|
|
35844
37186
|
entryPath: finalEntryPath
|
|
35845
37187
|
});
|
|
35846
|
-
|
|
37188
|
+
writeFileSync17(
|
|
35847
37189
|
join19(plan.stateDir, ".version"),
|
|
35848
37190
|
`${installedVersion}
|
|
35849
37191
|
`,
|
|
35850
37192
|
"utf8"
|
|
35851
37193
|
);
|
|
35852
|
-
|
|
37194
|
+
writeFileSync17(
|
|
35853
37195
|
join19(plan.stateDir, ".install-method"),
|
|
35854
37196
|
"python-sidecar\n",
|
|
35855
37197
|
"utf8"
|
|
35856
37198
|
);
|
|
35857
|
-
|
|
37199
|
+
writeFileSync17(
|
|
35858
37200
|
join19(plan.stateDir, ".command-path"),
|
|
35859
37201
|
`${plan.sidecarPath}
|
|
35860
37202
|
`,
|
|
35861
37203
|
"utf8"
|
|
35862
37204
|
);
|
|
35863
|
-
|
|
35864
|
-
|
|
37205
|
+
writeFileSync17(join19(plan.stateDir, ".runner"), "node\n", "utf8");
|
|
37206
|
+
writeFileSync17(join19(plan.stateDir, ".node-bin"), `${plan.nodeBin}
|
|
35865
37207
|
`, "utf8");
|
|
35866
|
-
|
|
37208
|
+
writeFileSync17(
|
|
35867
37209
|
join19(plan.stateDir, ".entry-path"),
|
|
35868
37210
|
`${finalEntryPath}
|
|
35869
37211
|
`,
|
|
@@ -36796,17 +38138,17 @@ import {
|
|
|
36796
38138
|
existsSync as existsSync18,
|
|
36797
38139
|
mkdtempSync,
|
|
36798
38140
|
readFileSync as readFileSync18,
|
|
36799
|
-
writeFileSync as
|
|
38141
|
+
writeFileSync as writeFileSync19
|
|
36800
38142
|
} from "fs";
|
|
36801
38143
|
import { tmpdir as tmpdir5 } from "os";
|
|
36802
|
-
import { join as join21, resolve as
|
|
38144
|
+
import { join as join21, resolve as resolve19 } from "path";
|
|
36803
38145
|
|
|
36804
38146
|
// src/tool-output.ts
|
|
36805
38147
|
import {
|
|
36806
38148
|
closeSync as closeSync3,
|
|
36807
38149
|
mkdirSync as mkdirSync14,
|
|
36808
38150
|
openSync as openSync3,
|
|
36809
|
-
writeFileSync as
|
|
38151
|
+
writeFileSync as writeFileSync18,
|
|
36810
38152
|
writeSync
|
|
36811
38153
|
} from "fs";
|
|
36812
38154
|
import { homedir as homedir12 } from "os";
|
|
@@ -36944,7 +38286,7 @@ function ensureOutputDir() {
|
|
|
36944
38286
|
function writeJsonOutputFile(payload, stem) {
|
|
36945
38287
|
const outputDir = ensureOutputDir();
|
|
36946
38288
|
const outputPath = join20(outputDir, `${stem}_${Date.now()}.json`);
|
|
36947
|
-
|
|
38289
|
+
writeFileSync18(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
36948
38290
|
return outputPath;
|
|
36949
38291
|
}
|
|
36950
38292
|
function writeCsvOutputFile(rows, stem, options) {
|
|
@@ -37285,9 +38627,9 @@ function requiredInputIds(tool) {
|
|
|
37285
38627
|
return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
|
|
37286
38628
|
}
|
|
37287
38629
|
function notConnectedSuffix(tool) {
|
|
37288
|
-
const
|
|
37289
|
-
const status = stringField2(
|
|
37290
|
-
const connected =
|
|
38630
|
+
const record2 = tool;
|
|
38631
|
+
const status = stringField2(record2, "credentialStatus", "credential_status");
|
|
38632
|
+
const connected = record2.connected;
|
|
37291
38633
|
if (status === "requires_connection" || connected === false) {
|
|
37292
38634
|
return " - \u26A0 requires your credentials \u2014 not connected (connect to use)";
|
|
37293
38635
|
}
|
|
@@ -37662,19 +39004,19 @@ function printPlayAliasToolError(toolId, play) {
|
|
|
37662
39004
|
console.error(playAliasToolErrorMessage(toolId, play));
|
|
37663
39005
|
}
|
|
37664
39006
|
function isPlayLikeTool(tool) {
|
|
37665
|
-
const
|
|
37666
|
-
if (
|
|
37667
|
-
const playExpansion = recordField2(
|
|
39007
|
+
const record2 = tool;
|
|
39008
|
+
if (record2.isPlay === true || record2.is_play === true) return true;
|
|
39009
|
+
const playExpansion = recordField2(record2, "playExpansion", "play_expansion");
|
|
37668
39010
|
if (Object.keys(playExpansion).length > 0) return true;
|
|
37669
|
-
const toolId = typeof
|
|
39011
|
+
const toolId = typeof record2.toolId === "string" ? record2.toolId : "";
|
|
37670
39012
|
return toolId.endsWith("_waterfall");
|
|
37671
39013
|
}
|
|
37672
39014
|
function isMonitorTypeTool(tool) {
|
|
37673
39015
|
return stringField2(tool, "kind") === "monitor_type";
|
|
37674
39016
|
}
|
|
37675
39017
|
function playReferenceForTool(tool) {
|
|
37676
|
-
const
|
|
37677
|
-
const declared = stringField2(
|
|
39018
|
+
const record2 = tool;
|
|
39019
|
+
const declared = stringField2(record2, "playReference", "play_reference");
|
|
37678
39020
|
if (declared.startsWith("prebuilt/")) {
|
|
37679
39021
|
return declared;
|
|
37680
39022
|
}
|
|
@@ -38632,12 +39974,12 @@ function singleLineText(value, maxLength = 260) {
|
|
|
38632
39974
|
return `${text.slice(0, maxLength - 3).trimEnd()}...`;
|
|
38633
39975
|
}
|
|
38634
39976
|
function listedToolDescription(tool) {
|
|
38635
|
-
const
|
|
38636
|
-
return singleLineText(
|
|
39977
|
+
const record2 = tool;
|
|
39978
|
+
return singleLineText(record2.bestFor ?? record2.best_for ?? tool.description);
|
|
38637
39979
|
}
|
|
38638
39980
|
function formatListedToolCost(tool) {
|
|
38639
|
-
const
|
|
38640
|
-
const pricing = recordField2(
|
|
39981
|
+
const record2 = tool;
|
|
39982
|
+
const pricing = recordField2(record2, "pricing");
|
|
38641
39983
|
const displayText = stringField2(pricing, "displayText", "display_text");
|
|
38642
39984
|
return displayText ? `Cost: ${displayText}` : "";
|
|
38643
39985
|
}
|
|
@@ -38918,10 +40260,10 @@ function normalizeOutputFormat(raw) {
|
|
|
38918
40260
|
}
|
|
38919
40261
|
function resolveAtFilePath(rawPath) {
|
|
38920
40262
|
const trimmed = rawPath.trim();
|
|
38921
|
-
const resolved =
|
|
40263
|
+
const resolved = resolve19(trimmed);
|
|
38922
40264
|
if (existsSync18(resolved)) return resolved;
|
|
38923
40265
|
if (process.platform !== "win32" && trimmed.includes("\\")) {
|
|
38924
|
-
const normalized =
|
|
40266
|
+
const normalized = resolve19(trimmed.replace(/\\/g, "/"));
|
|
38925
40267
|
if (existsSync18(normalized)) return normalized;
|
|
38926
40268
|
}
|
|
38927
40269
|
return resolved;
|
|
@@ -39010,7 +40352,7 @@ function parseExecuteOptions(args) {
|
|
|
39010
40352
|
continue;
|
|
39011
40353
|
}
|
|
39012
40354
|
if ((arg === "--out" || arg === "-o") && args[index + 1]) {
|
|
39013
|
-
outPath =
|
|
40355
|
+
outPath = resolve19(args[++index]);
|
|
39014
40356
|
continue;
|
|
39015
40357
|
}
|
|
39016
40358
|
throw new Error(`Unknown option: ${arg}`);
|
|
@@ -39085,7 +40427,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
39085
40427
|
description: ${JSON.stringify(`Seed ${input2.toolId} rows into a Deepline workflow-ready dataset.`)},
|
|
39086
40428
|
});
|
|
39087
40429
|
`;
|
|
39088
|
-
|
|
40430
|
+
writeFileSync19(scriptPath, script, { encoding: "utf-8", mode: 384 });
|
|
39089
40431
|
return {
|
|
39090
40432
|
path: scriptPath,
|
|
39091
40433
|
sourceCode: script,
|
|
@@ -39511,7 +40853,7 @@ Examples:
|
|
|
39511
40853
|
|
|
39512
40854
|
// src/cli/commands/workflow.ts
|
|
39513
40855
|
import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
|
|
39514
|
-
import { dirname as dirname20, join as join22, resolve as
|
|
40856
|
+
import { dirname as dirname20, join as join22, resolve as resolve20 } from "path";
|
|
39515
40857
|
|
|
39516
40858
|
// src/cli/workflow-to-play.ts
|
|
39517
40859
|
import { createHash as createHash5 } from "crypto";
|
|
@@ -39717,9 +41059,9 @@ function clientWithTimeout(timeoutSeconds) {
|
|
|
39717
41059
|
}
|
|
39718
41060
|
function readStatus(payload) {
|
|
39719
41061
|
if (!payload || typeof payload !== "object") return null;
|
|
39720
|
-
const
|
|
39721
|
-
if (typeof
|
|
39722
|
-
const run =
|
|
41062
|
+
const record2 = payload;
|
|
41063
|
+
if (typeof record2.status === "string") return record2.status;
|
|
41064
|
+
const run = record2.run;
|
|
39723
41065
|
if (run && typeof run === "object") {
|
|
39724
41066
|
const status = run.status;
|
|
39725
41067
|
if (typeof status === "string") return status;
|
|
@@ -39728,7 +41070,7 @@ function readStatus(payload) {
|
|
|
39728
41070
|
}
|
|
39729
41071
|
async function readJsonOption(payload, file) {
|
|
39730
41072
|
if (file) {
|
|
39731
|
-
const raw = await readFile4(
|
|
41073
|
+
const raw = await readFile4(resolve20(file), "utf8");
|
|
39732
41074
|
return JSON.parse(raw);
|
|
39733
41075
|
}
|
|
39734
41076
|
if (payload) {
|
|
@@ -39762,7 +41104,7 @@ async function transformOne(api, workflowId, outDir, publish) {
|
|
|
39762
41104
|
revision.config,
|
|
39763
41105
|
{ workflowName: workflow.name, version: revision.version }
|
|
39764
41106
|
);
|
|
39765
|
-
const file = join22(
|
|
41107
|
+
const file = join22(resolve20(outDir), `${compiled.playName}.play.ts`);
|
|
39766
41108
|
await mkdir5(dirname20(file), { recursive: true });
|
|
39767
41109
|
await writeFile5(file, compiled.sourceCode, "utf8");
|
|
39768
41110
|
let published = false;
|
|
@@ -40142,7 +41484,7 @@ function isDowngradeAutoUpdateResponse(response) {
|
|
|
40142
41484
|
return compareSemver(target, current) < 0;
|
|
40143
41485
|
}
|
|
40144
41486
|
function relaunchCurrentCommand(plan) {
|
|
40145
|
-
return new Promise((
|
|
41487
|
+
return new Promise((resolve21) => {
|
|
40146
41488
|
const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
|
|
40147
41489
|
const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
|
|
40148
41490
|
const child = spawn5(command, args, {
|
|
@@ -40158,9 +41500,9 @@ function relaunchCurrentCommand(plan) {
|
|
|
40158
41500
|
`Deepline SDK/CLI updated, but relaunch failed: ${error.message}
|
|
40159
41501
|
`
|
|
40160
41502
|
);
|
|
40161
|
-
|
|
41503
|
+
resolve21(1);
|
|
40162
41504
|
});
|
|
40163
|
-
child.on("close", (code) =>
|
|
41505
|
+
child.on("close", (code) => resolve21(code ?? 1));
|
|
40164
41506
|
});
|
|
40165
41507
|
}
|
|
40166
41508
|
async function maybeAutoUpdateAndRelaunch(response, baseUrl) {
|
|
@@ -40308,8 +41650,8 @@ function classifyNetworkFailure(error) {
|
|
|
40308
41650
|
let current = error;
|
|
40309
41651
|
while (current && !seen.has(current)) {
|
|
40310
41652
|
seen.add(current);
|
|
40311
|
-
const
|
|
40312
|
-
const code = String(
|
|
41653
|
+
const record2 = typeof current === "object" && current !== null ? current : {};
|
|
41654
|
+
const code = String(record2.code ?? "").toLowerCase();
|
|
40313
41655
|
const name = current instanceof Error ? current.name.toLowerCase() : "";
|
|
40314
41656
|
const text = String(
|
|
40315
41657
|
current instanceof Error ? current.message : current
|
|
@@ -40336,7 +41678,7 @@ function classifyNetworkFailure(error) {
|
|
|
40336
41678
|
if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
|
|
40337
41679
|
return "network_ssl_error";
|
|
40338
41680
|
}
|
|
40339
|
-
current =
|
|
41681
|
+
current = record2.cause ?? record2.context;
|
|
40340
41682
|
}
|
|
40341
41683
|
return "network_error";
|
|
40342
41684
|
}
|