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