deepline 0.3.74 → 0.3.76
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 +279 -21
- package/dist/bundling-sources/sdk/src/config.ts +21 -3
- package/dist/bundling-sources/sdk/src/index.ts +1 -0
- package/dist/bundling-sources/sdk/src/play.ts +3 -6
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +3 -2
- package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +186 -0
- package/dist/bundling-sources/shared_libs/monitors/monitor-fleet-limits.ts +41 -0
- package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +213 -55
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +172 -299
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +13 -32
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +5 -1
- package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +7 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +11 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/testkit.ts +5 -4
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +12 -2
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +74 -0
- package/dist/cli/index.js +940 -181
- package/dist/cli/index.mjs +940 -181
- package/dist/{compiler-manifest-CMNgA_JQ.d.mts → compiler-manifest-Dbov16F7.d.mts} +1 -1
- package/dist/{compiler-manifest-CMNgA_JQ.d.ts → compiler-manifest-Dbov16F7.d.ts} +1 -1
- package/dist/index.d.mts +176 -23
- package/dist/index.d.ts +176 -23
- package/dist/index.js +109 -12
- package/dist/index.mjs +109 -12
- package/dist/install-integrity.json +4 -2
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -905,6 +905,17 @@ function getResolvedProjectAuthSource(baseUrl, apiKey, startDir = process.cwd())
|
|
|
905
905
|
return projectBaseUrl === normalizedBaseUrl && (env[API_KEY_ENV] ?? "").trim() === normalizedApiKey;
|
|
906
906
|
}) ?? null;
|
|
907
907
|
}
|
|
908
|
+
function resolveBaseUrlOnly(options) {
|
|
909
|
+
const baseUrl = normalizeBaseUrl(
|
|
910
|
+
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
911
|
+
);
|
|
912
|
+
if (!baseUrl) {
|
|
913
|
+
throw new ConfigError(
|
|
914
|
+
`Invalid ${HOST_URL_ENV}. Expected an http(s) URL such as https://code.deepline.com.`
|
|
915
|
+
);
|
|
916
|
+
}
|
|
917
|
+
return baseUrl;
|
|
918
|
+
}
|
|
908
919
|
function resolveConfig(options) {
|
|
909
920
|
const baseUrl = normalizeBaseUrl(
|
|
910
921
|
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
@@ -1214,7 +1225,7 @@ var SDK_RELEASE = {
|
|
|
1214
1225
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1215
1226
|
// getters keep their established compatibility behavior.
|
|
1216
1227
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1217
|
-
version: "0.3.
|
|
1228
|
+
version: "0.3.76",
|
|
1218
1229
|
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.",
|
|
1219
1230
|
packageCapabilities: {
|
|
1220
1231
|
updatePreferences: 1
|
|
@@ -1636,7 +1647,7 @@ var RUNTIME_INCIDENT_DRILL_CATALOG = [
|
|
|
1636
1647
|
valueMeaning: "occurrence"
|
|
1637
1648
|
},
|
|
1638
1649
|
expected: {
|
|
1639
|
-
outcome: "The same logical run completes through
|
|
1650
|
+
outcome: "The same logical run completes through terminal-cache replay; any provider retry is governed by its separate operation policy.",
|
|
1640
1651
|
safetyFacts: ["same_logical_run", "bounded_provider_execution"]
|
|
1641
1652
|
},
|
|
1642
1653
|
verification: {
|
|
@@ -4491,6 +4502,10 @@ var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "ca
|
|
|
4491
4502
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
4492
4503
|
var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
|
|
4493
4504
|
var EXECUTE_RESPONSE_INTENT_HEADER = "x-deepline-execute-response-intent";
|
|
4505
|
+
var MONITOR_NON_RETRYABLE_MUTATION_OPTIONS = {
|
|
4506
|
+
maxRetries: 0,
|
|
4507
|
+
exactUrlOnly: true
|
|
4508
|
+
};
|
|
4494
4509
|
var RAW_V2_EXECUTE_RESPONSE_CONTRACT = RAW_V2_TOOL_RESPONSE_CONTRACT;
|
|
4495
4510
|
var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
|
|
4496
4511
|
var REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
|
|
@@ -5049,11 +5064,15 @@ var DeeplineClient = class {
|
|
|
5049
5064
|
update: (key, patch) => this.updateMonitor(key, patch),
|
|
5050
5065
|
delete: (key, options2) => this.deleteMonitor(key, options2),
|
|
5051
5066
|
reactivate: (key, options2) => this.reactivateMonitor(key, options2),
|
|
5067
|
+
audit: (options2) => this.auditMonitors(options2),
|
|
5068
|
+
repair: (options2) => this.repairMonitors(options2),
|
|
5069
|
+
health: (options2) => this.readMonitorsHealth(options2),
|
|
5052
5070
|
fleets: {
|
|
5053
5071
|
sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5054
5072
|
get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
|
|
5055
5073
|
list: () => this.listMonitorFleets(),
|
|
5056
5074
|
deactivate: (fleetId, options2) => this.deactivateMonitorFleet(fleetId, options2),
|
|
5075
|
+
reactivate: (fleetId, options2) => this.reactivateMonitorFleet(fleetId, options2),
|
|
5057
5076
|
waitForConvergence: (fleetId, options2) => this.waitForMonitorFleetConvergence(fleetId, options2)
|
|
5058
5077
|
}
|
|
5059
5078
|
};
|
|
@@ -6639,13 +6658,23 @@ var DeeplineClient = class {
|
|
|
6639
6658
|
if (options?.grep?.trim()) {
|
|
6640
6659
|
params.set("grep", options.grep.trim());
|
|
6641
6660
|
params.set("grep_mode", options.grepMode ?? "all");
|
|
6661
|
+
params.set("grep_paginated", "1");
|
|
6642
6662
|
params.set("limit", "60");
|
|
6643
6663
|
}
|
|
6644
|
-
const
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6664
|
+
const plays = [];
|
|
6665
|
+
let cursor = null;
|
|
6666
|
+
let hasMore = true;
|
|
6667
|
+
do {
|
|
6668
|
+
if (cursor) params.set("cursor", cursor);
|
|
6669
|
+
const suffix = params.toString() ? `?${params.toString()}` : "";
|
|
6670
|
+
const response = await this.http.get(
|
|
6671
|
+
`/api/v2/plays${suffix}`
|
|
6672
|
+
);
|
|
6673
|
+
plays.push(...response.plays ?? []);
|
|
6674
|
+
cursor = response.pagination?.cursor ?? response.cursor ?? null;
|
|
6675
|
+
hasMore = Boolean(response.pagination?.hasMore ?? response.hasMore);
|
|
6676
|
+
} while (Boolean(options?.grep?.trim()) && hasMore && cursor);
|
|
6677
|
+
return plays;
|
|
6649
6678
|
}
|
|
6650
6679
|
/** Set whether an org-owned Play sorts before unpinned Plays. */
|
|
6651
6680
|
async setPlayPinned(playName, pinned) {
|
|
@@ -7222,6 +7251,44 @@ var DeeplineClient = class {
|
|
|
7222
7251
|
...typeof payload.reason === "string" && payload.reason.trim() ? { reason: payload.reason.trim() } : {}
|
|
7223
7252
|
};
|
|
7224
7253
|
}
|
|
7254
|
+
/**
|
|
7255
|
+
* One bounded audit pass. Prefer `client.monitors.audit(...)`.
|
|
7256
|
+
*
|
|
7257
|
+
* Never auto-retried: it is idempotent, but a retry that races the caller's
|
|
7258
|
+
* own next pass would spend a provider slot to learn nothing new.
|
|
7259
|
+
*/
|
|
7260
|
+
async auditMonitors(options) {
|
|
7261
|
+
return this.http.request("/api/v2/monitors/audit", {
|
|
7262
|
+
method: "POST",
|
|
7263
|
+
body: {
|
|
7264
|
+
...options?.fleetId ? { fleet_id: options.fleetId } : {},
|
|
7265
|
+
...options?.cursor ? { cursor: options.cursor } : {}
|
|
7266
|
+
},
|
|
7267
|
+
maxRetries: 0
|
|
7268
|
+
});
|
|
7269
|
+
}
|
|
7270
|
+
/** One repair pass or plan. Prefer `client.monitors.repair(...)`. */
|
|
7271
|
+
async repairMonitors(options) {
|
|
7272
|
+
return this.http.request("/api/v2/monitors/repair", {
|
|
7273
|
+
method: "POST",
|
|
7274
|
+
body: {
|
|
7275
|
+
...options?.fleetId ? { fleet_id: options.fleetId } : {},
|
|
7276
|
+
...options?.dryRun === void 0 ? {} : { dry_run: options.dryRun }
|
|
7277
|
+
},
|
|
7278
|
+
maxRetries: 0
|
|
7279
|
+
});
|
|
7280
|
+
}
|
|
7281
|
+
/** Delivery and convergence health. Prefer `client.monitors.health(...)`. */
|
|
7282
|
+
async readMonitorsHealth(options) {
|
|
7283
|
+
const params = new URLSearchParams();
|
|
7284
|
+
if (options?.fleetId) params.set("fleet_id", options.fleetId);
|
|
7285
|
+
const query = params.toString();
|
|
7286
|
+
const suffix = query ? `?${query}` : "";
|
|
7287
|
+
return this.http.request(
|
|
7288
|
+
`/api/v2/monitors/health${suffix}`,
|
|
7289
|
+
{ method: "GET" }
|
|
7290
|
+
);
|
|
7291
|
+
}
|
|
7225
7292
|
/**
|
|
7226
7293
|
* The deployable monitor tools catalog. Pass a tool id (positional or
|
|
7227
7294
|
* `{ tool }`) to describe one tool's full payload/stream contract, or no tool
|
|
@@ -7299,7 +7366,6 @@ var DeeplineClient = class {
|
|
|
7299
7366
|
if (options?.limit !== void 0)
|
|
7300
7367
|
params.set("limit", String(options.limit));
|
|
7301
7368
|
if (options?.cursor) params.set("cursor", options.cursor);
|
|
7302
|
-
if (options?.compact) params.set("compact", "true");
|
|
7303
7369
|
if (options?.includeConsumers) params.set("include_consumers", "true");
|
|
7304
7370
|
const query = params.toString();
|
|
7305
7371
|
const suffix = query ? `?${query}` : "";
|
|
@@ -7316,13 +7382,22 @@ var DeeplineClient = class {
|
|
|
7316
7382
|
);
|
|
7317
7383
|
}
|
|
7318
7384
|
async testMonitorWebhook(key, payload, options) {
|
|
7385
|
+
if (options?.dispatch === true || options?.validationOnly === false) {
|
|
7386
|
+
throw new DeeplineError(
|
|
7387
|
+
"Monitor tests are validation-only and cannot dispatch events.",
|
|
7388
|
+
void 0,
|
|
7389
|
+
"MONITOR_TEST_DISPATCH_NOT_SUPPORTED"
|
|
7390
|
+
);
|
|
7391
|
+
}
|
|
7319
7392
|
return this.http.request(
|
|
7320
7393
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}/test`,
|
|
7321
7394
|
{
|
|
7322
7395
|
method: "POST",
|
|
7323
7396
|
body: {
|
|
7324
7397
|
payload,
|
|
7325
|
-
|
|
7398
|
+
// Send the legacy safe mode as well as accepting it server-side: an
|
|
7399
|
+
// upgraded SDK must be safe when it reaches a still-running server.
|
|
7400
|
+
mode: "validation_only"
|
|
7326
7401
|
}
|
|
7327
7402
|
}
|
|
7328
7403
|
);
|
|
@@ -7350,7 +7425,14 @@ var DeeplineClient = class {
|
|
|
7350
7425
|
async updateMonitor(key, patch) {
|
|
7351
7426
|
return this.http.request(
|
|
7352
7427
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}`,
|
|
7353
|
-
{
|
|
7428
|
+
{
|
|
7429
|
+
method: "PATCH",
|
|
7430
|
+
body: patch,
|
|
7431
|
+
// A monitor write may have reached the control plane before a network
|
|
7432
|
+
// failure reaches the caller. Do not turn that unknown outcome into a
|
|
7433
|
+
// second mutation with a fresh snapshot.
|
|
7434
|
+
...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
|
|
7435
|
+
}
|
|
7354
7436
|
);
|
|
7355
7437
|
}
|
|
7356
7438
|
/** Delete a deployed monitor and its upstream provider resource. `dryRun` returns the delete plan. Prefer `client.monitors.delete(...)`. */
|
|
@@ -7367,7 +7449,12 @@ var DeeplineClient = class {
|
|
|
7367
7449
|
const query = params.toString();
|
|
7368
7450
|
return this.http.request(
|
|
7369
7451
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}${query ? `?${query}` : ""}`,
|
|
7370
|
-
{ method: "DELETE" }
|
|
7452
|
+
options?.dryRun ? { method: "DELETE" } : {
|
|
7453
|
+
method: "DELETE",
|
|
7454
|
+
// Deletion is a provider lifecycle operation. A timeout is an
|
|
7455
|
+
// unknown outcome, not authority to begin another delete attempt.
|
|
7456
|
+
...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
|
|
7457
|
+
}
|
|
7371
7458
|
);
|
|
7372
7459
|
}
|
|
7373
7460
|
/**
|
|
@@ -7378,7 +7465,13 @@ var DeeplineClient = class {
|
|
|
7378
7465
|
const query = options?.dryRun ? "?dry_run=true" : "";
|
|
7379
7466
|
return this.http.request(
|
|
7380
7467
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}/reactivate${query}`,
|
|
7381
|
-
{ method: "POST", body: {} }
|
|
7468
|
+
options?.dryRun ? { method: "POST", body: {} } : {
|
|
7469
|
+
method: "POST",
|
|
7470
|
+
body: {},
|
|
7471
|
+
// Reactivation can create an upstream resource, so it must not use
|
|
7472
|
+
// the generic transport's automatic replay policy.
|
|
7473
|
+
...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
|
|
7474
|
+
}
|
|
7382
7475
|
);
|
|
7383
7476
|
}
|
|
7384
7477
|
// ——————————————————————————————————————————————————————————
|
|
@@ -7455,6 +7548,21 @@ var DeeplineClient = class {
|
|
|
7455
7548
|
}
|
|
7456
7549
|
);
|
|
7457
7550
|
}
|
|
7551
|
+
async reactivateMonitorFleet(fleetId, options) {
|
|
7552
|
+
return this.http.request(
|
|
7553
|
+
`${this.monitorFleetPath(fleetId)}/reactivate`,
|
|
7554
|
+
{
|
|
7555
|
+
method: "POST",
|
|
7556
|
+
body: {},
|
|
7557
|
+
headers: this.monitorFleetHeaders(
|
|
7558
|
+
"reactivate",
|
|
7559
|
+
options?.idempotencyKey
|
|
7560
|
+
),
|
|
7561
|
+
maxRetries: 0,
|
|
7562
|
+
exactUrlOnly: true
|
|
7563
|
+
}
|
|
7564
|
+
);
|
|
7565
|
+
}
|
|
7458
7566
|
/**
|
|
7459
7567
|
* Poll one fleet until the server reports a terminal status.
|
|
7460
7568
|
*
|
|
@@ -8349,6 +8457,7 @@ function printCommandEnvelope(envelope, options = {}) {
|
|
|
8349
8457
|
var EXIT_OK = 0;
|
|
8350
8458
|
var EXIT_AUTH = 3;
|
|
8351
8459
|
var EXIT_SERVER = 5;
|
|
8460
|
+
var AUTH_HTTP_TIMEOUT_MS = 1e4;
|
|
8352
8461
|
function statusBannerLine(value) {
|
|
8353
8462
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
8354
8463
|
const banner = value;
|
|
@@ -8515,30 +8624,37 @@ async function httpJson(method, url, apiKey, body) {
|
|
|
8515
8624
|
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
|
|
8516
8625
|
const bypassToken = process.env.VERCEL_PROTECTION_BYPASS_TOKEN?.trim();
|
|
8517
8626
|
if (bypassToken) headers["x-vercel-protection-bypass"] = bypassToken;
|
|
8518
|
-
let response = null;
|
|
8519
8627
|
let lastError = null;
|
|
8520
8628
|
for (const candidateUrl of buildCandidateUrls2(url)) {
|
|
8629
|
+
const controller = new AbortController();
|
|
8630
|
+
let requestTimedOut = false;
|
|
8631
|
+
const timeout = setTimeout(() => {
|
|
8632
|
+
requestTimedOut = true;
|
|
8633
|
+
controller.abort();
|
|
8634
|
+
}, AUTH_HTTP_TIMEOUT_MS);
|
|
8521
8635
|
try {
|
|
8522
|
-
response = await fetch(candidateUrl, {
|
|
8636
|
+
const response = await fetch(candidateUrl, {
|
|
8523
8637
|
method,
|
|
8524
8638
|
headers,
|
|
8525
|
-
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
8639
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
8640
|
+
signal: controller.signal
|
|
8526
8641
|
});
|
|
8527
|
-
|
|
8642
|
+
let data;
|
|
8643
|
+
try {
|
|
8644
|
+
data = await response.json();
|
|
8645
|
+
} catch (error) {
|
|
8646
|
+
if (controller.signal.aborted) throw error;
|
|
8647
|
+
data = {};
|
|
8648
|
+
}
|
|
8649
|
+
return { status: response.status, data };
|
|
8528
8650
|
} catch (error) {
|
|
8529
8651
|
lastError = error;
|
|
8652
|
+
if (requestTimedOut && method !== "GET") break;
|
|
8653
|
+
} finally {
|
|
8654
|
+
clearTimeout(timeout);
|
|
8530
8655
|
}
|
|
8531
8656
|
}
|
|
8532
|
-
|
|
8533
|
-
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
8534
|
-
}
|
|
8535
|
-
let data;
|
|
8536
|
-
try {
|
|
8537
|
-
data = await response.json();
|
|
8538
|
-
} catch {
|
|
8539
|
-
data = {};
|
|
8540
|
-
}
|
|
8541
|
-
return { status: response.status, data };
|
|
8657
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
8542
8658
|
}
|
|
8543
8659
|
async function reportSetupCompleted(input2) {
|
|
8544
8660
|
const apiKey = input2.authScope === "folder" ? resolveProjectApiKeyForBaseUrl(input2.baseUrl) : resolveGlobalApiKeyForBaseUrl(input2.baseUrl);
|
|
@@ -9037,6 +9153,12 @@ async function handleStatus(args) {
|
|
|
9037
9153
|
...payload.workspace.name ? [`Workspace: ${payload.workspace.name}`] : [],
|
|
9038
9154
|
...payload.workspace.slug ? [`Workspace slug: ${payload.workspace.slug}`] : [],
|
|
9039
9155
|
...payload.workspace.id != null ? [`Org ID: ${payload.workspace.id}`] : [],
|
|
9156
|
+
// Switching orgs lives under `deepline org`, but this is where
|
|
9157
|
+
// people look when they discover they are in the wrong
|
|
9158
|
+
// workspace. Without the pointer the reasonable next move is
|
|
9159
|
+
// `deepline auth register`, which re-approves the same account
|
|
9160
|
+
// and leaves the active org unchanged.
|
|
9161
|
+
"Switch workspace: deepline org list, then deepline org set <org-id>",
|
|
9040
9162
|
...payload.user.id != null ? [`User ID: ${payload.user.id}`] : [],
|
|
9041
9163
|
...payload.examples.length > 0 ? [
|
|
9042
9164
|
"Examples:",
|
|
@@ -9068,8 +9190,16 @@ Notes:
|
|
|
9068
9190
|
opening the approval page in Cowork. Use --wait no in CI or agent runs, then
|
|
9069
9191
|
finish with deepline auth wait.
|
|
9070
9192
|
Auth status shows the target host and active workspace without printing secrets.
|
|
9193
|
+
Registering again re-approves the same account; it does not change the active
|
|
9194
|
+
workspace. To switch, use deepline org list and deepline org set <org-id>.
|
|
9071
9195
|
`
|
|
9072
9196
|
);
|
|
9197
|
+
auth.command("workspaces").description("Deprecated. Use deepline org list to see workspaces.").action(() => {
|
|
9198
|
+
console.error(
|
|
9199
|
+
"Workspaces live under `deepline org`.\n List: deepline org list\n Switch: deepline org set <org-id>\n`deepline auth register` re-approves this device; it does not change the active workspace."
|
|
9200
|
+
);
|
|
9201
|
+
process.exitCode = 1;
|
|
9202
|
+
});
|
|
9073
9203
|
auth.command("register").description(
|
|
9074
9204
|
"Register this device and open the approval page in your browser."
|
|
9075
9205
|
).addHelpText(
|
|
@@ -9314,6 +9444,18 @@ function billingTopUpFailureFromError(error, input2) {
|
|
|
9314
9444
|
}
|
|
9315
9445
|
return null;
|
|
9316
9446
|
}
|
|
9447
|
+
function normalizeUnixMilliseconds(value) {
|
|
9448
|
+
const timestamp = Math.floor(value);
|
|
9449
|
+
return Number.isFinite(timestamp) && timestamp >= 0 && Number.isFinite(new Date(timestamp).getTime()) ? timestamp : null;
|
|
9450
|
+
}
|
|
9451
|
+
function parseSince(raw) {
|
|
9452
|
+
if (!raw?.trim()) return null;
|
|
9453
|
+
const numeric = Number(raw);
|
|
9454
|
+
const normalizedNumeric = normalizeUnixMilliseconds(numeric);
|
|
9455
|
+
if (normalizedNumeric !== null) return normalizedNumeric;
|
|
9456
|
+
const parsed = Date.parse(raw);
|
|
9457
|
+
return normalizeUnixMilliseconds(parsed);
|
|
9458
|
+
}
|
|
9317
9459
|
function humanize(value) {
|
|
9318
9460
|
return String(value || "").split("_").filter(Boolean).map((token) => token[0]?.toUpperCase() + token.slice(1)).join(" ") || "Unknown";
|
|
9319
9461
|
}
|
|
@@ -9599,6 +9741,18 @@ async function handleHistory(options) {
|
|
|
9599
9741
|
);
|
|
9600
9742
|
}
|
|
9601
9743
|
async function handleLedgerExportAll(options) {
|
|
9744
|
+
const sinceAt = parseSince(options.since);
|
|
9745
|
+
if (options.since && sinceAt === null) {
|
|
9746
|
+
reportBillingFailure(
|
|
9747
|
+
{
|
|
9748
|
+
exitCode: 2,
|
|
9749
|
+
code: "INVALID_SINCE",
|
|
9750
|
+
message: "--since must be an ISO-8601 timestamp or Unix milliseconds."
|
|
9751
|
+
},
|
|
9752
|
+
options
|
|
9753
|
+
);
|
|
9754
|
+
return;
|
|
9755
|
+
}
|
|
9602
9756
|
const { http } = getAuthedHttpClient();
|
|
9603
9757
|
const outputPath = options.output ? (0, import_node_path6.resolve)(String(options.output)) : defaultLedgerExportPath();
|
|
9604
9758
|
let summary = { row_count: 0, net_delta_credits: 0 };
|
|
@@ -9608,6 +9762,8 @@ async function handleLedgerExportAll(options) {
|
|
|
9608
9762
|
const params = new URLSearchParams({ limit: "5000" });
|
|
9609
9763
|
if (cursor !== null) params.set("cursor", cursor);
|
|
9610
9764
|
if (options.runId) params.set("run_id", options.runId);
|
|
9765
|
+
if (options.operation) params.set("operation", options.operation);
|
|
9766
|
+
if (sinceAt !== null) params.set("since_at", String(sinceAt));
|
|
9611
9767
|
const payload = await http.get(
|
|
9612
9768
|
`/api/v2/billing/ledger?${params.toString()}`
|
|
9613
9769
|
);
|
|
@@ -9636,13 +9792,15 @@ async function handleLedgerExportAll(options) {
|
|
|
9636
9792
|
net_delta_credits: summary.net_delta_credits,
|
|
9637
9793
|
scope: "workspace",
|
|
9638
9794
|
...options.runId ? { run_id: options.runId } : {},
|
|
9795
|
+
...options.operation ? { operation: options.operation } : {},
|
|
9796
|
+
...sinceAt !== null ? { since_at: sinceAt } : {},
|
|
9639
9797
|
render: {
|
|
9640
9798
|
sections: [
|
|
9641
9799
|
{
|
|
9642
9800
|
title: "billing ledger",
|
|
9643
9801
|
lines: [
|
|
9644
9802
|
`Billing ledger written to ${outputPath}`,
|
|
9645
|
-
`${summary.row_count} row(s) exported for the active workspace${options.runId ? ` and run ${options.runId}` : ""}.`,
|
|
9803
|
+
`${summary.row_count} row(s) exported for the active workspace${options.runId ? ` and run ${options.runId}` : ""}${options.operation ? ` and operation ${options.operation}` : ""}${sinceAt !== null ? ` since ${new Date(sinceAt).toISOString()}` : ""}.`,
|
|
9646
9804
|
`Net ledger delta: ${summary.net_delta_credits} Deepline Credits`
|
|
9647
9805
|
]
|
|
9648
9806
|
}
|
|
@@ -10339,6 +10497,7 @@ Examples:
|
|
|
10339
10497
|
deepline billing ledger export all
|
|
10340
10498
|
deepline billing ledger export all --output ./ledger.csv
|
|
10341
10499
|
deepline billing ledger export all --run-id play/demo/run/abc123
|
|
10500
|
+
deepline billing ledger export all --operation limadata_find_audience_identifiers --since 2026-09-01T00:00:00Z
|
|
10342
10501
|
deepline billing ledger export all --json
|
|
10343
10502
|
`
|
|
10344
10503
|
).addCommand(
|
|
@@ -10360,7 +10519,10 @@ Examples:
|
|
|
10360
10519
|
deepline billing ledger export all
|
|
10361
10520
|
deepline billing ledger export all --json
|
|
10362
10521
|
`
|
|
10363
|
-
).option("--output <path>", "Write CSV to an explicit path").option("--run-id <run_id>", "Export ledger rows for one play run.").option(
|
|
10522
|
+
).option("--output <path>", "Write CSV to an explicit path").option("--run-id <run_id>", "Export ledger rows for one play run.").option("--operation <id>", "Export rows for one tool operation.").option(
|
|
10523
|
+
"--since <timestamp>",
|
|
10524
|
+
"Only export rows since ISO-8601 time or Unix milliseconds."
|
|
10525
|
+
).option(
|
|
10364
10526
|
"--json",
|
|
10365
10527
|
"Emit JSON output. Also automatic when stdout is piped"
|
|
10366
10528
|
).action(handleLedgerExportAll)
|
|
@@ -16634,7 +16796,7 @@ async function traceCliSpan(phase, fields, run) {
|
|
|
16634
16796
|
var EXTRACTED_GETTER_ERROR_HINT = "Deepline hint: extractedValues/extractedLists .get() only works for declared Deepline getters listed by `deepline tools describe <tool> --json`. Use `toolExecutionResult.toolResponse.raw` for provider/tool-specific scalar fields, and `toolExecutionResult.extractedLists.<name>.get()` for declared row/list outputs.";
|
|
16635
16797
|
var DATASET_API_HINT = "Deepline hint: PlayDataset is lazy, durable, and async-only. Use `.count()`, `.first()`, `.at(index)`, `.peek(n)`, `.materialize(limit)`, or async iteration; do not use `.length`, numeric indexing, spread, synchronous iteration, `.rows`, or `.toArray()`.";
|
|
16636
16798
|
var ROW_PROPERTY_HINT = "Deepline hint: this row type only contains fields produced by the CSV/schema and previous map steps. Check source column casing and the exact output field names from earlier steps before scaling.";
|
|
16637
|
-
var TOOLS_EXECUTE_SIGNATURE_HINT = "Deepline hint: ctx.tools.execute requires a request object: `ctx.tools.execute({ id, tool, input, description })`. The stable `id` is required for logs, metadata, and
|
|
16799
|
+
var TOOLS_EXECUTE_SIGNATURE_HINT = "Deepline hint: ctx.tools.execute requires a request object: `ctx.tools.execute({ id, tool, input, description })`. The stable `id` is required for logs, metadata, and result-cache identity; terminal cache reuse is based on play, tool, semantic input, auth scope, provider action version, and cache policy.";
|
|
16638
16800
|
var RUN_PLAY_SIGNATURE_HINT = "Deepline hint: ctx.runPlay uses a stable key plus a composable child play reference. Direct-run-only or dataset-backed batch plays must be run directly, exported, then consumed by a separate play.";
|
|
16639
16801
|
var MAP_BACKED_CHILD_HINT = "Deepline hint: dataset-backed child plays own durable table state and cannot be called from another play. Run that play directly, export its dataset, then pass the CSV to the next play.";
|
|
16640
16802
|
function sourceLineForError(sourceCode, error) {
|
|
@@ -32469,7 +32631,7 @@ function renderDeployedListText(payload, requestedStatus) {
|
|
|
32469
32631
|
return status && count !== void 0 ? [`${status}: ${count}`] : [];
|
|
32470
32632
|
}).join(" ") : "";
|
|
32471
32633
|
if (summary) lines.push(`All lifecycle states: ${summary}`);
|
|
32472
|
-
if (payload.is_truncated === true) {
|
|
32634
|
+
if (payload.has_more === true || payload.is_truncated === true) {
|
|
32473
32635
|
const nextCursor = asString(payload.next_cursor);
|
|
32474
32636
|
lines.push(
|
|
32475
32637
|
total !== void 0 ? `List truncated \u2014 showing ${monitors.length} of ${total}. Before concluding "no matching monitor exists," page the full registry:` : 'List truncated. Before concluding "no matching monitor exists," page the full registry:',
|
|
@@ -32483,11 +32645,15 @@ function renderDeployedListText(payload, requestedStatus) {
|
|
|
32483
32645
|
`;
|
|
32484
32646
|
}
|
|
32485
32647
|
async function handleMonitorsList(options) {
|
|
32648
|
+
if (options.compact) {
|
|
32649
|
+
process.stderr.write(
|
|
32650
|
+
"`--compact` is deprecated and now does nothing; returning the complete monitor records.\n"
|
|
32651
|
+
);
|
|
32652
|
+
}
|
|
32486
32653
|
const payload = await new DeeplineClient().monitors.list({
|
|
32487
32654
|
...options.status ? { status: options.status } : {},
|
|
32488
32655
|
...options.limit ? { limit: options.limit } : {},
|
|
32489
32656
|
...options.cursor ? { cursor: options.cursor } : {},
|
|
32490
|
-
...options.compact ? { compact: true } : {},
|
|
32491
32657
|
...options.includeConsumers ? { includeConsumers: true } : {}
|
|
32492
32658
|
});
|
|
32493
32659
|
printCommandEnvelope(payload, {
|
|
@@ -32598,6 +32764,10 @@ var MONITOR_FLEET_COMMANDS = [
|
|
|
32598
32764
|
{
|
|
32599
32765
|
name: "deactivate",
|
|
32600
32766
|
summary: "Deactivate a fleet and the monitors it owns."
|
|
32767
|
+
},
|
|
32768
|
+
{
|
|
32769
|
+
name: "reactivate",
|
|
32770
|
+
summary: "Explicitly recreate a fleet after a credit-triggered suspension."
|
|
32601
32771
|
}
|
|
32602
32772
|
];
|
|
32603
32773
|
var MONITOR_FLEET_AGENT_NOTES = [
|
|
@@ -33100,6 +33270,72 @@ async function handleMonitorFleetsGet(fleetId, options) {
|
|
|
33100
33270
|
{ json: options.json, text }
|
|
33101
33271
|
);
|
|
33102
33272
|
}
|
|
33273
|
+
function fleetReactivateCommandLine(fleetId, options) {
|
|
33274
|
+
const parts = [
|
|
33275
|
+
"deepline",
|
|
33276
|
+
"monitors",
|
|
33277
|
+
"fleets",
|
|
33278
|
+
"reactivate",
|
|
33279
|
+
fleetShellArg(fleetId),
|
|
33280
|
+
"--yes"
|
|
33281
|
+
];
|
|
33282
|
+
if (options.wait) parts.push("--wait");
|
|
33283
|
+
if (options.timeout)
|
|
33284
|
+
parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
|
|
33285
|
+
if (options.idempotencyKey)
|
|
33286
|
+
parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
|
|
33287
|
+
parts.push(...fleetJsonFlag(options));
|
|
33288
|
+
return parts.join(" ");
|
|
33289
|
+
}
|
|
33290
|
+
async function handleMonitorFleetsReactivate(fleetId, options, idempotencyKey) {
|
|
33291
|
+
if (!options.yes) {
|
|
33292
|
+
throw new MonitorsUsageError(
|
|
33293
|
+
`reactivate can recreate every suspended provider monitor and restart lifecycle billing. Confirm with --yes:
|
|
33294
|
+
${fleetReactivateCommandLine(fleetId, options)}`
|
|
33295
|
+
);
|
|
33296
|
+
}
|
|
33297
|
+
const client2 = new DeeplineClient();
|
|
33298
|
+
const payload = await client2.monitors.fleets.reactivate(fleetId, {
|
|
33299
|
+
idempotencyKey
|
|
33300
|
+
});
|
|
33301
|
+
const accepted = { ...payload, idempotency_key: idempotencyKey };
|
|
33302
|
+
if (!options.wait) {
|
|
33303
|
+
printCommandEnvelope(accepted, {
|
|
33304
|
+
json: options.json,
|
|
33305
|
+
text: `Fleet ${fleetId} \u2014 ${asString(payload.status) ?? "billing_reactivating"}
|
|
33306
|
+
idempotency key ${idempotencyKey}
|
|
33307
|
+
`
|
|
33308
|
+
});
|
|
33309
|
+
return;
|
|
33310
|
+
}
|
|
33311
|
+
const timeoutMs = fleetTimeoutMs(options.timeout);
|
|
33312
|
+
const progress = fleetProgressReporter();
|
|
33313
|
+
let final;
|
|
33314
|
+
try {
|
|
33315
|
+
final = await client2.monitors.fleets.waitForConvergence(fleetId, {
|
|
33316
|
+
timeoutMs,
|
|
33317
|
+
pollIntervalMs: FLEET_POLL_INTERVAL_MS,
|
|
33318
|
+
onProgress: progress.report
|
|
33319
|
+
});
|
|
33320
|
+
} finally {
|
|
33321
|
+
progress.finish();
|
|
33322
|
+
}
|
|
33323
|
+
const envelope = { ...accepted, ...final };
|
|
33324
|
+
const text = renderFleetGet(final);
|
|
33325
|
+
if (fleetStatus(final) === "converged") {
|
|
33326
|
+
printCommandEnvelope(envelope, { json: options.json, text });
|
|
33327
|
+
return;
|
|
33328
|
+
}
|
|
33329
|
+
reportFleetState(
|
|
33330
|
+
envelope,
|
|
33331
|
+
new MonitorFleetStateError({
|
|
33332
|
+
code: "MONITOR_FLEET_WAIT_TIMEOUT",
|
|
33333
|
+
message: `Stopped waiting after ${timeoutMs}ms. Fleet ${fleetId} recovery is still in progress on the server.`,
|
|
33334
|
+
next: fleetServerNext(final) ?? `deepline monitors fleets get ${fleetShellArg(fleetId)} --json`
|
|
33335
|
+
}),
|
|
33336
|
+
{ json: options.json, text }
|
|
33337
|
+
);
|
|
33338
|
+
}
|
|
33103
33339
|
function fleetDeactivateCommandLine(fleetId, options) {
|
|
33104
33340
|
const parts = [
|
|
33105
33341
|
"deepline monitors fleets deactivate",
|
|
@@ -33397,18 +33633,11 @@ async function handleMonitorsGet(key, options) {
|
|
|
33397
33633
|
}
|
|
33398
33634
|
async function handleMonitorsTest(key, payload, options) {
|
|
33399
33635
|
const explicitPayload = parseJsonObjectArg(payload, "<payload>");
|
|
33400
|
-
const result = await new DeeplineClient().monitors.test(
|
|
33401
|
-
key,
|
|
33402
|
-
explicitPayload,
|
|
33403
|
-
{
|
|
33404
|
-
validationOnly: options.dispatch !== true,
|
|
33405
|
-
dispatch: options.dispatch === true
|
|
33406
|
-
}
|
|
33407
|
-
);
|
|
33408
|
-
const dispatch = options.dispatch === true;
|
|
33636
|
+
const result = await new DeeplineClient().monitors.test(key, explicitPayload);
|
|
33409
33637
|
const text = `Monitor diagnostic for ${key}: ${result.accepted === true ? "accepted" : "rejected"}
|
|
33410
|
-
|
|
33411
|
-
|
|
33638
|
+
mode: validation_only (no rows written, credits spent, or Plays dispatched)
|
|
33639
|
+
persisted rows: ${asFiniteNumber(result.persisted_rows) ?? 0}
|
|
33640
|
+
dispatched bound Plays: ${asFiniteNumber(result.dispatched_bound_plays) ?? 0}
|
|
33412
33641
|
`;
|
|
33413
33642
|
printCommandEnvelope(result, { json: options.json, text });
|
|
33414
33643
|
}
|
|
@@ -33488,6 +33717,206 @@ async function handleMonitorsReactivate(key, options) {
|
|
|
33488
33717
|
const payload = await client2.monitors.reactivate(key);
|
|
33489
33718
|
printCommandEnvelope(payload, { json: options.json });
|
|
33490
33719
|
}
|
|
33720
|
+
var MONITOR_VERB_POLL_INTERVAL_MS = 2e3;
|
|
33721
|
+
function monitorHealthLine(health) {
|
|
33722
|
+
return [
|
|
33723
|
+
`converged ${health.converged}/${health.scanned}`,
|
|
33724
|
+
`needs_repair ${health.needs_repair}`,
|
|
33725
|
+
`missing ${health.observed.missing}`,
|
|
33726
|
+
`unaudited ${health.observed.unknown + health.observed.unset}`,
|
|
33727
|
+
`silent ${health.silent}`
|
|
33728
|
+
].join(" \xB7 ");
|
|
33729
|
+
}
|
|
33730
|
+
function monitorVerbProgressReporter() {
|
|
33731
|
+
const interactive = process.stderr.isTTY === true;
|
|
33732
|
+
let wrote = false;
|
|
33733
|
+
let lastPlainAt = 0;
|
|
33734
|
+
return {
|
|
33735
|
+
report: (health) => {
|
|
33736
|
+
const line = monitorHealthLine(health);
|
|
33737
|
+
if (interactive) {
|
|
33738
|
+
process.stderr.write(`\r\x1B[2K${line}`);
|
|
33739
|
+
wrote = true;
|
|
33740
|
+
return;
|
|
33741
|
+
}
|
|
33742
|
+
const now = Date.now();
|
|
33743
|
+
if (wrote && now - lastPlainAt < FLEET_PLAIN_PROGRESS_INTERVAL_MS) return;
|
|
33744
|
+
lastPlainAt = now;
|
|
33745
|
+
wrote = true;
|
|
33746
|
+
process.stderr.write(`${line}
|
|
33747
|
+
`);
|
|
33748
|
+
},
|
|
33749
|
+
finish: () => {
|
|
33750
|
+
if (interactive && wrote) process.stderr.write("\n");
|
|
33751
|
+
}
|
|
33752
|
+
};
|
|
33753
|
+
}
|
|
33754
|
+
async function watchMonitorHealth(input2) {
|
|
33755
|
+
const deadlineAt = Date.now() + input2.timeoutMs;
|
|
33756
|
+
const scope = input2.fleetId ? { fleetId: input2.fleetId } : {};
|
|
33757
|
+
let last = await input2.client.monitors.health(scope);
|
|
33758
|
+
input2.onProgress(last);
|
|
33759
|
+
while (Date.now() < deadlineAt) {
|
|
33760
|
+
if (last.needs_repair === 0 && last.observed.unknown === 0) return last;
|
|
33761
|
+
await new Promise(
|
|
33762
|
+
(resolve21) => setTimeout(resolve21, MONITOR_VERB_POLL_INTERVAL_MS)
|
|
33763
|
+
);
|
|
33764
|
+
last = await input2.client.monitors.health(scope);
|
|
33765
|
+
input2.onProgress(last);
|
|
33766
|
+
}
|
|
33767
|
+
return last;
|
|
33768
|
+
}
|
|
33769
|
+
function monitorHealthText(health) {
|
|
33770
|
+
const partial = health.truncated ? " (partial \u2014 scope larger than one read)" : "";
|
|
33771
|
+
const lines = [
|
|
33772
|
+
`scope: ${health.scope.fleet_id ?? "workspace"}${partial}`,
|
|
33773
|
+
monitorHealthLine(health)
|
|
33774
|
+
];
|
|
33775
|
+
if (health.deactivation_reasons.length > 0) {
|
|
33776
|
+
lines.push("");
|
|
33777
|
+
lines.push("deactivated by Deepline:");
|
|
33778
|
+
for (const entry of health.deactivation_reasons) {
|
|
33779
|
+
const how = entry.resolution ? ` \u2014 ${entry.resolution}` : "";
|
|
33780
|
+
lines.push(` ${entry.reason} (${entry.count})${how}`);
|
|
33781
|
+
}
|
|
33782
|
+
}
|
|
33783
|
+
if (health.worst_offenders.length > 0) {
|
|
33784
|
+
lines.push("");
|
|
33785
|
+
lines.push(
|
|
33786
|
+
`silent longest (no delivery in ${health.silent_window_days}d):`
|
|
33787
|
+
);
|
|
33788
|
+
for (const entry of health.worst_offenders) {
|
|
33789
|
+
const when = entry.last_event_at === null ? "never" : new Date(entry.last_event_at).toISOString();
|
|
33790
|
+
lines.push(` ${entry.monitor_key} ${entry.tool} last event ${when}`);
|
|
33791
|
+
}
|
|
33792
|
+
}
|
|
33793
|
+
return `${lines.join("\n")}
|
|
33794
|
+
`;
|
|
33795
|
+
}
|
|
33796
|
+
async function handleMonitorsAudit(options) {
|
|
33797
|
+
const client2 = new DeeplineClient();
|
|
33798
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33799
|
+
const scope = fleetId ? { fleetId } : {};
|
|
33800
|
+
let result = await client2.monitors.audit(scope);
|
|
33801
|
+
const passes = [result.audit];
|
|
33802
|
+
while (result.audit.cursor !== null) {
|
|
33803
|
+
result = await client2.monitors.audit({
|
|
33804
|
+
...scope,
|
|
33805
|
+
cursor: result.audit.cursor
|
|
33806
|
+
});
|
|
33807
|
+
passes.push(result.audit);
|
|
33808
|
+
}
|
|
33809
|
+
const totals = passes.reduce(
|
|
33810
|
+
(sum, pass) => ({
|
|
33811
|
+
scanned: sum.scanned + pass.scanned,
|
|
33812
|
+
asked: sum.asked + pass.asked,
|
|
33813
|
+
stale: sum.stale + pass.stale,
|
|
33814
|
+
missing: sum.missing + pass.observed.missing
|
|
33815
|
+
}),
|
|
33816
|
+
{ scanned: 0, asked: 0, stale: 0, missing: 0 }
|
|
33817
|
+
);
|
|
33818
|
+
let health = result.health;
|
|
33819
|
+
if (options.watch) {
|
|
33820
|
+
const progress = monitorVerbProgressReporter();
|
|
33821
|
+
try {
|
|
33822
|
+
health = await watchMonitorHealth({
|
|
33823
|
+
client: client2,
|
|
33824
|
+
...scope,
|
|
33825
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
33826
|
+
onProgress: progress.report
|
|
33827
|
+
});
|
|
33828
|
+
} finally {
|
|
33829
|
+
progress.finish();
|
|
33830
|
+
}
|
|
33831
|
+
}
|
|
33832
|
+
const unauditable = result.audit.unauditable_capabilities;
|
|
33833
|
+
const overtaken = totals.stale > 0 ? ` \xB7 ${totals.stale} observations overtaken by a concurrent settle` : "";
|
|
33834
|
+
const text = [
|
|
33835
|
+
`audited ${totals.scanned} monitors \xB7 asked the provider about ${totals.asked}`,
|
|
33836
|
+
`missing ${totals.missing}${overtaken}`,
|
|
33837
|
+
...unauditable.length > 0 ? [`not auditable (no batch-read contract): ${unauditable.join(", ")}`] : [],
|
|
33838
|
+
"",
|
|
33839
|
+
monitorHealthText(health)
|
|
33840
|
+
].join("\n");
|
|
33841
|
+
printCommandEnvelope(
|
|
33842
|
+
{ ...result, audit: { ...result.audit, totals }, health },
|
|
33843
|
+
{ json: options.json, text }
|
|
33844
|
+
);
|
|
33845
|
+
}
|
|
33846
|
+
async function handleMonitorsRepair(options) {
|
|
33847
|
+
const client2 = new DeeplineClient();
|
|
33848
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33849
|
+
const scope = fleetId ? { fleetId } : {};
|
|
33850
|
+
const result = await client2.monitors.repair({
|
|
33851
|
+
...scope,
|
|
33852
|
+
...options.dryRun ? { dryRun: true } : {}
|
|
33853
|
+
});
|
|
33854
|
+
if (options.dryRun) {
|
|
33855
|
+
assertMonitorDryRunAcknowledged(
|
|
33856
|
+
result,
|
|
33857
|
+
{ command: "monitors repair", mutation: "repair" }
|
|
33858
|
+
);
|
|
33859
|
+
}
|
|
33860
|
+
let health = result.health;
|
|
33861
|
+
if (options.watch && !options.dryRun) {
|
|
33862
|
+
const progress = monitorVerbProgressReporter();
|
|
33863
|
+
try {
|
|
33864
|
+
health = await watchMonitorHealth({
|
|
33865
|
+
client: client2,
|
|
33866
|
+
...scope,
|
|
33867
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
33868
|
+
onProgress: progress.report
|
|
33869
|
+
});
|
|
33870
|
+
} finally {
|
|
33871
|
+
progress.finish();
|
|
33872
|
+
}
|
|
33873
|
+
}
|
|
33874
|
+
const verb = options.dryRun ? "would queue" : "queued";
|
|
33875
|
+
const lines = [
|
|
33876
|
+
`${verb} ${result.repair.queued} of ${result.repair.scanned} monitors`
|
|
33877
|
+
];
|
|
33878
|
+
for (const item of result.repair.plan.slice(0, REPAIR_PLAN_PREVIEW)) {
|
|
33879
|
+
const why = item.deactivation_reason ? ` \xB7 ${item.deactivation_reason}` : "";
|
|
33880
|
+
lines.push(
|
|
33881
|
+
` ${item.action.padEnd(6)} ${item.monitor_key} desired ${item.desired} \xB7 observed ${item.observed}${why}`
|
|
33882
|
+
);
|
|
33883
|
+
}
|
|
33884
|
+
if (result.repair.plan.length > REPAIR_PLAN_PREVIEW) {
|
|
33885
|
+
lines.push(` \u2026 ${result.repair.plan.length - REPAIR_PLAN_PREVIEW} more`);
|
|
33886
|
+
}
|
|
33887
|
+
if (result.repair.unaudited.length > 0) {
|
|
33888
|
+
lines.push(
|
|
33889
|
+
`${result.repair.unaudited.length} monitors have never been observed \u2014 run 'deepline monitors audit' first.`
|
|
33890
|
+
);
|
|
33891
|
+
}
|
|
33892
|
+
if (result.repair.unowned.length > 0) {
|
|
33893
|
+
lines.push(
|
|
33894
|
+
`${result.repair.unowned.length} monitors disagree but no fleet owns them; repair those with 'deepline monitors deploy' or 'deepline monitors delete'.`
|
|
33895
|
+
);
|
|
33896
|
+
}
|
|
33897
|
+
if (result.repair.fenced.length > 0) {
|
|
33898
|
+
lines.push(
|
|
33899
|
+
`${result.repair.fenced.length} monitors have a provider operation in flight; Deepline is finishing those and repair left them alone.`
|
|
33900
|
+
);
|
|
33901
|
+
}
|
|
33902
|
+
lines.push("");
|
|
33903
|
+
lines.push(monitorHealthText(health));
|
|
33904
|
+
printCommandEnvelope(
|
|
33905
|
+
{ ...result, health },
|
|
33906
|
+
{ json: options.json, text: lines.join("\n") }
|
|
33907
|
+
);
|
|
33908
|
+
}
|
|
33909
|
+
var REPAIR_PLAN_PREVIEW = 20;
|
|
33910
|
+
async function handleMonitorsHealth(options) {
|
|
33911
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33912
|
+
const health = await new DeeplineClient().monitors.health(
|
|
33913
|
+
fleetId ? { fleetId } : {}
|
|
33914
|
+
);
|
|
33915
|
+
printCommandEnvelope(health, {
|
|
33916
|
+
json: options.json,
|
|
33917
|
+
text: monitorHealthText(health)
|
|
33918
|
+
});
|
|
33919
|
+
}
|
|
33491
33920
|
function registerMonitorsCommands(program) {
|
|
33492
33921
|
const monitors = program.command("monitors").description("Discover, deploy, and manage Deepline monitors.").showSuggestionAfterError(true).addHelpText(
|
|
33493
33922
|
"after",
|
|
@@ -33523,6 +33952,75 @@ Examples:
|
|
|
33523
33952
|
deepline monitors reactivate my-monitor --dry-run
|
|
33524
33953
|
`
|
|
33525
33954
|
);
|
|
33955
|
+
withJsonOption(
|
|
33956
|
+
monitors.command("audit").description(
|
|
33957
|
+
"Re-read what the provider actually holds for your monitors."
|
|
33958
|
+
).option("--fleet <fleet-id>", "Audit one fleet instead of every monitor").option("--watch", "Keep polling health until the scope settles").option(
|
|
33959
|
+
"--timeout <duration>",
|
|
33960
|
+
"How long --watch waits, e.g. 90s, 5m, 1h (default 10m)"
|
|
33961
|
+
).addHelpText(
|
|
33962
|
+
"after",
|
|
33963
|
+
`
|
|
33964
|
+
Notes:
|
|
33965
|
+
Asks the provider, by resource id, what it still holds, and records the answer
|
|
33966
|
+
on each monitor. It changes nothing upstream: no creates, no deletes, no
|
|
33967
|
+
intent. Safe to run at any time, as often as you like \u2014 running it twice is
|
|
33968
|
+
running it once, twice.
|
|
33969
|
+
|
|
33970
|
+
A monitor the provider does not return is recorded "missing". Use
|
|
33971
|
+
'deepline monitors repair' to act on that.
|
|
33972
|
+
|
|
33973
|
+
Examples:
|
|
33974
|
+
deepline monitors audit
|
|
33975
|
+
deepline monitors audit --fleet accounts-eu --json
|
|
33976
|
+
deepline monitors audit --fleet accounts-eu --watch --timeout 5m
|
|
33977
|
+
`
|
|
33978
|
+
)
|
|
33979
|
+
).action(monitorsAction(handleMonitorsAudit));
|
|
33980
|
+
withJsonOption(
|
|
33981
|
+
monitors.command("repair").description(
|
|
33982
|
+
"Converge the monitors whose desired and observed states disagree."
|
|
33983
|
+
).option("--fleet <fleet-id>", "Repair one fleet instead of every monitor").option("--dry-run", "Show what would be queued without queueing it").option("--watch", "Keep polling health until the scope settles").option(
|
|
33984
|
+
"--timeout <duration>",
|
|
33985
|
+
"How long --watch waits, e.g. 90s, 5m, 1h (default 10m)"
|
|
33986
|
+
).addHelpText(
|
|
33987
|
+
"after",
|
|
33988
|
+
`
|
|
33989
|
+
Notes:
|
|
33990
|
+
Queues the monitors that disagree with the provider onto the same convergence
|
|
33991
|
+
loop a fleet sync uses; the provider work happens on Deepline's own schedule.
|
|
33992
|
+
Idempotent \u2014 the queue IS the disagreement, so a repeat run queues only what
|
|
33993
|
+
is still wrong.
|
|
33994
|
+
|
|
33995
|
+
Monitors nobody has observed are never repaired: run 'deepline monitors audit'
|
|
33996
|
+
first. Monitors no fleet owns are reported rather than queued; deploy or delete
|
|
33997
|
+
those directly.
|
|
33998
|
+
|
|
33999
|
+
Examples:
|
|
34000
|
+
deepline monitors repair --dry-run
|
|
34001
|
+
deepline monitors repair --fleet accounts-eu --watch
|
|
34002
|
+
`
|
|
34003
|
+
)
|
|
34004
|
+
).action(monitorsAction(handleMonitorsRepair));
|
|
34005
|
+
withJsonOption(
|
|
34006
|
+
monitors.command("health").description("Delivery and convergence health for your monitors.").option(
|
|
34007
|
+
"--fleet <fleet-id>",
|
|
34008
|
+
"Report on one fleet instead of every monitor"
|
|
34009
|
+
).addHelpText(
|
|
34010
|
+
"after",
|
|
34011
|
+
`
|
|
34012
|
+
Notes:
|
|
34013
|
+
Read-only. Reports how many monitors the provider holds as asked, how many
|
|
34014
|
+
disagree, how many Deepline deactivated and why, and how many are "silent" \u2014
|
|
34015
|
+
the provider holds them but nothing has been delivered recently. The worst
|
|
34016
|
+
offenders are listed longest-quiet first.
|
|
34017
|
+
|
|
34018
|
+
Examples:
|
|
34019
|
+
deepline monitors health
|
|
34020
|
+
deepline monitors health --fleet accounts-eu --json
|
|
34021
|
+
`
|
|
34022
|
+
)
|
|
34023
|
+
).action(monitorsAction(handleMonitorsHealth));
|
|
33526
34024
|
withJsonOption(
|
|
33527
34025
|
monitors.command("status").description("Check whether you have access to Deepline monitors.").addHelpText(
|
|
33528
34026
|
"after",
|
|
@@ -33575,10 +34073,10 @@ Examples:
|
|
|
33575
34073
|
`
|
|
33576
34074
|
Notes:
|
|
33577
34075
|
Read-only. --status filters by monitor status: active (default), disabled, or
|
|
33578
|
-
all. The output echoes the status filter that was applied.
|
|
33579
|
-
|
|
33580
|
-
|
|
33581
|
-
is
|
|
34076
|
+
all. The output echoes the status filter that was applied. The response reports
|
|
34077
|
+
total (the true registry count, not the page size), returned, has_more, and
|
|
34078
|
+
next_cursor. When has_more is true, page with --cursor <next_cursor> until it
|
|
34079
|
+
is false \u2014 a "no matching
|
|
33582
34080
|
monitor" reuse conclusion off a truncated page deploys a duplicate paid feed.
|
|
33583
34081
|
The default list stays cheap: it includes the current downstream Play binding
|
|
33584
34082
|
metadata but does not resolve per-monitor delivery/run health. Pass
|
|
@@ -33589,7 +34087,6 @@ Examples:
|
|
|
33589
34087
|
deepline monitors list
|
|
33590
34088
|
deepline monitors list --status all --json
|
|
33591
34089
|
deepline monitors list --status all --cursor <next_cursor> --json
|
|
33592
|
-
deepline monitors list --compact --json
|
|
33593
34090
|
deepline monitors list --include-consumers --limit 20 --json
|
|
33594
34091
|
`
|
|
33595
34092
|
).option(
|
|
@@ -33598,7 +34095,10 @@ Examples:
|
|
|
33598
34095
|
).option("--limit <n>", "Limit the number of deployed monitors returned").option(
|
|
33599
34096
|
"--cursor <cursor>",
|
|
33600
34097
|
"Page past a truncated result using the next_cursor from a prior list response"
|
|
33601
|
-
).option(
|
|
34098
|
+
).option(
|
|
34099
|
+
"--compact",
|
|
34100
|
+
"Deprecated no-op; complete records are always returned"
|
|
34101
|
+
).option(
|
|
33602
34102
|
"--include-consumers",
|
|
33603
34103
|
"Include current SQL-listener consumer health (requires --limit 20 or fewer)"
|
|
33604
34104
|
)
|
|
@@ -33621,10 +34121,7 @@ Examples:
|
|
|
33621
34121
|
).action(monitorsAction(handleMonitorsGet));
|
|
33622
34122
|
withJsonOption(
|
|
33623
34123
|
monitors.command("test <key> <payload>").description(
|
|
33624
|
-
"
|
|
33625
|
-
).option(
|
|
33626
|
-
"--dispatch",
|
|
33627
|
-
"Inject the test event through normal ingestion (writes rows and may dispatch bound Plays)"
|
|
34124
|
+
"Validate an explicit payload against a monitor\u2019s webhook contract."
|
|
33628
34125
|
).addHelpText(
|
|
33629
34126
|
"after",
|
|
33630
34127
|
`
|
|
@@ -33632,9 +34129,8 @@ Notes:
|
|
|
33632
34129
|
<payload> must be an explicit JSON object. The command uses the deployed
|
|
33633
34130
|
monitor\u2019s real binding and payload validation, but is a side-effect-free
|
|
33634
34131
|
diagnostic: it does not persist rows, spend credits, dispatch Plays, or alter
|
|
33635
|
-
monitor state.
|
|
33636
|
-
|
|
33637
|
-
not synthesize a provider event or accept an omitted payload.
|
|
34132
|
+
monitor state. It does not synthesize a provider event or accept an omitted
|
|
34133
|
+
payload.
|
|
33638
34134
|
|
|
33639
34135
|
Examples:
|
|
33640
34136
|
deepline monitors test rb2b-website-visitors '{"LinkedIn URL":"https://www.linkedin.com/in/example","Website":"https://example.com"}' --json
|
|
@@ -33951,6 +34447,40 @@ Examples:
|
|
|
33951
34447
|
reportMonitorsFailure(error, { retryCommand });
|
|
33952
34448
|
}
|
|
33953
34449
|
});
|
|
34450
|
+
withJsonOption(
|
|
34451
|
+
fleets.command("reactivate <fleet-id>").description(
|
|
34452
|
+
"Explicitly recreate a fleet after a credit-triggered suspension."
|
|
34453
|
+
).addHelpText(
|
|
34454
|
+
"after",
|
|
34455
|
+
`
|
|
34456
|
+
Notes:
|
|
34457
|
+
TAMRadar cannot reactivate a deleted radar. This command starts normal,
|
|
34458
|
+
fenced provider creates from the fleet's retained desired definitions and
|
|
34459
|
+
may restart lifecycle billing. A credit top-up alone never does this.
|
|
34460
|
+
|
|
34461
|
+
Example:
|
|
34462
|
+
deepline monitors fleets reactivate account-job-openings --yes --wait --json
|
|
34463
|
+
`
|
|
34464
|
+
).option("--wait", "Poll until the fleet reports converged").option(
|
|
34465
|
+
"--timeout <duration>",
|
|
34466
|
+
"How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
|
|
34467
|
+
).option("--yes", "Confirm recreating suspended provider monitors").option("--idempotency-key <key>", "Stable retry key")
|
|
34468
|
+
).action(async (fleetId, options) => {
|
|
34469
|
+
let retryCommand = fleetReactivateCommandLine(fleetId, options);
|
|
34470
|
+
try {
|
|
34471
|
+
const idempotencyKey = fleetIdempotencyKey(
|
|
34472
|
+
"reactivate",
|
|
34473
|
+
options.idempotencyKey
|
|
34474
|
+
);
|
|
34475
|
+
retryCommand = fleetReactivateCommandLine(fleetId, {
|
|
34476
|
+
...options,
|
|
34477
|
+
idempotencyKey
|
|
34478
|
+
});
|
|
34479
|
+
await handleMonitorFleetsReactivate(fleetId, options, idempotencyKey);
|
|
34480
|
+
} catch (error) {
|
|
34481
|
+
reportMonitorsFailure(error, { retryCommand });
|
|
34482
|
+
}
|
|
34483
|
+
});
|
|
33954
34484
|
const deployed = withJsonOption(
|
|
33955
34485
|
monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
|
|
33956
34486
|
"--status <status>",
|
|
@@ -33958,7 +34488,10 @@ Examples:
|
|
|
33958
34488
|
).option("--limit <n>", "Limit the number of deployed monitors returned").option(
|
|
33959
34489
|
"--cursor <cursor>",
|
|
33960
34490
|
"Page past a truncated result using the next_cursor from a prior list response"
|
|
33961
|
-
).option(
|
|
34491
|
+
).option(
|
|
34492
|
+
"--compact",
|
|
34493
|
+
"Deprecated no-op; complete records are always returned"
|
|
34494
|
+
).option(
|
|
33962
34495
|
"--include-consumers",
|
|
33963
34496
|
"Include current SQL-listener consumer health (requires --limit 20 or fewer)"
|
|
33964
34497
|
)
|
|
@@ -34280,11 +34813,13 @@ async function handleOrgStatus(options) {
|
|
|
34280
34813
|
host_env_path: hostPath,
|
|
34281
34814
|
folder_target: folderTargetPayload,
|
|
34282
34815
|
project_pin: provenance.scope === "global" && provenance.project.state === "project" ? {
|
|
34283
|
-
|
|
34816
|
+
available: true,
|
|
34817
|
+
required: false,
|
|
34284
34818
|
path: provenance.project.pinPath,
|
|
34285
|
-
cloud_mutations_blocked:
|
|
34819
|
+
cloud_mutations_blocked: false,
|
|
34286
34820
|
command: "deepline org set --auth-scope folder"
|
|
34287
34821
|
} : {
|
|
34822
|
+
available: false,
|
|
34288
34823
|
required: false,
|
|
34289
34824
|
cloud_mutations_blocked: false
|
|
34290
34825
|
},
|
|
@@ -34705,8 +35240,8 @@ Examples:
|
|
|
34705
35240
|
Notes:
|
|
34706
35241
|
Selection can be a list number, exact organization name, or organization id.
|
|
34707
35242
|
Without a selection, prints choices. With --auth-scope folder while this
|
|
34708
|
-
project is using global host auth, it pins the current target directly
|
|
34709
|
-
|
|
35243
|
+
project is using global host auth, it pins the current target directly
|
|
35244
|
+
without an additional organization lookup.
|
|
34710
35245
|
|
|
34711
35246
|
Mutates local auth state and asks Deepline for an org-scoped API key. It
|
|
34712
35247
|
writes only the selected scope:
|
|
@@ -34723,7 +35258,9 @@ Notes:
|
|
|
34723
35258
|
|
|
34724
35259
|
Prefer --auth-scope folder for a repository or customer workspace. Use
|
|
34725
35260
|
--auth-scope global only for deliberate host-wide interactive defaults; it
|
|
34726
|
-
is shared by every unpinned CLI on this machine.
|
|
35261
|
+
is shared by every unpinned CLI on this machine. Global auth remains
|
|
35262
|
+
supported in projects; use a folder pin when you want a project-specific
|
|
35263
|
+
default. For automation, pass
|
|
34727
35264
|
DEEPLINE_API_KEY only to that invocation and confirm with org status --json.
|
|
34728
35265
|
|
|
34729
35266
|
Use --json for stable fields including effective_auth_scope,
|
|
@@ -34766,6 +35303,318 @@ Examples:
|
|
|
34766
35303
|
);
|
|
34767
35304
|
}
|
|
34768
35305
|
|
|
35306
|
+
// src/cli/commands/git.ts
|
|
35307
|
+
function renderProject(project) {
|
|
35308
|
+
const root = project.rootDirectory ? ` (${project.rootDirectory})` : "";
|
|
35309
|
+
const flags = [
|
|
35310
|
+
project.disabled ? "unlinked" : "linked",
|
|
35311
|
+
`deploys ${project.productionBranch}`,
|
|
35312
|
+
project.checkOnPullRequest ? "PR checks on" : "PR checks off"
|
|
35313
|
+
].join(", ");
|
|
35314
|
+
return `${project.id} ${project.repoFullName}${root} - ${flags}`;
|
|
35315
|
+
}
|
|
35316
|
+
function renderDeployment(deployment) {
|
|
35317
|
+
const ref = deployment.ref.replace("refs/heads/", "");
|
|
35318
|
+
const kind = deployment.isProduction ? "production" : deployment.trigger === "pull_request" ? `pr #${deployment.pullRequestNumber ?? "?"}` : deployment.trigger;
|
|
35319
|
+
const suffix = deployment.error ? ` - ${deployment.error.slice(0, 80)}` : "";
|
|
35320
|
+
return `${deployment.id} ${deployment.commitSha.slice(0, 10)} ${ref} (${kind}) - ${deployment.status}${suffix}`;
|
|
35321
|
+
}
|
|
35322
|
+
async function handleList(options) {
|
|
35323
|
+
const { http } = getAuthedHttpClient();
|
|
35324
|
+
const payload = await http.get(
|
|
35325
|
+
`/api/v2/play-projects${options.all ? "?includeDisabled=1" : ""}`
|
|
35326
|
+
);
|
|
35327
|
+
printCommandEnvelope(
|
|
35328
|
+
{
|
|
35329
|
+
projects: payload.projects,
|
|
35330
|
+
count: payload.projects.length,
|
|
35331
|
+
render: {
|
|
35332
|
+
sections: [
|
|
35333
|
+
{
|
|
35334
|
+
title: "linked repositories",
|
|
35335
|
+
lines: payload.projects.length ? payload.projects.map(renderProject) : [
|
|
35336
|
+
"No repositories are linked. Run `deepline git repos` to see what the GitHub installation can reach, then `deepline git link`."
|
|
35337
|
+
]
|
|
35338
|
+
}
|
|
35339
|
+
]
|
|
35340
|
+
}
|
|
35341
|
+
},
|
|
35342
|
+
{ json: options.json }
|
|
35343
|
+
);
|
|
35344
|
+
}
|
|
35345
|
+
async function handleRepos(options) {
|
|
35346
|
+
const { http } = getAuthedHttpClient();
|
|
35347
|
+
const query = options.installation ? `?installationId=${encodeURIComponent(options.installation)}` : "";
|
|
35348
|
+
const payload = await http.get(`/api/v2/github/repos${query}`);
|
|
35349
|
+
printCommandEnvelope(
|
|
35350
|
+
{
|
|
35351
|
+
installation: payload.installation,
|
|
35352
|
+
repositories: payload.repositories,
|
|
35353
|
+
count: payload.repositories.length,
|
|
35354
|
+
render: {
|
|
35355
|
+
sections: [
|
|
35356
|
+
{
|
|
35357
|
+
title: `repos on installation @${payload.installation.accountLogin} (${payload.installation.repositorySelection})`,
|
|
35358
|
+
lines: payload.repositories.map(
|
|
35359
|
+
(repo) => `${repo.repoId} ${repo.fullName} (default: ${repo.defaultBranch}${repo.private ? ", private" : ""}${repo.fork ? ", fork" : ""})`
|
|
35360
|
+
)
|
|
35361
|
+
}
|
|
35362
|
+
]
|
|
35363
|
+
}
|
|
35364
|
+
},
|
|
35365
|
+
{ json: options.json }
|
|
35366
|
+
);
|
|
35367
|
+
}
|
|
35368
|
+
async function resolveRepoId(repo, installation) {
|
|
35369
|
+
if (/^\d+$/.test(repo)) return Number(repo);
|
|
35370
|
+
const { http } = getAuthedHttpClient();
|
|
35371
|
+
const query = installation ? `?installationId=${encodeURIComponent(installation)}` : "";
|
|
35372
|
+
const payload = await http.get(
|
|
35373
|
+
`/api/v2/github/repos${query}`
|
|
35374
|
+
);
|
|
35375
|
+
const match = payload.repositories.find(
|
|
35376
|
+
(entry) => entry.fullName.toLowerCase() === repo.toLowerCase()
|
|
35377
|
+
);
|
|
35378
|
+
if (!match) {
|
|
35379
|
+
throw new Error(
|
|
35380
|
+
`Repo "${repo}" is not accessible to the workspace's GitHub installation. Run \`deepline git repos\` to list what is.`
|
|
35381
|
+
);
|
|
35382
|
+
}
|
|
35383
|
+
return match.repoId;
|
|
35384
|
+
}
|
|
35385
|
+
async function handleLink(repo, options) {
|
|
35386
|
+
const repoId = await resolveRepoId(repo, options.installation);
|
|
35387
|
+
const { http } = getAuthedHttpClient();
|
|
35388
|
+
const payload = await http.post("/api/v2/play-projects", {
|
|
35389
|
+
repoId,
|
|
35390
|
+
...options.installation !== void 0 ? { installationId: options.installation } : {},
|
|
35391
|
+
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
35392
|
+
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
35393
|
+
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
35394
|
+
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {}
|
|
35395
|
+
});
|
|
35396
|
+
printCommandEnvelope(
|
|
35397
|
+
{
|
|
35398
|
+
project: payload.project,
|
|
35399
|
+
render: {
|
|
35400
|
+
sections: [
|
|
35401
|
+
{
|
|
35402
|
+
title: "linked",
|
|
35403
|
+
lines: [
|
|
35404
|
+
renderProject(payload.project),
|
|
35405
|
+
...(payload.warnings ?? []).map(
|
|
35406
|
+
(warning) => `WARNING: ${warning}`
|
|
35407
|
+
),
|
|
35408
|
+
"Pushes to the production branch now register and promote changed plays.",
|
|
35409
|
+
"Anyone who can push to this repo can change what runs in this workspace."
|
|
35410
|
+
]
|
|
35411
|
+
}
|
|
35412
|
+
]
|
|
35413
|
+
}
|
|
35414
|
+
},
|
|
35415
|
+
{ json: options.json }
|
|
35416
|
+
);
|
|
35417
|
+
}
|
|
35418
|
+
async function handleGet(id, options) {
|
|
35419
|
+
const { http } = getAuthedHttpClient();
|
|
35420
|
+
const payload = await http.get(
|
|
35421
|
+
`/api/v2/play-projects/${encodeURIComponent(id)}`
|
|
35422
|
+
);
|
|
35423
|
+
printCommandEnvelope(
|
|
35424
|
+
{
|
|
35425
|
+
project: payload.project,
|
|
35426
|
+
render: {
|
|
35427
|
+
sections: [
|
|
35428
|
+
{
|
|
35429
|
+
title: "linked repository",
|
|
35430
|
+
lines: [renderProject(payload.project)]
|
|
35431
|
+
}
|
|
35432
|
+
]
|
|
35433
|
+
}
|
|
35434
|
+
},
|
|
35435
|
+
{ json: options.json }
|
|
35436
|
+
);
|
|
35437
|
+
}
|
|
35438
|
+
async function handleSet(id, options) {
|
|
35439
|
+
const { http } = getAuthedHttpClient();
|
|
35440
|
+
const payload = await http.patch(
|
|
35441
|
+
`/api/v2/play-projects/${encodeURIComponent(id)}`,
|
|
35442
|
+
{
|
|
35443
|
+
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
35444
|
+
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
35445
|
+
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
35446
|
+
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {},
|
|
35447
|
+
...options.disabled !== void 0 ? { disabled: options.disabled } : {}
|
|
35448
|
+
}
|
|
35449
|
+
);
|
|
35450
|
+
printCommandEnvelope(
|
|
35451
|
+
{
|
|
35452
|
+
project: payload.project,
|
|
35453
|
+
render: {
|
|
35454
|
+
sections: [
|
|
35455
|
+
{ title: "updated", lines: [renderProject(payload.project)] }
|
|
35456
|
+
]
|
|
35457
|
+
}
|
|
35458
|
+
},
|
|
35459
|
+
{ json: options.json }
|
|
35460
|
+
);
|
|
35461
|
+
}
|
|
35462
|
+
async function handleUnlink(id, options) {
|
|
35463
|
+
const { http } = getAuthedHttpClient();
|
|
35464
|
+
await http.delete(`/api/v2/play-projects/${encodeURIComponent(id)}`);
|
|
35465
|
+
printCommandEnvelope(
|
|
35466
|
+
{
|
|
35467
|
+
ok: true,
|
|
35468
|
+
id,
|
|
35469
|
+
render: {
|
|
35470
|
+
sections: [
|
|
35471
|
+
{
|
|
35472
|
+
title: "unlinked",
|
|
35473
|
+
lines: [
|
|
35474
|
+
`Repository link ${id} removed. Deployments stop immediately and in-flight deploy credentials die; live plays keep running.`
|
|
35475
|
+
]
|
|
35476
|
+
}
|
|
35477
|
+
]
|
|
35478
|
+
}
|
|
35479
|
+
},
|
|
35480
|
+
{ json: options.json }
|
|
35481
|
+
);
|
|
35482
|
+
}
|
|
35483
|
+
async function handleConnect(options) {
|
|
35484
|
+
const baseUrl = resolveBaseUrlOnly();
|
|
35485
|
+
const connectUrl = `${baseUrl.replace(/\/$/, "")}/api/v2/github/connect`;
|
|
35486
|
+
const opened = openInBrowser(connectUrl);
|
|
35487
|
+
printCommandEnvelope(
|
|
35488
|
+
{
|
|
35489
|
+
connectUrl,
|
|
35490
|
+
browser: opened,
|
|
35491
|
+
render: {
|
|
35492
|
+
sections: [
|
|
35493
|
+
{
|
|
35494
|
+
title: "connect GitHub",
|
|
35495
|
+
lines: [
|
|
35496
|
+
opened === "opened" ? `Opened ${connectUrl} in your browser.` : `Open ${connectUrl} in your browser.`,
|
|
35497
|
+
"Sign in as a workspace admin if prompted, approve the GitHub",
|
|
35498
|
+
"installation, then return here and run `deepline git repos`."
|
|
35499
|
+
]
|
|
35500
|
+
}
|
|
35501
|
+
]
|
|
35502
|
+
}
|
|
35503
|
+
},
|
|
35504
|
+
{ json: options.json }
|
|
35505
|
+
);
|
|
35506
|
+
}
|
|
35507
|
+
async function handleDeploymentsList(options) {
|
|
35508
|
+
const { http } = getAuthedHttpClient();
|
|
35509
|
+
const query = new URLSearchParams();
|
|
35510
|
+
if (options.repo) query.set("projectId", options.repo);
|
|
35511
|
+
if (options.limit) query.set("limit", options.limit);
|
|
35512
|
+
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
35513
|
+
const payload = await http.get(
|
|
35514
|
+
`/api/v2/deployments${suffix}`
|
|
35515
|
+
);
|
|
35516
|
+
printCommandEnvelope(
|
|
35517
|
+
{
|
|
35518
|
+
deployments: payload.deployments,
|
|
35519
|
+
count: payload.deployments.length,
|
|
35520
|
+
render: {
|
|
35521
|
+
sections: [
|
|
35522
|
+
{
|
|
35523
|
+
title: "deployments",
|
|
35524
|
+
lines: payload.deployments.length ? payload.deployments.map(renderDeployment) : [
|
|
35525
|
+
"No deployments yet. Push to a linked repository to create one."
|
|
35526
|
+
]
|
|
35527
|
+
}
|
|
35528
|
+
]
|
|
35529
|
+
}
|
|
35530
|
+
},
|
|
35531
|
+
{ json: options.json }
|
|
35532
|
+
);
|
|
35533
|
+
}
|
|
35534
|
+
async function handleDeploymentGet(id, options) {
|
|
35535
|
+
const { http } = getAuthedHttpClient();
|
|
35536
|
+
const payload = await http.get(`/api/v2/deployments/${encodeURIComponent(id)}`);
|
|
35537
|
+
const results = payload.deployment.results;
|
|
35538
|
+
const playLines = Array.isArray(results?.plays) ? results.plays.map(
|
|
35539
|
+
(play) => `${play.name ?? "?"} - ${play.status ?? "?"}${play.error ? `: ${play.error}` : ""}`
|
|
35540
|
+
) : [];
|
|
35541
|
+
printCommandEnvelope(
|
|
35542
|
+
{
|
|
35543
|
+
deployment: payload.deployment,
|
|
35544
|
+
project: payload.project,
|
|
35545
|
+
render: {
|
|
35546
|
+
sections: [
|
|
35547
|
+
{
|
|
35548
|
+
title: `deployment ${payload.deployment.id}${payload.project ? ` (${payload.project.repoFullName})` : ""}`,
|
|
35549
|
+
lines: [renderDeployment(payload.deployment)]
|
|
35550
|
+
},
|
|
35551
|
+
...playLines.length ? [{ title: "plays", lines: playLines }] : []
|
|
35552
|
+
]
|
|
35553
|
+
}
|
|
35554
|
+
},
|
|
35555
|
+
{ json: options.json }
|
|
35556
|
+
);
|
|
35557
|
+
}
|
|
35558
|
+
function registerGitCommands(program) {
|
|
35559
|
+
const git = program.command("git").alias("projects").description(
|
|
35560
|
+
"Git deploys: link repositories to this workspace and deploy plays on push."
|
|
35561
|
+
).addHelpText(
|
|
35562
|
+
"after",
|
|
35563
|
+
`
|
|
35564
|
+
Examples:
|
|
35565
|
+
deepline git connect
|
|
35566
|
+
deepline git repos
|
|
35567
|
+
deepline git link acme/growth --branch main
|
|
35568
|
+
deepline git list
|
|
35569
|
+
deepline git set <id> --branch release
|
|
35570
|
+
deepline git unlink <id>
|
|
35571
|
+
deepline git deployments --repo <id>
|
|
35572
|
+
`
|
|
35573
|
+
);
|
|
35574
|
+
git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
|
|
35575
|
+
git.command("repos").description("List repos the workspace's GitHub installation can reach.").option(
|
|
35576
|
+
"--installation <id>",
|
|
35577
|
+
"GitHub installation id (required when several are connected)"
|
|
35578
|
+
).option("--json", "Emit JSON output").action(
|
|
35579
|
+
async (options) => handleRepos(options)
|
|
35580
|
+
);
|
|
35581
|
+
git.command("list").description("List linked repositories.").option("--all", "Include unlinked repositories").option("--json", "Emit JSON output").action(
|
|
35582
|
+
async (options) => handleList(options)
|
|
35583
|
+
);
|
|
35584
|
+
git.command("link").description("Link a repository to this workspace for deploy-on-push.").argument("<repo>", "Repo full name (owner/name) or numeric repo id").option("--root-dir <path>", "Base path inside the repo for this link").option("--branch <name>", "Production branch (default: repo default)").option(
|
|
35585
|
+
"--manifest <file>",
|
|
35586
|
+
"Manifest file name under the base path (default: deepline.json)"
|
|
35587
|
+
).option(
|
|
35588
|
+
"--installation <id>",
|
|
35589
|
+
"GitHub installation id (required when several are connected)"
|
|
35590
|
+
).option("--no-pr-checks", "Skip Check Runs on pull requests").option("--json", "Emit JSON output").action(
|
|
35591
|
+
async (repo, options) => handleLink(repo, options)
|
|
35592
|
+
);
|
|
35593
|
+
git.command("get").description("Show one linked repository.").argument("<id>", "Repository link id").option("--json", "Emit JSON output").action(async (id, options) => handleGet(id, options));
|
|
35594
|
+
git.command("set").description("Update a linked repository.").argument("<id>", "Repository link id").option("--branch <name>", "Production branch").option("--root-dir <path>", "Base path inside the repo for this link").option(
|
|
35595
|
+
"--manifest <file>",
|
|
35596
|
+
"Manifest file name under the base path (default: deepline.json)"
|
|
35597
|
+
).option("--pr-checks", "Enable Check Runs on pull requests").option("--no-pr-checks", "Disable Check Runs on pull requests").option("--disabled", "Pause deployments for this link").option("--enabled", "Resume deployments for this link").option("--json", "Emit JSON output").action(
|
|
35598
|
+
async (id, options) => handleSet(id, {
|
|
35599
|
+
...options,
|
|
35600
|
+
disabled: options.enabled === true ? false : options.disabled === true ? true : void 0
|
|
35601
|
+
})
|
|
35602
|
+
);
|
|
35603
|
+
git.command("unlink").description("Unlink a repository (live plays keep running).").argument("<id>", "Repository link id").option("--json", "Emit JSON output").action(
|
|
35604
|
+
async (id, options) => handleUnlink(id, options)
|
|
35605
|
+
);
|
|
35606
|
+
git.command("deployments").description("Deployment history; pass an id for one deployment.").argument("[id]", "Deployment id (omit to list)").option("--repo <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
|
|
35607
|
+
async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
|
|
35608
|
+
);
|
|
35609
|
+
const deployments = program.command("deployments", { hidden: true });
|
|
35610
|
+
deployments.command("list").option("--project <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
|
|
35611
|
+
async (options) => handleDeploymentsList({ ...options, repo: options.project })
|
|
35612
|
+
);
|
|
35613
|
+
deployments.command("get").argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
|
|
35614
|
+
async (id, options) => handleDeploymentGet(id, options)
|
|
35615
|
+
);
|
|
35616
|
+
}
|
|
35617
|
+
|
|
34769
35618
|
// src/cli/getting-started.ts
|
|
34770
35619
|
var DEEPLINE_GTM_SKILL = "/deepline-gtm";
|
|
34771
35620
|
var DEEPLINE_GTM_STARTER_PROMPTS = [
|
|
@@ -35006,7 +35855,7 @@ function preventShellHistoryLeak(forbidden) {
|
|
|
35006
35855
|
);
|
|
35007
35856
|
}
|
|
35008
35857
|
}
|
|
35009
|
-
async function
|
|
35858
|
+
async function handleList2(options) {
|
|
35010
35859
|
const client2 = new DeeplineClient();
|
|
35011
35860
|
const secrets = await client2.listSecrets();
|
|
35012
35861
|
printCommandEnvelope(
|
|
@@ -35049,7 +35898,7 @@ async function handleCheck(nameInput, options) {
|
|
|
35049
35898
|
);
|
|
35050
35899
|
if (!secret) process.exitCode = 4;
|
|
35051
35900
|
}
|
|
35052
|
-
async function
|
|
35901
|
+
async function handleSet2(nameInput, forbidden, options) {
|
|
35053
35902
|
preventShellHistoryLeak(forbidden);
|
|
35054
35903
|
const name = normalizeSecretName(nameInput);
|
|
35055
35904
|
const scope = options.scope === "play" ? "play" : "org";
|
|
@@ -35108,14 +35957,14 @@ Examples:
|
|
|
35108
35957
|
`
|
|
35109
35958
|
);
|
|
35110
35959
|
secrets.command("list").description("List secret metadata only.").option("--json", "Emit JSON output").action(async (options) => {
|
|
35111
|
-
await
|
|
35960
|
+
await handleList2(options);
|
|
35112
35961
|
});
|
|
35113
35962
|
secrets.command("check").description("Check whether a secret exists and is active.").argument("<name>", "Secret name").option("--json", "Emit JSON output").action(async (name, options) => {
|
|
35114
35963
|
await handleCheck(name, options);
|
|
35115
35964
|
});
|
|
35116
35965
|
secrets.command("set").description("Set or rotate a secret without exposing its value in argv.").argument("<name>", "Secret name").argument("[forbidden...]", "Do not pass secret values here").option("--json", "Emit JSON output").option("--scope <scope>", "Secret scope: org or play", "org").option("--play <name>", "Play name for play-scoped secrets").option("--value-stdin", "Read the value from piped stdin").option("--from-env <name>", "Read the value from an environment variable").option("--from-file <path>", "Read the value from a file").action(
|
|
35117
35966
|
async (name, forbidden, options) => {
|
|
35118
|
-
await
|
|
35967
|
+
await handleSet2(name, forbidden ?? [], options);
|
|
35119
35968
|
}
|
|
35120
35969
|
);
|
|
35121
35970
|
}
|
|
@@ -36746,7 +37595,7 @@ function failSetupPhase(phases, phase, code) {
|
|
|
36746
37595
|
}
|
|
36747
37596
|
function rollbackCommand(scope, root) {
|
|
36748
37597
|
const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify((0, import_node_path22.join)(root, ".deepline", "runtime"))}` : "";
|
|
36749
|
-
return `npm install -g${prefix} --no-audit --no-fund --include=optional
|
|
37598
|
+
return `npm install -g${prefix} --no-audit --no-fund --include=optional deepline@${SDK_VERSION}`;
|
|
36750
37599
|
}
|
|
36751
37600
|
function setupResumeCommand(baseUrl, scope) {
|
|
36752
37601
|
const hostPrefix = baseUrl === "https://code.deepline.com" ? "" : `DEEPLINE_HOST_URL=${JSON.stringify(baseUrl)} `;
|
|
@@ -37315,9 +38164,7 @@ async function runSetupCommand(options) {
|
|
|
37315
38164
|
title: "setup",
|
|
37316
38165
|
lines: [
|
|
37317
38166
|
workspaceName ? `Deepline is installed and connected to ${workspaceName}.` : "Deepline is installed and connected.",
|
|
37318
|
-
...workspaceName ? [
|
|
37319
|
-
"To link a different workspace, run: deepline auth register"
|
|
37320
|
-
] : [],
|
|
38167
|
+
...workspaceName ? ["To link a different workspace, run: deepline auth register"] : [],
|
|
37321
38168
|
`Use ${DEEPLINE_GTM_SKILL} in your agent.`,
|
|
37322
38169
|
...DEEPLINE_GTM_STARTER_PROMPTS.map(
|
|
37323
38170
|
(example, index) => `${index + 1}. ${example.title}: ${example.prompt}`
|
|
@@ -37661,12 +38508,6 @@ var NPM_SDK_INSTALL_COMMON_FLAGS = [
|
|
|
37661
38508
|
"--no-fund",
|
|
37662
38509
|
"--include=optional"
|
|
37663
38510
|
];
|
|
37664
|
-
var NPM_SDK_GLOBAL_INSTALL_FLAGS = [
|
|
37665
|
-
"--no-audit",
|
|
37666
|
-
"--no-fund",
|
|
37667
|
-
"--include=optional",
|
|
37668
|
-
"--allow-scripts=esbuild"
|
|
37669
|
-
];
|
|
37670
38511
|
var NPM_SDK_SIDECAR_PACKAGE_JSON = `${JSON.stringify(
|
|
37671
38512
|
{
|
|
37672
38513
|
private: true,
|
|
@@ -37901,9 +38742,9 @@ function resolveUpdatePlan(options = {}) {
|
|
|
37901
38742
|
"-g",
|
|
37902
38743
|
"--prefix",
|
|
37903
38744
|
installPrefix,
|
|
37904
|
-
...
|
|
38745
|
+
...NPM_SDK_INSTALL_COMMON_FLAGS,
|
|
37905
38746
|
packageSpec
|
|
37906
|
-
] : ["install", "-g", ...
|
|
38747
|
+
] : ["install", "-g", ...NPM_SDK_INSTALL_COMMON_FLAGS, packageSpec];
|
|
37907
38748
|
const fallbackRegistryUrl = options.npmFallbackRegistryUrl !== void 0 ? options.npmFallbackRegistryUrl : publicNpmFallbackRegistryUrl(
|
|
37908
38749
|
env.DEEPLINE_HOST_URL?.trim() || autoDetectBaseUrl()
|
|
37909
38750
|
);
|
|
@@ -39643,6 +40484,17 @@ function numberValue(value) {
|
|
|
39643
40484
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
39644
40485
|
}
|
|
39645
40486
|
|
|
40487
|
+
// src/cli/tool-connection-status.ts
|
|
40488
|
+
function toolConnectionStatusMessage(input2) {
|
|
40489
|
+
if (input2.credentialStatus === "requires_connection") {
|
|
40490
|
+
return "requires your credentials \u2014 not connected (connect to use)";
|
|
40491
|
+
}
|
|
40492
|
+
if (input2.connected === false && input2.credentialStatus === "managed") {
|
|
40493
|
+
return "temporarily unavailable";
|
|
40494
|
+
}
|
|
40495
|
+
return null;
|
|
40496
|
+
}
|
|
40497
|
+
|
|
39646
40498
|
// src/cli/commands/tools.ts
|
|
39647
40499
|
var TOOL_COMMAND_TEMPLATES = {
|
|
39648
40500
|
describe: "deepline tools describe <toolId>",
|
|
@@ -39767,10 +40619,11 @@ function notConnectedSuffix(tool) {
|
|
|
39767
40619
|
const record2 = tool;
|
|
39768
40620
|
const status = stringField2(record2, "credentialStatus", "credential_status");
|
|
39769
40621
|
const connected = record2.connected;
|
|
39770
|
-
|
|
39771
|
-
|
|
39772
|
-
|
|
39773
|
-
|
|
40622
|
+
const message = toolConnectionStatusMessage({
|
|
40623
|
+
connected: connected === false ? false : void 0,
|
|
40624
|
+
credentialStatus: status || void 0
|
|
40625
|
+
});
|
|
40626
|
+
return message ? ` - \u26A0 ${message}` : "";
|
|
39774
40627
|
}
|
|
39775
40628
|
function shortPricingHint(tool) {
|
|
39776
40629
|
const pricing = recordField2(
|
|
@@ -42320,14 +43173,14 @@ async function handleTransform(id, options) {
|
|
|
42320
43173
|
);
|
|
42321
43174
|
return outcomes.every((o) => o.ok) ? 0 : 1;
|
|
42322
43175
|
}
|
|
42323
|
-
async function
|
|
43176
|
+
async function handleList3(options) {
|
|
42324
43177
|
const limit = options.limit ? Number(options.limit) : void 0;
|
|
42325
43178
|
const result = await client().listWorkflows({
|
|
42326
43179
|
limit: Number.isFinite(limit) ? limit : void 0
|
|
42327
43180
|
});
|
|
42328
43181
|
emitPassThrough("list", result, options);
|
|
42329
43182
|
}
|
|
42330
|
-
async function
|
|
43183
|
+
async function handleGet2(id, options) {
|
|
42331
43184
|
emitPassThrough("get", await client().getWorkflow(id), options);
|
|
42332
43185
|
}
|
|
42333
43186
|
async function handleDelete(id, options) {
|
|
@@ -42446,12 +43299,12 @@ Notes:
|
|
|
42446
43299
|
});
|
|
42447
43300
|
withJsonOption2(
|
|
42448
43301
|
workflows.command("list").description("List workspace workflows.").option("--limit <n>", "Max workflows to return")
|
|
42449
|
-
).action(
|
|
43302
|
+
).action(handleList3);
|
|
42450
43303
|
withJsonOption2(
|
|
42451
43304
|
workflows.command("get <id>").description(
|
|
42452
43305
|
"Fetch a workflow, including its published-revision config."
|
|
42453
43306
|
)
|
|
42454
|
-
).action(
|
|
43307
|
+
).action(handleGet2);
|
|
42455
43308
|
withJsonOption2(
|
|
42456
43309
|
workflows.command("disable <id>").description("Turn a workflow off.")
|
|
42457
43310
|
).action(handleDisable);
|
|
@@ -42504,6 +43357,7 @@ function registerDeeplineCommandGroups(program) {
|
|
|
42504
43357
|
registerBillingCommands(program);
|
|
42505
43358
|
registerMonitorsCommands(program);
|
|
42506
43359
|
registerOrgCommands(program);
|
|
43360
|
+
registerGitCommands(program);
|
|
42507
43361
|
registerEnrichCommand(program);
|
|
42508
43362
|
registerCsvCommands(program);
|
|
42509
43363
|
registerDbCommands(program);
|
|
@@ -42717,97 +43571,6 @@ What changed in ${response.update_summary.version}: ${response.update_summary.su
|
|
|
42717
43571
|
|
|
42718
43572
|
// src/cli/index.ts
|
|
42719
43573
|
var PREFLIGHT_TIMEOUT_MS = 3e3;
|
|
42720
|
-
var ProjectOrgPinRequiredError = class extends Error {
|
|
42721
|
-
code = "PROJECT_ORG_NOT_PINNED";
|
|
42722
|
-
exitCode = 3;
|
|
42723
|
-
payload;
|
|
42724
|
-
constructor(input2) {
|
|
42725
|
-
super("Cloud work is blocked because this project uses global host auth.");
|
|
42726
|
-
this.name = "ProjectOrgPinRequiredError";
|
|
42727
|
-
this.payload = {
|
|
42728
|
-
ok: false,
|
|
42729
|
-
exitCode: this.exitCode,
|
|
42730
|
-
code: this.code,
|
|
42731
|
-
message: this.message,
|
|
42732
|
-
command: input2.command,
|
|
42733
|
-
auth: { scope: "global", source: "host", projectPinned: false },
|
|
42734
|
-
project: { dir: input2.projectDir, pinPath: input2.pinPath },
|
|
42735
|
-
next: "deepline org set --auth-scope folder"
|
|
42736
|
-
};
|
|
42737
|
-
}
|
|
42738
|
-
};
|
|
42739
|
-
function commandUsesOnlyReadOrLocalOperations(command) {
|
|
42740
|
-
const [group, action] = command.split(" ");
|
|
42741
|
-
if ([
|
|
42742
|
-
"auth",
|
|
42743
|
-
"org",
|
|
42744
|
-
"health",
|
|
42745
|
-
"preflight",
|
|
42746
|
-
"version",
|
|
42747
|
-
"update",
|
|
42748
|
-
"skills",
|
|
42749
|
-
"doctor",
|
|
42750
|
-
"quickstart"
|
|
42751
|
-
].includes(group ?? "")) {
|
|
42752
|
-
return true;
|
|
42753
|
-
}
|
|
42754
|
-
if (group === "plays") {
|
|
42755
|
-
return [
|
|
42756
|
-
"check",
|
|
42757
|
-
"get",
|
|
42758
|
-
"list",
|
|
42759
|
-
"search",
|
|
42760
|
-
"grep",
|
|
42761
|
-
"describe",
|
|
42762
|
-
"versions"
|
|
42763
|
-
].includes(action ?? "");
|
|
42764
|
-
}
|
|
42765
|
-
if (group === "runs") {
|
|
42766
|
-
return ["get", "list", "tail", "logs", "export"].includes(action ?? "");
|
|
42767
|
-
}
|
|
42768
|
-
if (group === "tools") {
|
|
42769
|
-
return ["list", "search", "get", "describe"].includes(action ?? "");
|
|
42770
|
-
}
|
|
42771
|
-
if (group === "providers") return ["list", "get"].includes(action ?? "");
|
|
42772
|
-
if (group === "secrets") return ["list", "check"].includes(action ?? "");
|
|
42773
|
-
if (group === "billing")
|
|
42774
|
-
return ["balance", "usage", "history"].includes(action ?? "");
|
|
42775
|
-
return false;
|
|
42776
|
-
}
|
|
42777
|
-
function assertProjectCloudWorkIsPinned(command) {
|
|
42778
|
-
if (process.argv.includes("--dry-run") || commandUsesOnlyReadOrLocalOperations(command)) {
|
|
42779
|
-
return;
|
|
42780
|
-
}
|
|
42781
|
-
const config = resolveConfig();
|
|
42782
|
-
const provenance = resolveCliAuthProvenance(config);
|
|
42783
|
-
if (provenance.scope !== "global" || provenance.project.state !== "project") {
|
|
42784
|
-
return;
|
|
42785
|
-
}
|
|
42786
|
-
throw new ProjectOrgPinRequiredError({
|
|
42787
|
-
command,
|
|
42788
|
-
projectDir: provenance.project.dir,
|
|
42789
|
-
pinPath: provenance.project.pinPath
|
|
42790
|
-
});
|
|
42791
|
-
}
|
|
42792
|
-
function printProjectOrgPinRequiredError(error) {
|
|
42793
|
-
if (shouldEmitJson(process.argv.includes("--json"))) {
|
|
42794
|
-
printJson(error.payload);
|
|
42795
|
-
return;
|
|
42796
|
-
}
|
|
42797
|
-
const project = error.payload.project;
|
|
42798
|
-
process.stderr.write(
|
|
42799
|
-
[
|
|
42800
|
-
"\u2717 Cloud work is blocked in this project",
|
|
42801
|
-
"",
|
|
42802
|
-
" Auth: global host default",
|
|
42803
|
-
" This project is not pinned. Global auth is shared by every unpinned CLI on this machine.",
|
|
42804
|
-
"",
|
|
42805
|
-
" Pin this folder to the current target:",
|
|
42806
|
-
" deepline org set --auth-scope folder",
|
|
42807
|
-
` This writes: ${project.pinPath}`
|
|
42808
|
-
].join("\n") + "\n"
|
|
42809
|
-
);
|
|
42810
|
-
}
|
|
42811
43574
|
function asCommanderError(error) {
|
|
42812
43575
|
if (!(error instanceof Error) || !("code" in error)) {
|
|
42813
43576
|
return null;
|
|
@@ -43118,7 +43881,6 @@ Exit codes:
|
|
|
43118
43881
|
return;
|
|
43119
43882
|
}
|
|
43120
43883
|
const compatibilityCommand = compatibilityCommandPath(actionCommand) || actionCommand.name();
|
|
43121
|
-
assertProjectCloudWorkIsPinned(compatibilityCommand);
|
|
43122
43884
|
if (printStartupPhase) {
|
|
43123
43885
|
progress?.phase("checking sdk compatibility");
|
|
43124
43886
|
}
|
|
@@ -43295,10 +44057,7 @@ Examples:
|
|
|
43295
44057
|
});
|
|
43296
44058
|
progress?.fail();
|
|
43297
44059
|
const wantsJson = process.argv.includes("--json");
|
|
43298
|
-
if (
|
|
43299
|
-
printProjectOrgPinRequiredError(error);
|
|
43300
|
-
process.exitCode = error.exitCode;
|
|
43301
|
-
} else if (commanderError) {
|
|
44060
|
+
if (commanderError) {
|
|
43302
44061
|
if (commanderError.code === "commander.unknownCommand") {
|
|
43303
44062
|
}
|
|
43304
44063
|
process.exitCode = commanderError.code === "commander.unknownCommand" && !wantsJson ? 2 : commanderError.exitCode ?? 1;
|