deepline 0.3.54 → 0.3.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/client.ts +232 -0
- package/dist/bundling-sources/sdk/src/index.ts +29 -0
- package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +556 -0
- package/dist/bundling-sources/sdk/src/monitor-fleets.ts +31 -0
- package/dist/bundling-sources/sdk/src/play.ts +2 -8
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/monitor-fleet-limits.ts +14 -0
- package/dist/bundling-sources/shared_libs/monitors/org-monitor-limits.ts +102 -0
- package/dist/bundling-sources/shared_libs/monitors/validation.ts +244 -0
- package/dist/cli/index.js +1718 -376
- package/dist/cli/index.mjs +1654 -312
- package/dist/index.d.mts +220 -9
- package/dist/index.d.ts +220 -9
- package/dist/index.js +474 -14
- package/dist/index.mjs +464 -14
- package/dist/install-integrity.json +5 -0
- package/package.json +1 -1
package/dist/cli/index.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 = {
|
|
@@ -33022,7 +34348,7 @@ var install_commands_default = {
|
|
|
33022
34348
|
npx_binary: "npx",
|
|
33023
34349
|
npx_add_args_template: [
|
|
33024
34350
|
"--yes",
|
|
33025
|
-
"skills@1.5.
|
|
34351
|
+
"skills@1.5.15",
|
|
33026
34352
|
"add",
|
|
33027
34353
|
"{skills_source_url}",
|
|
33028
34354
|
"--agent",
|
|
@@ -33042,9 +34368,15 @@ var install_commands_default = {
|
|
|
33042
34368
|
// src/cli/install-commands.ts
|
|
33043
34369
|
var INSTALL_COMMANDS = install_commands_default;
|
|
33044
34370
|
var DEFAULT_SKILL_AGENTS = INSTALL_COMMANDS.skills.default_agents;
|
|
33045
|
-
var
|
|
33046
|
-
(arg) => arg
|
|
33047
|
-
)
|
|
34371
|
+
var skillsNpxPackage = INSTALL_COMMANDS.skills.npx_add_args_template.find(
|
|
34372
|
+
(arg) => /^skills@\d+\.\d+\.\d+$/.test(arg)
|
|
34373
|
+
);
|
|
34374
|
+
if (!skillsNpxPackage) {
|
|
34375
|
+
throw new Error(
|
|
34376
|
+
"shared_libs/cli/install-commands.json must pin an exact skills package version."
|
|
34377
|
+
);
|
|
34378
|
+
}
|
|
34379
|
+
var SKILLS_NPX_PACKAGE = skillsNpxPackage;
|
|
33048
34380
|
var DEFAULT_V1_SKILL_NAMES = [
|
|
33049
34381
|
"build-tam",
|
|
33050
34382
|
"clay-to-deepline",
|
|
@@ -33111,7 +34443,7 @@ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
|
|
|
33111
34443
|
// src/cli/skills-sync.ts
|
|
33112
34444
|
var import_node_child_process2 = require("child_process");
|
|
33113
34445
|
var import_node_fs16 = require("fs");
|
|
33114
|
-
var
|
|
34446
|
+
var import_node_path19 = require("path");
|
|
33115
34447
|
|
|
33116
34448
|
// src/cli/windows-arg-escape.ts
|
|
33117
34449
|
var CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
|
|
@@ -33146,10 +34478,10 @@ function shouldSkipSkillsSync() {
|
|
|
33146
34478
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
33147
34479
|
}
|
|
33148
34480
|
function unavailableSkillsNoticePath(baseUrl) {
|
|
33149
|
-
return (0,
|
|
34481
|
+
return (0, import_node_path19.join)(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
|
|
33150
34482
|
}
|
|
33151
34483
|
function failedSkillsSyncPath(baseUrl, agents) {
|
|
33152
|
-
return (0,
|
|
34484
|
+
return (0, import_node_path19.join)(
|
|
33153
34485
|
sdkCliStateDirPath(baseUrl),
|
|
33154
34486
|
`skills-sync-failed-${agents.join("-")}-version`
|
|
33155
34487
|
);
|
|
@@ -33166,7 +34498,7 @@ function readMarkedSkillsSyncVersion(path) {
|
|
|
33166
34498
|
}
|
|
33167
34499
|
function writeMarkedSkillsSyncVersion(path, version) {
|
|
33168
34500
|
try {
|
|
33169
|
-
(0, import_node_fs16.mkdirSync)((0,
|
|
34501
|
+
(0, import_node_fs16.mkdirSync)((0, import_node_path19.dirname)(path), { recursive: true });
|
|
33170
34502
|
(0, import_node_fs16.writeFileSync)(path, `${version}
|
|
33171
34503
|
`, "utf-8");
|
|
33172
34504
|
} catch {
|
|
@@ -33320,7 +34652,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
|
|
|
33320
34652
|
return commands;
|
|
33321
34653
|
}
|
|
33322
34654
|
function runOneSkillsInstall(install) {
|
|
33323
|
-
return new Promise((
|
|
34655
|
+
return new Promise((resolve21) => {
|
|
33324
34656
|
const plan = resolveSkillsInstallSpawn(install);
|
|
33325
34657
|
const child = (0, import_node_child_process2.spawn)(plan.command, plan.args, {
|
|
33326
34658
|
stdio: ["ignore", "ignore", "pipe"],
|
|
@@ -33332,7 +34664,7 @@ function runOneSkillsInstall(install) {
|
|
|
33332
34664
|
stderr += chunk.toString("utf-8");
|
|
33333
34665
|
});
|
|
33334
34666
|
child.on("error", (error) => {
|
|
33335
|
-
|
|
34667
|
+
resolve21({
|
|
33336
34668
|
ok: false,
|
|
33337
34669
|
detail: `failed to start ${install.command}: ${error.message}`,
|
|
33338
34670
|
manualCommand: install.manualCommand
|
|
@@ -33340,11 +34672,11 @@ function runOneSkillsInstall(install) {
|
|
|
33340
34672
|
});
|
|
33341
34673
|
child.on("close", (code) => {
|
|
33342
34674
|
if (code === 0) {
|
|
33343
|
-
|
|
34675
|
+
resolve21({ ok: true, detail: "", manualCommand: install.manualCommand });
|
|
33344
34676
|
return;
|
|
33345
34677
|
}
|
|
33346
34678
|
const detail = stderr.trim();
|
|
33347
|
-
|
|
34679
|
+
resolve21({
|
|
33348
34680
|
ok: false,
|
|
33349
34681
|
detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
|
|
33350
34682
|
manualCommand: install.manualCommand
|
|
@@ -33380,7 +34712,7 @@ function runLegacySkillsCleanup(agents) {
|
|
|
33380
34712
|
command: "bunx",
|
|
33381
34713
|
args: [
|
|
33382
34714
|
"--bun",
|
|
33383
|
-
|
|
34715
|
+
SKILLS_NPX_PACKAGE,
|
|
33384
34716
|
"remove",
|
|
33385
34717
|
"--global",
|
|
33386
34718
|
"--agent",
|
|
@@ -33393,7 +34725,7 @@ function runLegacySkillsCleanup(agents) {
|
|
|
33393
34725
|
command: "npx",
|
|
33394
34726
|
args: [
|
|
33395
34727
|
"--yes",
|
|
33396
|
-
|
|
34728
|
+
SKILLS_NPX_PACKAGE,
|
|
33397
34729
|
"remove",
|
|
33398
34730
|
"--global",
|
|
33399
34731
|
"--agent",
|
|
@@ -33407,7 +34739,7 @@ function runLegacySkillsCleanup(agents) {
|
|
|
33407
34739
|
command: "npx",
|
|
33408
34740
|
args: [
|
|
33409
34741
|
"--yes",
|
|
33410
|
-
|
|
34742
|
+
SKILLS_NPX_PACKAGE,
|
|
33411
34743
|
"remove",
|
|
33412
34744
|
"--global",
|
|
33413
34745
|
"--agent",
|
|
@@ -33546,19 +34878,19 @@ function detectSkillsAgents(input2) {
|
|
|
33546
34878
|
];
|
|
33547
34879
|
const detected = AGENT_MARKERS.filter(
|
|
33548
34880
|
(marker) => roots.some(
|
|
33549
|
-
(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)))
|
|
33550
34882
|
)
|
|
33551
34883
|
).map((marker) => marker.agent);
|
|
33552
34884
|
return detected.length > 0 ? detected : ["*"];
|
|
33553
34885
|
}
|
|
33554
34886
|
function skillsStatePathForScope(baseUrl, scope, root) {
|
|
33555
|
-
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");
|
|
33556
34888
|
}
|
|
33557
34889
|
function buildSkillsPlan(input2) {
|
|
33558
34890
|
const scopeArgs = input2.scope === "global" ? ["--global"] : [];
|
|
33559
|
-
const
|
|
33560
|
-
|
|
33561
|
-
|
|
34891
|
+
const legacyNames = [...LEGACY_SKILL_NAMES_TO_REMOVE].sort(
|
|
34892
|
+
(a, b) => a.localeCompare(b)
|
|
34893
|
+
);
|
|
33562
34894
|
return {
|
|
33563
34895
|
scope: input2.scope,
|
|
33564
34896
|
root: input2.root,
|
|
@@ -33578,7 +34910,7 @@ function buildSkillsPlan(input2) {
|
|
|
33578
34910
|
"--agent",
|
|
33579
34911
|
...input2.agents,
|
|
33580
34912
|
"-y",
|
|
33581
|
-
...
|
|
34913
|
+
...legacyNames
|
|
33582
34914
|
]
|
|
33583
34915
|
},
|
|
33584
34916
|
install: {
|
|
@@ -33626,7 +34958,7 @@ function readSkillsInstallState(path) {
|
|
|
33626
34958
|
}
|
|
33627
34959
|
}
|
|
33628
34960
|
function runProcess(command, args, cwd) {
|
|
33629
|
-
return new Promise((
|
|
34961
|
+
return new Promise((resolve21, reject) => {
|
|
33630
34962
|
const plan = resolveShellSpawn(command, args);
|
|
33631
34963
|
const child = (0, import_node_child_process3.spawn)(plan.command, plan.args, {
|
|
33632
34964
|
cwd,
|
|
@@ -33645,7 +34977,7 @@ function runProcess(command, args, cwd) {
|
|
|
33645
34977
|
process.stderr.write(`${SKILLS_NPX_PACKAGE} exited ${code}.
|
|
33646
34978
|
`);
|
|
33647
34979
|
}
|
|
33648
|
-
|
|
34980
|
+
resolve21(code ?? 1);
|
|
33649
34981
|
});
|
|
33650
34982
|
});
|
|
33651
34983
|
}
|
|
@@ -33729,16 +35061,8 @@ async function runSkillsCommand(options, dependencies = {}) {
|
|
|
33729
35061
|
`Replacing Deepline skills for ${agents.join(", ")} (${scope})...
|
|
33730
35062
|
`
|
|
33731
35063
|
);
|
|
35064
|
+
const execute = dependencies.runProcess ?? runProcess;
|
|
33732
35065
|
try {
|
|
33733
|
-
const execute = dependencies.runProcess ?? runProcess;
|
|
33734
|
-
const removeCode = await execute(
|
|
33735
|
-
plan.remove.command,
|
|
33736
|
-
plan.remove.args,
|
|
33737
|
-
root ?? void 0
|
|
33738
|
-
);
|
|
33739
|
-
if (removeCode !== 0) {
|
|
33740
|
-
throw new Error("Could not remove the existing Deepline skills.");
|
|
33741
|
-
}
|
|
33742
35066
|
const installCode = await execute(
|
|
33743
35067
|
plan.install.command,
|
|
33744
35068
|
plan.install.args,
|
|
@@ -33763,7 +35087,24 @@ async function runSkillsCommand(options, dependencies = {}) {
|
|
|
33763
35087
|
);
|
|
33764
35088
|
return 5;
|
|
33765
35089
|
}
|
|
33766
|
-
|
|
35090
|
+
try {
|
|
35091
|
+
const removeCode = await execute(
|
|
35092
|
+
plan.remove.command,
|
|
35093
|
+
plan.remove.args,
|
|
35094
|
+
root ?? void 0
|
|
35095
|
+
);
|
|
35096
|
+
if (removeCode !== 0) {
|
|
35097
|
+
process.stderr.write(
|
|
35098
|
+
"Current Deepline skills installed, but legacy skill cleanup failed. The installed skills remain usable.\n"
|
|
35099
|
+
);
|
|
35100
|
+
}
|
|
35101
|
+
} catch (error) {
|
|
35102
|
+
process.stderr.write(
|
|
35103
|
+
`Current Deepline skills installed, but legacy skill cleanup failed: ${error instanceof Error ? error.message : String(error)}. The installed skills remain usable.
|
|
35104
|
+
`
|
|
35105
|
+
);
|
|
35106
|
+
}
|
|
35107
|
+
(0, import_node_fs17.mkdirSync)((0, import_node_path20.dirname)(plan.statePath), { recursive: true });
|
|
33767
35108
|
(0, import_node_fs17.writeFileSync)(
|
|
33768
35109
|
plan.statePath,
|
|
33769
35110
|
`${JSON.stringify(
|
|
@@ -33816,8 +35157,9 @@ function registerSkillsCommand(program) {
|
|
|
33816
35157
|
"after",
|
|
33817
35158
|
`
|
|
33818
35159
|
Notes:
|
|
33819
|
-
This command
|
|
33820
|
-
|
|
35160
|
+
This command reinstalls current Deepline-managed skills using ${SKILLS_NPX_PACKAGE},
|
|
35161
|
+
then removes legacy Deepline skill names. Local scope writes into the resolved
|
|
35162
|
+
persistent project.
|
|
33821
35163
|
|
|
33822
35164
|
Examples:
|
|
33823
35165
|
deepline skills --json
|
|
@@ -33858,26 +35200,26 @@ function parseSetupPhases(value) {
|
|
|
33858
35200
|
if (!phase || typeof phase !== "object" || Array.isArray(phase)) {
|
|
33859
35201
|
return null;
|
|
33860
35202
|
}
|
|
33861
|
-
const
|
|
33862
|
-
if (!isSetupPhaseStatus(
|
|
33863
|
-
switch (
|
|
35203
|
+
const record2 = phase;
|
|
35204
|
+
if (!isSetupPhaseStatus(record2.status)) return null;
|
|
35205
|
+
switch (record2.status) {
|
|
33864
35206
|
case "pending":
|
|
33865
35207
|
case "in_progress":
|
|
33866
|
-
phases[name] = { status:
|
|
35208
|
+
phases[name] = { status: record2.status };
|
|
33867
35209
|
break;
|
|
33868
35210
|
case "complete":
|
|
33869
35211
|
phases[name] = {
|
|
33870
35212
|
status: "complete",
|
|
33871
|
-
...typeof
|
|
35213
|
+
...typeof record2.outcome === "string" ? { outcome: record2.outcome } : {}
|
|
33872
35214
|
};
|
|
33873
35215
|
break;
|
|
33874
35216
|
case "waiting":
|
|
33875
|
-
if (typeof
|
|
33876
|
-
phases[name] = { status: "waiting", outcome:
|
|
35217
|
+
if (typeof record2.outcome !== "string") return null;
|
|
35218
|
+
phases[name] = { status: "waiting", outcome: record2.outcome };
|
|
33877
35219
|
break;
|
|
33878
35220
|
case "failed":
|
|
33879
|
-
if (typeof
|
|
33880
|
-
phases[name] = { status: "failed", code:
|
|
35221
|
+
if (typeof record2.code !== "string") return null;
|
|
35222
|
+
phases[name] = { status: "failed", code: record2.code };
|
|
33881
35223
|
break;
|
|
33882
35224
|
}
|
|
33883
35225
|
}
|
|
@@ -33977,7 +35319,7 @@ function buildPendingAuthorizationOutput(input2) {
|
|
|
33977
35319
|
};
|
|
33978
35320
|
}
|
|
33979
35321
|
function setupStatePath(baseUrl, scope, root) {
|
|
33980
|
-
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");
|
|
33981
35323
|
}
|
|
33982
35324
|
async function captureStdout2(run) {
|
|
33983
35325
|
let stdout = "";
|
|
@@ -34025,7 +35367,7 @@ function resolvePathCommands(command) {
|
|
|
34025
35367
|
);
|
|
34026
35368
|
return [
|
|
34027
35369
|
...new Set(
|
|
34028
|
-
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))
|
|
34029
35371
|
)
|
|
34030
35372
|
];
|
|
34031
35373
|
}
|
|
@@ -34058,7 +35400,7 @@ function resolvePersistentGlobalCommand(dependencies = {}) {
|
|
|
34058
35400
|
if (prefix.status !== 0) return null;
|
|
34059
35401
|
const root = String(prefix.stdout ?? "").trim();
|
|
34060
35402
|
if (!root) return null;
|
|
34061
|
-
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")];
|
|
34062
35404
|
return candidates.find((candidate) => pathExists(candidate)) ?? null;
|
|
34063
35405
|
}
|
|
34064
35406
|
function inspectGlobalCliAvailability(input2) {
|
|
@@ -34073,18 +35415,18 @@ function pathsResolveToSameFile(left, right) {
|
|
|
34073
35415
|
try {
|
|
34074
35416
|
return (0, import_node_fs18.realpathSync)(left) === (0, import_node_fs18.realpathSync)(right);
|
|
34075
35417
|
} catch {
|
|
34076
|
-
return (0,
|
|
35418
|
+
return (0, import_node_path21.resolve)(left) === (0, import_node_path21.resolve)(right);
|
|
34077
35419
|
}
|
|
34078
35420
|
}
|
|
34079
35421
|
function isKnownDeeplineCommand(path) {
|
|
34080
|
-
const entrypoint = process.argv[1] ? (0,
|
|
35422
|
+
const entrypoint = process.argv[1] ? (0, import_node_path21.resolve)(process.argv[1]) : "";
|
|
34081
35423
|
let resolvedPath = path;
|
|
34082
35424
|
try {
|
|
34083
35425
|
resolvedPath = (0, import_node_fs18.realpathSync)(path);
|
|
34084
35426
|
} catch {
|
|
34085
35427
|
}
|
|
34086
35428
|
if (entrypoint && resolvedPath === entrypoint) return true;
|
|
34087
|
-
if (resolvedPath.includes(`${(0,
|
|
35429
|
+
if (resolvedPath.includes(`${(0, import_node_path21.join)("node_modules", "deepline")}`)) return true;
|
|
34088
35430
|
const content = safeRead(path);
|
|
34089
35431
|
return content.includes("node_modules/deepline") || content.includes("node_modules\\deepline") || content.includes("DEEPLINE_CONFIG_SCOPE") || content.includes("deepline-real");
|
|
34090
35432
|
}
|
|
@@ -34094,7 +35436,7 @@ function inspectPathConflict() {
|
|
|
34094
35436
|
try {
|
|
34095
35437
|
if ((0, import_node_fs18.lstatSync)(commandPath).isSymbolicLink()) {
|
|
34096
35438
|
const target = (0, import_node_fs18.realpathSync)(commandPath);
|
|
34097
|
-
if (target.includes(`${(0,
|
|
35439
|
+
if (target.includes(`${(0, import_node_path21.join)("node_modules", "deepline")}`)) return null;
|
|
34098
35440
|
}
|
|
34099
35441
|
} catch {
|
|
34100
35442
|
}
|
|
@@ -34102,7 +35444,7 @@ function inspectPathConflict() {
|
|
|
34102
35444
|
}
|
|
34103
35445
|
function writeSetupState(input2) {
|
|
34104
35446
|
const path = setupStatePath(input2.baseUrl, input2.scope, input2.root);
|
|
34105
|
-
(0, import_node_fs18.mkdirSync)((0,
|
|
35447
|
+
(0, import_node_fs18.mkdirSync)((0, import_node_path21.dirname)(path), { recursive: true });
|
|
34106
35448
|
(0, import_node_fs18.writeFileSync)(
|
|
34107
35449
|
path,
|
|
34108
35450
|
`${JSON.stringify(
|
|
@@ -34143,7 +35485,7 @@ function failSetupPhase(phases, phase, code) {
|
|
|
34143
35485
|
phases[phase] = { status: "failed", code };
|
|
34144
35486
|
}
|
|
34145
35487
|
function rollbackCommand(scope, root) {
|
|
34146
|
-
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"))}` : "";
|
|
34147
35489
|
return `npm install -g${prefix} --no-audit --no-fund --include=optional --allow-scripts=esbuild deepline@${SDK_VERSION}`;
|
|
34148
35490
|
}
|
|
34149
35491
|
function setupResumeCommand(baseUrl, scope) {
|
|
@@ -34230,12 +35572,12 @@ function buildDoctorAssessment(input2) {
|
|
|
34230
35572
|
const connected = input2.authStatus.payload?.connected === true;
|
|
34231
35573
|
const authScopeOk = input2.scope === "local" ? Boolean(projectAuth) : Boolean(apiKey && !projectAuth);
|
|
34232
35574
|
const skillsOk = skillsState?.scope === input2.scope && typeof skillsState.skillsVersion === "string" && Array.isArray(skillsState.agents) && skillsState.agents.length > 0;
|
|
34233
|
-
const runningCliPath = process.argv[1] ? (0,
|
|
35575
|
+
const runningCliPath = process.argv[1] ? (0, import_node_path21.resolve)(process.argv[1]) : null;
|
|
34234
35576
|
const globalCli = input2.scope === "global" ? inspectGlobalCliAvailability() : null;
|
|
34235
35577
|
const pathGlobalCli = globalCli?.path ?? null;
|
|
34236
35578
|
const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
|
|
34237
35579
|
const cliScopeOk = input2.scope === "global" ? Boolean(pathGlobalCli) : Boolean(
|
|
34238
|
-
input2.root && runningCliPath?.includes((0,
|
|
35580
|
+
input2.root && runningCliPath?.includes((0, import_node_path21.join)(input2.root, ".deepline", "runtime"))
|
|
34239
35581
|
);
|
|
34240
35582
|
const checks = {
|
|
34241
35583
|
cli: {
|
|
@@ -34769,7 +36111,7 @@ Examples:
|
|
|
34769
36111
|
// src/cli/update-preferences.ts
|
|
34770
36112
|
var import_node_fs19 = require("fs");
|
|
34771
36113
|
var import_node_os13 = require("os");
|
|
34772
|
-
var
|
|
36114
|
+
var import_node_path22 = require("path");
|
|
34773
36115
|
var UPDATE_PREFERENCES_SCHEMA_VERSION = 1;
|
|
34774
36116
|
var CLI_UPDATE_MESSAGES = [
|
|
34775
36117
|
{
|
|
@@ -34798,7 +36140,7 @@ function unreadablePreferences(path, error) {
|
|
|
34798
36140
|
};
|
|
34799
36141
|
}
|
|
34800
36142
|
function cliUpdatePreferencesPath(homeDir2 = (0, import_node_os13.homedir)()) {
|
|
34801
|
-
return (0,
|
|
36143
|
+
return (0, import_node_path22.join)(
|
|
34802
36144
|
homeDir2,
|
|
34803
36145
|
".local",
|
|
34804
36146
|
"deepline",
|
|
@@ -34826,7 +36168,7 @@ function readCliUpdatePreferences(homeDir2 = (0, import_node_os13.homedir)()) {
|
|
|
34826
36168
|
function writeCliUpdatePreferences(preferences, homeDir2 = (0, import_node_os13.homedir)()) {
|
|
34827
36169
|
const path = cliUpdatePreferencesPath(homeDir2);
|
|
34828
36170
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
34829
|
-
(0, import_node_fs19.mkdirSync)((0,
|
|
36171
|
+
(0, import_node_fs19.mkdirSync)((0, import_node_path22.dirname)(path), { recursive: true });
|
|
34830
36172
|
try {
|
|
34831
36173
|
(0, import_node_fs19.writeFileSync)(tempPath, `${JSON.stringify(preferences, null, 2)}
|
|
34832
36174
|
`, {
|
|
@@ -34887,12 +36229,12 @@ function consumePendingCliUpdateMessages(homeDir2 = (0, import_node_os13.homedir
|
|
|
34887
36229
|
var import_node_child_process5 = require("child_process");
|
|
34888
36230
|
var import_node_fs21 = require("fs");
|
|
34889
36231
|
var import_node_os14 = require("os");
|
|
34890
|
-
var
|
|
36232
|
+
var import_node_path24 = require("path");
|
|
34891
36233
|
|
|
34892
36234
|
// src/cli/install-integrity.ts
|
|
34893
36235
|
var import_node_module2 = require("module");
|
|
34894
36236
|
var import_node_fs20 = require("fs");
|
|
34895
|
-
var
|
|
36237
|
+
var import_node_path23 = require("path");
|
|
34896
36238
|
var SDK_SIDECAR_CRITICAL_PACKAGE_FILES = [
|
|
34897
36239
|
"dist/cli/index.mjs",
|
|
34898
36240
|
"dist/index.mjs",
|
|
@@ -34909,7 +36251,7 @@ var SDK_SIDECAR_CRITICAL_DEPENDENCY_FILES = [
|
|
|
34909
36251
|
"esbuild/lib/main.js"
|
|
34910
36252
|
];
|
|
34911
36253
|
function safeRelativePath(value) {
|
|
34912
|
-
if (typeof value !== "string" || !value || (0,
|
|
36254
|
+
if (typeof value !== "string" || !value || (0, import_node_path23.isAbsolute)(value)) return false;
|
|
34913
36255
|
const segments = value.split(/[\\/]+/);
|
|
34914
36256
|
return segments.every(
|
|
34915
36257
|
(segment) => Boolean(segment) && segment !== "." && segment !== ".."
|
|
@@ -34917,9 +36259,9 @@ function safeRelativePath(value) {
|
|
|
34917
36259
|
}
|
|
34918
36260
|
function resolveContainedPath(root, value) {
|
|
34919
36261
|
if (!safeRelativePath(value)) return null;
|
|
34920
|
-
const target = (0,
|
|
34921
|
-
const relativeTarget = (0,
|
|
34922
|
-
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)) {
|
|
34923
36265
|
return null;
|
|
34924
36266
|
}
|
|
34925
36267
|
return target;
|
|
@@ -34935,7 +36277,7 @@ function isFile(path) {
|
|
|
34935
36277
|
}
|
|
34936
36278
|
}
|
|
34937
36279
|
function readManifest(packageRoot) {
|
|
34938
|
-
const packageJsonPath = (0,
|
|
36280
|
+
const packageJsonPath = (0, import_node_path23.join)(packageRoot, "package.json");
|
|
34939
36281
|
let packageJson;
|
|
34940
36282
|
try {
|
|
34941
36283
|
packageJson = parseJson(packageJsonPath);
|
|
@@ -35009,8 +36351,8 @@ function readManifest(packageRoot) {
|
|
|
35009
36351
|
return { mode: "manifest", manifest };
|
|
35010
36352
|
}
|
|
35011
36353
|
function inspectSdkSidecarInstall(versionDir) {
|
|
35012
|
-
const nodeModulesRoot = (0,
|
|
35013
|
-
const packageRoot = (0,
|
|
36354
|
+
const nodeModulesRoot = (0, import_node_path23.join)(versionDir, "node_modules");
|
|
36355
|
+
const packageRoot = (0, import_node_path23.join)(nodeModulesRoot, "deepline");
|
|
35014
36356
|
const manifestResult = readManifest(packageRoot);
|
|
35015
36357
|
if ("invalidReason" in manifestResult) {
|
|
35016
36358
|
return {
|
|
@@ -35021,8 +36363,8 @@ function inspectSdkSidecarInstall(versionDir) {
|
|
|
35021
36363
|
};
|
|
35022
36364
|
}
|
|
35023
36365
|
const missing = [
|
|
35024
|
-
...manifestResult.manifest.packageFiles.filter((path) => !isFile((0,
|
|
35025
|
-
...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}`)
|
|
35026
36368
|
];
|
|
35027
36369
|
return {
|
|
35028
36370
|
ok: missing.length === 0,
|
|
@@ -35033,7 +36375,7 @@ function inspectSdkSidecarInstall(versionDir) {
|
|
|
35033
36375
|
}
|
|
35034
36376
|
function probeSdkSidecarEsbuild(versionDir) {
|
|
35035
36377
|
try {
|
|
35036
|
-
const requireFromInstall = (0, import_node_module2.createRequire)((0,
|
|
36378
|
+
const requireFromInstall = (0, import_node_module2.createRequire)((0, import_node_path23.join)(versionDir, "package.json"));
|
|
35037
36379
|
const esbuild = requireFromInstall("esbuild");
|
|
35038
36380
|
if (typeof esbuild.transformSync !== "function") {
|
|
35039
36381
|
return "esbuild does not export transformSync";
|
|
@@ -35108,7 +36450,7 @@ function sidecarStateDir(input2) {
|
|
|
35108
36450
|
if (!scope || scope.includes("/") || scope.includes("\\")) {
|
|
35109
36451
|
return null;
|
|
35110
36452
|
}
|
|
35111
|
-
return (0,
|
|
36453
|
+
return (0, import_node_path24.join)(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
|
|
35112
36454
|
}
|
|
35113
36455
|
function sidecarRegistryUrl(hostUrl) {
|
|
35114
36456
|
let url;
|
|
@@ -35143,19 +36485,19 @@ function readOptionalText(path) {
|
|
|
35143
36485
|
function resolvePythonSidecarUpdatePlan(options) {
|
|
35144
36486
|
const stateDir = sidecarStateDir(options);
|
|
35145
36487
|
if (!stateDir) return null;
|
|
35146
|
-
const relativeEntrypoint = (0,
|
|
35147
|
-
(0,
|
|
35148
|
-
(0,
|
|
36488
|
+
const relativeEntrypoint = (0, import_node_path24.relative)(
|
|
36489
|
+
(0, import_node_path24.resolve)(stateDir),
|
|
36490
|
+
(0, import_node_path24.resolve)(options.entrypoint)
|
|
35149
36491
|
);
|
|
35150
|
-
if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || (0,
|
|
36492
|
+
if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || (0, import_node_path24.isAbsolute)(relativeEntrypoint)) {
|
|
35151
36493
|
return null;
|
|
35152
36494
|
}
|
|
35153
|
-
const installMethod = readOptionalText((0,
|
|
36495
|
+
const installMethod = readOptionalText((0, import_node_path24.join)(stateDir, ".install-method"));
|
|
35154
36496
|
if (installMethod !== "python-sidecar") return null;
|
|
35155
36497
|
const scope = options.env.DEEPLINE_CONFIG_SCOPE?.trim() || "";
|
|
35156
36498
|
const hostUrl = options.env.DEEPLINE_HOST_URL?.trim() || "";
|
|
35157
|
-
const nodeBin = readOptionalText((0,
|
|
35158
|
-
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)(
|
|
35159
36501
|
stateDir,
|
|
35160
36502
|
"bin",
|
|
35161
36503
|
process.platform === "win32" ? "deepline-sdk.cmd" : "deepline-sdk"
|
|
@@ -35163,7 +36505,7 @@ function resolvePythonSidecarUpdatePlan(options) {
|
|
|
35163
36505
|
const packageSpec = options.packageSpec || "deepline@latest";
|
|
35164
36506
|
const npmCommand = "npm";
|
|
35165
36507
|
const registryUrl = sidecarRegistryUrl(hostUrl);
|
|
35166
|
-
const versionDir = (0,
|
|
36508
|
+
const versionDir = (0, import_node_path24.join)(stateDir, "versions", "<version>");
|
|
35167
36509
|
const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote4(versionDir)} --registry ${shellQuote4(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote4).join(" ")} ${shellQuote4(packageSpec)}`;
|
|
35168
36510
|
return {
|
|
35169
36511
|
kind: "python-sidecar",
|
|
@@ -35179,16 +36521,16 @@ function resolvePythonSidecarUpdatePlan(options) {
|
|
|
35179
36521
|
};
|
|
35180
36522
|
}
|
|
35181
36523
|
function findRepoBackedSdkRoot(startPath) {
|
|
35182
|
-
let current = (0,
|
|
36524
|
+
let current = (0, import_node_path24.resolve)(startPath);
|
|
35183
36525
|
while (true) {
|
|
35184
|
-
if ((0, import_node_fs21.existsSync)((0,
|
|
35185
|
-
const parent2 = (0,
|
|
35186
|
-
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;
|
|
35187
36529
|
}
|
|
35188
|
-
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"))) {
|
|
35189
36531
|
return current;
|
|
35190
36532
|
}
|
|
35191
|
-
const parent = (0,
|
|
36533
|
+
const parent = (0, import_node_path24.dirname)(current);
|
|
35192
36534
|
if (parent === current) return null;
|
|
35193
36535
|
current = parent;
|
|
35194
36536
|
}
|
|
@@ -35198,7 +36540,7 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
|
|
|
35198
36540
|
try {
|
|
35199
36541
|
return (0, import_node_fs21.realpathSync)(entrypoint);
|
|
35200
36542
|
} catch {
|
|
35201
|
-
return (0,
|
|
36543
|
+
return (0, import_node_path24.resolve)(entrypoint);
|
|
35202
36544
|
}
|
|
35203
36545
|
})();
|
|
35204
36546
|
const parts = normalized.split(/[\\/]+/);
|
|
@@ -35213,10 +36555,10 @@ function inferNpmGlobalPrefixFromEntrypoint(entrypoint, env) {
|
|
|
35213
36555
|
const directPrefix = prefixParts.join("/").toLowerCase();
|
|
35214
36556
|
const knownWindowsPrefixes = [
|
|
35215
36557
|
env.npm_config_prefix,
|
|
35216
|
-
env.APPDATA ? (0,
|
|
35217
|
-
].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());
|
|
35218
36560
|
if (!knownWindowsPrefixes.includes(
|
|
35219
|
-
(0,
|
|
36561
|
+
(0, import_node_path24.resolve)(directPrefix).replace(/\\/g, "/").toLowerCase()
|
|
35220
36562
|
)) {
|
|
35221
36563
|
return null;
|
|
35222
36564
|
}
|
|
@@ -35229,9 +36571,9 @@ function normalizedNpmPrefix(value) {
|
|
|
35229
36571
|
if (!trimmed) return null;
|
|
35230
36572
|
const normalized = (() => {
|
|
35231
36573
|
try {
|
|
35232
|
-
return (0, import_node_fs21.realpathSync)((0,
|
|
36574
|
+
return (0, import_node_fs21.realpathSync)((0, import_node_path24.resolve)(trimmed));
|
|
35233
36575
|
} catch {
|
|
35234
|
-
return (0,
|
|
36576
|
+
return (0, import_node_path24.resolve)(trimmed);
|
|
35235
36577
|
}
|
|
35236
36578
|
})().replace(/\\/g, "/");
|
|
35237
36579
|
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
@@ -35256,7 +36598,7 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
|
|
|
35256
36598
|
try {
|
|
35257
36599
|
return (0, import_node_fs21.realpathSync)(entrypoint);
|
|
35258
36600
|
} catch {
|
|
35259
|
-
return (0,
|
|
36601
|
+
return (0, import_node_path24.resolve)(entrypoint);
|
|
35260
36602
|
}
|
|
35261
36603
|
})();
|
|
35262
36604
|
const parts = normalized.split(/[\\/]+/);
|
|
@@ -35266,8 +36608,8 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
|
|
|
35266
36608
|
function resolveUpdatePlan(options = {}) {
|
|
35267
36609
|
const env = options.env ?? process.env;
|
|
35268
36610
|
const homeDir2 = options.homeDir ?? (0, import_node_os14.homedir)();
|
|
35269
|
-
const entrypoint = options.entrypoint ?? (process.argv[1] ? (0,
|
|
35270
|
-
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;
|
|
35271
36613
|
if (sourceRoot) {
|
|
35272
36614
|
return {
|
|
35273
36615
|
kind: "source",
|
|
@@ -35318,9 +36660,9 @@ var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
|
|
|
35318
36660
|
function autoUpdateFailurePath(plan) {
|
|
35319
36661
|
if (plan.kind === "source" || plan.kind === "homebrew") return null;
|
|
35320
36662
|
if (plan.kind === "python-sidecar") {
|
|
35321
|
-
return (0,
|
|
36663
|
+
return (0, import_node_path24.join)(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
|
|
35322
36664
|
}
|
|
35323
|
-
return (0,
|
|
36665
|
+
return (0, import_node_path24.join)(
|
|
35324
36666
|
(0, import_node_os14.homedir)(),
|
|
35325
36667
|
".local",
|
|
35326
36668
|
"deepline",
|
|
@@ -35359,7 +36701,7 @@ function writeAutoUpdateFailure(plan, exitCode) {
|
|
|
35359
36701
|
manualCommand: plan.manualCommand
|
|
35360
36702
|
};
|
|
35361
36703
|
try {
|
|
35362
|
-
(0, import_node_fs21.mkdirSync)((0,
|
|
36704
|
+
(0, import_node_fs21.mkdirSync)((0, import_node_path24.dirname)(path), { recursive: true });
|
|
35363
36705
|
(0, import_node_fs21.writeFileSync)(path, `${JSON.stringify(marker, null, 2)}
|
|
35364
36706
|
`, "utf8");
|
|
35365
36707
|
} catch {
|
|
@@ -35407,7 +36749,7 @@ function safeVersionSegment(value) {
|
|
|
35407
36749
|
return /^[0-9A-Za-z._-]+$/.test(normalized) ? normalized : "";
|
|
35408
36750
|
}
|
|
35409
36751
|
function entryPathInVersionDir(versionDir) {
|
|
35410
|
-
return (0,
|
|
36752
|
+
return (0, import_node_path24.join)(
|
|
35411
36753
|
versionDir,
|
|
35412
36754
|
"node_modules",
|
|
35413
36755
|
"deepline",
|
|
@@ -35417,7 +36759,7 @@ function entryPathInVersionDir(versionDir) {
|
|
|
35417
36759
|
);
|
|
35418
36760
|
}
|
|
35419
36761
|
function installedPackageVersion(versionDir) {
|
|
35420
|
-
const packageJsonPath = (0,
|
|
36762
|
+
const packageJsonPath = (0, import_node_path24.join)(
|
|
35421
36763
|
versionDir,
|
|
35422
36764
|
"node_modules",
|
|
35423
36765
|
"deepline",
|
|
@@ -35539,16 +36881,16 @@ async function runNpmInstallWithRegistryFallback(input2) {
|
|
|
35539
36881
|
return first.exitCode;
|
|
35540
36882
|
}
|
|
35541
36883
|
function writeSidecarLauncher(input2) {
|
|
35542
|
-
(0, import_node_fs21.mkdirSync)((0,
|
|
35543
|
-
const packageRoot = (0,
|
|
35544
|
-
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));
|
|
35545
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);";
|
|
35546
36888
|
const criticalPaths = [
|
|
35547
36889
|
...SDK_SIDECAR_CRITICAL_PACKAGE_FILES.map(
|
|
35548
|
-
(path) => (0,
|
|
36890
|
+
(path) => (0, import_node_path24.join)(packageRoot, path)
|
|
35549
36891
|
),
|
|
35550
36892
|
...SDK_SIDECAR_CRITICAL_DEPENDENCY_FILES.map(
|
|
35551
|
-
(path) => (0,
|
|
36893
|
+
(path) => (0, import_node_path24.join)(versionDir, "node_modules", path)
|
|
35552
36894
|
)
|
|
35553
36895
|
];
|
|
35554
36896
|
if (process.platform === "win32") {
|
|
@@ -35602,17 +36944,17 @@ function writeSidecarLauncher(input2) {
|
|
|
35602
36944
|
);
|
|
35603
36945
|
}
|
|
35604
36946
|
async function runPythonSidecarUpdatePlan(plan) {
|
|
35605
|
-
const versionsDir = (0,
|
|
35606
|
-
const tempDir = (0,
|
|
36947
|
+
const versionsDir = (0, import_node_path24.join)(plan.stateDir, "versions");
|
|
36948
|
+
const tempDir = (0, import_node_path24.join)(
|
|
35607
36949
|
versionsDir,
|
|
35608
36950
|
`.tmp-sdk-update-${process.pid}-${Date.now()}`
|
|
35609
36951
|
);
|
|
35610
36952
|
(0, import_node_fs21.rmSync)(tempDir, { recursive: true, force: true });
|
|
35611
36953
|
(0, import_node_fs21.mkdirSync)(tempDir, { recursive: true });
|
|
35612
|
-
(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);
|
|
35613
36955
|
const env = {
|
|
35614
36956
|
...process.env,
|
|
35615
|
-
PATH: `${(0,
|
|
36957
|
+
PATH: `${(0, import_node_path24.dirname)(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
|
|
35616
36958
|
};
|
|
35617
36959
|
const installResult = await runCommand(
|
|
35618
36960
|
plan.npmCommand,
|
|
@@ -35649,7 +36991,7 @@ async function runPythonSidecarUpdatePlan(plan) {
|
|
|
35649
36991
|
(0, import_node_fs21.rmSync)(tempDir, { recursive: true, force: true });
|
|
35650
36992
|
return 1;
|
|
35651
36993
|
}
|
|
35652
|
-
const finalDir = (0,
|
|
36994
|
+
const finalDir = (0, import_node_path24.join)(versionsDir, installedVersion);
|
|
35653
36995
|
const finalEntryPath = entryPathInVersionDir(finalDir);
|
|
35654
36996
|
const finalFailure = sidecarInstallFailure(finalDir);
|
|
35655
36997
|
let backupDir = null;
|
|
@@ -35658,7 +37000,7 @@ async function runPythonSidecarUpdatePlan(plan) {
|
|
|
35658
37000
|
} else {
|
|
35659
37001
|
let shouldPublishTemp = true;
|
|
35660
37002
|
if ((0, import_node_fs21.existsSync)(finalDir)) {
|
|
35661
|
-
backupDir = (0,
|
|
37003
|
+
backupDir = (0, import_node_path24.join)(
|
|
35662
37004
|
versionsDir,
|
|
35663
37005
|
`.backup-${installedVersion}-${process.pid}-${Date.now()}`
|
|
35664
37006
|
);
|
|
@@ -35733,27 +37075,27 @@ async function runPythonSidecarUpdatePlan(plan) {
|
|
|
35733
37075
|
entryPath: finalEntryPath
|
|
35734
37076
|
});
|
|
35735
37077
|
(0, import_node_fs21.writeFileSync)(
|
|
35736
|
-
(0,
|
|
37078
|
+
(0, import_node_path24.join)(plan.stateDir, ".version"),
|
|
35737
37079
|
`${installedVersion}
|
|
35738
37080
|
`,
|
|
35739
37081
|
"utf8"
|
|
35740
37082
|
);
|
|
35741
37083
|
(0, import_node_fs21.writeFileSync)(
|
|
35742
|
-
(0,
|
|
37084
|
+
(0, import_node_path24.join)(plan.stateDir, ".install-method"),
|
|
35743
37085
|
"python-sidecar\n",
|
|
35744
37086
|
"utf8"
|
|
35745
37087
|
);
|
|
35746
37088
|
(0, import_node_fs21.writeFileSync)(
|
|
35747
|
-
(0,
|
|
37089
|
+
(0, import_node_path24.join)(plan.stateDir, ".command-path"),
|
|
35748
37090
|
`${plan.sidecarPath}
|
|
35749
37091
|
`,
|
|
35750
37092
|
"utf8"
|
|
35751
37093
|
);
|
|
35752
|
-
(0, import_node_fs21.writeFileSync)((0,
|
|
35753
|
-
(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}
|
|
35754
37096
|
`, "utf8");
|
|
35755
37097
|
(0, import_node_fs21.writeFileSync)(
|
|
35756
|
-
(0,
|
|
37098
|
+
(0, import_node_path24.join)(plan.stateDir, ".entry-path"),
|
|
35757
37099
|
`${finalEntryPath}
|
|
35758
37100
|
`,
|
|
35759
37101
|
"utf8"
|
|
@@ -36682,12 +38024,12 @@ chooses the connected Slack channel or member and the events it receives.
|
|
|
36682
38024
|
var import_commander3 = require("commander");
|
|
36683
38025
|
var import_node_fs23 = require("fs");
|
|
36684
38026
|
var import_node_os16 = require("os");
|
|
36685
|
-
var
|
|
38027
|
+
var import_node_path26 = require("path");
|
|
36686
38028
|
|
|
36687
38029
|
// src/tool-output.ts
|
|
36688
38030
|
var import_node_fs22 = require("fs");
|
|
36689
38031
|
var import_node_os15 = require("os");
|
|
36690
|
-
var
|
|
38032
|
+
var import_node_path25 = require("path");
|
|
36691
38033
|
function isPlainObject(value) {
|
|
36692
38034
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
36693
38035
|
}
|
|
@@ -36814,19 +38156,19 @@ function projectRowOutput(conversion) {
|
|
|
36814
38156
|
};
|
|
36815
38157
|
}
|
|
36816
38158
|
function ensureOutputDir() {
|
|
36817
|
-
const outputDir = (0,
|
|
38159
|
+
const outputDir = (0, import_node_path25.join)((0, import_node_os15.homedir)(), ".local", "share", "deepline", "data");
|
|
36818
38160
|
(0, import_node_fs22.mkdirSync)(outputDir, { recursive: true });
|
|
36819
38161
|
return outputDir;
|
|
36820
38162
|
}
|
|
36821
38163
|
function writeJsonOutputFile(payload, stem) {
|
|
36822
38164
|
const outputDir = ensureOutputDir();
|
|
36823
|
-
const outputPath = (0,
|
|
38165
|
+
const outputPath = (0, import_node_path25.join)(outputDir, `${stem}_${Date.now()}.json`);
|
|
36824
38166
|
(0, import_node_fs22.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
36825
38167
|
return outputPath;
|
|
36826
38168
|
}
|
|
36827
38169
|
function writeCsvOutputFile(rows, stem, options) {
|
|
36828
|
-
const outputPath = options?.outPath ? options.outPath : (0,
|
|
36829
|
-
(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 });
|
|
36830
38172
|
const columns = columnsForRows(rows);
|
|
36831
38173
|
const escapeCell = (value) => {
|
|
36832
38174
|
const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
|
|
@@ -37162,9 +38504,9 @@ function requiredInputIds(tool) {
|
|
|
37162
38504
|
return toolInputFieldsForDisplay(inputSchema).filter((field) => field.required === true).map((field) => String(field.name ?? "")).filter(Boolean);
|
|
37163
38505
|
}
|
|
37164
38506
|
function notConnectedSuffix(tool) {
|
|
37165
|
-
const
|
|
37166
|
-
const status = stringField2(
|
|
37167
|
-
const connected =
|
|
38507
|
+
const record2 = tool;
|
|
38508
|
+
const status = stringField2(record2, "credentialStatus", "credential_status");
|
|
38509
|
+
const connected = record2.connected;
|
|
37168
38510
|
if (status === "requires_connection" || connected === false) {
|
|
37169
38511
|
return " - \u26A0 requires your credentials \u2014 not connected (connect to use)";
|
|
37170
38512
|
}
|
|
@@ -37539,19 +38881,19 @@ function printPlayAliasToolError(toolId, play) {
|
|
|
37539
38881
|
console.error(playAliasToolErrorMessage(toolId, play));
|
|
37540
38882
|
}
|
|
37541
38883
|
function isPlayLikeTool(tool) {
|
|
37542
|
-
const
|
|
37543
|
-
if (
|
|
37544
|
-
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");
|
|
37545
38887
|
if (Object.keys(playExpansion).length > 0) return true;
|
|
37546
|
-
const toolId = typeof
|
|
38888
|
+
const toolId = typeof record2.toolId === "string" ? record2.toolId : "";
|
|
37547
38889
|
return toolId.endsWith("_waterfall");
|
|
37548
38890
|
}
|
|
37549
38891
|
function isMonitorTypeTool(tool) {
|
|
37550
38892
|
return stringField2(tool, "kind") === "monitor_type";
|
|
37551
38893
|
}
|
|
37552
38894
|
function playReferenceForTool(tool) {
|
|
37553
|
-
const
|
|
37554
|
-
const declared = stringField2(
|
|
38895
|
+
const record2 = tool;
|
|
38896
|
+
const declared = stringField2(record2, "playReference", "play_reference");
|
|
37555
38897
|
if (declared.startsWith("prebuilt/")) {
|
|
37556
38898
|
return declared;
|
|
37557
38899
|
}
|
|
@@ -38509,12 +39851,12 @@ function singleLineText(value, maxLength = 260) {
|
|
|
38509
39851
|
return `${text.slice(0, maxLength - 3).trimEnd()}...`;
|
|
38510
39852
|
}
|
|
38511
39853
|
function listedToolDescription(tool) {
|
|
38512
|
-
const
|
|
38513
|
-
return singleLineText(
|
|
39854
|
+
const record2 = tool;
|
|
39855
|
+
return singleLineText(record2.bestFor ?? record2.best_for ?? tool.description);
|
|
38514
39856
|
}
|
|
38515
39857
|
function formatListedToolCost(tool) {
|
|
38516
|
-
const
|
|
38517
|
-
const pricing = recordField2(
|
|
39858
|
+
const record2 = tool;
|
|
39859
|
+
const pricing = recordField2(record2, "pricing");
|
|
38518
39860
|
const displayText = stringField2(pricing, "displayText", "display_text");
|
|
38519
39861
|
return displayText ? `Cost: ${displayText}` : "";
|
|
38520
39862
|
}
|
|
@@ -38795,10 +40137,10 @@ function normalizeOutputFormat(raw) {
|
|
|
38795
40137
|
}
|
|
38796
40138
|
function resolveAtFilePath(rawPath) {
|
|
38797
40139
|
const trimmed = rawPath.trim();
|
|
38798
|
-
const resolved = (0,
|
|
40140
|
+
const resolved = (0, import_node_path26.resolve)(trimmed);
|
|
38799
40141
|
if ((0, import_node_fs23.existsSync)(resolved)) return resolved;
|
|
38800
40142
|
if (process.platform !== "win32" && trimmed.includes("\\")) {
|
|
38801
|
-
const normalized = (0,
|
|
40143
|
+
const normalized = (0, import_node_path26.resolve)(trimmed.replace(/\\/g, "/"));
|
|
38802
40144
|
if ((0, import_node_fs23.existsSync)(normalized)) return normalized;
|
|
38803
40145
|
}
|
|
38804
40146
|
return resolved;
|
|
@@ -38887,7 +40229,7 @@ function parseExecuteOptions(args) {
|
|
|
38887
40229
|
continue;
|
|
38888
40230
|
}
|
|
38889
40231
|
if ((arg === "--out" || arg === "-o") && args[index + 1]) {
|
|
38890
|
-
outPath = (0,
|
|
40232
|
+
outPath = (0, import_node_path26.resolve)(args[++index]);
|
|
38891
40233
|
continue;
|
|
38892
40234
|
}
|
|
38893
40235
|
throw new Error(`Unknown option: ${arg}`);
|
|
@@ -38917,9 +40259,9 @@ function starterScriptJson(script) {
|
|
|
38917
40259
|
function seedToolListScript(input2) {
|
|
38918
40260
|
const stem = safeFileStem(input2.toolId);
|
|
38919
40261
|
const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
|
|
38920
|
-
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-"));
|
|
38921
40263
|
(0, import_node_fs23.chmodSync)(scriptDir, 448);
|
|
38922
|
-
const scriptPath = (0,
|
|
40264
|
+
const scriptPath = (0, import_node_path26.join)(scriptDir, fileName);
|
|
38923
40265
|
const projectDir = `deepline/projects/${stem}-workflow`;
|
|
38924
40266
|
const playName = `${stem}-workflow`;
|
|
38925
40267
|
const sampleRows = input2.rows.length > 0 ? `${JSON.stringify(input2.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
|
|
@@ -39388,10 +40730,10 @@ Examples:
|
|
|
39388
40730
|
|
|
39389
40731
|
// src/cli/commands/workflow.ts
|
|
39390
40732
|
var import_promises9 = require("fs/promises");
|
|
39391
|
-
var
|
|
40733
|
+
var import_node_path27 = require("path");
|
|
39392
40734
|
|
|
39393
40735
|
// src/cli/workflow-to-play.ts
|
|
39394
|
-
var
|
|
40736
|
+
var import_node_crypto9 = require("crypto");
|
|
39395
40737
|
var HITL_WAIT_FOR_SIGNAL_TOOL = "deepline_workflow_wait_for_signal";
|
|
39396
40738
|
var HITL_SLACK_TOOL = "slack_message_with_hitl";
|
|
39397
40739
|
var SUB_WORKFLOW_TOOL_PREFIX = "deepline_workflow_";
|
|
@@ -39497,7 +40839,7 @@ function sanitizePlayNameSegment(value) {
|
|
|
39497
40839
|
}
|
|
39498
40840
|
function deriveWorkflowPlayName(workflowName) {
|
|
39499
40841
|
const base = sanitizePlayNameSegment(workflowName) || "workflow";
|
|
39500
|
-
const suffix = (0,
|
|
40842
|
+
const suffix = (0, import_node_crypto9.createHash)("sha256").update(workflowName).digest("hex").slice(0, 8);
|
|
39501
40843
|
const reserved = suffix.length + 1;
|
|
39502
40844
|
const allowedBase = Math.max(1, MAX_PLAY_NAME_LENGTH - reserved);
|
|
39503
40845
|
let name = `${base.slice(0, allowedBase)}_${suffix}`;
|
|
@@ -39594,9 +40936,9 @@ function clientWithTimeout(timeoutSeconds) {
|
|
|
39594
40936
|
}
|
|
39595
40937
|
function readStatus(payload) {
|
|
39596
40938
|
if (!payload || typeof payload !== "object") return null;
|
|
39597
|
-
const
|
|
39598
|
-
if (typeof
|
|
39599
|
-
const run =
|
|
40939
|
+
const record2 = payload;
|
|
40940
|
+
if (typeof record2.status === "string") return record2.status;
|
|
40941
|
+
const run = record2.run;
|
|
39600
40942
|
if (run && typeof run === "object") {
|
|
39601
40943
|
const status = run.status;
|
|
39602
40944
|
if (typeof status === "string") return status;
|
|
@@ -39605,7 +40947,7 @@ function readStatus(payload) {
|
|
|
39605
40947
|
}
|
|
39606
40948
|
async function readJsonOption(payload, file) {
|
|
39607
40949
|
if (file) {
|
|
39608
|
-
const raw = await (0, import_promises9.readFile)((0,
|
|
40950
|
+
const raw = await (0, import_promises9.readFile)((0, import_node_path27.resolve)(file), "utf8");
|
|
39609
40951
|
return JSON.parse(raw);
|
|
39610
40952
|
}
|
|
39611
40953
|
if (payload) {
|
|
@@ -39639,8 +40981,8 @@ async function transformOne(api, workflowId, outDir, publish) {
|
|
|
39639
40981
|
revision.config,
|
|
39640
40982
|
{ workflowName: workflow.name, version: revision.version }
|
|
39641
40983
|
);
|
|
39642
|
-
const file = (0,
|
|
39643
|
-
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 });
|
|
39644
40986
|
await (0, import_promises9.writeFile)(file, compiled.sourceCode, "utf8");
|
|
39645
40987
|
let published = false;
|
|
39646
40988
|
if (publish) {
|
|
@@ -40019,7 +41361,7 @@ function isDowngradeAutoUpdateResponse(response) {
|
|
|
40019
41361
|
return compareSemver(target, current) < 0;
|
|
40020
41362
|
}
|
|
40021
41363
|
function relaunchCurrentCommand(plan) {
|
|
40022
|
-
return new Promise((
|
|
41364
|
+
return new Promise((resolve21) => {
|
|
40023
41365
|
const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
|
|
40024
41366
|
const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
|
|
40025
41367
|
const child = (0, import_node_child_process6.spawn)(command, args, {
|
|
@@ -40035,9 +41377,9 @@ function relaunchCurrentCommand(plan) {
|
|
|
40035
41377
|
`Deepline SDK/CLI updated, but relaunch failed: ${error.message}
|
|
40036
41378
|
`
|
|
40037
41379
|
);
|
|
40038
|
-
|
|
41380
|
+
resolve21(1);
|
|
40039
41381
|
});
|
|
40040
|
-
child.on("close", (code) =>
|
|
41382
|
+
child.on("close", (code) => resolve21(code ?? 1));
|
|
40041
41383
|
});
|
|
40042
41384
|
}
|
|
40043
41385
|
async function maybeAutoUpdateAndRelaunch(response, baseUrl) {
|
|
@@ -40185,8 +41527,8 @@ function classifyNetworkFailure(error) {
|
|
|
40185
41527
|
let current = error;
|
|
40186
41528
|
while (current && !seen.has(current)) {
|
|
40187
41529
|
seen.add(current);
|
|
40188
|
-
const
|
|
40189
|
-
const code = String(
|
|
41530
|
+
const record2 = typeof current === "object" && current !== null ? current : {};
|
|
41531
|
+
const code = String(record2.code ?? "").toLowerCase();
|
|
40190
41532
|
const name = current instanceof Error ? current.name.toLowerCase() : "";
|
|
40191
41533
|
const text = String(
|
|
40192
41534
|
current instanceof Error ? current.message : current
|
|
@@ -40213,7 +41555,7 @@ function classifyNetworkFailure(error) {
|
|
|
40213
41555
|
if (combined.includes("ssl") || combined.includes("tls") || combined.includes("unexpected_eof_while_reading")) {
|
|
40214
41556
|
return "network_ssl_error";
|
|
40215
41557
|
}
|
|
40216
|
-
current =
|
|
41558
|
+
current = record2.cause ?? record2.context;
|
|
40217
41559
|
}
|
|
40218
41560
|
return "network_error";
|
|
40219
41561
|
}
|
|
@@ -40428,8 +41770,8 @@ function topLevelCommandKnown(program, commandName) {
|
|
|
40428
41770
|
);
|
|
40429
41771
|
}
|
|
40430
41772
|
async function runPlayRunnerHealthCheck() {
|
|
40431
|
-
const dir = await (0, import_promises10.mkdtemp)((0,
|
|
40432
|
-
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");
|
|
40433
41775
|
try {
|
|
40434
41776
|
await (0, import_promises10.writeFile)(
|
|
40435
41777
|
file,
|