deepline 0.3.73 → 0.3.75
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/monitor-fleet-contract.ts +1 -1
- 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 +46 -3
- package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +213 -55
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +243 -356
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +18 -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/play-artifact-runtime-contract.ts +62 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +122 -0
- 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 +919 -168
- package/dist/cli/index.mjs +919 -168
- 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 +177 -24
- package/dist/index.d.ts +177 -24
- package/dist/index.js +110 -13
- package/dist/index.mjs +110 -13
- package/dist/install-integrity.json +6 -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.75",
|
|
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
|
*
|
|
@@ -9037,6 +9145,12 @@ async function handleStatus(args) {
|
|
|
9037
9145
|
...payload.workspace.name ? [`Workspace: ${payload.workspace.name}`] : [],
|
|
9038
9146
|
...payload.workspace.slug ? [`Workspace slug: ${payload.workspace.slug}`] : [],
|
|
9039
9147
|
...payload.workspace.id != null ? [`Org ID: ${payload.workspace.id}`] : [],
|
|
9148
|
+
// Switching orgs lives under `deepline org`, but this is where
|
|
9149
|
+
// people look when they discover they are in the wrong
|
|
9150
|
+
// workspace. Without the pointer the reasonable next move is
|
|
9151
|
+
// `deepline auth register`, which re-approves the same account
|
|
9152
|
+
// and leaves the active org unchanged.
|
|
9153
|
+
"Switch workspace: deepline org list, then deepline org set <org-id>",
|
|
9040
9154
|
...payload.user.id != null ? [`User ID: ${payload.user.id}`] : [],
|
|
9041
9155
|
...payload.examples.length > 0 ? [
|
|
9042
9156
|
"Examples:",
|
|
@@ -9068,8 +9182,16 @@ Notes:
|
|
|
9068
9182
|
opening the approval page in Cowork. Use --wait no in CI or agent runs, then
|
|
9069
9183
|
finish with deepline auth wait.
|
|
9070
9184
|
Auth status shows the target host and active workspace without printing secrets.
|
|
9185
|
+
Registering again re-approves the same account; it does not change the active
|
|
9186
|
+
workspace. To switch, use deepline org list and deepline org set <org-id>.
|
|
9071
9187
|
`
|
|
9072
9188
|
);
|
|
9189
|
+
auth.command("workspaces").description("Deprecated. Use deepline org list to see workspaces.").action(() => {
|
|
9190
|
+
console.error(
|
|
9191
|
+
"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."
|
|
9192
|
+
);
|
|
9193
|
+
process.exitCode = 1;
|
|
9194
|
+
});
|
|
9073
9195
|
auth.command("register").description(
|
|
9074
9196
|
"Register this device and open the approval page in your browser."
|
|
9075
9197
|
).addHelpText(
|
|
@@ -9314,6 +9436,18 @@ function billingTopUpFailureFromError(error, input2) {
|
|
|
9314
9436
|
}
|
|
9315
9437
|
return null;
|
|
9316
9438
|
}
|
|
9439
|
+
function normalizeUnixMilliseconds(value) {
|
|
9440
|
+
const timestamp = Math.floor(value);
|
|
9441
|
+
return Number.isFinite(timestamp) && timestamp >= 0 && Number.isFinite(new Date(timestamp).getTime()) ? timestamp : null;
|
|
9442
|
+
}
|
|
9443
|
+
function parseSince(raw) {
|
|
9444
|
+
if (!raw?.trim()) return null;
|
|
9445
|
+
const numeric = Number(raw);
|
|
9446
|
+
const normalizedNumeric = normalizeUnixMilliseconds(numeric);
|
|
9447
|
+
if (normalizedNumeric !== null) return normalizedNumeric;
|
|
9448
|
+
const parsed = Date.parse(raw);
|
|
9449
|
+
return normalizeUnixMilliseconds(parsed);
|
|
9450
|
+
}
|
|
9317
9451
|
function humanize(value) {
|
|
9318
9452
|
return String(value || "").split("_").filter(Boolean).map((token) => token[0]?.toUpperCase() + token.slice(1)).join(" ") || "Unknown";
|
|
9319
9453
|
}
|
|
@@ -9599,6 +9733,18 @@ async function handleHistory(options) {
|
|
|
9599
9733
|
);
|
|
9600
9734
|
}
|
|
9601
9735
|
async function handleLedgerExportAll(options) {
|
|
9736
|
+
const sinceAt = parseSince(options.since);
|
|
9737
|
+
if (options.since && sinceAt === null) {
|
|
9738
|
+
reportBillingFailure(
|
|
9739
|
+
{
|
|
9740
|
+
exitCode: 2,
|
|
9741
|
+
code: "INVALID_SINCE",
|
|
9742
|
+
message: "--since must be an ISO-8601 timestamp or Unix milliseconds."
|
|
9743
|
+
},
|
|
9744
|
+
options
|
|
9745
|
+
);
|
|
9746
|
+
return;
|
|
9747
|
+
}
|
|
9602
9748
|
const { http } = getAuthedHttpClient();
|
|
9603
9749
|
const outputPath = options.output ? (0, import_node_path6.resolve)(String(options.output)) : defaultLedgerExportPath();
|
|
9604
9750
|
let summary = { row_count: 0, net_delta_credits: 0 };
|
|
@@ -9608,6 +9754,8 @@ async function handleLedgerExportAll(options) {
|
|
|
9608
9754
|
const params = new URLSearchParams({ limit: "5000" });
|
|
9609
9755
|
if (cursor !== null) params.set("cursor", cursor);
|
|
9610
9756
|
if (options.runId) params.set("run_id", options.runId);
|
|
9757
|
+
if (options.operation) params.set("operation", options.operation);
|
|
9758
|
+
if (sinceAt !== null) params.set("since_at", String(sinceAt));
|
|
9611
9759
|
const payload = await http.get(
|
|
9612
9760
|
`/api/v2/billing/ledger?${params.toString()}`
|
|
9613
9761
|
);
|
|
@@ -9636,13 +9784,15 @@ async function handleLedgerExportAll(options) {
|
|
|
9636
9784
|
net_delta_credits: summary.net_delta_credits,
|
|
9637
9785
|
scope: "workspace",
|
|
9638
9786
|
...options.runId ? { run_id: options.runId } : {},
|
|
9787
|
+
...options.operation ? { operation: options.operation } : {},
|
|
9788
|
+
...sinceAt !== null ? { since_at: sinceAt } : {},
|
|
9639
9789
|
render: {
|
|
9640
9790
|
sections: [
|
|
9641
9791
|
{
|
|
9642
9792
|
title: "billing ledger",
|
|
9643
9793
|
lines: [
|
|
9644
9794
|
`Billing ledger written to ${outputPath}`,
|
|
9645
|
-
`${summary.row_count} row(s) exported for the active workspace${options.runId ? ` and run ${options.runId}` : ""}.`,
|
|
9795
|
+
`${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
9796
|
`Net ledger delta: ${summary.net_delta_credits} Deepline Credits`
|
|
9647
9797
|
]
|
|
9648
9798
|
}
|
|
@@ -10339,6 +10489,7 @@ Examples:
|
|
|
10339
10489
|
deepline billing ledger export all
|
|
10340
10490
|
deepline billing ledger export all --output ./ledger.csv
|
|
10341
10491
|
deepline billing ledger export all --run-id play/demo/run/abc123
|
|
10492
|
+
deepline billing ledger export all --operation limadata_find_audience_identifiers --since 2026-09-01T00:00:00Z
|
|
10342
10493
|
deepline billing ledger export all --json
|
|
10343
10494
|
`
|
|
10344
10495
|
).addCommand(
|
|
@@ -10360,7 +10511,10 @@ Examples:
|
|
|
10360
10511
|
deepline billing ledger export all
|
|
10361
10512
|
deepline billing ledger export all --json
|
|
10362
10513
|
`
|
|
10363
|
-
).option("--output <path>", "Write CSV to an explicit path").option("--run-id <run_id>", "Export ledger rows for one play run.").option(
|
|
10514
|
+
).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(
|
|
10515
|
+
"--since <timestamp>",
|
|
10516
|
+
"Only export rows since ISO-8601 time or Unix milliseconds."
|
|
10517
|
+
).option(
|
|
10364
10518
|
"--json",
|
|
10365
10519
|
"Emit JSON output. Also automatic when stdout is piped"
|
|
10366
10520
|
).action(handleLedgerExportAll)
|
|
@@ -16634,7 +16788,7 @@ async function traceCliSpan(phase, fields, run) {
|
|
|
16634
16788
|
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
16789
|
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
16790
|
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
|
|
16791
|
+
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
16792
|
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
16793
|
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
16794
|
function sourceLineForError(sourceCode, error) {
|
|
@@ -31595,7 +31749,7 @@ var MONITOR_FLEET_REMOVAL_GRACE_MS = 7 * 24 * 60 * 6e4;
|
|
|
31595
31749
|
var MONITOR_FLEET_DOCUMENTATION = {
|
|
31596
31750
|
summary: "A Monitor Fleet keeps one bounded, sticky set of ordinary monitors aligned with Customer DB rows.",
|
|
31597
31751
|
authoredFields: {
|
|
31598
|
-
id: "Stable lowercase fleet id used by sync,
|
|
31752
|
+
id: "Stable lowercase fleet id used by sync, get, and deactivate.",
|
|
31599
31753
|
source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
|
|
31600
31754
|
member: "Ordinary monitor tool, stable key template, and payload evaluated for each selected source row.",
|
|
31601
31755
|
selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
|
|
@@ -32469,7 +32623,7 @@ function renderDeployedListText(payload, requestedStatus) {
|
|
|
32469
32623
|
return status && count !== void 0 ? [`${status}: ${count}`] : [];
|
|
32470
32624
|
}).join(" ") : "";
|
|
32471
32625
|
if (summary) lines.push(`All lifecycle states: ${summary}`);
|
|
32472
|
-
if (payload.is_truncated === true) {
|
|
32626
|
+
if (payload.has_more === true || payload.is_truncated === true) {
|
|
32473
32627
|
const nextCursor = asString(payload.next_cursor);
|
|
32474
32628
|
lines.push(
|
|
32475
32629
|
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 +32637,15 @@ function renderDeployedListText(payload, requestedStatus) {
|
|
|
32483
32637
|
`;
|
|
32484
32638
|
}
|
|
32485
32639
|
async function handleMonitorsList(options) {
|
|
32640
|
+
if (options.compact) {
|
|
32641
|
+
process.stderr.write(
|
|
32642
|
+
"`--compact` is deprecated and now does nothing; returning the complete monitor records.\n"
|
|
32643
|
+
);
|
|
32644
|
+
}
|
|
32486
32645
|
const payload = await new DeeplineClient().monitors.list({
|
|
32487
32646
|
...options.status ? { status: options.status } : {},
|
|
32488
32647
|
...options.limit ? { limit: options.limit } : {},
|
|
32489
32648
|
...options.cursor ? { cursor: options.cursor } : {},
|
|
32490
|
-
...options.compact ? { compact: true } : {},
|
|
32491
32649
|
...options.includeConsumers ? { includeConsumers: true } : {}
|
|
32492
32650
|
});
|
|
32493
32651
|
printCommandEnvelope(payload, {
|
|
@@ -32598,6 +32756,10 @@ var MONITOR_FLEET_COMMANDS = [
|
|
|
32598
32756
|
{
|
|
32599
32757
|
name: "deactivate",
|
|
32600
32758
|
summary: "Deactivate a fleet and the monitors it owns."
|
|
32759
|
+
},
|
|
32760
|
+
{
|
|
32761
|
+
name: "reactivate",
|
|
32762
|
+
summary: "Explicitly recreate a fleet after a credit-triggered suspension."
|
|
32601
32763
|
}
|
|
32602
32764
|
];
|
|
32603
32765
|
var MONITOR_FLEET_AGENT_NOTES = [
|
|
@@ -33100,6 +33262,72 @@ async function handleMonitorFleetsGet(fleetId, options) {
|
|
|
33100
33262
|
{ json: options.json, text }
|
|
33101
33263
|
);
|
|
33102
33264
|
}
|
|
33265
|
+
function fleetReactivateCommandLine(fleetId, options) {
|
|
33266
|
+
const parts = [
|
|
33267
|
+
"deepline",
|
|
33268
|
+
"monitors",
|
|
33269
|
+
"fleets",
|
|
33270
|
+
"reactivate",
|
|
33271
|
+
fleetShellArg(fleetId),
|
|
33272
|
+
"--yes"
|
|
33273
|
+
];
|
|
33274
|
+
if (options.wait) parts.push("--wait");
|
|
33275
|
+
if (options.timeout)
|
|
33276
|
+
parts.push(`--timeout ${fleetShellArg(options.timeout)}`);
|
|
33277
|
+
if (options.idempotencyKey)
|
|
33278
|
+
parts.push(`--idempotency-key ${fleetShellArg(options.idempotencyKey)}`);
|
|
33279
|
+
parts.push(...fleetJsonFlag(options));
|
|
33280
|
+
return parts.join(" ");
|
|
33281
|
+
}
|
|
33282
|
+
async function handleMonitorFleetsReactivate(fleetId, options, idempotencyKey) {
|
|
33283
|
+
if (!options.yes) {
|
|
33284
|
+
throw new MonitorsUsageError(
|
|
33285
|
+
`reactivate can recreate every suspended provider monitor and restart lifecycle billing. Confirm with --yes:
|
|
33286
|
+
${fleetReactivateCommandLine(fleetId, options)}`
|
|
33287
|
+
);
|
|
33288
|
+
}
|
|
33289
|
+
const client2 = new DeeplineClient();
|
|
33290
|
+
const payload = await client2.monitors.fleets.reactivate(fleetId, {
|
|
33291
|
+
idempotencyKey
|
|
33292
|
+
});
|
|
33293
|
+
const accepted = { ...payload, idempotency_key: idempotencyKey };
|
|
33294
|
+
if (!options.wait) {
|
|
33295
|
+
printCommandEnvelope(accepted, {
|
|
33296
|
+
json: options.json,
|
|
33297
|
+
text: `Fleet ${fleetId} \u2014 ${asString(payload.status) ?? "billing_reactivating"}
|
|
33298
|
+
idempotency key ${idempotencyKey}
|
|
33299
|
+
`
|
|
33300
|
+
});
|
|
33301
|
+
return;
|
|
33302
|
+
}
|
|
33303
|
+
const timeoutMs = fleetTimeoutMs(options.timeout);
|
|
33304
|
+
const progress = fleetProgressReporter();
|
|
33305
|
+
let final;
|
|
33306
|
+
try {
|
|
33307
|
+
final = await client2.monitors.fleets.waitForConvergence(fleetId, {
|
|
33308
|
+
timeoutMs,
|
|
33309
|
+
pollIntervalMs: FLEET_POLL_INTERVAL_MS,
|
|
33310
|
+
onProgress: progress.report
|
|
33311
|
+
});
|
|
33312
|
+
} finally {
|
|
33313
|
+
progress.finish();
|
|
33314
|
+
}
|
|
33315
|
+
const envelope = { ...accepted, ...final };
|
|
33316
|
+
const text = renderFleetGet(final);
|
|
33317
|
+
if (fleetStatus(final) === "converged") {
|
|
33318
|
+
printCommandEnvelope(envelope, { json: options.json, text });
|
|
33319
|
+
return;
|
|
33320
|
+
}
|
|
33321
|
+
reportFleetState(
|
|
33322
|
+
envelope,
|
|
33323
|
+
new MonitorFleetStateError({
|
|
33324
|
+
code: "MONITOR_FLEET_WAIT_TIMEOUT",
|
|
33325
|
+
message: `Stopped waiting after ${timeoutMs}ms. Fleet ${fleetId} recovery is still in progress on the server.`,
|
|
33326
|
+
next: fleetServerNext(final) ?? `deepline monitors fleets get ${fleetShellArg(fleetId)} --json`
|
|
33327
|
+
}),
|
|
33328
|
+
{ json: options.json, text }
|
|
33329
|
+
);
|
|
33330
|
+
}
|
|
33103
33331
|
function fleetDeactivateCommandLine(fleetId, options) {
|
|
33104
33332
|
const parts = [
|
|
33105
33333
|
"deepline monitors fleets deactivate",
|
|
@@ -33397,18 +33625,11 @@ async function handleMonitorsGet(key, options) {
|
|
|
33397
33625
|
}
|
|
33398
33626
|
async function handleMonitorsTest(key, payload, options) {
|
|
33399
33627
|
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;
|
|
33628
|
+
const result = await new DeeplineClient().monitors.test(key, explicitPayload);
|
|
33409
33629
|
const text = `Monitor diagnostic for ${key}: ${result.accepted === true ? "accepted" : "rejected"}
|
|
33410
|
-
|
|
33411
|
-
|
|
33630
|
+
mode: validation_only (no rows written, credits spent, or Plays dispatched)
|
|
33631
|
+
persisted rows: ${asFiniteNumber(result.persisted_rows) ?? 0}
|
|
33632
|
+
dispatched bound Plays: ${asFiniteNumber(result.dispatched_bound_plays) ?? 0}
|
|
33412
33633
|
`;
|
|
33413
33634
|
printCommandEnvelope(result, { json: options.json, text });
|
|
33414
33635
|
}
|
|
@@ -33488,6 +33709,206 @@ async function handleMonitorsReactivate(key, options) {
|
|
|
33488
33709
|
const payload = await client2.monitors.reactivate(key);
|
|
33489
33710
|
printCommandEnvelope(payload, { json: options.json });
|
|
33490
33711
|
}
|
|
33712
|
+
var MONITOR_VERB_POLL_INTERVAL_MS = 2e3;
|
|
33713
|
+
function monitorHealthLine(health) {
|
|
33714
|
+
return [
|
|
33715
|
+
`converged ${health.converged}/${health.scanned}`,
|
|
33716
|
+
`needs_repair ${health.needs_repair}`,
|
|
33717
|
+
`missing ${health.observed.missing}`,
|
|
33718
|
+
`unaudited ${health.observed.unknown + health.observed.unset}`,
|
|
33719
|
+
`silent ${health.silent}`
|
|
33720
|
+
].join(" \xB7 ");
|
|
33721
|
+
}
|
|
33722
|
+
function monitorVerbProgressReporter() {
|
|
33723
|
+
const interactive = process.stderr.isTTY === true;
|
|
33724
|
+
let wrote = false;
|
|
33725
|
+
let lastPlainAt = 0;
|
|
33726
|
+
return {
|
|
33727
|
+
report: (health) => {
|
|
33728
|
+
const line = monitorHealthLine(health);
|
|
33729
|
+
if (interactive) {
|
|
33730
|
+
process.stderr.write(`\r\x1B[2K${line}`);
|
|
33731
|
+
wrote = true;
|
|
33732
|
+
return;
|
|
33733
|
+
}
|
|
33734
|
+
const now = Date.now();
|
|
33735
|
+
if (wrote && now - lastPlainAt < FLEET_PLAIN_PROGRESS_INTERVAL_MS) return;
|
|
33736
|
+
lastPlainAt = now;
|
|
33737
|
+
wrote = true;
|
|
33738
|
+
process.stderr.write(`${line}
|
|
33739
|
+
`);
|
|
33740
|
+
},
|
|
33741
|
+
finish: () => {
|
|
33742
|
+
if (interactive && wrote) process.stderr.write("\n");
|
|
33743
|
+
}
|
|
33744
|
+
};
|
|
33745
|
+
}
|
|
33746
|
+
async function watchMonitorHealth(input2) {
|
|
33747
|
+
const deadlineAt = Date.now() + input2.timeoutMs;
|
|
33748
|
+
const scope = input2.fleetId ? { fleetId: input2.fleetId } : {};
|
|
33749
|
+
let last = await input2.client.monitors.health(scope);
|
|
33750
|
+
input2.onProgress(last);
|
|
33751
|
+
while (Date.now() < deadlineAt) {
|
|
33752
|
+
if (last.needs_repair === 0 && last.observed.unknown === 0) return last;
|
|
33753
|
+
await new Promise(
|
|
33754
|
+
(resolve21) => setTimeout(resolve21, MONITOR_VERB_POLL_INTERVAL_MS)
|
|
33755
|
+
);
|
|
33756
|
+
last = await input2.client.monitors.health(scope);
|
|
33757
|
+
input2.onProgress(last);
|
|
33758
|
+
}
|
|
33759
|
+
return last;
|
|
33760
|
+
}
|
|
33761
|
+
function monitorHealthText(health) {
|
|
33762
|
+
const partial = health.truncated ? " (partial \u2014 scope larger than one read)" : "";
|
|
33763
|
+
const lines = [
|
|
33764
|
+
`scope: ${health.scope.fleet_id ?? "workspace"}${partial}`,
|
|
33765
|
+
monitorHealthLine(health)
|
|
33766
|
+
];
|
|
33767
|
+
if (health.deactivation_reasons.length > 0) {
|
|
33768
|
+
lines.push("");
|
|
33769
|
+
lines.push("deactivated by Deepline:");
|
|
33770
|
+
for (const entry of health.deactivation_reasons) {
|
|
33771
|
+
const how = entry.resolution ? ` \u2014 ${entry.resolution}` : "";
|
|
33772
|
+
lines.push(` ${entry.reason} (${entry.count})${how}`);
|
|
33773
|
+
}
|
|
33774
|
+
}
|
|
33775
|
+
if (health.worst_offenders.length > 0) {
|
|
33776
|
+
lines.push("");
|
|
33777
|
+
lines.push(
|
|
33778
|
+
`silent longest (no delivery in ${health.silent_window_days}d):`
|
|
33779
|
+
);
|
|
33780
|
+
for (const entry of health.worst_offenders) {
|
|
33781
|
+
const when = entry.last_event_at === null ? "never" : new Date(entry.last_event_at).toISOString();
|
|
33782
|
+
lines.push(` ${entry.monitor_key} ${entry.tool} last event ${when}`);
|
|
33783
|
+
}
|
|
33784
|
+
}
|
|
33785
|
+
return `${lines.join("\n")}
|
|
33786
|
+
`;
|
|
33787
|
+
}
|
|
33788
|
+
async function handleMonitorsAudit(options) {
|
|
33789
|
+
const client2 = new DeeplineClient();
|
|
33790
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33791
|
+
const scope = fleetId ? { fleetId } : {};
|
|
33792
|
+
let result = await client2.monitors.audit(scope);
|
|
33793
|
+
const passes = [result.audit];
|
|
33794
|
+
while (result.audit.cursor !== null) {
|
|
33795
|
+
result = await client2.monitors.audit({
|
|
33796
|
+
...scope,
|
|
33797
|
+
cursor: result.audit.cursor
|
|
33798
|
+
});
|
|
33799
|
+
passes.push(result.audit);
|
|
33800
|
+
}
|
|
33801
|
+
const totals = passes.reduce(
|
|
33802
|
+
(sum, pass) => ({
|
|
33803
|
+
scanned: sum.scanned + pass.scanned,
|
|
33804
|
+
asked: sum.asked + pass.asked,
|
|
33805
|
+
stale: sum.stale + pass.stale,
|
|
33806
|
+
missing: sum.missing + pass.observed.missing
|
|
33807
|
+
}),
|
|
33808
|
+
{ scanned: 0, asked: 0, stale: 0, missing: 0 }
|
|
33809
|
+
);
|
|
33810
|
+
let health = result.health;
|
|
33811
|
+
if (options.watch) {
|
|
33812
|
+
const progress = monitorVerbProgressReporter();
|
|
33813
|
+
try {
|
|
33814
|
+
health = await watchMonitorHealth({
|
|
33815
|
+
client: client2,
|
|
33816
|
+
...scope,
|
|
33817
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
33818
|
+
onProgress: progress.report
|
|
33819
|
+
});
|
|
33820
|
+
} finally {
|
|
33821
|
+
progress.finish();
|
|
33822
|
+
}
|
|
33823
|
+
}
|
|
33824
|
+
const unauditable = result.audit.unauditable_capabilities;
|
|
33825
|
+
const overtaken = totals.stale > 0 ? ` \xB7 ${totals.stale} observations overtaken by a concurrent settle` : "";
|
|
33826
|
+
const text = [
|
|
33827
|
+
`audited ${totals.scanned} monitors \xB7 asked the provider about ${totals.asked}`,
|
|
33828
|
+
`missing ${totals.missing}${overtaken}`,
|
|
33829
|
+
...unauditable.length > 0 ? [`not auditable (no batch-read contract): ${unauditable.join(", ")}`] : [],
|
|
33830
|
+
"",
|
|
33831
|
+
monitorHealthText(health)
|
|
33832
|
+
].join("\n");
|
|
33833
|
+
printCommandEnvelope(
|
|
33834
|
+
{ ...result, audit: { ...result.audit, totals }, health },
|
|
33835
|
+
{ json: options.json, text }
|
|
33836
|
+
);
|
|
33837
|
+
}
|
|
33838
|
+
async function handleMonitorsRepair(options) {
|
|
33839
|
+
const client2 = new DeeplineClient();
|
|
33840
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33841
|
+
const scope = fleetId ? { fleetId } : {};
|
|
33842
|
+
const result = await client2.monitors.repair({
|
|
33843
|
+
...scope,
|
|
33844
|
+
...options.dryRun ? { dryRun: true } : {}
|
|
33845
|
+
});
|
|
33846
|
+
if (options.dryRun) {
|
|
33847
|
+
assertMonitorDryRunAcknowledged(
|
|
33848
|
+
result,
|
|
33849
|
+
{ command: "monitors repair", mutation: "repair" }
|
|
33850
|
+
);
|
|
33851
|
+
}
|
|
33852
|
+
let health = result.health;
|
|
33853
|
+
if (options.watch && !options.dryRun) {
|
|
33854
|
+
const progress = monitorVerbProgressReporter();
|
|
33855
|
+
try {
|
|
33856
|
+
health = await watchMonitorHealth({
|
|
33857
|
+
client: client2,
|
|
33858
|
+
...scope,
|
|
33859
|
+
timeoutMs: fleetTimeoutMs(options.timeout),
|
|
33860
|
+
onProgress: progress.report
|
|
33861
|
+
});
|
|
33862
|
+
} finally {
|
|
33863
|
+
progress.finish();
|
|
33864
|
+
}
|
|
33865
|
+
}
|
|
33866
|
+
const verb = options.dryRun ? "would queue" : "queued";
|
|
33867
|
+
const lines = [
|
|
33868
|
+
`${verb} ${result.repair.queued} of ${result.repair.scanned} monitors`
|
|
33869
|
+
];
|
|
33870
|
+
for (const item of result.repair.plan.slice(0, REPAIR_PLAN_PREVIEW)) {
|
|
33871
|
+
const why = item.deactivation_reason ? ` \xB7 ${item.deactivation_reason}` : "";
|
|
33872
|
+
lines.push(
|
|
33873
|
+
` ${item.action.padEnd(6)} ${item.monitor_key} desired ${item.desired} \xB7 observed ${item.observed}${why}`
|
|
33874
|
+
);
|
|
33875
|
+
}
|
|
33876
|
+
if (result.repair.plan.length > REPAIR_PLAN_PREVIEW) {
|
|
33877
|
+
lines.push(` \u2026 ${result.repair.plan.length - REPAIR_PLAN_PREVIEW} more`);
|
|
33878
|
+
}
|
|
33879
|
+
if (result.repair.unaudited.length > 0) {
|
|
33880
|
+
lines.push(
|
|
33881
|
+
`${result.repair.unaudited.length} monitors have never been observed \u2014 run 'deepline monitors audit' first.`
|
|
33882
|
+
);
|
|
33883
|
+
}
|
|
33884
|
+
if (result.repair.unowned.length > 0) {
|
|
33885
|
+
lines.push(
|
|
33886
|
+
`${result.repair.unowned.length} monitors disagree but no fleet owns them; repair those with 'deepline monitors deploy' or 'deepline monitors delete'.`
|
|
33887
|
+
);
|
|
33888
|
+
}
|
|
33889
|
+
if (result.repair.fenced.length > 0) {
|
|
33890
|
+
lines.push(
|
|
33891
|
+
`${result.repair.fenced.length} monitors have a provider operation in flight; Deepline is finishing those and repair left them alone.`
|
|
33892
|
+
);
|
|
33893
|
+
}
|
|
33894
|
+
lines.push("");
|
|
33895
|
+
lines.push(monitorHealthText(health));
|
|
33896
|
+
printCommandEnvelope(
|
|
33897
|
+
{ ...result, health },
|
|
33898
|
+
{ json: options.json, text: lines.join("\n") }
|
|
33899
|
+
);
|
|
33900
|
+
}
|
|
33901
|
+
var REPAIR_PLAN_PREVIEW = 20;
|
|
33902
|
+
async function handleMonitorsHealth(options) {
|
|
33903
|
+
const fleetId = options.fleet?.trim() || void 0;
|
|
33904
|
+
const health = await new DeeplineClient().monitors.health(
|
|
33905
|
+
fleetId ? { fleetId } : {}
|
|
33906
|
+
);
|
|
33907
|
+
printCommandEnvelope(health, {
|
|
33908
|
+
json: options.json,
|
|
33909
|
+
text: monitorHealthText(health)
|
|
33910
|
+
});
|
|
33911
|
+
}
|
|
33491
33912
|
function registerMonitorsCommands(program) {
|
|
33492
33913
|
const monitors = program.command("monitors").description("Discover, deploy, and manage Deepline monitors.").showSuggestionAfterError(true).addHelpText(
|
|
33493
33914
|
"after",
|
|
@@ -33523,6 +33944,75 @@ Examples:
|
|
|
33523
33944
|
deepline monitors reactivate my-monitor --dry-run
|
|
33524
33945
|
`
|
|
33525
33946
|
);
|
|
33947
|
+
withJsonOption(
|
|
33948
|
+
monitors.command("audit").description(
|
|
33949
|
+
"Re-read what the provider actually holds for your monitors."
|
|
33950
|
+
).option("--fleet <fleet-id>", "Audit one fleet instead of every monitor").option("--watch", "Keep polling health until the scope settles").option(
|
|
33951
|
+
"--timeout <duration>",
|
|
33952
|
+
"How long --watch waits, e.g. 90s, 5m, 1h (default 10m)"
|
|
33953
|
+
).addHelpText(
|
|
33954
|
+
"after",
|
|
33955
|
+
`
|
|
33956
|
+
Notes:
|
|
33957
|
+
Asks the provider, by resource id, what it still holds, and records the answer
|
|
33958
|
+
on each monitor. It changes nothing upstream: no creates, no deletes, no
|
|
33959
|
+
intent. Safe to run at any time, as often as you like \u2014 running it twice is
|
|
33960
|
+
running it once, twice.
|
|
33961
|
+
|
|
33962
|
+
A monitor the provider does not return is recorded "missing". Use
|
|
33963
|
+
'deepline monitors repair' to act on that.
|
|
33964
|
+
|
|
33965
|
+
Examples:
|
|
33966
|
+
deepline monitors audit
|
|
33967
|
+
deepline monitors audit --fleet accounts-eu --json
|
|
33968
|
+
deepline monitors audit --fleet accounts-eu --watch --timeout 5m
|
|
33969
|
+
`
|
|
33970
|
+
)
|
|
33971
|
+
).action(monitorsAction(handleMonitorsAudit));
|
|
33972
|
+
withJsonOption(
|
|
33973
|
+
monitors.command("repair").description(
|
|
33974
|
+
"Converge the monitors whose desired and observed states disagree."
|
|
33975
|
+
).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(
|
|
33976
|
+
"--timeout <duration>",
|
|
33977
|
+
"How long --watch waits, e.g. 90s, 5m, 1h (default 10m)"
|
|
33978
|
+
).addHelpText(
|
|
33979
|
+
"after",
|
|
33980
|
+
`
|
|
33981
|
+
Notes:
|
|
33982
|
+
Queues the monitors that disagree with the provider onto the same convergence
|
|
33983
|
+
loop a fleet sync uses; the provider work happens on Deepline's own schedule.
|
|
33984
|
+
Idempotent \u2014 the queue IS the disagreement, so a repeat run queues only what
|
|
33985
|
+
is still wrong.
|
|
33986
|
+
|
|
33987
|
+
Monitors nobody has observed are never repaired: run 'deepline monitors audit'
|
|
33988
|
+
first. Monitors no fleet owns are reported rather than queued; deploy or delete
|
|
33989
|
+
those directly.
|
|
33990
|
+
|
|
33991
|
+
Examples:
|
|
33992
|
+
deepline monitors repair --dry-run
|
|
33993
|
+
deepline monitors repair --fleet accounts-eu --watch
|
|
33994
|
+
`
|
|
33995
|
+
)
|
|
33996
|
+
).action(monitorsAction(handleMonitorsRepair));
|
|
33997
|
+
withJsonOption(
|
|
33998
|
+
monitors.command("health").description("Delivery and convergence health for your monitors.").option(
|
|
33999
|
+
"--fleet <fleet-id>",
|
|
34000
|
+
"Report on one fleet instead of every monitor"
|
|
34001
|
+
).addHelpText(
|
|
34002
|
+
"after",
|
|
34003
|
+
`
|
|
34004
|
+
Notes:
|
|
34005
|
+
Read-only. Reports how many monitors the provider holds as asked, how many
|
|
34006
|
+
disagree, how many Deepline deactivated and why, and how many are "silent" \u2014
|
|
34007
|
+
the provider holds them but nothing has been delivered recently. The worst
|
|
34008
|
+
offenders are listed longest-quiet first.
|
|
34009
|
+
|
|
34010
|
+
Examples:
|
|
34011
|
+
deepline monitors health
|
|
34012
|
+
deepline monitors health --fleet accounts-eu --json
|
|
34013
|
+
`
|
|
34014
|
+
)
|
|
34015
|
+
).action(monitorsAction(handleMonitorsHealth));
|
|
33526
34016
|
withJsonOption(
|
|
33527
34017
|
monitors.command("status").description("Check whether you have access to Deepline monitors.").addHelpText(
|
|
33528
34018
|
"after",
|
|
@@ -33575,10 +34065,10 @@ Examples:
|
|
|
33575
34065
|
`
|
|
33576
34066
|
Notes:
|
|
33577
34067
|
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
|
|
34068
|
+
all. The output echoes the status filter that was applied. The response reports
|
|
34069
|
+
total (the true registry count, not the page size), returned, has_more, and
|
|
34070
|
+
next_cursor. When has_more is true, page with --cursor <next_cursor> until it
|
|
34071
|
+
is false \u2014 a "no matching
|
|
33582
34072
|
monitor" reuse conclusion off a truncated page deploys a duplicate paid feed.
|
|
33583
34073
|
The default list stays cheap: it includes the current downstream Play binding
|
|
33584
34074
|
metadata but does not resolve per-monitor delivery/run health. Pass
|
|
@@ -33589,7 +34079,6 @@ Examples:
|
|
|
33589
34079
|
deepline monitors list
|
|
33590
34080
|
deepline monitors list --status all --json
|
|
33591
34081
|
deepline monitors list --status all --cursor <next_cursor> --json
|
|
33592
|
-
deepline monitors list --compact --json
|
|
33593
34082
|
deepline monitors list --include-consumers --limit 20 --json
|
|
33594
34083
|
`
|
|
33595
34084
|
).option(
|
|
@@ -33598,7 +34087,10 @@ Examples:
|
|
|
33598
34087
|
).option("--limit <n>", "Limit the number of deployed monitors returned").option(
|
|
33599
34088
|
"--cursor <cursor>",
|
|
33600
34089
|
"Page past a truncated result using the next_cursor from a prior list response"
|
|
33601
|
-
).option(
|
|
34090
|
+
).option(
|
|
34091
|
+
"--compact",
|
|
34092
|
+
"Deprecated no-op; complete records are always returned"
|
|
34093
|
+
).option(
|
|
33602
34094
|
"--include-consumers",
|
|
33603
34095
|
"Include current SQL-listener consumer health (requires --limit 20 or fewer)"
|
|
33604
34096
|
)
|
|
@@ -33621,10 +34113,7 @@ Examples:
|
|
|
33621
34113
|
).action(monitorsAction(handleMonitorsGet));
|
|
33622
34114
|
withJsonOption(
|
|
33623
34115
|
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)"
|
|
34116
|
+
"Validate an explicit payload against a monitor\u2019s webhook contract."
|
|
33628
34117
|
).addHelpText(
|
|
33629
34118
|
"after",
|
|
33630
34119
|
`
|
|
@@ -33632,9 +34121,8 @@ Notes:
|
|
|
33632
34121
|
<payload> must be an explicit JSON object. The command uses the deployed
|
|
33633
34122
|
monitor\u2019s real binding and payload validation, but is a side-effect-free
|
|
33634
34123
|
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.
|
|
34124
|
+
monitor state. It does not synthesize a provider event or accept an omitted
|
|
34125
|
+
payload.
|
|
33638
34126
|
|
|
33639
34127
|
Examples:
|
|
33640
34128
|
deepline monitors test rb2b-website-visitors '{"LinkedIn URL":"https://www.linkedin.com/in/example","Website":"https://example.com"}' --json
|
|
@@ -33951,6 +34439,40 @@ Examples:
|
|
|
33951
34439
|
reportMonitorsFailure(error, { retryCommand });
|
|
33952
34440
|
}
|
|
33953
34441
|
});
|
|
34442
|
+
withJsonOption(
|
|
34443
|
+
fleets.command("reactivate <fleet-id>").description(
|
|
34444
|
+
"Explicitly recreate a fleet after a credit-triggered suspension."
|
|
34445
|
+
).addHelpText(
|
|
34446
|
+
"after",
|
|
34447
|
+
`
|
|
34448
|
+
Notes:
|
|
34449
|
+
TAMRadar cannot reactivate a deleted radar. This command starts normal,
|
|
34450
|
+
fenced provider creates from the fleet's retained desired definitions and
|
|
34451
|
+
may restart lifecycle billing. A credit top-up alone never does this.
|
|
34452
|
+
|
|
34453
|
+
Example:
|
|
34454
|
+
deepline monitors fleets reactivate account-job-openings --yes --wait --json
|
|
34455
|
+
`
|
|
34456
|
+
).option("--wait", "Poll until the fleet reports converged").option(
|
|
34457
|
+
"--timeout <duration>",
|
|
34458
|
+
"How long --wait may poll: 500ms, 90s, 10m, 1h (default 10m)"
|
|
34459
|
+
).option("--yes", "Confirm recreating suspended provider monitors").option("--idempotency-key <key>", "Stable retry key")
|
|
34460
|
+
).action(async (fleetId, options) => {
|
|
34461
|
+
let retryCommand = fleetReactivateCommandLine(fleetId, options);
|
|
34462
|
+
try {
|
|
34463
|
+
const idempotencyKey = fleetIdempotencyKey(
|
|
34464
|
+
"reactivate",
|
|
34465
|
+
options.idempotencyKey
|
|
34466
|
+
);
|
|
34467
|
+
retryCommand = fleetReactivateCommandLine(fleetId, {
|
|
34468
|
+
...options,
|
|
34469
|
+
idempotencyKey
|
|
34470
|
+
});
|
|
34471
|
+
await handleMonitorFleetsReactivate(fleetId, options, idempotencyKey);
|
|
34472
|
+
} catch (error) {
|
|
34473
|
+
reportMonitorsFailure(error, { retryCommand });
|
|
34474
|
+
}
|
|
34475
|
+
});
|
|
33954
34476
|
const deployed = withJsonOption(
|
|
33955
34477
|
monitors.command("deployed", { hidden: true }).description("Alias of `monitors list` (plus get/update/delete aliases).").option(
|
|
33956
34478
|
"--status <status>",
|
|
@@ -33958,7 +34480,10 @@ Examples:
|
|
|
33958
34480
|
).option("--limit <n>", "Limit the number of deployed monitors returned").option(
|
|
33959
34481
|
"--cursor <cursor>",
|
|
33960
34482
|
"Page past a truncated result using the next_cursor from a prior list response"
|
|
33961
|
-
).option(
|
|
34483
|
+
).option(
|
|
34484
|
+
"--compact",
|
|
34485
|
+
"Deprecated no-op; complete records are always returned"
|
|
34486
|
+
).option(
|
|
33962
34487
|
"--include-consumers",
|
|
33963
34488
|
"Include current SQL-listener consumer health (requires --limit 20 or fewer)"
|
|
33964
34489
|
)
|
|
@@ -34280,11 +34805,13 @@ async function handleOrgStatus(options) {
|
|
|
34280
34805
|
host_env_path: hostPath,
|
|
34281
34806
|
folder_target: folderTargetPayload,
|
|
34282
34807
|
project_pin: provenance.scope === "global" && provenance.project.state === "project" ? {
|
|
34283
|
-
|
|
34808
|
+
available: true,
|
|
34809
|
+
required: false,
|
|
34284
34810
|
path: provenance.project.pinPath,
|
|
34285
|
-
cloud_mutations_blocked:
|
|
34811
|
+
cloud_mutations_blocked: false,
|
|
34286
34812
|
command: "deepline org set --auth-scope folder"
|
|
34287
34813
|
} : {
|
|
34814
|
+
available: false,
|
|
34288
34815
|
required: false,
|
|
34289
34816
|
cloud_mutations_blocked: false
|
|
34290
34817
|
},
|
|
@@ -34705,8 +35232,8 @@ Examples:
|
|
|
34705
35232
|
Notes:
|
|
34706
35233
|
Selection can be a list number, exact organization name, or organization id.
|
|
34707
35234
|
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
|
-
|
|
35235
|
+
project is using global host auth, it pins the current target directly
|
|
35236
|
+
without an additional organization lookup.
|
|
34710
35237
|
|
|
34711
35238
|
Mutates local auth state and asks Deepline for an org-scoped API key. It
|
|
34712
35239
|
writes only the selected scope:
|
|
@@ -34723,7 +35250,9 @@ Notes:
|
|
|
34723
35250
|
|
|
34724
35251
|
Prefer --auth-scope folder for a repository or customer workspace. Use
|
|
34725
35252
|
--auth-scope global only for deliberate host-wide interactive defaults; it
|
|
34726
|
-
is shared by every unpinned CLI on this machine.
|
|
35253
|
+
is shared by every unpinned CLI on this machine. Global auth remains
|
|
35254
|
+
supported in projects; use a folder pin when you want a project-specific
|
|
35255
|
+
default. For automation, pass
|
|
34727
35256
|
DEEPLINE_API_KEY only to that invocation and confirm with org status --json.
|
|
34728
35257
|
|
|
34729
35258
|
Use --json for stable fields including effective_auth_scope,
|
|
@@ -34766,6 +35295,318 @@ Examples:
|
|
|
34766
35295
|
);
|
|
34767
35296
|
}
|
|
34768
35297
|
|
|
35298
|
+
// src/cli/commands/git.ts
|
|
35299
|
+
function renderProject(project) {
|
|
35300
|
+
const root = project.rootDirectory ? ` (${project.rootDirectory})` : "";
|
|
35301
|
+
const flags = [
|
|
35302
|
+
project.disabled ? "unlinked" : "linked",
|
|
35303
|
+
`deploys ${project.productionBranch}`,
|
|
35304
|
+
project.checkOnPullRequest ? "PR checks on" : "PR checks off"
|
|
35305
|
+
].join(", ");
|
|
35306
|
+
return `${project.id} ${project.repoFullName}${root} - ${flags}`;
|
|
35307
|
+
}
|
|
35308
|
+
function renderDeployment(deployment) {
|
|
35309
|
+
const ref = deployment.ref.replace("refs/heads/", "");
|
|
35310
|
+
const kind = deployment.isProduction ? "production" : deployment.trigger === "pull_request" ? `pr #${deployment.pullRequestNumber ?? "?"}` : deployment.trigger;
|
|
35311
|
+
const suffix = deployment.error ? ` - ${deployment.error.slice(0, 80)}` : "";
|
|
35312
|
+
return `${deployment.id} ${deployment.commitSha.slice(0, 10)} ${ref} (${kind}) - ${deployment.status}${suffix}`;
|
|
35313
|
+
}
|
|
35314
|
+
async function handleList(options) {
|
|
35315
|
+
const { http } = getAuthedHttpClient();
|
|
35316
|
+
const payload = await http.get(
|
|
35317
|
+
`/api/v2/play-projects${options.all ? "?includeDisabled=1" : ""}`
|
|
35318
|
+
);
|
|
35319
|
+
printCommandEnvelope(
|
|
35320
|
+
{
|
|
35321
|
+
projects: payload.projects,
|
|
35322
|
+
count: payload.projects.length,
|
|
35323
|
+
render: {
|
|
35324
|
+
sections: [
|
|
35325
|
+
{
|
|
35326
|
+
title: "linked repositories",
|
|
35327
|
+
lines: payload.projects.length ? payload.projects.map(renderProject) : [
|
|
35328
|
+
"No repositories are linked. Run `deepline git repos` to see what the GitHub installation can reach, then `deepline git link`."
|
|
35329
|
+
]
|
|
35330
|
+
}
|
|
35331
|
+
]
|
|
35332
|
+
}
|
|
35333
|
+
},
|
|
35334
|
+
{ json: options.json }
|
|
35335
|
+
);
|
|
35336
|
+
}
|
|
35337
|
+
async function handleRepos(options) {
|
|
35338
|
+
const { http } = getAuthedHttpClient();
|
|
35339
|
+
const query = options.installation ? `?installationId=${encodeURIComponent(options.installation)}` : "";
|
|
35340
|
+
const payload = await http.get(`/api/v2/github/repos${query}`);
|
|
35341
|
+
printCommandEnvelope(
|
|
35342
|
+
{
|
|
35343
|
+
installation: payload.installation,
|
|
35344
|
+
repositories: payload.repositories,
|
|
35345
|
+
count: payload.repositories.length,
|
|
35346
|
+
render: {
|
|
35347
|
+
sections: [
|
|
35348
|
+
{
|
|
35349
|
+
title: `repos on installation @${payload.installation.accountLogin} (${payload.installation.repositorySelection})`,
|
|
35350
|
+
lines: payload.repositories.map(
|
|
35351
|
+
(repo) => `${repo.repoId} ${repo.fullName} (default: ${repo.defaultBranch}${repo.private ? ", private" : ""}${repo.fork ? ", fork" : ""})`
|
|
35352
|
+
)
|
|
35353
|
+
}
|
|
35354
|
+
]
|
|
35355
|
+
}
|
|
35356
|
+
},
|
|
35357
|
+
{ json: options.json }
|
|
35358
|
+
);
|
|
35359
|
+
}
|
|
35360
|
+
async function resolveRepoId(repo, installation) {
|
|
35361
|
+
if (/^\d+$/.test(repo)) return Number(repo);
|
|
35362
|
+
const { http } = getAuthedHttpClient();
|
|
35363
|
+
const query = installation ? `?installationId=${encodeURIComponent(installation)}` : "";
|
|
35364
|
+
const payload = await http.get(
|
|
35365
|
+
`/api/v2/github/repos${query}`
|
|
35366
|
+
);
|
|
35367
|
+
const match = payload.repositories.find(
|
|
35368
|
+
(entry) => entry.fullName.toLowerCase() === repo.toLowerCase()
|
|
35369
|
+
);
|
|
35370
|
+
if (!match) {
|
|
35371
|
+
throw new Error(
|
|
35372
|
+
`Repo "${repo}" is not accessible to the workspace's GitHub installation. Run \`deepline git repos\` to list what is.`
|
|
35373
|
+
);
|
|
35374
|
+
}
|
|
35375
|
+
return match.repoId;
|
|
35376
|
+
}
|
|
35377
|
+
async function handleLink(repo, options) {
|
|
35378
|
+
const repoId = await resolveRepoId(repo, options.installation);
|
|
35379
|
+
const { http } = getAuthedHttpClient();
|
|
35380
|
+
const payload = await http.post("/api/v2/play-projects", {
|
|
35381
|
+
repoId,
|
|
35382
|
+
...options.installation !== void 0 ? { installationId: options.installation } : {},
|
|
35383
|
+
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
35384
|
+
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
35385
|
+
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
35386
|
+
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {}
|
|
35387
|
+
});
|
|
35388
|
+
printCommandEnvelope(
|
|
35389
|
+
{
|
|
35390
|
+
project: payload.project,
|
|
35391
|
+
render: {
|
|
35392
|
+
sections: [
|
|
35393
|
+
{
|
|
35394
|
+
title: "linked",
|
|
35395
|
+
lines: [
|
|
35396
|
+
renderProject(payload.project),
|
|
35397
|
+
...(payload.warnings ?? []).map(
|
|
35398
|
+
(warning) => `WARNING: ${warning}`
|
|
35399
|
+
),
|
|
35400
|
+
"Pushes to the production branch now register and promote changed plays.",
|
|
35401
|
+
"Anyone who can push to this repo can change what runs in this workspace."
|
|
35402
|
+
]
|
|
35403
|
+
}
|
|
35404
|
+
]
|
|
35405
|
+
}
|
|
35406
|
+
},
|
|
35407
|
+
{ json: options.json }
|
|
35408
|
+
);
|
|
35409
|
+
}
|
|
35410
|
+
async function handleGet(id, options) {
|
|
35411
|
+
const { http } = getAuthedHttpClient();
|
|
35412
|
+
const payload = await http.get(
|
|
35413
|
+
`/api/v2/play-projects/${encodeURIComponent(id)}`
|
|
35414
|
+
);
|
|
35415
|
+
printCommandEnvelope(
|
|
35416
|
+
{
|
|
35417
|
+
project: payload.project,
|
|
35418
|
+
render: {
|
|
35419
|
+
sections: [
|
|
35420
|
+
{
|
|
35421
|
+
title: "linked repository",
|
|
35422
|
+
lines: [renderProject(payload.project)]
|
|
35423
|
+
}
|
|
35424
|
+
]
|
|
35425
|
+
}
|
|
35426
|
+
},
|
|
35427
|
+
{ json: options.json }
|
|
35428
|
+
);
|
|
35429
|
+
}
|
|
35430
|
+
async function handleSet(id, options) {
|
|
35431
|
+
const { http } = getAuthedHttpClient();
|
|
35432
|
+
const payload = await http.patch(
|
|
35433
|
+
`/api/v2/play-projects/${encodeURIComponent(id)}`,
|
|
35434
|
+
{
|
|
35435
|
+
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
35436
|
+
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
35437
|
+
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
35438
|
+
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {},
|
|
35439
|
+
...options.disabled !== void 0 ? { disabled: options.disabled } : {}
|
|
35440
|
+
}
|
|
35441
|
+
);
|
|
35442
|
+
printCommandEnvelope(
|
|
35443
|
+
{
|
|
35444
|
+
project: payload.project,
|
|
35445
|
+
render: {
|
|
35446
|
+
sections: [
|
|
35447
|
+
{ title: "updated", lines: [renderProject(payload.project)] }
|
|
35448
|
+
]
|
|
35449
|
+
}
|
|
35450
|
+
},
|
|
35451
|
+
{ json: options.json }
|
|
35452
|
+
);
|
|
35453
|
+
}
|
|
35454
|
+
async function handleUnlink(id, options) {
|
|
35455
|
+
const { http } = getAuthedHttpClient();
|
|
35456
|
+
await http.delete(`/api/v2/play-projects/${encodeURIComponent(id)}`);
|
|
35457
|
+
printCommandEnvelope(
|
|
35458
|
+
{
|
|
35459
|
+
ok: true,
|
|
35460
|
+
id,
|
|
35461
|
+
render: {
|
|
35462
|
+
sections: [
|
|
35463
|
+
{
|
|
35464
|
+
title: "unlinked",
|
|
35465
|
+
lines: [
|
|
35466
|
+
`Repository link ${id} removed. Deployments stop immediately and in-flight deploy credentials die; live plays keep running.`
|
|
35467
|
+
]
|
|
35468
|
+
}
|
|
35469
|
+
]
|
|
35470
|
+
}
|
|
35471
|
+
},
|
|
35472
|
+
{ json: options.json }
|
|
35473
|
+
);
|
|
35474
|
+
}
|
|
35475
|
+
async function handleConnect(options) {
|
|
35476
|
+
const baseUrl = resolveBaseUrlOnly();
|
|
35477
|
+
const connectUrl = `${baseUrl.replace(/\/$/, "")}/api/v2/github/connect`;
|
|
35478
|
+
const opened = openInBrowser(connectUrl);
|
|
35479
|
+
printCommandEnvelope(
|
|
35480
|
+
{
|
|
35481
|
+
connectUrl,
|
|
35482
|
+
browser: opened,
|
|
35483
|
+
render: {
|
|
35484
|
+
sections: [
|
|
35485
|
+
{
|
|
35486
|
+
title: "connect GitHub",
|
|
35487
|
+
lines: [
|
|
35488
|
+
opened === "opened" ? `Opened ${connectUrl} in your browser.` : `Open ${connectUrl} in your browser.`,
|
|
35489
|
+
"Sign in as a workspace admin if prompted, approve the GitHub",
|
|
35490
|
+
"installation, then return here and run `deepline git repos`."
|
|
35491
|
+
]
|
|
35492
|
+
}
|
|
35493
|
+
]
|
|
35494
|
+
}
|
|
35495
|
+
},
|
|
35496
|
+
{ json: options.json }
|
|
35497
|
+
);
|
|
35498
|
+
}
|
|
35499
|
+
async function handleDeploymentsList(options) {
|
|
35500
|
+
const { http } = getAuthedHttpClient();
|
|
35501
|
+
const query = new URLSearchParams();
|
|
35502
|
+
if (options.repo) query.set("projectId", options.repo);
|
|
35503
|
+
if (options.limit) query.set("limit", options.limit);
|
|
35504
|
+
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
35505
|
+
const payload = await http.get(
|
|
35506
|
+
`/api/v2/deployments${suffix}`
|
|
35507
|
+
);
|
|
35508
|
+
printCommandEnvelope(
|
|
35509
|
+
{
|
|
35510
|
+
deployments: payload.deployments,
|
|
35511
|
+
count: payload.deployments.length,
|
|
35512
|
+
render: {
|
|
35513
|
+
sections: [
|
|
35514
|
+
{
|
|
35515
|
+
title: "deployments",
|
|
35516
|
+
lines: payload.deployments.length ? payload.deployments.map(renderDeployment) : [
|
|
35517
|
+
"No deployments yet. Push to a linked repository to create one."
|
|
35518
|
+
]
|
|
35519
|
+
}
|
|
35520
|
+
]
|
|
35521
|
+
}
|
|
35522
|
+
},
|
|
35523
|
+
{ json: options.json }
|
|
35524
|
+
);
|
|
35525
|
+
}
|
|
35526
|
+
async function handleDeploymentGet(id, options) {
|
|
35527
|
+
const { http } = getAuthedHttpClient();
|
|
35528
|
+
const payload = await http.get(`/api/v2/deployments/${encodeURIComponent(id)}`);
|
|
35529
|
+
const results = payload.deployment.results;
|
|
35530
|
+
const playLines = Array.isArray(results?.plays) ? results.plays.map(
|
|
35531
|
+
(play) => `${play.name ?? "?"} - ${play.status ?? "?"}${play.error ? `: ${play.error}` : ""}`
|
|
35532
|
+
) : [];
|
|
35533
|
+
printCommandEnvelope(
|
|
35534
|
+
{
|
|
35535
|
+
deployment: payload.deployment,
|
|
35536
|
+
project: payload.project,
|
|
35537
|
+
render: {
|
|
35538
|
+
sections: [
|
|
35539
|
+
{
|
|
35540
|
+
title: `deployment ${payload.deployment.id}${payload.project ? ` (${payload.project.repoFullName})` : ""}`,
|
|
35541
|
+
lines: [renderDeployment(payload.deployment)]
|
|
35542
|
+
},
|
|
35543
|
+
...playLines.length ? [{ title: "plays", lines: playLines }] : []
|
|
35544
|
+
]
|
|
35545
|
+
}
|
|
35546
|
+
},
|
|
35547
|
+
{ json: options.json }
|
|
35548
|
+
);
|
|
35549
|
+
}
|
|
35550
|
+
function registerGitCommands(program) {
|
|
35551
|
+
const git = program.command("git").alias("projects").description(
|
|
35552
|
+
"Git deploys: link repositories to this workspace and deploy plays on push."
|
|
35553
|
+
).addHelpText(
|
|
35554
|
+
"after",
|
|
35555
|
+
`
|
|
35556
|
+
Examples:
|
|
35557
|
+
deepline git connect
|
|
35558
|
+
deepline git repos
|
|
35559
|
+
deepline git link acme/growth --branch main
|
|
35560
|
+
deepline git list
|
|
35561
|
+
deepline git set <id> --branch release
|
|
35562
|
+
deepline git unlink <id>
|
|
35563
|
+
deepline git deployments --repo <id>
|
|
35564
|
+
`
|
|
35565
|
+
);
|
|
35566
|
+
git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
|
|
35567
|
+
git.command("repos").description("List repos the workspace's GitHub installation can reach.").option(
|
|
35568
|
+
"--installation <id>",
|
|
35569
|
+
"GitHub installation id (required when several are connected)"
|
|
35570
|
+
).option("--json", "Emit JSON output").action(
|
|
35571
|
+
async (options) => handleRepos(options)
|
|
35572
|
+
);
|
|
35573
|
+
git.command("list").description("List linked repositories.").option("--all", "Include unlinked repositories").option("--json", "Emit JSON output").action(
|
|
35574
|
+
async (options) => handleList(options)
|
|
35575
|
+
);
|
|
35576
|
+
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(
|
|
35577
|
+
"--manifest <file>",
|
|
35578
|
+
"Manifest file name under the base path (default: deepline.json)"
|
|
35579
|
+
).option(
|
|
35580
|
+
"--installation <id>",
|
|
35581
|
+
"GitHub installation id (required when several are connected)"
|
|
35582
|
+
).option("--no-pr-checks", "Skip Check Runs on pull requests").option("--json", "Emit JSON output").action(
|
|
35583
|
+
async (repo, options) => handleLink(repo, options)
|
|
35584
|
+
);
|
|
35585
|
+
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));
|
|
35586
|
+
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(
|
|
35587
|
+
"--manifest <file>",
|
|
35588
|
+
"Manifest file name under the base path (default: deepline.json)"
|
|
35589
|
+
).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(
|
|
35590
|
+
async (id, options) => handleSet(id, {
|
|
35591
|
+
...options,
|
|
35592
|
+
disabled: options.enabled === true ? false : options.disabled === true ? true : void 0
|
|
35593
|
+
})
|
|
35594
|
+
);
|
|
35595
|
+
git.command("unlink").description("Unlink a repository (live plays keep running).").argument("<id>", "Repository link id").option("--json", "Emit JSON output").action(
|
|
35596
|
+
async (id, options) => handleUnlink(id, options)
|
|
35597
|
+
);
|
|
35598
|
+
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(
|
|
35599
|
+
async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
|
|
35600
|
+
);
|
|
35601
|
+
const deployments = program.command("deployments", { hidden: true });
|
|
35602
|
+
deployments.command("list").option("--project <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
|
|
35603
|
+
async (options) => handleDeploymentsList({ ...options, repo: options.project })
|
|
35604
|
+
);
|
|
35605
|
+
deployments.command("get").argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
|
|
35606
|
+
async (id, options) => handleDeploymentGet(id, options)
|
|
35607
|
+
);
|
|
35608
|
+
}
|
|
35609
|
+
|
|
34769
35610
|
// src/cli/getting-started.ts
|
|
34770
35611
|
var DEEPLINE_GTM_SKILL = "/deepline-gtm";
|
|
34771
35612
|
var DEEPLINE_GTM_STARTER_PROMPTS = [
|
|
@@ -35006,7 +35847,7 @@ function preventShellHistoryLeak(forbidden) {
|
|
|
35006
35847
|
);
|
|
35007
35848
|
}
|
|
35008
35849
|
}
|
|
35009
|
-
async function
|
|
35850
|
+
async function handleList2(options) {
|
|
35010
35851
|
const client2 = new DeeplineClient();
|
|
35011
35852
|
const secrets = await client2.listSecrets();
|
|
35012
35853
|
printCommandEnvelope(
|
|
@@ -35049,7 +35890,7 @@ async function handleCheck(nameInput, options) {
|
|
|
35049
35890
|
);
|
|
35050
35891
|
if (!secret) process.exitCode = 4;
|
|
35051
35892
|
}
|
|
35052
|
-
async function
|
|
35893
|
+
async function handleSet2(nameInput, forbidden, options) {
|
|
35053
35894
|
preventShellHistoryLeak(forbidden);
|
|
35054
35895
|
const name = normalizeSecretName(nameInput);
|
|
35055
35896
|
const scope = options.scope === "play" ? "play" : "org";
|
|
@@ -35108,14 +35949,14 @@ Examples:
|
|
|
35108
35949
|
`
|
|
35109
35950
|
);
|
|
35110
35951
|
secrets.command("list").description("List secret metadata only.").option("--json", "Emit JSON output").action(async (options) => {
|
|
35111
|
-
await
|
|
35952
|
+
await handleList2(options);
|
|
35112
35953
|
});
|
|
35113
35954
|
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
35955
|
await handleCheck(name, options);
|
|
35115
35956
|
});
|
|
35116
35957
|
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
35958
|
async (name, forbidden, options) => {
|
|
35118
|
-
await
|
|
35959
|
+
await handleSet2(name, forbidden ?? [], options);
|
|
35119
35960
|
}
|
|
35120
35961
|
);
|
|
35121
35962
|
}
|
|
@@ -36746,7 +37587,7 @@ function failSetupPhase(phases, phase, code) {
|
|
|
36746
37587
|
}
|
|
36747
37588
|
function rollbackCommand(scope, root) {
|
|
36748
37589
|
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
|
|
37590
|
+
return `npm install -g${prefix} --no-audit --no-fund --include=optional deepline@${SDK_VERSION}`;
|
|
36750
37591
|
}
|
|
36751
37592
|
function setupResumeCommand(baseUrl, scope) {
|
|
36752
37593
|
const hostPrefix = baseUrl === "https://code.deepline.com" ? "" : `DEEPLINE_HOST_URL=${JSON.stringify(baseUrl)} `;
|
|
@@ -37315,9 +38156,7 @@ async function runSetupCommand(options) {
|
|
|
37315
38156
|
title: "setup",
|
|
37316
38157
|
lines: [
|
|
37317
38158
|
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
|
-
] : [],
|
|
38159
|
+
...workspaceName ? ["To link a different workspace, run: deepline auth register"] : [],
|
|
37321
38160
|
`Use ${DEEPLINE_GTM_SKILL} in your agent.`,
|
|
37322
38161
|
...DEEPLINE_GTM_STARTER_PROMPTS.map(
|
|
37323
38162
|
(example, index) => `${index + 1}. ${example.title}: ${example.prompt}`
|
|
@@ -37661,12 +38500,6 @@ var NPM_SDK_INSTALL_COMMON_FLAGS = [
|
|
|
37661
38500
|
"--no-fund",
|
|
37662
38501
|
"--include=optional"
|
|
37663
38502
|
];
|
|
37664
|
-
var NPM_SDK_GLOBAL_INSTALL_FLAGS = [
|
|
37665
|
-
"--no-audit",
|
|
37666
|
-
"--no-fund",
|
|
37667
|
-
"--include=optional",
|
|
37668
|
-
"--allow-scripts=esbuild"
|
|
37669
|
-
];
|
|
37670
38503
|
var NPM_SDK_SIDECAR_PACKAGE_JSON = `${JSON.stringify(
|
|
37671
38504
|
{
|
|
37672
38505
|
private: true,
|
|
@@ -37901,9 +38734,9 @@ function resolveUpdatePlan(options = {}) {
|
|
|
37901
38734
|
"-g",
|
|
37902
38735
|
"--prefix",
|
|
37903
38736
|
installPrefix,
|
|
37904
|
-
...
|
|
38737
|
+
...NPM_SDK_INSTALL_COMMON_FLAGS,
|
|
37905
38738
|
packageSpec
|
|
37906
|
-
] : ["install", "-g", ...
|
|
38739
|
+
] : ["install", "-g", ...NPM_SDK_INSTALL_COMMON_FLAGS, packageSpec];
|
|
37907
38740
|
const fallbackRegistryUrl = options.npmFallbackRegistryUrl !== void 0 ? options.npmFallbackRegistryUrl : publicNpmFallbackRegistryUrl(
|
|
37908
38741
|
env.DEEPLINE_HOST_URL?.trim() || autoDetectBaseUrl()
|
|
37909
38742
|
);
|
|
@@ -39643,6 +40476,17 @@ function numberValue(value) {
|
|
|
39643
40476
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
39644
40477
|
}
|
|
39645
40478
|
|
|
40479
|
+
// src/cli/tool-connection-status.ts
|
|
40480
|
+
function toolConnectionStatusMessage(input2) {
|
|
40481
|
+
if (input2.credentialStatus === "requires_connection") {
|
|
40482
|
+
return "requires your credentials \u2014 not connected (connect to use)";
|
|
40483
|
+
}
|
|
40484
|
+
if (input2.connected === false && input2.credentialStatus === "managed") {
|
|
40485
|
+
return "temporarily unavailable";
|
|
40486
|
+
}
|
|
40487
|
+
return null;
|
|
40488
|
+
}
|
|
40489
|
+
|
|
39646
40490
|
// src/cli/commands/tools.ts
|
|
39647
40491
|
var TOOL_COMMAND_TEMPLATES = {
|
|
39648
40492
|
describe: "deepline tools describe <toolId>",
|
|
@@ -39767,10 +40611,11 @@ function notConnectedSuffix(tool) {
|
|
|
39767
40611
|
const record2 = tool;
|
|
39768
40612
|
const status = stringField2(record2, "credentialStatus", "credential_status");
|
|
39769
40613
|
const connected = record2.connected;
|
|
39770
|
-
|
|
39771
|
-
|
|
39772
|
-
|
|
39773
|
-
|
|
40614
|
+
const message = toolConnectionStatusMessage({
|
|
40615
|
+
connected: connected === false ? false : void 0,
|
|
40616
|
+
credentialStatus: status || void 0
|
|
40617
|
+
});
|
|
40618
|
+
return message ? ` - \u26A0 ${message}` : "";
|
|
39774
40619
|
}
|
|
39775
40620
|
function shortPricingHint(tool) {
|
|
39776
40621
|
const pricing = recordField2(
|
|
@@ -42320,14 +43165,14 @@ async function handleTransform(id, options) {
|
|
|
42320
43165
|
);
|
|
42321
43166
|
return outcomes.every((o) => o.ok) ? 0 : 1;
|
|
42322
43167
|
}
|
|
42323
|
-
async function
|
|
43168
|
+
async function handleList3(options) {
|
|
42324
43169
|
const limit = options.limit ? Number(options.limit) : void 0;
|
|
42325
43170
|
const result = await client().listWorkflows({
|
|
42326
43171
|
limit: Number.isFinite(limit) ? limit : void 0
|
|
42327
43172
|
});
|
|
42328
43173
|
emitPassThrough("list", result, options);
|
|
42329
43174
|
}
|
|
42330
|
-
async function
|
|
43175
|
+
async function handleGet2(id, options) {
|
|
42331
43176
|
emitPassThrough("get", await client().getWorkflow(id), options);
|
|
42332
43177
|
}
|
|
42333
43178
|
async function handleDelete(id, options) {
|
|
@@ -42446,12 +43291,12 @@ Notes:
|
|
|
42446
43291
|
});
|
|
42447
43292
|
withJsonOption2(
|
|
42448
43293
|
workflows.command("list").description("List workspace workflows.").option("--limit <n>", "Max workflows to return")
|
|
42449
|
-
).action(
|
|
43294
|
+
).action(handleList3);
|
|
42450
43295
|
withJsonOption2(
|
|
42451
43296
|
workflows.command("get <id>").description(
|
|
42452
43297
|
"Fetch a workflow, including its published-revision config."
|
|
42453
43298
|
)
|
|
42454
|
-
).action(
|
|
43299
|
+
).action(handleGet2);
|
|
42455
43300
|
withJsonOption2(
|
|
42456
43301
|
workflows.command("disable <id>").description("Turn a workflow off.")
|
|
42457
43302
|
).action(handleDisable);
|
|
@@ -42504,6 +43349,7 @@ function registerDeeplineCommandGroups(program) {
|
|
|
42504
43349
|
registerBillingCommands(program);
|
|
42505
43350
|
registerMonitorsCommands(program);
|
|
42506
43351
|
registerOrgCommands(program);
|
|
43352
|
+
registerGitCommands(program);
|
|
42507
43353
|
registerEnrichCommand(program);
|
|
42508
43354
|
registerCsvCommands(program);
|
|
42509
43355
|
registerDbCommands(program);
|
|
@@ -42717,97 +43563,6 @@ What changed in ${response.update_summary.version}: ${response.update_summary.su
|
|
|
42717
43563
|
|
|
42718
43564
|
// src/cli/index.ts
|
|
42719
43565
|
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
43566
|
function asCommanderError(error) {
|
|
42812
43567
|
if (!(error instanceof Error) || !("code" in error)) {
|
|
42813
43568
|
return null;
|
|
@@ -43118,7 +43873,6 @@ Exit codes:
|
|
|
43118
43873
|
return;
|
|
43119
43874
|
}
|
|
43120
43875
|
const compatibilityCommand = compatibilityCommandPath(actionCommand) || actionCommand.name();
|
|
43121
|
-
assertProjectCloudWorkIsPinned(compatibilityCommand);
|
|
43122
43876
|
if (printStartupPhase) {
|
|
43123
43877
|
progress?.phase("checking sdk compatibility");
|
|
43124
43878
|
}
|
|
@@ -43295,10 +44049,7 @@ Examples:
|
|
|
43295
44049
|
});
|
|
43296
44050
|
progress?.fail();
|
|
43297
44051
|
const wantsJson = process.argv.includes("--json");
|
|
43298
|
-
if (
|
|
43299
|
-
printProjectOrgPinRequiredError(error);
|
|
43300
|
-
process.exitCode = error.exitCode;
|
|
43301
|
-
} else if (commanderError) {
|
|
44052
|
+
if (commanderError) {
|
|
43302
44053
|
if (commanderError.code === "commander.unknownCommand") {
|
|
43303
44054
|
}
|
|
43304
44055
|
process.exitCode = commanderError.code === "commander.unknownCommand" && !wantsJson ? 2 : commanderError.exitCode ?? 1;
|