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.mjs
CHANGED
|
@@ -890,6 +890,17 @@ function getResolvedProjectAuthSource(baseUrl, apiKey, startDir = process.cwd())
|
|
|
890
890
|
return projectBaseUrl === normalizedBaseUrl && (env[API_KEY_ENV] ?? "").trim() === normalizedApiKey;
|
|
891
891
|
}) ?? null;
|
|
892
892
|
}
|
|
893
|
+
function resolveBaseUrlOnly(options) {
|
|
894
|
+
const baseUrl = normalizeBaseUrl(
|
|
895
|
+
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
896
|
+
);
|
|
897
|
+
if (!baseUrl) {
|
|
898
|
+
throw new ConfigError(
|
|
899
|
+
`Invalid ${HOST_URL_ENV}. Expected an http(s) URL such as https://code.deepline.com.`
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
return baseUrl;
|
|
903
|
+
}
|
|
893
904
|
function resolveConfig(options) {
|
|
894
905
|
const baseUrl = normalizeBaseUrl(
|
|
895
906
|
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
@@ -1199,7 +1210,7 @@ var SDK_RELEASE = {
|
|
|
1199
1210
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1200
1211
|
// getters keep their established compatibility behavior.
|
|
1201
1212
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1202
|
-
version: "0.3.
|
|
1213
|
+
version: "0.3.76",
|
|
1203
1214
|
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.",
|
|
1204
1215
|
packageCapabilities: {
|
|
1205
1216
|
updatePreferences: 1
|
|
@@ -1621,7 +1632,7 @@ var RUNTIME_INCIDENT_DRILL_CATALOG = [
|
|
|
1621
1632
|
valueMeaning: "occurrence"
|
|
1622
1633
|
},
|
|
1623
1634
|
expected: {
|
|
1624
|
-
outcome: "The same logical run completes through
|
|
1635
|
+
outcome: "The same logical run completes through terminal-cache replay; any provider retry is governed by its separate operation policy.",
|
|
1625
1636
|
safetyFacts: ["same_logical_run", "bounded_provider_execution"]
|
|
1626
1637
|
},
|
|
1627
1638
|
verification: {
|
|
@@ -4476,6 +4487,10 @@ var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "ca
|
|
|
4476
4487
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
4477
4488
|
var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
|
|
4478
4489
|
var EXECUTE_RESPONSE_INTENT_HEADER = "x-deepline-execute-response-intent";
|
|
4490
|
+
var MONITOR_NON_RETRYABLE_MUTATION_OPTIONS = {
|
|
4491
|
+
maxRetries: 0,
|
|
4492
|
+
exactUrlOnly: true
|
|
4493
|
+
};
|
|
4479
4494
|
var RAW_V2_EXECUTE_RESPONSE_CONTRACT = RAW_V2_TOOL_RESPONSE_CONTRACT;
|
|
4480
4495
|
var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
|
|
4481
4496
|
var REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
|
|
@@ -5034,11 +5049,15 @@ var DeeplineClient = class {
|
|
|
5034
5049
|
update: (key, patch) => this.updateMonitor(key, patch),
|
|
5035
5050
|
delete: (key, options2) => this.deleteMonitor(key, options2),
|
|
5036
5051
|
reactivate: (key, options2) => this.reactivateMonitor(key, options2),
|
|
5052
|
+
audit: (options2) => this.auditMonitors(options2),
|
|
5053
|
+
repair: (options2) => this.repairMonitors(options2),
|
|
5054
|
+
health: (options2) => this.readMonitorsHealth(options2),
|
|
5037
5055
|
fleets: {
|
|
5038
5056
|
sync: (definitionOrId, options2) => this.syncMonitorFleet(definitionOrId, options2),
|
|
5039
5057
|
get: (fleetId, options2) => fleetId === void 0 ? this.listMonitorFleets() : this.getMonitorFleet(fleetId, options2),
|
|
5040
5058
|
list: () => this.listMonitorFleets(),
|
|
5041
5059
|
deactivate: (fleetId, options2) => this.deactivateMonitorFleet(fleetId, options2),
|
|
5060
|
+
reactivate: (fleetId, options2) => this.reactivateMonitorFleet(fleetId, options2),
|
|
5042
5061
|
waitForConvergence: (fleetId, options2) => this.waitForMonitorFleetConvergence(fleetId, options2)
|
|
5043
5062
|
}
|
|
5044
5063
|
};
|
|
@@ -6624,13 +6643,23 @@ var DeeplineClient = class {
|
|
|
6624
6643
|
if (options?.grep?.trim()) {
|
|
6625
6644
|
params.set("grep", options.grep.trim());
|
|
6626
6645
|
params.set("grep_mode", options.grepMode ?? "all");
|
|
6646
|
+
params.set("grep_paginated", "1");
|
|
6627
6647
|
params.set("limit", "60");
|
|
6628
6648
|
}
|
|
6629
|
-
const
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6649
|
+
const plays = [];
|
|
6650
|
+
let cursor = null;
|
|
6651
|
+
let hasMore = true;
|
|
6652
|
+
do {
|
|
6653
|
+
if (cursor) params.set("cursor", cursor);
|
|
6654
|
+
const suffix = params.toString() ? `?${params.toString()}` : "";
|
|
6655
|
+
const response = await this.http.get(
|
|
6656
|
+
`/api/v2/plays${suffix}`
|
|
6657
|
+
);
|
|
6658
|
+
plays.push(...response.plays ?? []);
|
|
6659
|
+
cursor = response.pagination?.cursor ?? response.cursor ?? null;
|
|
6660
|
+
hasMore = Boolean(response.pagination?.hasMore ?? response.hasMore);
|
|
6661
|
+
} while (Boolean(options?.grep?.trim()) && hasMore && cursor);
|
|
6662
|
+
return plays;
|
|
6634
6663
|
}
|
|
6635
6664
|
/** Set whether an org-owned Play sorts before unpinned Plays. */
|
|
6636
6665
|
async setPlayPinned(playName, pinned) {
|
|
@@ -7207,6 +7236,44 @@ var DeeplineClient = class {
|
|
|
7207
7236
|
...typeof payload.reason === "string" && payload.reason.trim() ? { reason: payload.reason.trim() } : {}
|
|
7208
7237
|
};
|
|
7209
7238
|
}
|
|
7239
|
+
/**
|
|
7240
|
+
* One bounded audit pass. Prefer `client.monitors.audit(...)`.
|
|
7241
|
+
*
|
|
7242
|
+
* Never auto-retried: it is idempotent, but a retry that races the caller's
|
|
7243
|
+
* own next pass would spend a provider slot to learn nothing new.
|
|
7244
|
+
*/
|
|
7245
|
+
async auditMonitors(options) {
|
|
7246
|
+
return this.http.request("/api/v2/monitors/audit", {
|
|
7247
|
+
method: "POST",
|
|
7248
|
+
body: {
|
|
7249
|
+
...options?.fleetId ? { fleet_id: options.fleetId } : {},
|
|
7250
|
+
...options?.cursor ? { cursor: options.cursor } : {}
|
|
7251
|
+
},
|
|
7252
|
+
maxRetries: 0
|
|
7253
|
+
});
|
|
7254
|
+
}
|
|
7255
|
+
/** One repair pass or plan. Prefer `client.monitors.repair(...)`. */
|
|
7256
|
+
async repairMonitors(options) {
|
|
7257
|
+
return this.http.request("/api/v2/monitors/repair", {
|
|
7258
|
+
method: "POST",
|
|
7259
|
+
body: {
|
|
7260
|
+
...options?.fleetId ? { fleet_id: options.fleetId } : {},
|
|
7261
|
+
...options?.dryRun === void 0 ? {} : { dry_run: options.dryRun }
|
|
7262
|
+
},
|
|
7263
|
+
maxRetries: 0
|
|
7264
|
+
});
|
|
7265
|
+
}
|
|
7266
|
+
/** Delivery and convergence health. Prefer `client.monitors.health(...)`. */
|
|
7267
|
+
async readMonitorsHealth(options) {
|
|
7268
|
+
const params = new URLSearchParams();
|
|
7269
|
+
if (options?.fleetId) params.set("fleet_id", options.fleetId);
|
|
7270
|
+
const query = params.toString();
|
|
7271
|
+
const suffix = query ? `?${query}` : "";
|
|
7272
|
+
return this.http.request(
|
|
7273
|
+
`/api/v2/monitors/health${suffix}`,
|
|
7274
|
+
{ method: "GET" }
|
|
7275
|
+
);
|
|
7276
|
+
}
|
|
7210
7277
|
/**
|
|
7211
7278
|
* The deployable monitor tools catalog. Pass a tool id (positional or
|
|
7212
7279
|
* `{ tool }`) to describe one tool's full payload/stream contract, or no tool
|
|
@@ -7284,7 +7351,6 @@ var DeeplineClient = class {
|
|
|
7284
7351
|
if (options?.limit !== void 0)
|
|
7285
7352
|
params.set("limit", String(options.limit));
|
|
7286
7353
|
if (options?.cursor) params.set("cursor", options.cursor);
|
|
7287
|
-
if (options?.compact) params.set("compact", "true");
|
|
7288
7354
|
if (options?.includeConsumers) params.set("include_consumers", "true");
|
|
7289
7355
|
const query = params.toString();
|
|
7290
7356
|
const suffix = query ? `?${query}` : "";
|
|
@@ -7301,13 +7367,22 @@ var DeeplineClient = class {
|
|
|
7301
7367
|
);
|
|
7302
7368
|
}
|
|
7303
7369
|
async testMonitorWebhook(key, payload, options) {
|
|
7370
|
+
if (options?.dispatch === true || options?.validationOnly === false) {
|
|
7371
|
+
throw new DeeplineError(
|
|
7372
|
+
"Monitor tests are validation-only and cannot dispatch events.",
|
|
7373
|
+
void 0,
|
|
7374
|
+
"MONITOR_TEST_DISPATCH_NOT_SUPPORTED"
|
|
7375
|
+
);
|
|
7376
|
+
}
|
|
7304
7377
|
return this.http.request(
|
|
7305
7378
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}/test`,
|
|
7306
7379
|
{
|
|
7307
7380
|
method: "POST",
|
|
7308
7381
|
body: {
|
|
7309
7382
|
payload,
|
|
7310
|
-
|
|
7383
|
+
// Send the legacy safe mode as well as accepting it server-side: an
|
|
7384
|
+
// upgraded SDK must be safe when it reaches a still-running server.
|
|
7385
|
+
mode: "validation_only"
|
|
7311
7386
|
}
|
|
7312
7387
|
}
|
|
7313
7388
|
);
|
|
@@ -7335,7 +7410,14 @@ var DeeplineClient = class {
|
|
|
7335
7410
|
async updateMonitor(key, patch) {
|
|
7336
7411
|
return this.http.request(
|
|
7337
7412
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}`,
|
|
7338
|
-
{
|
|
7413
|
+
{
|
|
7414
|
+
method: "PATCH",
|
|
7415
|
+
body: patch,
|
|
7416
|
+
// A monitor write may have reached the control plane before a network
|
|
7417
|
+
// failure reaches the caller. Do not turn that unknown outcome into a
|
|
7418
|
+
// second mutation with a fresh snapshot.
|
|
7419
|
+
...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
|
|
7420
|
+
}
|
|
7339
7421
|
);
|
|
7340
7422
|
}
|
|
7341
7423
|
/** Delete a deployed monitor and its upstream provider resource. `dryRun` returns the delete plan. Prefer `client.monitors.delete(...)`. */
|
|
@@ -7352,7 +7434,12 @@ var DeeplineClient = class {
|
|
|
7352
7434
|
const query = params.toString();
|
|
7353
7435
|
return this.http.request(
|
|
7354
7436
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}${query ? `?${query}` : ""}`,
|
|
7355
|
-
{ method: "DELETE" }
|
|
7437
|
+
options?.dryRun ? { method: "DELETE" } : {
|
|
7438
|
+
method: "DELETE",
|
|
7439
|
+
// Deletion is a provider lifecycle operation. A timeout is an
|
|
7440
|
+
// unknown outcome, not authority to begin another delete attempt.
|
|
7441
|
+
...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
|
|
7442
|
+
}
|
|
7356
7443
|
);
|
|
7357
7444
|
}
|
|
7358
7445
|
/**
|
|
@@ -7363,7 +7450,13 @@ var DeeplineClient = class {
|
|
|
7363
7450
|
const query = options?.dryRun ? "?dry_run=true" : "";
|
|
7364
7451
|
return this.http.request(
|
|
7365
7452
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}/reactivate${query}`,
|
|
7366
|
-
{ method: "POST", body: {} }
|
|
7453
|
+
options?.dryRun ? { method: "POST", body: {} } : {
|
|
7454
|
+
method: "POST",
|
|
7455
|
+
body: {},
|
|
7456
|
+
// Reactivation can create an upstream resource, so it must not use
|
|
7457
|
+
// the generic transport's automatic replay policy.
|
|
7458
|
+
...MONITOR_NON_RETRYABLE_MUTATION_OPTIONS
|
|
7459
|
+
}
|
|
7367
7460
|
);
|
|
7368
7461
|
}
|
|
7369
7462
|
// ——————————————————————————————————————————————————————————
|
|
@@ -7440,6 +7533,21 @@ var DeeplineClient = class {
|
|
|
7440
7533
|
}
|
|
7441
7534
|
);
|
|
7442
7535
|
}
|
|
7536
|
+
async reactivateMonitorFleet(fleetId, options) {
|
|
7537
|
+
return this.http.request(
|
|
7538
|
+
`${this.monitorFleetPath(fleetId)}/reactivate`,
|
|
7539
|
+
{
|
|
7540
|
+
method: "POST",
|
|
7541
|
+
body: {},
|
|
7542
|
+
headers: this.monitorFleetHeaders(
|
|
7543
|
+
"reactivate",
|
|
7544
|
+
options?.idempotencyKey
|
|
7545
|
+
),
|
|
7546
|
+
maxRetries: 0,
|
|
7547
|
+
exactUrlOnly: true
|
|
7548
|
+
}
|
|
7549
|
+
);
|
|
7550
|
+
}
|
|
7443
7551
|
/**
|
|
7444
7552
|
* Poll one fleet until the server reports a terminal status.
|
|
7445
7553
|
*
|
|
@@ -8346,6 +8454,7 @@ function printCommandEnvelope(envelope, options = {}) {
|
|
|
8346
8454
|
var EXIT_OK = 0;
|
|
8347
8455
|
var EXIT_AUTH = 3;
|
|
8348
8456
|
var EXIT_SERVER = 5;
|
|
8457
|
+
var AUTH_HTTP_TIMEOUT_MS = 1e4;
|
|
8349
8458
|
function statusBannerLine(value) {
|
|
8350
8459
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
8351
8460
|
const banner = value;
|
|
@@ -8512,30 +8621,37 @@ async function httpJson(method, url, apiKey, body) {
|
|
|
8512
8621
|
if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
|
|
8513
8622
|
const bypassToken = process.env.VERCEL_PROTECTION_BYPASS_TOKEN?.trim();
|
|
8514
8623
|
if (bypassToken) headers["x-vercel-protection-bypass"] = bypassToken;
|
|
8515
|
-
let response = null;
|
|
8516
8624
|
let lastError = null;
|
|
8517
8625
|
for (const candidateUrl of buildCandidateUrls2(url)) {
|
|
8626
|
+
const controller = new AbortController();
|
|
8627
|
+
let requestTimedOut = false;
|
|
8628
|
+
const timeout = setTimeout(() => {
|
|
8629
|
+
requestTimedOut = true;
|
|
8630
|
+
controller.abort();
|
|
8631
|
+
}, AUTH_HTTP_TIMEOUT_MS);
|
|
8518
8632
|
try {
|
|
8519
|
-
response = await fetch(candidateUrl, {
|
|
8633
|
+
const response = await fetch(candidateUrl, {
|
|
8520
8634
|
method,
|
|
8521
8635
|
headers,
|
|
8522
|
-
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
8636
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
8637
|
+
signal: controller.signal
|
|
8523
8638
|
});
|
|
8524
|
-
|
|
8639
|
+
let data;
|
|
8640
|
+
try {
|
|
8641
|
+
data = await response.json();
|
|
8642
|
+
} catch (error) {
|
|
8643
|
+
if (controller.signal.aborted) throw error;
|
|
8644
|
+
data = {};
|
|
8645
|
+
}
|
|
8646
|
+
return { status: response.status, data };
|
|
8525
8647
|
} catch (error) {
|
|
8526
8648
|
lastError = error;
|
|
8649
|
+
if (requestTimedOut && method !== "GET") break;
|
|
8650
|
+
} finally {
|
|
8651
|
+
clearTimeout(timeout);
|
|
8527
8652
|
}
|
|
8528
8653
|
}
|
|
8529
|
-
|
|
8530
|
-
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
8531
|
-
}
|
|
8532
|
-
let data;
|
|
8533
|
-
try {
|
|
8534
|
-
data = await response.json();
|
|
8535
|
-
} catch {
|
|
8536
|
-
data = {};
|
|
8537
|
-
}
|
|
8538
|
-
return { status: response.status, data };
|
|
8654
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
8539
8655
|
}
|
|
8540
8656
|
async function reportSetupCompleted(input2) {
|
|
8541
8657
|
const apiKey = input2.authScope === "folder" ? resolveProjectApiKeyForBaseUrl(input2.baseUrl) : resolveGlobalApiKeyForBaseUrl(input2.baseUrl);
|
|
@@ -9034,6 +9150,12 @@ async function handleStatus(args) {
|
|
|
9034
9150
|
...payload.workspace.name ? [`Workspace: ${payload.workspace.name}`] : [],
|
|
9035
9151
|
...payload.workspace.slug ? [`Workspace slug: ${payload.workspace.slug}`] : [],
|
|
9036
9152
|
...payload.workspace.id != null ? [`Org ID: ${payload.workspace.id}`] : [],
|
|
9153
|
+
// Switching orgs lives under `deepline org`, but this is where
|
|
9154
|
+
// people look when they discover they are in the wrong
|
|
9155
|
+
// workspace. Without the pointer the reasonable next move is
|
|
9156
|
+
// `deepline auth register`, which re-approves the same account
|
|
9157
|
+
// and leaves the active org unchanged.
|
|
9158
|
+
"Switch workspace: deepline org list, then deepline org set <org-id>",
|
|
9037
9159
|
...payload.user.id != null ? [`User ID: ${payload.user.id}`] : [],
|
|
9038
9160
|
...payload.examples.length > 0 ? [
|
|
9039
9161
|
"Examples:",
|
|
@@ -9065,8 +9187,16 @@ Notes:
|
|
|
9065
9187
|
opening the approval page in Cowork. Use --wait no in CI or agent runs, then
|
|
9066
9188
|
finish with deepline auth wait.
|
|
9067
9189
|
Auth status shows the target host and active workspace without printing secrets.
|
|
9190
|
+
Registering again re-approves the same account; it does not change the active
|
|
9191
|
+
workspace. To switch, use deepline org list and deepline org set <org-id>.
|
|
9068
9192
|
`
|
|
9069
9193
|
);
|
|
9194
|
+
auth.command("workspaces").description("Deprecated. Use deepline org list to see workspaces.").action(() => {
|
|
9195
|
+
console.error(
|
|
9196
|
+
"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."
|
|
9197
|
+
);
|
|
9198
|
+
process.exitCode = 1;
|
|
9199
|
+
});
|
|
9070
9200
|
auth.command("register").description(
|
|
9071
9201
|
"Register this device and open the approval page in your browser."
|
|
9072
9202
|
).addHelpText(
|
|
@@ -9311,6 +9441,18 @@ function billingTopUpFailureFromError(error, input2) {
|
|
|
9311
9441
|
}
|
|
9312
9442
|
return null;
|
|
9313
9443
|
}
|
|
9444
|
+
function normalizeUnixMilliseconds(value) {
|
|
9445
|
+
const timestamp = Math.floor(value);
|
|
9446
|
+
return Number.isFinite(timestamp) && timestamp >= 0 && Number.isFinite(new Date(timestamp).getTime()) ? timestamp : null;
|
|
9447
|
+
}
|
|
9448
|
+
function parseSince(raw) {
|
|
9449
|
+
if (!raw?.trim()) return null;
|
|
9450
|
+
const numeric = Number(raw);
|
|
9451
|
+
const normalizedNumeric = normalizeUnixMilliseconds(numeric);
|
|
9452
|
+
if (normalizedNumeric !== null) return normalizedNumeric;
|
|
9453
|
+
const parsed = Date.parse(raw);
|
|
9454
|
+
return normalizeUnixMilliseconds(parsed);
|
|
9455
|
+
}
|
|
9314
9456
|
function humanize(value) {
|
|
9315
9457
|
return String(value || "").split("_").filter(Boolean).map((token) => token[0]?.toUpperCase() + token.slice(1)).join(" ") || "Unknown";
|
|
9316
9458
|
}
|
|
@@ -9596,6 +9738,18 @@ async function handleHistory(options) {
|
|
|
9596
9738
|
);
|
|
9597
9739
|
}
|
|
9598
9740
|
async function handleLedgerExportAll(options) {
|
|
9741
|
+
const sinceAt = parseSince(options.since);
|
|
9742
|
+
if (options.since && sinceAt === null) {
|
|
9743
|
+
reportBillingFailure(
|
|
9744
|
+
{
|
|
9745
|
+
exitCode: 2,
|
|
9746
|
+
code: "INVALID_SINCE",
|
|
9747
|
+
message: "--since must be an ISO-8601 timestamp or Unix milliseconds."
|
|
9748
|
+
},
|
|
9749
|
+
options
|
|
9750
|
+
);
|
|
9751
|
+
return;
|
|
9752
|
+
}
|
|
9599
9753
|
const { http } = getAuthedHttpClient();
|
|
9600
9754
|
const outputPath = options.output ? resolve3(String(options.output)) : defaultLedgerExportPath();
|
|
9601
9755
|
let summary = { row_count: 0, net_delta_credits: 0 };
|
|
@@ -9605,6 +9759,8 @@ async function handleLedgerExportAll(options) {
|
|
|
9605
9759
|
const params = new URLSearchParams({ limit: "5000" });
|
|
9606
9760
|
if (cursor !== null) params.set("cursor", cursor);
|
|
9607
9761
|
if (options.runId) params.set("run_id", options.runId);
|
|
9762
|
+
if (options.operation) params.set("operation", options.operation);
|
|
9763
|
+
if (sinceAt !== null) params.set("since_at", String(sinceAt));
|
|
9608
9764
|
const payload = await http.get(
|
|
9609
9765
|
`/api/v2/billing/ledger?${params.toString()}`
|
|
9610
9766
|
);
|
|
@@ -9633,13 +9789,15 @@ async function handleLedgerExportAll(options) {
|
|
|
9633
9789
|
net_delta_credits: summary.net_delta_credits,
|
|
9634
9790
|
scope: "workspace",
|
|
9635
9791
|
...options.runId ? { run_id: options.runId } : {},
|
|
9792
|
+
...options.operation ? { operation: options.operation } : {},
|
|
9793
|
+
...sinceAt !== null ? { since_at: sinceAt } : {},
|
|
9636
9794
|
render: {
|
|
9637
9795
|
sections: [
|
|
9638
9796
|
{
|
|
9639
9797
|
title: "billing ledger",
|
|
9640
9798
|
lines: [
|
|
9641
9799
|
`Billing ledger written to ${outputPath}`,
|
|
9642
|
-
`${summary.row_count} row(s) exported for the active workspace${options.runId ? ` and run ${options.runId}` : ""}.`,
|
|
9800
|
+
`${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()}` : ""}.`,
|
|
9643
9801
|
`Net ledger delta: ${summary.net_delta_credits} Deepline Credits`
|
|
9644
9802
|
]
|
|
9645
9803
|
}
|
|
@@ -10336,6 +10494,7 @@ Examples:
|
|
|
10336
10494
|
deepline billing ledger export all
|
|
10337
10495
|
deepline billing ledger export all --output ./ledger.csv
|
|
10338
10496
|
deepline billing ledger export all --run-id play/demo/run/abc123
|
|
10497
|
+
deepline billing ledger export all --operation limadata_find_audience_identifiers --since 2026-09-01T00:00:00Z
|
|
10339
10498
|
deepline billing ledger export all --json
|
|
10340
10499
|
`
|
|
10341
10500
|
).addCommand(
|
|
@@ -10357,7 +10516,10 @@ Examples:
|
|
|
10357
10516
|
deepline billing ledger export all
|
|
10358
10517
|
deepline billing ledger export all --json
|
|
10359
10518
|
`
|
|
10360
|
-
).option("--output <path>", "Write CSV to an explicit path").option("--run-id <run_id>", "Export ledger rows for one play run.").option(
|
|
10519
|
+
).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(
|
|
10520
|
+
"--since <timestamp>",
|
|
10521
|
+
"Only export rows since ISO-8601 time or Unix milliseconds."
|
|
10522
|
+
).option(
|
|
10361
10523
|
"--json",
|
|
10362
10524
|
"Emit JSON output. Also automatic when stdout is piped"
|
|
10363
10525
|
).action(handleLedgerExportAll)
|
|
@@ -16696,7 +16858,7 @@ async function traceCliSpan(phase, fields, run) {
|
|
|
16696
16858
|
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.";
|
|
16697
16859
|
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()`.";
|
|
16698
16860
|
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.";
|
|
16699
|
-
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
|
|
16861
|
+
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.";
|
|
16700
16862
|
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.";
|
|
16701
16863
|
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.";
|
|
16702
16864
|
function sourceLineForError(sourceCode, error) {
|
|
@@ -32538,7 +32700,7 @@ function renderDeployedListText(payload, requestedStatus) {
|
|
|
32538
32700
|
return status && count !== void 0 ? [`${status}: ${count}`] : [];
|
|
32539
32701
|
}).join(" ") : "";
|
|
32540
32702
|
if (summary) lines.push(`All lifecycle states: ${summary}`);
|
|
32541
|
-
if (payload.is_truncated === true) {
|
|
32703
|
+
if (payload.has_more === true || payload.is_truncated === true) {
|
|
32542
32704
|
const nextCursor = asString(payload.next_cursor);
|
|
32543
32705
|
lines.push(
|
|
32544
32706
|
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:',
|
|
@@ -32552,11 +32714,15 @@ function renderDeployedListText(payload, requestedStatus) {
|
|
|
32552
32714
|
`;
|
|
32553
32715
|
}
|
|
32554
32716
|
async function handleMonitorsList(options) {
|
|
32717
|
+
if (options.compact) {
|
|
32718
|
+
process.stderr.write(
|
|
32719
|
+
"`--compact` is deprecated and now does nothing; returning the complete monitor records.\n"
|
|
32720
|
+
);
|
|
32721
|
+
}
|
|
32555
32722
|
const payload = await new DeeplineClient().monitors.list({
|
|
32556
32723
|
...options.status ? { status: options.status } : {},
|
|
32557
32724
|
...options.limit ? { limit: options.limit } : {},
|
|
32558
32725
|
...options.cursor ? { cursor: options.cursor } : {},
|
|
32559
|
-
...options.compact ? { compact: true } : {},
|
|
32560
32726
|
...options.includeConsumers ? { includeConsumers: true } : {}
|
|
32561
32727
|
});
|
|
32562
32728
|
printCommandEnvelope(payload, {
|
|
@@ -32667,6 +32833,10 @@ var MONITOR_FLEET_COMMANDS = [
|
|
|
32667
32833
|
{
|
|
32668
32834
|
name: "deactivate",
|
|
32669
32835
|
summary: "Deactivate a fleet and the monitors it owns."
|
|
32836
|
+
},
|
|
32837
|
+
{
|
|
32838
|
+
name: "reactivate",
|
|
32839
|
+
summary: "Explicitly recreate a fleet after a credit-triggered suspension."
|
|
32670
32840
|
}
|
|
32671
32841
|
];
|
|
32672
32842
|
var MONITOR_FLEET_AGENT_NOTES = [
|
|
@@ -33169,6 +33339,72 @@ async function handleMonitorFleetsGet(fleetId, options) {
|
|
|
33169
33339
|
{ json: options.json, text }
|
|
33170
33340
|
);
|
|
33171
33341
|
}
|
|
33342
|
+
function fleetReactivateCommandLine(fleetId, options) {
|
|
33343
|
+
const parts = [
|
|
33344
|
+
"deepline",
|
|
33345
|
+
"monitors",
|
|
33346
|
+
"fleets",
|
|
33347
|
+
"reactivate",
|
|
33348
|
+
fleetShellArg(fleetId),
|
|
33349
|
+
"--yes"
|
|
33350
|
+
];
|
|
33351
|
+
if (options.wait) parts.push("--wait");
|
|
33352
|
+
if (options.timeout)
|
|
33353
|
+
parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
|
|
33354
|
+
if (options.idempotencyKey)
|
|
33355
|
+
parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
|
|
33356
|
+
parts.push(...fleetJsonFlag(options));
|
|
33357
|
+
return parts.join(" ");
|
|
33358
|
+
}
|
|
33359
|
+
async function handleMonitorFleetsReactivate(fleetId, options, idempotencyKey) {
|
|
33360
|
+
if (!options.yes) {
|
|
33361
|
+
throw new MonitorsUsageError(
|
|
33362
|
+
`reactivate can recreate every suspended provider monitor and restart lifecycle billing. Confirm with --yes:
|
|
33363
|
+
${fleetReactivateCommandLine(fleetId, options)}`
|
|
33364
|
+
);
|
|
33365
|
+
}
|
|
33366
|
+
const client2 = new DeeplineClient();
|
|
33367
|
+
const payload = await client2.monitors.fleets.reactivate(fleetId, {
|
|
33368
|
+
idempotencyKey
|
|
33369
|
+
});
|
|
33370
|
+
const accepted = { ...payload, idempotency_key: idempotencyKey };
|
|
33371
|
+
if (!options.wait) {
|
|
33372
|
+
printCommandEnvelope(accepted, {
|
|
33373
|
+
json: options.json,
|
|
33374
|
+
text: `Fleet ${fleetId} \u2014 ${asString(payload.status) ?? "billing_reactivating"}
|
|
33375
|
+
idempotency key ${idempotencyKey}
|
|
33376
|
+
`
|
|
33377
|
+
});
|
|
33378
|
+
return;
|
|
33379
|
+
}
|
|
33380
|
+
const timeoutMs = fleetTimeoutMs(options.timeout);
|
|
33381
|
+
const progress = fleetProgressReporter();
|
|
33382
|
+
let final;
|
|
33383
|
+
try {
|
|
33384
|
+
final = await client2.monitors.fleets.waitForConvergence(fleetId, {
|
|
33385
|
+
timeoutMs,
|
|
33386
|
+
pollIntervalMs: FLEET_POLL_INTERVAL_MS,
|
|
33387
|
+
onProgress: progress.report
|
|
33388
|
+
});
|
|
33389
|
+
} finally {
|
|
33390
|
+
progress.finish();
|
|
33391
|
+
}
|
|
33392
|
+
const envelope = { ...accepted, ...final };
|
|
33393
|
+
const text = renderFleetGet(final);
|
|
33394
|
+
if (fleetStatus(final) === "converged") {
|
|
33395
|
+
printCommandEnvelope(envelope, { json: options.json, text });
|
|
33396
|
+
return;
|
|
33397
|
+
}
|
|
33398
|
+
reportFleetState(
|
|
33399
|
+
envelope,
|
|
33400
|
+
new MonitorFleetStateError({
|
|
33401
|
+
code: "MONITOR_FLEET_WAIT_TIMEOUT",
|
|
33402
|
+
message: `Stopped waiting after ${timeoutMs}ms. Fleet ${fleetId} recovery is still in progress on the server.`,
|
|
33403
|
+
next: fleetServerNext(final) ?? `deepline monitors fleets get ${fleetShellArg(fleetId)} --json`
|
|
33404
|
+
}),
|
|
33405
|
+
{ json: options.json, text }
|
|
33406
|
+
);
|
|
33407
|
+
}
|
|
33172
33408
|
function fleetDeactivateCommandLine(fleetId, options) {
|
|
33173
33409
|
const parts = [
|
|
33174
33410
|
"deepline monitors fleets deactivate",
|
|
@@ -33466,18 +33702,11 @@ async function handleMonitorsGet(key, options) {
|
|
|
33466
33702
|
}
|
|
33467
33703
|
async function handleMonitorsTest(key, payload, options) {
|
|
33468
33704
|
const explicitPayload = parseJsonObjectArg(payload, "<payload>");
|
|
33469
|
-
const result = await new DeeplineClient().monitors.test(
|
|
33470
|
-
key,
|
|
33471
|
-
explicitPayload,
|
|
33472
|
-
{
|
|
33473
|
-
validationOnly: options.dispatch !== true,
|
|
33474
|
-
dispatch: options.dispatch === true
|
|
33475
|
-
}
|
|
33476
|
-
);
|
|
33477
|
-
const dispatch = options.dispatch === true;
|
|
33705
|
+
const result = await new DeeplineClient().monitors.test(key, explicitPayload);
|
|
33478
33706
|
const text = `Monitor diagnostic for ${key}: ${result.accepted === true ? "accepted" : "rejected"}
|
|
33479
|
-
|
|
33480
|
-
|
|
33707
|
+
mode: validation_only (no rows written, credits spent, or Plays dispatched)
|
|
33708
|
+
persisted rows: ${asFiniteNumber(result.persisted_rows) ?? 0}
|
|
33709
|
+
dispatched bound Plays: ${asFiniteNumber(result.dispatched_bound_plays) ?? 0}
|
|
33481
33710
|
`;
|
|
33482
33711
|
printCommandEnvelope(result, { json: options.json, text });
|
|
33483
33712
|
}
|
|
@@ -33557,6 +33786,206 @@ async function handleMonitorsReactivate(key, options) {
|
|
|
33557
33786
|
const payload = await client2.monitors.reactivate(key);
|
|
33558
33787
|
printCommandEnvelope(payload, { json: options.json });
|
|
33559
33788
|
}
|
|
33789
|
+
var MONITOR_VERB_POLL_INTERVAL_MS = 2e3;
|
|
33790
|
+
function monitorHealthLine(health) {
|
|
33791
|
+
return [
|
|
33792
|
+
`converged ${health.converged}/${health.scanned}`,
|
|
33793
|
+
`needs_repair ${health.needs_repair}`,
|
|
33794
|
+
`missing ${health.observed.missing}`,
|
|
33795
|
+
`unaudited ${health.observed.unknown + health.observed.unset}`,
|
|
33796
|
+
`silent ${health.silent}`
|
|
33797
|
+
].join(" \xB7 ");
|
|
33798
|
+
}
|
|
33799
|
+
function monitorVerbProgressReporter() {
|
|
33800
|
+
const interactive = process.stderr.isTTY === true;
|
|
33801
|
+
let wrote = false;
|
|
33802
|
+
let lastPlainAt = 0;
|
|
33803
|
+
return {
|
|
33804
|
+
report: (health) => {
|
|
33805
|
+
const line = monitorHealthLine(health);
|
|
33806
|
+
if (interactive) {
|
|
33807
|
+
process.stderr.write(`\r\x1B[2K${line}`);
|
|
33808
|
+
wrote = true;
|
|
33809
|
+
return;
|
|
33810
|
+
}
|
|
33811
|
+
const now = Date.now();
|
|
33812
|
+
if (wrote && now - lastPlainAt < FLEET_PLAIN_PROGRESS_INTERVAL_MS) return;
|
|
33813
|
+
lastPlainAt = now;
|
|
33814
|
+
wrote = true;
|
|
33815
|
+
process.stderr.write(`${line}
|
|
33816
|
+
`);
|
|
33817
|
+
},
|
|
33818
|
+
finish: () => {
|
|
33819
|
+
if (interactive && wrote) process.stderr.write("\n");
|
|
33820
|
+
}
|
|
33821
|
+
};
|
|
33822
|
+
}
|
|
33823
|
+
async function watchMonitorHealth(input2) {
|
|
33824
|
+
const deadlineAt = Date.now() + input2.timeoutMs;
|
|
33825
|
+
const scope = input2.fleetId ? { fleetId: input2.fleetId } : {};
|
|
33826
|
+
let last = await input2.client.monitors.health(scope);
|
|
33827
|
+
input2.onProgress(last);
|
|
33828
|
+
while (Date.now() < deadlineAt) {
|
|
33829
|
+
if (last.needs_repair === 0 && last.observed.unknown === 0) return last;
|
|
33830
|
+
await new Promise(
|
|
33831
|
+
(resolve21) => setTimeout(resolve21, MONITOR_VERB_POLL_INTERVAL_MS)
|
|
33832
|
+
);
|
|
33833
|
+
last = await input2.client.monitors.health(scope);
|
|
33834
|
+
input2.onProgress(last);
|
|
33835
|
+
}
|
|
33836
|
+
return last;
|
|
33837
|
+
}
|
|
33838
|
+
function monitorHealthText(health) {
|
|
33839
|
+
const partial = health.truncated ? " (partial \u2014 scope larger than one read)" : "";
|
|
33840
|
+
const lines = [
|
|
33841
|
+
`scope: ${health.scope.fleet_id ?? "workspace"}${partial}`,
|
|
33842
|
+
monitorHealthLine(health)
|
|
33843
|
+
];
|
|
33844
|
+
if (health.deactivation_reasons.length > 0) {
|
|
33845
|
+
lines.push("");
|
|
33846
|
+
lines.push("deactivated by Deepline:");
|
|
33847
|
+
for (const entry of health.deactivation_reasons) {
|
|
33848
|
+
const how = entry.resolution ? ` \u2014 ${entry.resolution}` : "";
|
|
33849
|
+
lines.push(` ${entry.reason} (${entry.count})${how}`);
|
|
33850
|
+
}
|
|
33851
|
+
}
|
|
33852
|
+
if (health.worst_offenders.length > 0) {
|
|
33853
|
+
lines.push("");
|
|
33854
|
+
lines.push(
|
|
33855
|
+
`silent longest (no delivery in ${health.silent_window_days}d):`
|
|
33856
|
+
);
|
|
33857
|
+
for (const entry of health.worst_offenders) {
|
|
33858
|
+
const when = entry.last_event_at === null ? "never" : new Date(entry.last_event_at).toISOString();
|
|
33859
|
+
lines.push(` ${entry.monitor_key} ${entry.tool} last event ${when}`);
|
|
33860
|
+
}
|
|
33861
|
+
}
|
|
33862
|
+
return `${lines.join("\n")}
|
|
33863
|
+
`;
|
|
33864
|
+
}
|
|
33865
|
+
async function handleMonitorsAudit(options) {
|
|
33866
|
+
const client2 = new DeeplineClient();
|
|
33867
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33868
|
+
const scope = fleetId ? { fleetId } : {};
|
|
33869
|
+
let result = await client2.monitors.audit(scope);
|
|
33870
|
+
const passes = [result.audit];
|
|
33871
|
+
while (result.audit.cursor !== null) {
|
|
33872
|
+
result = await client2.monitors.audit({
|
|
33873
|
+
...scope,
|
|
33874
|
+
cursor: result.audit.cursor
|
|
33875
|
+
});
|
|
33876
|
+
passes.push(result.audit);
|
|
33877
|
+
}
|
|
33878
|
+
const totals = passes.reduce(
|
|
33879
|
+
(sum, pass) => ({
|
|
33880
|
+
scanned: sum.scanned + pass.scanned,
|
|
33881
|
+
asked: sum.asked + pass.asked,
|
|
33882
|
+
stale: sum.stale + pass.stale,
|
|
33883
|
+
missing: sum.missing + pass.observed.missing
|
|
33884
|
+
}),
|
|
33885
|
+
{ scanned: 0, asked: 0, stale: 0, missing: 0 }
|
|
33886
|
+
);
|
|
33887
|
+
let health = result.health;
|
|
33888
|
+
if (options.watch) {
|
|
33889
|
+
const progress = monitorVerbProgressReporter();
|
|
33890
|
+
try {
|
|
33891
|
+
health = await watchMonitorHealth({
|
|
33892
|
+
client: client2,
|
|
33893
|
+
...scope,
|
|
33894
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
33895
|
+
onProgress: progress.report
|
|
33896
|
+
});
|
|
33897
|
+
} finally {
|
|
33898
|
+
progress.finish();
|
|
33899
|
+
}
|
|
33900
|
+
}
|
|
33901
|
+
const unauditable = result.audit.unauditable_capabilities;
|
|
33902
|
+
const overtaken = totals.stale > 0 ? ` \xB7 ${totals.stale} observations overtaken by a concurrent settle` : "";
|
|
33903
|
+
const text = [
|
|
33904
|
+
`audited ${totals.scanned} monitors \xB7 asked the provider about ${totals.asked}`,
|
|
33905
|
+
`missing ${totals.missing}${overtaken}`,
|
|
33906
|
+
...unauditable.length > 0 ? [`not auditable (no batch-read contract): ${unauditable.join(", ")}`] : [],
|
|
33907
|
+
"",
|
|
33908
|
+
monitorHealthText(health)
|
|
33909
|
+
].join("\n");
|
|
33910
|
+
printCommandEnvelope(
|
|
33911
|
+
{ ...result, audit: { ...result.audit, totals }, health },
|
|
33912
|
+
{ json: options.json, text }
|
|
33913
|
+
);
|
|
33914
|
+
}
|
|
33915
|
+
async function handleMonitorsRepair(options) {
|
|
33916
|
+
const client2 = new DeeplineClient();
|
|
33917
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33918
|
+
const scope = fleetId ? { fleetId } : {};
|
|
33919
|
+
const result = await client2.monitors.repair({
|
|
33920
|
+
...scope,
|
|
33921
|
+
...options.dryRun ? { dryRun: true } : {}
|
|
33922
|
+
});
|
|
33923
|
+
if (options.dryRun) {
|
|
33924
|
+
assertMonitorDryRunAcknowledged(
|
|
33925
|
+
result,
|
|
33926
|
+
{ command: "monitors repair", mutation: "repair" }
|
|
33927
|
+
);
|
|
33928
|
+
}
|
|
33929
|
+
let health = result.health;
|
|
33930
|
+
if (options.watch && !options.dryRun) {
|
|
33931
|
+
const progress = monitorVerbProgressReporter();
|
|
33932
|
+
try {
|
|
33933
|
+
health = await watchMonitorHealth({
|
|
33934
|
+
client: client2,
|
|
33935
|
+
...scope,
|
|
33936
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
33937
|
+
onProgress: progress.report
|
|
33938
|
+
});
|
|
33939
|
+
} finally {
|
|
33940
|
+
progress.finish();
|
|
33941
|
+
}
|
|
33942
|
+
}
|
|
33943
|
+
const verb = options.dryRun ? "would queue" : "queued";
|
|
33944
|
+
const lines = [
|
|
33945
|
+
`${verb} ${result.repair.queued} of ${result.repair.scanned} monitors`
|
|
33946
|
+
];
|
|
33947
|
+
for (const item of result.repair.plan.slice(0, REPAIR_PLAN_PREVIEW)) {
|
|
33948
|
+
const why = item.deactivation_reason ? ` \xB7 ${item.deactivation_reason}` : "";
|
|
33949
|
+
lines.push(
|
|
33950
|
+
` ${item.action.padEnd(6)} ${item.monitor_key} desired ${item.desired} \xB7 observed ${item.observed}${why}`
|
|
33951
|
+
);
|
|
33952
|
+
}
|
|
33953
|
+
if (result.repair.plan.length > REPAIR_PLAN_PREVIEW) {
|
|
33954
|
+
lines.push(` \u2026 ${result.repair.plan.length - REPAIR_PLAN_PREVIEW} more`);
|
|
33955
|
+
}
|
|
33956
|
+
if (result.repair.unaudited.length > 0) {
|
|
33957
|
+
lines.push(
|
|
33958
|
+
`${result.repair.unaudited.length} monitors have never been observed \u2014 run 'deepline monitors audit' first.`
|
|
33959
|
+
);
|
|
33960
|
+
}
|
|
33961
|
+
if (result.repair.unowned.length > 0) {
|
|
33962
|
+
lines.push(
|
|
33963
|
+
`${result.repair.unowned.length} monitors disagree but no fleet owns them; repair those with 'deepline monitors deploy' or 'deepline monitors delete'.`
|
|
33964
|
+
);
|
|
33965
|
+
}
|
|
33966
|
+
if (result.repair.fenced.length > 0) {
|
|
33967
|
+
lines.push(
|
|
33968
|
+
`${result.repair.fenced.length} monitors have a provider operation in flight; Deepline is finishing those and repair left them alone.`
|
|
33969
|
+
);
|
|
33970
|
+
}
|
|
33971
|
+
lines.push("");
|
|
33972
|
+
lines.push(monitorHealthText(health));
|
|
33973
|
+
printCommandEnvelope(
|
|
33974
|
+
{ ...result, health },
|
|
33975
|
+
{ json: options.json, text: lines.join("\n") }
|
|
33976
|
+
);
|
|
33977
|
+
}
|
|
33978
|
+
var REPAIR_PLAN_PREVIEW = 20;
|
|
33979
|
+
async function handleMonitorsHealth(options) {
|
|
33980
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33981
|
+
const health = await new DeeplineClient().monitors.health(
|
|
33982
|
+
fleetId ? { fleetId } : {}
|
|
33983
|
+
);
|
|
33984
|
+
printCommandEnvelope(health, {
|
|
33985
|
+
json: options.json,
|
|
33986
|
+
text: monitorHealthText(health)
|
|
33987
|
+
});
|
|
33988
|
+
}
|
|
33560
33989
|
function registerMonitorsCommands(program) {
|
|
33561
33990
|
const monitors = program.command("monitors").description("Discover, deploy, and manage Deepline monitors.").showSuggestionAfterError(true).addHelpText(
|
|
33562
33991
|
"after",
|
|
@@ -33592,6 +34021,75 @@ Examples:
|
|
|
33592
34021
|
deepline monitors reactivate my-monitor --dry-run
|
|
33593
34022
|
`
|
|
33594
34023
|
);
|
|
34024
|
+
withJsonOption(
|
|
34025
|
+
monitors.command("audit").description(
|
|
34026
|
+
"Re-read what the provider actually holds for your monitors."
|
|
34027
|
+
).option("--fleet <fleet-id>", "Audit one fleet instead of every monitor").option("--watch", "Keep polling health until the scope settles").option(
|
|
34028
|
+
"--timeout <duration>",
|
|
34029
|
+
"How long --watch waits, e.g. 90s, 5m, 1h (default 10m)"
|
|
34030
|
+
).addHelpText(
|
|
34031
|
+
"after",
|
|
34032
|
+
`
|
|
34033
|
+
Notes:
|
|
34034
|
+
Asks the provider, by resource id, what it still holds, and records the answer
|
|
34035
|
+
on each monitor. It changes nothing upstream: no creates, no deletes, no
|
|
34036
|
+
intent. Safe to run at any time, as often as you like \u2014 running it twice is
|
|
34037
|
+
running it once, twice.
|
|
34038
|
+
|
|
34039
|
+
A monitor the provider does not return is recorded "missing". Use
|
|
34040
|
+
'deepline monitors repair' to act on that.
|
|
34041
|
+
|
|
34042
|
+
Examples:
|
|
34043
|
+
deepline monitors audit
|
|
34044
|
+
deepline monitors audit --fleet accounts-eu --json
|
|
34045
|
+
deepline monitors audit --fleet accounts-eu --watch --timeout 5m
|
|
34046
|
+
`
|
|
34047
|
+
)
|
|
34048
|
+
).action(monitorsAction(handleMonitorsAudit));
|
|
34049
|
+
withJsonOption(
|
|
34050
|
+
monitors.command("repair").description(
|
|
34051
|
+
"Converge the monitors whose desired and observed states disagree."
|
|
34052
|
+
).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(
|
|
34053
|
+
"--timeout <duration>",
|
|
34054
|
+
"How long --watch waits, e.g. 90s, 5m, 1h (default 10m)"
|
|
34055
|
+
).addHelpText(
|
|
34056
|
+
"after",
|
|
34057
|
+
`
|
|
34058
|
+
Notes:
|
|
34059
|
+
Queues the monitors that disagree with the provider onto the same convergence
|
|
34060
|
+
loop a fleet sync uses; the provider work happens on Deepline's own schedule.
|
|
34061
|
+
Idempotent \u2014 the queue IS the disagreement, so a repeat run queues only what
|
|
34062
|
+
is still wrong.
|
|
34063
|
+
|
|
34064
|
+
Monitors nobody has observed are never repaired: run 'deepline monitors audit'
|
|
34065
|
+
first. Monitors no fleet owns are reported rather than queued; deploy or delete
|
|
34066
|
+
those directly.
|
|
34067
|
+
|
|
34068
|
+
Examples:
|
|
34069
|
+
deepline monitors repair --dry-run
|
|
34070
|
+
deepline monitors repair --fleet accounts-eu --watch
|
|
34071
|
+
`
|
|
34072
|
+
)
|
|
34073
|
+
).action(monitorsAction(handleMonitorsRepair));
|
|
34074
|
+
withJsonOption(
|
|
34075
|
+
monitors.command("health").description("Delivery and convergence health for your monitors.").option(
|
|
34076
|
+
"--fleet <fleet-id>",
|
|
34077
|
+
"Report on one fleet instead of every monitor"
|
|
34078
|
+
).addHelpText(
|
|
34079
|
+
"after",
|
|
34080
|
+
`
|
|
34081
|
+
Notes:
|
|
34082
|
+
Read-only. Reports how many monitors the provider holds as asked, how many
|
|
34083
|
+
disagree, how many Deepline deactivated and why, and how many are "silent" \u2014
|
|
34084
|
+
the provider holds them but nothing has been delivered recently. The worst
|
|
34085
|
+
offenders are listed longest-quiet first.
|
|
34086
|
+
|
|
34087
|
+
Examples:
|
|
34088
|
+
deepline monitors health
|
|
34089
|
+
deepline monitors health --fleet accounts-eu --json
|
|
34090
|
+
`
|
|
34091
|
+
)
|
|
34092
|
+
).action(monitorsAction(handleMonitorsHealth));
|
|
33595
34093
|
withJsonOption(
|
|
33596
34094
|
monitors.command("status").description("Check whether you have access to Deepline monitors.").addHelpText(
|
|
33597
34095
|
"after",
|
|
@@ -33644,10 +34142,10 @@ Examples:
|
|
|
33644
34142
|
`
|
|
33645
34143
|
Notes:
|
|
33646
34144
|
Read-only. --status filters by monitor status: active (default), disabled, or
|
|
33647
|
-
all. The output echoes the status filter that was applied.
|
|
33648
|
-
|
|
33649
|
-
|
|
33650
|
-
is
|
|
34145
|
+
all. The output echoes the status filter that was applied. The response reports
|
|
34146
|
+
total (the true registry count, not the page size), returned, has_more, and
|
|
34147
|
+
next_cursor. When has_more is true, page with --cursor <next_cursor> until it
|
|
34148
|
+
is false \u2014 a "no matching
|
|
33651
34149
|
monitor" reuse conclusion off a truncated page deploys a duplicate paid feed.
|
|
33652
34150
|
The default list stays cheap: it includes the current downstream Play binding
|
|
33653
34151
|
metadata but does not resolve per-monitor delivery/run health. Pass
|
|
@@ -33658,7 +34156,6 @@ Examples:
|
|
|
33658
34156
|
deepline monitors list
|
|
33659
34157
|
deepline monitors list --status all --json
|
|
33660
34158
|
deepline monitors list --status all --cursor <next_cursor> --json
|
|
33661
|
-
deepline monitors list --compact --json
|
|
33662
34159
|
deepline monitors list --include-consumers --limit 20 --json
|
|
33663
34160
|
`
|
|
33664
34161
|
).option(
|
|
@@ -33667,7 +34164,10 @@ Examples:
|
|
|
33667
34164
|
).option("--limit <n>", "Limit the number of deployed monitors returned").option(
|
|
33668
34165
|
"--cursor <cursor>",
|
|
33669
34166
|
"Page past a truncated result using the next_cursor from a prior list response"
|
|
33670
|
-
).option(
|
|
34167
|
+
).option(
|
|
34168
|
+
"--compact",
|
|
34169
|
+
"Deprecated no-op; complete records are always returned"
|
|
34170
|
+
).option(
|
|
33671
34171
|
"--include-consumers",
|
|
33672
34172
|
"Include current SQL-listener consumer health (requires --limit 20 or fewer)"
|
|
33673
34173
|
)
|
|
@@ -33690,10 +34190,7 @@ Examples:
|
|
|
33690
34190
|
).action(monitorsAction(handleMonitorsGet));
|
|
33691
34191
|
withJsonOption(
|
|
33692
34192
|
monitors.command("test <key> <payload>").description(
|
|
33693
|
-
"
|
|
33694
|
-
).option(
|
|
33695
|
-
"--dispatch",
|
|
33696
|
-
"Inject the test event through normal ingestion (writes rows and may dispatch bound Plays)"
|
|
34193
|
+
"Validate an explicit payload against a monitor\u2019s webhook contract."
|
|
33697
34194
|
).addHelpText(
|
|
33698
34195
|
"after",
|
|
33699
34196
|
`
|
|
@@ -33701,9 +34198,8 @@ Notes:
|
|
|
33701
34198
|
<payload> must be an explicit JSON object. The command uses the deployed
|
|
33702
34199
|
monitor\u2019s real binding and payload validation, but is a side-effect-free
|
|
33703
34200
|
diagnostic: it does not persist rows, spend credits, dispatch Plays, or alter
|
|
33704
|
-
monitor state.
|
|
33705
|
-
|
|
33706
|
-
not synthesize a provider event or accept an omitted payload.
|
|
34201
|
+
monitor state. It does not synthesize a provider event or accept an omitted
|
|
34202
|
+
payload.
|
|
33707
34203
|
|
|
33708
34204
|
Examples:
|
|
33709
34205
|
deepline monitors test rb2b-website-visitors '{"LinkedIn URL":"https://www.linkedin.com/in/example","Website":"https://example.com"}' --json
|
|
@@ -34020,6 +34516,40 @@ Examples:
|
|
|
34020
34516
|
reportMonitorsFailure(error, { retryCommand });
|
|
34021
34517
|
}
|
|
34022
34518
|
});
|
|
34519
|
+
withJsonOption(
|
|
34520
|
+
fleets.command("reactivate <fleet-id>").description(
|
|
34521
|
+
"Explicitly recreate a fleet after a credit-triggered suspension."
|
|
34522
|
+
).addHelpText(
|
|
34523
|
+
"after",
|
|
34524
|
+
`
|
|
34525
|
+
Notes:
|
|
34526
|
+
TAMRadar cannot reactivate a deleted radar. This command starts normal,
|
|
34527
|
+
fenced provider creates from the fleet's retained desired definitions and
|
|
34528
|
+
may restart lifecycle billing. A credit top-up alone never does this.
|
|
34529
|
+
|
|
34530
|
+
Example:
|
|
34531
|
+
deepline monitors fleets reactivate account-job-openings --yes --wait --json
|
|
34532
|
+
`
|
|
34533
|
+
).option("--wait", "Poll until the fleet reports converged").option(
|
|
34534
|
+
"--timeout <duration>",
|
|
34535
|
+
"How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
|
|
34536
|
+
).option("--yes", "Confirm recreating suspended provider monitors").option("--idempotency-key <key>", "Stable retry key")
|
|
34537
|
+
).action(async (fleetId, options) => {
|
|
34538
|
+
let retryCommand = fleetReactivateCommandLine(fleetId, options);
|
|
34539
|
+
try {
|
|
34540
|
+
const idempotencyKey = fleetIdempotencyKey(
|
|
34541
|
+
"reactivate",
|
|
34542
|
+
options.idempotencyKey
|
|
34543
|
+
);
|
|
34544
|
+
retryCommand = fleetReactivateCommandLine(fleetId, {
|
|
34545
|
+
...options,
|
|
34546
|
+
idempotencyKey
|
|
34547
|
+
});
|
|
34548
|
+
await handleMonitorFleetsReactivate(fleetId, options, idempotencyKey);
|
|
34549
|
+
} catch (error) {
|
|
34550
|
+
reportMonitorsFailure(error, { retryCommand });
|
|
34551
|
+
}
|
|
34552
|
+
});
|
|
34023
34553
|
const deployed = withJsonOption(
|
|
34024
34554
|
monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
|
|
34025
34555
|
"--status <status>",
|
|
@@ -34027,7 +34557,10 @@ Examples:
|
|
|
34027
34557
|
).option("--limit <n>", "Limit the number of deployed monitors returned").option(
|
|
34028
34558
|
"--cursor <cursor>",
|
|
34029
34559
|
"Page past a truncated result using the next_cursor from a prior list response"
|
|
34030
|
-
).option(
|
|
34560
|
+
).option(
|
|
34561
|
+
"--compact",
|
|
34562
|
+
"Deprecated no-op; complete records are always returned"
|
|
34563
|
+
).option(
|
|
34031
34564
|
"--include-consumers",
|
|
34032
34565
|
"Include current SQL-listener consumer health (requires --limit 20 or fewer)"
|
|
34033
34566
|
)
|
|
@@ -34355,11 +34888,13 @@ async function handleOrgStatus(options) {
|
|
|
34355
34888
|
host_env_path: hostPath,
|
|
34356
34889
|
folder_target: folderTargetPayload,
|
|
34357
34890
|
project_pin: provenance.scope === "global" && provenance.project.state === "project" ? {
|
|
34358
|
-
|
|
34891
|
+
available: true,
|
|
34892
|
+
required: false,
|
|
34359
34893
|
path: provenance.project.pinPath,
|
|
34360
|
-
cloud_mutations_blocked:
|
|
34894
|
+
cloud_mutations_blocked: false,
|
|
34361
34895
|
command: "deepline org set --auth-scope folder"
|
|
34362
34896
|
} : {
|
|
34897
|
+
available: false,
|
|
34363
34898
|
required: false,
|
|
34364
34899
|
cloud_mutations_blocked: false
|
|
34365
34900
|
},
|
|
@@ -34780,8 +35315,8 @@ Examples:
|
|
|
34780
35315
|
Notes:
|
|
34781
35316
|
Selection can be a list number, exact organization name, or organization id.
|
|
34782
35317
|
Without a selection, prints choices. With --auth-scope folder while this
|
|
34783
|
-
project is using global host auth, it pins the current target directly
|
|
34784
|
-
|
|
35318
|
+
project is using global host auth, it pins the current target directly
|
|
35319
|
+
without an additional organization lookup.
|
|
34785
35320
|
|
|
34786
35321
|
Mutates local auth state and asks Deepline for an org-scoped API key. It
|
|
34787
35322
|
writes only the selected scope:
|
|
@@ -34798,7 +35333,9 @@ Notes:
|
|
|
34798
35333
|
|
|
34799
35334
|
Prefer --auth-scope folder for a repository or customer workspace. Use
|
|
34800
35335
|
--auth-scope global only for deliberate host-wide interactive defaults; it
|
|
34801
|
-
is shared by every unpinned CLI on this machine.
|
|
35336
|
+
is shared by every unpinned CLI on this machine. Global auth remains
|
|
35337
|
+
supported in projects; use a folder pin when you want a project-specific
|
|
35338
|
+
default. For automation, pass
|
|
34802
35339
|
DEEPLINE_API_KEY only to that invocation and confirm with org status --json.
|
|
34803
35340
|
|
|
34804
35341
|
Use --json for stable fields including effective_auth_scope,
|
|
@@ -34841,6 +35378,318 @@ Examples:
|
|
|
34841
35378
|
);
|
|
34842
35379
|
}
|
|
34843
35380
|
|
|
35381
|
+
// src/cli/commands/git.ts
|
|
35382
|
+
function renderProject(project) {
|
|
35383
|
+
const root = project.rootDirectory ? ` (${project.rootDirectory})` : "";
|
|
35384
|
+
const flags = [
|
|
35385
|
+
project.disabled ? "unlinked" : "linked",
|
|
35386
|
+
`deploys ${project.productionBranch}`,
|
|
35387
|
+
project.checkOnPullRequest ? "PR checks on" : "PR checks off"
|
|
35388
|
+
].join(", ");
|
|
35389
|
+
return `${project.id} ${project.repoFullName}${root} - ${flags}`;
|
|
35390
|
+
}
|
|
35391
|
+
function renderDeployment(deployment) {
|
|
35392
|
+
const ref = deployment.ref.replace("refs/heads/", "");
|
|
35393
|
+
const kind = deployment.isProduction ? "production" : deployment.trigger === "pull_request" ? `pr #${deployment.pullRequestNumber ?? "?"}` : deployment.trigger;
|
|
35394
|
+
const suffix = deployment.error ? ` - ${deployment.error.slice(0, 80)}` : "";
|
|
35395
|
+
return `${deployment.id} ${deployment.commitSha.slice(0, 10)} ${ref} (${kind}) - ${deployment.status}${suffix}`;
|
|
35396
|
+
}
|
|
35397
|
+
async function handleList(options) {
|
|
35398
|
+
const { http } = getAuthedHttpClient();
|
|
35399
|
+
const payload = await http.get(
|
|
35400
|
+
`/api/v2/play-projects${options.all ? "?includeDisabled=1" : ""}`
|
|
35401
|
+
);
|
|
35402
|
+
printCommandEnvelope(
|
|
35403
|
+
{
|
|
35404
|
+
projects: payload.projects,
|
|
35405
|
+
count: payload.projects.length,
|
|
35406
|
+
render: {
|
|
35407
|
+
sections: [
|
|
35408
|
+
{
|
|
35409
|
+
title: "linked repositories",
|
|
35410
|
+
lines: payload.projects.length ? payload.projects.map(renderProject) : [
|
|
35411
|
+
"No repositories are linked. Run `deepline git repos` to see what the GitHub installation can reach, then `deepline git link`."
|
|
35412
|
+
]
|
|
35413
|
+
}
|
|
35414
|
+
]
|
|
35415
|
+
}
|
|
35416
|
+
},
|
|
35417
|
+
{ json: options.json }
|
|
35418
|
+
);
|
|
35419
|
+
}
|
|
35420
|
+
async function handleRepos(options) {
|
|
35421
|
+
const { http } = getAuthedHttpClient();
|
|
35422
|
+
const query = options.installation ? `?installationId=${encodeURIComponent(options.installation)}` : "";
|
|
35423
|
+
const payload = await http.get(`/api/v2/github/repos${query}`);
|
|
35424
|
+
printCommandEnvelope(
|
|
35425
|
+
{
|
|
35426
|
+
installation: payload.installation,
|
|
35427
|
+
repositories: payload.repositories,
|
|
35428
|
+
count: payload.repositories.length,
|
|
35429
|
+
render: {
|
|
35430
|
+
sections: [
|
|
35431
|
+
{
|
|
35432
|
+
title: `repos on installation @${payload.installation.accountLogin} (${payload.installation.repositorySelection})`,
|
|
35433
|
+
lines: payload.repositories.map(
|
|
35434
|
+
(repo) => `${repo.repoId} ${repo.fullName} (default: ${repo.defaultBranch}${repo.private ? ", private" : ""}${repo.fork ? ", fork" : ""})`
|
|
35435
|
+
)
|
|
35436
|
+
}
|
|
35437
|
+
]
|
|
35438
|
+
}
|
|
35439
|
+
},
|
|
35440
|
+
{ json: options.json }
|
|
35441
|
+
);
|
|
35442
|
+
}
|
|
35443
|
+
async function resolveRepoId(repo, installation) {
|
|
35444
|
+
if (/^\d+$/.test(repo)) return Number(repo);
|
|
35445
|
+
const { http } = getAuthedHttpClient();
|
|
35446
|
+
const query = installation ? `?installationId=${encodeURIComponent(installation)}` : "";
|
|
35447
|
+
const payload = await http.get(
|
|
35448
|
+
`/api/v2/github/repos${query}`
|
|
35449
|
+
);
|
|
35450
|
+
const match = payload.repositories.find(
|
|
35451
|
+
(entry) => entry.fullName.toLowerCase() === repo.toLowerCase()
|
|
35452
|
+
);
|
|
35453
|
+
if (!match) {
|
|
35454
|
+
throw new Error(
|
|
35455
|
+
`Repo "${repo}" is not accessible to the workspace's GitHub installation. Run \`deepline git repos\` to list what is.`
|
|
35456
|
+
);
|
|
35457
|
+
}
|
|
35458
|
+
return match.repoId;
|
|
35459
|
+
}
|
|
35460
|
+
async function handleLink(repo, options) {
|
|
35461
|
+
const repoId = await resolveRepoId(repo, options.installation);
|
|
35462
|
+
const { http } = getAuthedHttpClient();
|
|
35463
|
+
const payload = await http.post("/api/v2/play-projects", {
|
|
35464
|
+
repoId,
|
|
35465
|
+
...options.installation !== void 0 ? { installationId: options.installation } : {},
|
|
35466
|
+
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
35467
|
+
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
35468
|
+
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
35469
|
+
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {}
|
|
35470
|
+
});
|
|
35471
|
+
printCommandEnvelope(
|
|
35472
|
+
{
|
|
35473
|
+
project: payload.project,
|
|
35474
|
+
render: {
|
|
35475
|
+
sections: [
|
|
35476
|
+
{
|
|
35477
|
+
title: "linked",
|
|
35478
|
+
lines: [
|
|
35479
|
+
renderProject(payload.project),
|
|
35480
|
+
...(payload.warnings ?? []).map(
|
|
35481
|
+
(warning) => `WARNING: ${warning}`
|
|
35482
|
+
),
|
|
35483
|
+
"Pushes to the production branch now register and promote changed plays.",
|
|
35484
|
+
"Anyone who can push to this repo can change what runs in this workspace."
|
|
35485
|
+
]
|
|
35486
|
+
}
|
|
35487
|
+
]
|
|
35488
|
+
}
|
|
35489
|
+
},
|
|
35490
|
+
{ json: options.json }
|
|
35491
|
+
);
|
|
35492
|
+
}
|
|
35493
|
+
async function handleGet(id, options) {
|
|
35494
|
+
const { http } = getAuthedHttpClient();
|
|
35495
|
+
const payload = await http.get(
|
|
35496
|
+
`/api/v2/play-projects/${encodeURIComponent(id)}`
|
|
35497
|
+
);
|
|
35498
|
+
printCommandEnvelope(
|
|
35499
|
+
{
|
|
35500
|
+
project: payload.project,
|
|
35501
|
+
render: {
|
|
35502
|
+
sections: [
|
|
35503
|
+
{
|
|
35504
|
+
title: "linked repository",
|
|
35505
|
+
lines: [renderProject(payload.project)]
|
|
35506
|
+
}
|
|
35507
|
+
]
|
|
35508
|
+
}
|
|
35509
|
+
},
|
|
35510
|
+
{ json: options.json }
|
|
35511
|
+
);
|
|
35512
|
+
}
|
|
35513
|
+
async function handleSet(id, options) {
|
|
35514
|
+
const { http } = getAuthedHttpClient();
|
|
35515
|
+
const payload = await http.patch(
|
|
35516
|
+
`/api/v2/play-projects/${encodeURIComponent(id)}`,
|
|
35517
|
+
{
|
|
35518
|
+
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
35519
|
+
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
35520
|
+
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
35521
|
+
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {},
|
|
35522
|
+
...options.disabled !== void 0 ? { disabled: options.disabled } : {}
|
|
35523
|
+
}
|
|
35524
|
+
);
|
|
35525
|
+
printCommandEnvelope(
|
|
35526
|
+
{
|
|
35527
|
+
project: payload.project,
|
|
35528
|
+
render: {
|
|
35529
|
+
sections: [
|
|
35530
|
+
{ title: "updated", lines: [renderProject(payload.project)] }
|
|
35531
|
+
]
|
|
35532
|
+
}
|
|
35533
|
+
},
|
|
35534
|
+
{ json: options.json }
|
|
35535
|
+
);
|
|
35536
|
+
}
|
|
35537
|
+
async function handleUnlink(id, options) {
|
|
35538
|
+
const { http } = getAuthedHttpClient();
|
|
35539
|
+
await http.delete(`/api/v2/play-projects/${encodeURIComponent(id)}`);
|
|
35540
|
+
printCommandEnvelope(
|
|
35541
|
+
{
|
|
35542
|
+
ok: true,
|
|
35543
|
+
id,
|
|
35544
|
+
render: {
|
|
35545
|
+
sections: [
|
|
35546
|
+
{
|
|
35547
|
+
title: "unlinked",
|
|
35548
|
+
lines: [
|
|
35549
|
+
`Repository link ${id} removed. Deployments stop immediately and in-flight deploy credentials die; live plays keep running.`
|
|
35550
|
+
]
|
|
35551
|
+
}
|
|
35552
|
+
]
|
|
35553
|
+
}
|
|
35554
|
+
},
|
|
35555
|
+
{ json: options.json }
|
|
35556
|
+
);
|
|
35557
|
+
}
|
|
35558
|
+
async function handleConnect(options) {
|
|
35559
|
+
const baseUrl = resolveBaseUrlOnly();
|
|
35560
|
+
const connectUrl = `${baseUrl.replace(/\/$/, "")}/api/v2/github/connect`;
|
|
35561
|
+
const opened = openInBrowser(connectUrl);
|
|
35562
|
+
printCommandEnvelope(
|
|
35563
|
+
{
|
|
35564
|
+
connectUrl,
|
|
35565
|
+
browser: opened,
|
|
35566
|
+
render: {
|
|
35567
|
+
sections: [
|
|
35568
|
+
{
|
|
35569
|
+
title: "connect GitHub",
|
|
35570
|
+
lines: [
|
|
35571
|
+
opened === "opened" ? `Opened ${connectUrl} in your browser.` : `Open ${connectUrl} in your browser.`,
|
|
35572
|
+
"Sign in as a workspace admin if prompted, approve the GitHub",
|
|
35573
|
+
"installation, then return here and run `deepline git repos`."
|
|
35574
|
+
]
|
|
35575
|
+
}
|
|
35576
|
+
]
|
|
35577
|
+
}
|
|
35578
|
+
},
|
|
35579
|
+
{ json: options.json }
|
|
35580
|
+
);
|
|
35581
|
+
}
|
|
35582
|
+
async function handleDeploymentsList(options) {
|
|
35583
|
+
const { http } = getAuthedHttpClient();
|
|
35584
|
+
const query = new URLSearchParams();
|
|
35585
|
+
if (options.repo) query.set("projectId", options.repo);
|
|
35586
|
+
if (options.limit) query.set("limit", options.limit);
|
|
35587
|
+
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
35588
|
+
const payload = await http.get(
|
|
35589
|
+
`/api/v2/deployments${suffix}`
|
|
35590
|
+
);
|
|
35591
|
+
printCommandEnvelope(
|
|
35592
|
+
{
|
|
35593
|
+
deployments: payload.deployments,
|
|
35594
|
+
count: payload.deployments.length,
|
|
35595
|
+
render: {
|
|
35596
|
+
sections: [
|
|
35597
|
+
{
|
|
35598
|
+
title: "deployments",
|
|
35599
|
+
lines: payload.deployments.length ? payload.deployments.map(renderDeployment) : [
|
|
35600
|
+
"No deployments yet. Push to a linked repository to create one."
|
|
35601
|
+
]
|
|
35602
|
+
}
|
|
35603
|
+
]
|
|
35604
|
+
}
|
|
35605
|
+
},
|
|
35606
|
+
{ json: options.json }
|
|
35607
|
+
);
|
|
35608
|
+
}
|
|
35609
|
+
async function handleDeploymentGet(id, options) {
|
|
35610
|
+
const { http } = getAuthedHttpClient();
|
|
35611
|
+
const payload = await http.get(`/api/v2/deployments/${encodeURIComponent(id)}`);
|
|
35612
|
+
const results = payload.deployment.results;
|
|
35613
|
+
const playLines = Array.isArray(results?.plays) ? results.plays.map(
|
|
35614
|
+
(play) => `${play.name ?? "?"} - ${play.status ?? "?"}${play.error ? `: ${play.error}` : ""}`
|
|
35615
|
+
) : [];
|
|
35616
|
+
printCommandEnvelope(
|
|
35617
|
+
{
|
|
35618
|
+
deployment: payload.deployment,
|
|
35619
|
+
project: payload.project,
|
|
35620
|
+
render: {
|
|
35621
|
+
sections: [
|
|
35622
|
+
{
|
|
35623
|
+
title: `deployment ${payload.deployment.id}${payload.project ? ` (${payload.project.repoFullName})` : ""}`,
|
|
35624
|
+
lines: [renderDeployment(payload.deployment)]
|
|
35625
|
+
},
|
|
35626
|
+
...playLines.length ? [{ title: "plays", lines: playLines }] : []
|
|
35627
|
+
]
|
|
35628
|
+
}
|
|
35629
|
+
},
|
|
35630
|
+
{ json: options.json }
|
|
35631
|
+
);
|
|
35632
|
+
}
|
|
35633
|
+
function registerGitCommands(program) {
|
|
35634
|
+
const git = program.command("git").alias("projects").description(
|
|
35635
|
+
"Git deploys: link repositories to this workspace and deploy plays on push."
|
|
35636
|
+
).addHelpText(
|
|
35637
|
+
"after",
|
|
35638
|
+
`
|
|
35639
|
+
Examples:
|
|
35640
|
+
deepline git connect
|
|
35641
|
+
deepline git repos
|
|
35642
|
+
deepline git link acme/growth --branch main
|
|
35643
|
+
deepline git list
|
|
35644
|
+
deepline git set <id> --branch release
|
|
35645
|
+
deepline git unlink <id>
|
|
35646
|
+
deepline git deployments --repo <id>
|
|
35647
|
+
`
|
|
35648
|
+
);
|
|
35649
|
+
git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
|
|
35650
|
+
git.command("repos").description("List repos the workspace's GitHub installation can reach.").option(
|
|
35651
|
+
"--installation <id>",
|
|
35652
|
+
"GitHub installation id (required when several are connected)"
|
|
35653
|
+
).option("--json", "Emit JSON output").action(
|
|
35654
|
+
async (options) => handleRepos(options)
|
|
35655
|
+
);
|
|
35656
|
+
git.command("list").description("List linked repositories.").option("--all", "Include unlinked repositories").option("--json", "Emit JSON output").action(
|
|
35657
|
+
async (options) => handleList(options)
|
|
35658
|
+
);
|
|
35659
|
+
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(
|
|
35660
|
+
"--manifest <file>",
|
|
35661
|
+
"Manifest file name under the base path (default: deepline.json)"
|
|
35662
|
+
).option(
|
|
35663
|
+
"--installation <id>",
|
|
35664
|
+
"GitHub installation id (required when several are connected)"
|
|
35665
|
+
).option("--no-pr-checks", "Skip Check Runs on pull requests").option("--json", "Emit JSON output").action(
|
|
35666
|
+
async (repo, options) => handleLink(repo, options)
|
|
35667
|
+
);
|
|
35668
|
+
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));
|
|
35669
|
+
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(
|
|
35670
|
+
"--manifest <file>",
|
|
35671
|
+
"Manifest file name under the base path (default: deepline.json)"
|
|
35672
|
+
).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(
|
|
35673
|
+
async (id, options) => handleSet(id, {
|
|
35674
|
+
...options,
|
|
35675
|
+
disabled: options.enabled === true ? false : options.disabled === true ? true : void 0
|
|
35676
|
+
})
|
|
35677
|
+
);
|
|
35678
|
+
git.command("unlink").description("Unlink a repository (live plays keep running).").argument("<id>", "Repository link id").option("--json", "Emit JSON output").action(
|
|
35679
|
+
async (id, options) => handleUnlink(id, options)
|
|
35680
|
+
);
|
|
35681
|
+
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(
|
|
35682
|
+
async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
|
|
35683
|
+
);
|
|
35684
|
+
const deployments = program.command("deployments", { hidden: true });
|
|
35685
|
+
deployments.command("list").option("--project <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
|
|
35686
|
+
async (options) => handleDeploymentsList({ ...options, repo: options.project })
|
|
35687
|
+
);
|
|
35688
|
+
deployments.command("get").argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
|
|
35689
|
+
async (id, options) => handleDeploymentGet(id, options)
|
|
35690
|
+
);
|
|
35691
|
+
}
|
|
35692
|
+
|
|
34844
35693
|
// src/cli/getting-started.ts
|
|
34845
35694
|
var DEEPLINE_GTM_SKILL = "/deepline-gtm";
|
|
34846
35695
|
var DEEPLINE_GTM_STARTER_PROMPTS = [
|
|
@@ -35081,7 +35930,7 @@ function preventShellHistoryLeak(forbidden) {
|
|
|
35081
35930
|
);
|
|
35082
35931
|
}
|
|
35083
35932
|
}
|
|
35084
|
-
async function
|
|
35933
|
+
async function handleList2(options) {
|
|
35085
35934
|
const client2 = new DeeplineClient();
|
|
35086
35935
|
const secrets = await client2.listSecrets();
|
|
35087
35936
|
printCommandEnvelope(
|
|
@@ -35124,7 +35973,7 @@ async function handleCheck(nameInput, options) {
|
|
|
35124
35973
|
);
|
|
35125
35974
|
if (!secret) process.exitCode = 4;
|
|
35126
35975
|
}
|
|
35127
|
-
async function
|
|
35976
|
+
async function handleSet2(nameInput, forbidden, options) {
|
|
35128
35977
|
preventShellHistoryLeak(forbidden);
|
|
35129
35978
|
const name = normalizeSecretName(nameInput);
|
|
35130
35979
|
const scope = options.scope === "play" ? "play" : "org";
|
|
@@ -35183,14 +36032,14 @@ Examples:
|
|
|
35183
36032
|
`
|
|
35184
36033
|
);
|
|
35185
36034
|
secrets.command("list").description("List secret metadata only.").option("--json", "Emit JSON output").action(async (options) => {
|
|
35186
|
-
await
|
|
36035
|
+
await handleList2(options);
|
|
35187
36036
|
});
|
|
35188
36037
|
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) => {
|
|
35189
36038
|
await handleCheck(name, options);
|
|
35190
36039
|
});
|
|
35191
36040
|
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(
|
|
35192
36041
|
async (name, forbidden, options) => {
|
|
35193
|
-
await
|
|
36042
|
+
await handleSet2(name, forbidden ?? [], options);
|
|
35194
36043
|
}
|
|
35195
36044
|
);
|
|
35196
36045
|
}
|
|
@@ -36840,7 +37689,7 @@ function failSetupPhase(phases, phase, code) {
|
|
|
36840
37689
|
}
|
|
36841
37690
|
function rollbackCommand(scope, root) {
|
|
36842
37691
|
const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify(join17(root, ".deepline", "runtime"))}` : "";
|
|
36843
|
-
return `npm install -g${prefix} --no-audit --no-fund --include=optional
|
|
37692
|
+
return `npm install -g${prefix} --no-audit --no-fund --include=optional deepline@${SDK_VERSION}`;
|
|
36844
37693
|
}
|
|
36845
37694
|
function setupResumeCommand(baseUrl, scope) {
|
|
36846
37695
|
const hostPrefix = baseUrl === "https://code.deepline.com" ? "" : `DEEPLINE_HOST_URL=${JSON.stringify(baseUrl)} `;
|
|
@@ -37409,9 +38258,7 @@ async function runSetupCommand(options) {
|
|
|
37409
38258
|
title: "setup",
|
|
37410
38259
|
lines: [
|
|
37411
38260
|
workspaceName ? `Deepline is installed and connected to ${workspaceName}.` : "Deepline is installed and connected.",
|
|
37412
|
-
...workspaceName ? [
|
|
37413
|
-
"To link a different workspace, run: deepline auth register"
|
|
37414
|
-
] : [],
|
|
38261
|
+
...workspaceName ? ["To link a different workspace, run: deepline auth register"] : [],
|
|
37415
38262
|
`Use ${DEEPLINE_GTM_SKILL} in your agent.`,
|
|
37416
38263
|
...DEEPLINE_GTM_STARTER_PROMPTS.map(
|
|
37417
38264
|
(example, index) => `${index + 1}. ${example.title}: ${example.prompt}`
|
|
@@ -37778,12 +38625,6 @@ var NPM_SDK_INSTALL_COMMON_FLAGS = [
|
|
|
37778
38625
|
"--no-fund",
|
|
37779
38626
|
"--include=optional"
|
|
37780
38627
|
];
|
|
37781
|
-
var NPM_SDK_GLOBAL_INSTALL_FLAGS = [
|
|
37782
|
-
"--no-audit",
|
|
37783
|
-
"--no-fund",
|
|
37784
|
-
"--include=optional",
|
|
37785
|
-
"--allow-scripts=esbuild"
|
|
37786
|
-
];
|
|
37787
38628
|
var NPM_SDK_SIDECAR_PACKAGE_JSON = `${JSON.stringify(
|
|
37788
38629
|
{
|
|
37789
38630
|
private: true,
|
|
@@ -38018,9 +38859,9 @@ function resolveUpdatePlan(options = {}) {
|
|
|
38018
38859
|
"-g",
|
|
38019
38860
|
"--prefix",
|
|
38020
38861
|
installPrefix,
|
|
38021
|
-
...
|
|
38862
|
+
...NPM_SDK_INSTALL_COMMON_FLAGS,
|
|
38022
38863
|
packageSpec
|
|
38023
|
-
] : ["install", "-g", ...
|
|
38864
|
+
] : ["install", "-g", ...NPM_SDK_INSTALL_COMMON_FLAGS, packageSpec];
|
|
38024
38865
|
const fallbackRegistryUrl = options.npmFallbackRegistryUrl !== void 0 ? options.npmFallbackRegistryUrl : publicNpmFallbackRegistryUrl(
|
|
38025
38866
|
env.DEEPLINE_HOST_URL?.trim() || autoDetectBaseUrl()
|
|
38026
38867
|
);
|
|
@@ -39772,6 +40613,17 @@ function numberValue(value) {
|
|
|
39772
40613
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
39773
40614
|
}
|
|
39774
40615
|
|
|
40616
|
+
// src/cli/tool-connection-status.ts
|
|
40617
|
+
function toolConnectionStatusMessage(input2) {
|
|
40618
|
+
if (input2.credentialStatus === "requires_connection") {
|
|
40619
|
+
return "requires your credentials \u2014 not connected (connect to use)";
|
|
40620
|
+
}
|
|
40621
|
+
if (input2.connected === false && input2.credentialStatus === "managed") {
|
|
40622
|
+
return "temporarily unavailable";
|
|
40623
|
+
}
|
|
40624
|
+
return null;
|
|
40625
|
+
}
|
|
40626
|
+
|
|
39775
40627
|
// src/cli/commands/tools.ts
|
|
39776
40628
|
var TOOL_COMMAND_TEMPLATES = {
|
|
39777
40629
|
describe: "deepline tools describe <toolId>",
|
|
@@ -39896,10 +40748,11 @@ function notConnectedSuffix(tool) {
|
|
|
39896
40748
|
const record2 = tool;
|
|
39897
40749
|
const status = stringField2(record2, "credentialStatus", "credential_status");
|
|
39898
40750
|
const connected = record2.connected;
|
|
39899
|
-
|
|
39900
|
-
|
|
39901
|
-
|
|
39902
|
-
|
|
40751
|
+
const message = toolConnectionStatusMessage({
|
|
40752
|
+
connected: connected === false ? false : void 0,
|
|
40753
|
+
credentialStatus: status || void 0
|
|
40754
|
+
});
|
|
40755
|
+
return message ? ` - \u26A0 ${message}` : "";
|
|
39903
40756
|
}
|
|
39904
40757
|
function shortPricingHint(tool) {
|
|
39905
40758
|
const pricing = recordField2(
|
|
@@ -42449,14 +43302,14 @@ async function handleTransform(id, options) {
|
|
|
42449
43302
|
);
|
|
42450
43303
|
return outcomes.every((o) => o.ok) ? 0 : 1;
|
|
42451
43304
|
}
|
|
42452
|
-
async function
|
|
43305
|
+
async function handleList3(options) {
|
|
42453
43306
|
const limit = options.limit ? Number(options.limit) : void 0;
|
|
42454
43307
|
const result = await client().listWorkflows({
|
|
42455
43308
|
limit: Number.isFinite(limit) ? limit : void 0
|
|
42456
43309
|
});
|
|
42457
43310
|
emitPassThrough("list", result, options);
|
|
42458
43311
|
}
|
|
42459
|
-
async function
|
|
43312
|
+
async function handleGet2(id, options) {
|
|
42460
43313
|
emitPassThrough("get", await client().getWorkflow(id), options);
|
|
42461
43314
|
}
|
|
42462
43315
|
async function handleDelete(id, options) {
|
|
@@ -42575,12 +43428,12 @@ Notes:
|
|
|
42575
43428
|
});
|
|
42576
43429
|
withJsonOption2(
|
|
42577
43430
|
workflows.command("list").description("List workspace workflows.").option("--limit <n>", "Max workflows to return")
|
|
42578
|
-
).action(
|
|
43431
|
+
).action(handleList3);
|
|
42579
43432
|
withJsonOption2(
|
|
42580
43433
|
workflows.command("get <id>").description(
|
|
42581
43434
|
"Fetch a workflow, including its published-revision config."
|
|
42582
43435
|
)
|
|
42583
|
-
).action(
|
|
43436
|
+
).action(handleGet2);
|
|
42584
43437
|
withJsonOption2(
|
|
42585
43438
|
workflows.command("disable <id>").description("Turn a workflow off.")
|
|
42586
43439
|
).action(handleDisable);
|
|
@@ -42633,6 +43486,7 @@ function registerDeeplineCommandGroups(program) {
|
|
|
42633
43486
|
registerBillingCommands(program);
|
|
42634
43487
|
registerMonitorsCommands(program);
|
|
42635
43488
|
registerOrgCommands(program);
|
|
43489
|
+
registerGitCommands(program);
|
|
42636
43490
|
registerEnrichCommand(program);
|
|
42637
43491
|
registerCsvCommands(program);
|
|
42638
43492
|
registerDbCommands(program);
|
|
@@ -42846,97 +43700,6 @@ What changed in ${response.update_summary.version}: ${response.update_summary.su
|
|
|
42846
43700
|
|
|
42847
43701
|
// src/cli/index.ts
|
|
42848
43702
|
var PREFLIGHT_TIMEOUT_MS = 3e3;
|
|
42849
|
-
var ProjectOrgPinRequiredError = class extends Error {
|
|
42850
|
-
code = "PROJECT_ORG_NOT_PINNED";
|
|
42851
|
-
exitCode = 3;
|
|
42852
|
-
payload;
|
|
42853
|
-
constructor(input2) {
|
|
42854
|
-
super("Cloud work is blocked because this project uses global host auth.");
|
|
42855
|
-
this.name = "ProjectOrgPinRequiredError";
|
|
42856
|
-
this.payload = {
|
|
42857
|
-
ok: false,
|
|
42858
|
-
exitCode: this.exitCode,
|
|
42859
|
-
code: this.code,
|
|
42860
|
-
message: this.message,
|
|
42861
|
-
command: input2.command,
|
|
42862
|
-
auth: { scope: "global", source: "host", projectPinned: false },
|
|
42863
|
-
project: { dir: input2.projectDir, pinPath: input2.pinPath },
|
|
42864
|
-
next: "deepline org set --auth-scope folder"
|
|
42865
|
-
};
|
|
42866
|
-
}
|
|
42867
|
-
};
|
|
42868
|
-
function commandUsesOnlyReadOrLocalOperations(command) {
|
|
42869
|
-
const [group, action] = command.split(" ");
|
|
42870
|
-
if ([
|
|
42871
|
-
"auth",
|
|
42872
|
-
"org",
|
|
42873
|
-
"health",
|
|
42874
|
-
"preflight",
|
|
42875
|
-
"version",
|
|
42876
|
-
"update",
|
|
42877
|
-
"skills",
|
|
42878
|
-
"doctor",
|
|
42879
|
-
"quickstart"
|
|
42880
|
-
].includes(group ?? "")) {
|
|
42881
|
-
return true;
|
|
42882
|
-
}
|
|
42883
|
-
if (group === "plays") {
|
|
42884
|
-
return [
|
|
42885
|
-
"check",
|
|
42886
|
-
"get",
|
|
42887
|
-
"list",
|
|
42888
|
-
"search",
|
|
42889
|
-
"grep",
|
|
42890
|
-
"describe",
|
|
42891
|
-
"versions"
|
|
42892
|
-
].includes(action ?? "");
|
|
42893
|
-
}
|
|
42894
|
-
if (group === "runs") {
|
|
42895
|
-
return ["get", "list", "tail", "logs", "export"].includes(action ?? "");
|
|
42896
|
-
}
|
|
42897
|
-
if (group === "tools") {
|
|
42898
|
-
return ["list", "search", "get", "describe"].includes(action ?? "");
|
|
42899
|
-
}
|
|
42900
|
-
if (group === "providers") return ["list", "get"].includes(action ?? "");
|
|
42901
|
-
if (group === "secrets") return ["list", "check"].includes(action ?? "");
|
|
42902
|
-
if (group === "billing")
|
|
42903
|
-
return ["balance", "usage", "history"].includes(action ?? "");
|
|
42904
|
-
return false;
|
|
42905
|
-
}
|
|
42906
|
-
function assertProjectCloudWorkIsPinned(command) {
|
|
42907
|
-
if (process.argv.includes("--dry-run") || commandUsesOnlyReadOrLocalOperations(command)) {
|
|
42908
|
-
return;
|
|
42909
|
-
}
|
|
42910
|
-
const config = resolveConfig();
|
|
42911
|
-
const provenance = resolveCliAuthProvenance(config);
|
|
42912
|
-
if (provenance.scope !== "global" || provenance.project.state !== "project") {
|
|
42913
|
-
return;
|
|
42914
|
-
}
|
|
42915
|
-
throw new ProjectOrgPinRequiredError({
|
|
42916
|
-
command,
|
|
42917
|
-
projectDir: provenance.project.dir,
|
|
42918
|
-
pinPath: provenance.project.pinPath
|
|
42919
|
-
});
|
|
42920
|
-
}
|
|
42921
|
-
function printProjectOrgPinRequiredError(error) {
|
|
42922
|
-
if (shouldEmitJson(process.argv.includes("--json"))) {
|
|
42923
|
-
printJson(error.payload);
|
|
42924
|
-
return;
|
|
42925
|
-
}
|
|
42926
|
-
const project = error.payload.project;
|
|
42927
|
-
process.stderr.write(
|
|
42928
|
-
[
|
|
42929
|
-
"\u2717 Cloud work is blocked in this project",
|
|
42930
|
-
"",
|
|
42931
|
-
" Auth: global host default",
|
|
42932
|
-
" This project is not pinned. Global auth is shared by every unpinned CLI on this machine.",
|
|
42933
|
-
"",
|
|
42934
|
-
" Pin this folder to the current target:",
|
|
42935
|
-
" deepline org set --auth-scope folder",
|
|
42936
|
-
` This writes: ${project.pinPath}`
|
|
42937
|
-
].join("\n") + "\n"
|
|
42938
|
-
);
|
|
42939
|
-
}
|
|
42940
43703
|
function asCommanderError(error) {
|
|
42941
43704
|
if (!(error instanceof Error) || !("code" in error)) {
|
|
42942
43705
|
return null;
|
|
@@ -43247,7 +44010,6 @@ Exit codes:
|
|
|
43247
44010
|
return;
|
|
43248
44011
|
}
|
|
43249
44012
|
const compatibilityCommand = compatibilityCommandPath(actionCommand) || actionCommand.name();
|
|
43250
|
-
assertProjectCloudWorkIsPinned(compatibilityCommand);
|
|
43251
44013
|
if (printStartupPhase) {
|
|
43252
44014
|
progress?.phase("checking sdk compatibility");
|
|
43253
44015
|
}
|
|
@@ -43424,10 +44186,7 @@ Examples:
|
|
|
43424
44186
|
});
|
|
43425
44187
|
progress?.fail();
|
|
43426
44188
|
const wantsJson = process.argv.includes("--json");
|
|
43427
|
-
if (
|
|
43428
|
-
printProjectOrgPinRequiredError(error);
|
|
43429
|
-
process.exitCode = error.exitCode;
|
|
43430
|
-
} else if (commanderError) {
|
|
44189
|
+
if (commanderError) {
|
|
43431
44190
|
if (commanderError.code === "commander.unknownCommand") {
|
|
43432
44191
|
}
|
|
43433
44192
|
process.exitCode = commanderError.code === "commander.unknownCommand" && !wantsJson ? 2 : commanderError.exitCode ?? 1;
|