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