deepline 0.3.123 → 0.3.125
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 +25 -2
- package/dist/bundling-sources/sdk/src/compat.ts +17 -2
- package/dist/bundling-sources/sdk/src/play.ts +3 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/package.json +2 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +61 -10
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-control-plane-capability.ts +47 -0
- package/dist/bundling-sources/shared_libs/observability/redaction.ts +3 -0
- package/dist/bundling-sources/shared_libs/observability/runtime-console.ts +174 -0
- package/dist/bundling-sources/shared_libs/observability/telemetry.ts +26 -2
- package/dist/bundling-sources/shared_libs/play-runtime/play-admission-outcome.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +28 -11
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-telemetry.ts +121 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +91 -2
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +87 -41
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-capacity.ts +5 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +1 -0
- package/dist/cli/index.js +538 -469
- package/dist/cli/index.mjs +538 -469
- package/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +11 -4
- package/dist/index.mjs +11 -4
- package/dist/install-integrity.json +2 -0
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3068,7 +3068,7 @@ var SDK_RELEASE = {
|
|
|
3068
3068
|
// getters keep their established compatibility behavior.
|
|
3069
3069
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3070
3070
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3071
|
-
version: "0.3.
|
|
3071
|
+
version: "0.3.125",
|
|
3072
3072
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
3073
3073
|
packageCapabilities: {
|
|
3074
3074
|
updatePreferences: 1
|
|
@@ -6919,7 +6919,7 @@ function playRunStatusFromState(state) {
|
|
|
6919
6919
|
..."result" in state ? { result: state.result } : {}
|
|
6920
6920
|
};
|
|
6921
6921
|
}
|
|
6922
|
-
var DeeplineClient = class {
|
|
6922
|
+
var DeeplineClient = class _DeeplineClient {
|
|
6923
6923
|
http;
|
|
6924
6924
|
config;
|
|
6925
6925
|
/** Canonical run lifecycle namespace backed by `/api/v2/runs`. */
|
|
@@ -9844,9 +9844,16 @@ var DeeplineClient = class {
|
|
|
9844
9844
|
// ——————————————————————————————————————————————————————————
|
|
9845
9845
|
// Monitor Jobs, Batches, and Fleets
|
|
9846
9846
|
// ——————————————————————————————————————————————————————————
|
|
9847
|
+
static MONITOR_JOB_IDEMPOTENCY_KEY_MAX_LENGTH = 96;
|
|
9847
9848
|
monitorJobIdempotencyKey(operation) {
|
|
9848
|
-
const uuid = globalThis.crypto?.randomUUID?.()
|
|
9849
|
-
|
|
9849
|
+
const uuid = globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
9850
|
+
const prefix = "monitor-job-";
|
|
9851
|
+
const safeOperation = operation.replace(/[^A-Za-z0-9._-]/g, "-");
|
|
9852
|
+
const maxOperationLength = Math.max(
|
|
9853
|
+
0,
|
|
9854
|
+
_DeeplineClient.MONITOR_JOB_IDEMPOTENCY_KEY_MAX_LENGTH - prefix.length - uuid.length - 1
|
|
9855
|
+
);
|
|
9856
|
+
return `${prefix}${safeOperation.slice(0, maxOperationLength)}-${uuid}`;
|
|
9850
9857
|
}
|
|
9851
9858
|
monitorJobHeaders(operation, idempotencyKey) {
|
|
9852
9859
|
return {
|
|
@@ -10296,6 +10303,12 @@ async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
|
10296
10303
|
clearTimeout(timeout);
|
|
10297
10304
|
}
|
|
10298
10305
|
}
|
|
10306
|
+
function isCiEnvironment() {
|
|
10307
|
+
return ["CI", "GITHUB_ACTIONS"].some((name) => {
|
|
10308
|
+
const value = process.env[name]?.trim().toLowerCase();
|
|
10309
|
+
return value === "1" || value === "true" || value === "yes";
|
|
10310
|
+
});
|
|
10311
|
+
}
|
|
10299
10312
|
function enforceSdkCompatibilityResponse(response) {
|
|
10300
10313
|
if (!response) {
|
|
10301
10314
|
return;
|
|
@@ -10303,7 +10316,7 @@ function enforceSdkCompatibilityResponse(response) {
|
|
|
10303
10316
|
if (response.update_required) {
|
|
10304
10317
|
throw new Error(response.message);
|
|
10305
10318
|
}
|
|
10306
|
-
if (response.status === "deprecated" || response.status === "update_available") {
|
|
10319
|
+
if ((response.status === "deprecated" || response.status === "update_available") && !isCiEnvironment()) {
|
|
10307
10320
|
process.stderr.write(`${response.message}
|
|
10308
10321
|
`);
|
|
10309
10322
|
}
|
|
@@ -21232,7 +21245,8 @@ function printResult(input2) {
|
|
|
21232
21245
|
lines: [
|
|
21233
21246
|
`${input2.directory}: ${input2.status}`,
|
|
21234
21247
|
...input2.outcomes.map(renderOutcome),
|
|
21235
|
-
...failed && input2.deployment.error ? [input2.deployment.error] : []
|
|
21248
|
+
...failed && input2.deployment.error ? [input2.deployment.error] : [],
|
|
21249
|
+
`Details: deepline plays deployments ${input2.deployment.id}`
|
|
21236
21250
|
]
|
|
21237
21251
|
}
|
|
21238
21252
|
]
|
|
@@ -21311,6 +21325,461 @@ async function handlePlaysDeploy(directory, options) {
|
|
|
21311
21325
|
}
|
|
21312
21326
|
}
|
|
21313
21327
|
|
|
21328
|
+
// src/cli/commands/git.ts
|
|
21329
|
+
var GIT_DEPLOY_FEATURE = "github-deploy";
|
|
21330
|
+
function shellQuote2(value) {
|
|
21331
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
21332
|
+
}
|
|
21333
|
+
function renderProject(project) {
|
|
21334
|
+
const root = project.rootDirectory ? ` (${project.rootDirectory})` : "";
|
|
21335
|
+
const flags = [
|
|
21336
|
+
project.disabled ? "unlinked" : "linked",
|
|
21337
|
+
`deploys ${project.productionBranch}`,
|
|
21338
|
+
project.checkOnPullRequest ? "PR checks on" : "PR checks off"
|
|
21339
|
+
].join(", ");
|
|
21340
|
+
return `${project.id} ${project.repoFullName}${root} - ${flags}`;
|
|
21341
|
+
}
|
|
21342
|
+
function renderDeployment(deployment) {
|
|
21343
|
+
const fromDirectory = deployment.playProjectId === null;
|
|
21344
|
+
const kind = fromDirectory ? "directory deploy" : deployment.isProduction ? "production" : deployment.trigger === "pull_request" ? `pr #${deployment.pullRequestNumber ?? "?"}` : deployment.trigger;
|
|
21345
|
+
const suffix = deployment.error ? ` - ${deployment.error.slice(0, 80)}` : "";
|
|
21346
|
+
const source = [
|
|
21347
|
+
deployment.commitSha?.slice(0, 10),
|
|
21348
|
+
deployment.ref?.replace("refs/heads/", ""),
|
|
21349
|
+
fromDirectory ? deployment.repoFullName : null
|
|
21350
|
+
].filter(Boolean).join(" ") || "no git metadata";
|
|
21351
|
+
return `${deployment.id} ${source} (${kind}) - ${deployment.status}${suffix}`;
|
|
21352
|
+
}
|
|
21353
|
+
async function handleList(options) {
|
|
21354
|
+
const { http } = getAuthedHttpClient();
|
|
21355
|
+
const payload = await http.get(
|
|
21356
|
+
`/api/v2/play-projects${options.all ? "?includeDisabled=1" : ""}`
|
|
21357
|
+
);
|
|
21358
|
+
printCommandEnvelope(
|
|
21359
|
+
{
|
|
21360
|
+
projects: payload.projects,
|
|
21361
|
+
count: payload.projects.length,
|
|
21362
|
+
render: {
|
|
21363
|
+
sections: [
|
|
21364
|
+
{
|
|
21365
|
+
title: "linked repositories",
|
|
21366
|
+
lines: payload.projects.length ? payload.projects.map(renderProject) : [
|
|
21367
|
+
"No repositories are linked. Run `deepline git repos` to see what the GitHub installation can reach, then `deepline git link`."
|
|
21368
|
+
]
|
|
21369
|
+
}
|
|
21370
|
+
]
|
|
21371
|
+
}
|
|
21372
|
+
},
|
|
21373
|
+
{ json: options.json }
|
|
21374
|
+
);
|
|
21375
|
+
}
|
|
21376
|
+
function describeInstallationStatus(installation) {
|
|
21377
|
+
switch (installation.status) {
|
|
21378
|
+
case "active":
|
|
21379
|
+
return [
|
|
21380
|
+
`Connected to ${installation.accountLogin} (installation ${installation.installationId}).`
|
|
21381
|
+
];
|
|
21382
|
+
case "uninstalled":
|
|
21383
|
+
return [
|
|
21384
|
+
`The Deepline GitHub App was uninstalled from ${installation.accountLogin}${installation.uninstalledAt ? ` at ${new Date(installation.uninstalledAt).toISOString()}` : ""}.`,
|
|
21385
|
+
"Deploys are paused for every linked repository. Run `deepline git connect`, then `deepline git link <owner/repo>` again for each repository; links from the old installation cannot be resumed."
|
|
21386
|
+
];
|
|
21387
|
+
case "suspended":
|
|
21388
|
+
return [
|
|
21389
|
+
`GitHub suspended the Deepline App on ${installation.accountLogin}${installation.suspendedAt ? ` at ${new Date(installation.suspendedAt).toISOString()}` : ""}.`,
|
|
21390
|
+
"Pushes are not delivered while it is suspended; unsuspend it in GitHub settings."
|
|
21391
|
+
];
|
|
21392
|
+
}
|
|
21393
|
+
}
|
|
21394
|
+
async function handleStatus2(options) {
|
|
21395
|
+
const { http } = getAuthedHttpClient();
|
|
21396
|
+
const payload = await http.get("/api/v2/github/installation");
|
|
21397
|
+
const installation = payload.installation;
|
|
21398
|
+
const others = (payload.installations ?? []).filter(
|
|
21399
|
+
(row) => row.installationId !== installation?.installationId
|
|
21400
|
+
);
|
|
21401
|
+
const lines = installation ? describeInstallationStatus(installation) : [
|
|
21402
|
+
"No GitHub installation is connected to this workspace. Run `deepline git connect`."
|
|
21403
|
+
];
|
|
21404
|
+
for (const other of others) {
|
|
21405
|
+
lines.push(
|
|
21406
|
+
`Also: ${other.accountLogin} (installation ${other.installationId}) is ${other.status}.`
|
|
21407
|
+
);
|
|
21408
|
+
}
|
|
21409
|
+
const byId = new Map(
|
|
21410
|
+
(payload.installations ?? []).map((row) => [row.installationId, row])
|
|
21411
|
+
);
|
|
21412
|
+
const { projects } = await http.get(
|
|
21413
|
+
"/api/v2/play-projects?includeDisabled=1"
|
|
21414
|
+
);
|
|
21415
|
+
const affected_links = projects.map((project) => {
|
|
21416
|
+
const own = byId.get(project.installationId);
|
|
21417
|
+
const verdict = !own ? "unknown" : own.status === "active" ? null : own.status;
|
|
21418
|
+
return verdict ? {
|
|
21419
|
+
id: project.id,
|
|
21420
|
+
repoId: project.repoId,
|
|
21421
|
+
repoFullName: project.repoFullName,
|
|
21422
|
+
rootDirectory: project.rootDirectory,
|
|
21423
|
+
productionBranch: project.productionBranch,
|
|
21424
|
+
manifestPath: project.manifestPath,
|
|
21425
|
+
checkOnPullRequest: project.checkOnPullRequest,
|
|
21426
|
+
disabled: project.disabled,
|
|
21427
|
+
installationId: project.installationId,
|
|
21428
|
+
installationStatus: verdict
|
|
21429
|
+
} : null;
|
|
21430
|
+
}).filter((row) => row !== null);
|
|
21431
|
+
const activeInstallations = (payload.installations ?? []).filter(
|
|
21432
|
+
(row) => row.status === "active"
|
|
21433
|
+
);
|
|
21434
|
+
const relinkCommand = (link2) => [
|
|
21435
|
+
// The numeric repo id, not the name: a repository renamed while the
|
|
21436
|
+
// App was gone keeps a stale name here, and `git link` accepts the id.
|
|
21437
|
+
`deepline git link ${link2.repoId}`,
|
|
21438
|
+
// Stored values are admin-controlled text and this line is
|
|
21439
|
+
// copy-pasted into a shell by whoever reads it, so every
|
|
21440
|
+
// interpolated value below is quoted.
|
|
21441
|
+
`--branch ${shellQuote2(link2.productionBranch)}`,
|
|
21442
|
+
link2.rootDirectory ? `--root-dir ${shellQuote2(link2.rootDirectory)}` : "",
|
|
21443
|
+
link2.manifestPath && link2.manifestPath !== "deepline.json" ? `--manifest ${shellQuote2(link2.manifestPath)}` : "",
|
|
21444
|
+
link2.checkOnPullRequest ? "" : "--no-pr-checks",
|
|
21445
|
+
// With several active installations no id is guessed: the reader picks.
|
|
21446
|
+
activeInstallations.length > 1 ? "--installation <id>" : ""
|
|
21447
|
+
].filter(Boolean).join(" ");
|
|
21448
|
+
for (const link2 of affected_links) {
|
|
21449
|
+
const label = `${link2.repoFullName}${link2.rootDirectory ? ` (${link2.rootDirectory})` : ""}`;
|
|
21450
|
+
lines.push(
|
|
21451
|
+
link2.installationStatus !== "suspended" ? `Link again: ${label} \u2014 its installation ${link2.installationId} is ${link2.installationStatus}; run \`${relinkCommand(link2)}\`${activeInstallations.length > 1 ? ` with <id> being the installation that reaches this repo: ${activeInstallations.map((row) => `${row.installationId} (${row.accountLogin})`).join(", ")}` : ""}.` : (
|
|
21452
|
+
// A link disabled during the suspension stays disabled; only an
|
|
21453
|
+
// enabled one picks up again on its own when GitHub unsuspends.
|
|
21454
|
+
link2.disabled ? `Paused and disabled: ${label} \u2014 its installation is suspended, and the link stays disabled after GitHub unsuspends it until you run \`deepline git set ${link2.id} --enabled\`.` : `Paused: ${label} \u2014 its installation is suspended; pushes resume when GitHub unsuspends it.`
|
|
21455
|
+
)
|
|
21456
|
+
);
|
|
21457
|
+
}
|
|
21458
|
+
printCommandEnvelope(
|
|
21459
|
+
{
|
|
21460
|
+
installation,
|
|
21461
|
+
installations: payload.installations ?? [],
|
|
21462
|
+
affected_links,
|
|
21463
|
+
render: { sections: [{ title: "github installation", lines }] }
|
|
21464
|
+
},
|
|
21465
|
+
{ json: options.json }
|
|
21466
|
+
);
|
|
21467
|
+
}
|
|
21468
|
+
async function handleRepos(options) {
|
|
21469
|
+
const { http } = getAuthedHttpClient();
|
|
21470
|
+
const query = options.installation ? `?installationId=${encodeURIComponent(options.installation)}` : "";
|
|
21471
|
+
const payload = await http.get(`/api/v2/github/repos${query}`);
|
|
21472
|
+
printCommandEnvelope(
|
|
21473
|
+
{
|
|
21474
|
+
installation: payload.installation,
|
|
21475
|
+
repositories: payload.repositories,
|
|
21476
|
+
count: payload.repositories.length,
|
|
21477
|
+
render: {
|
|
21478
|
+
sections: [
|
|
21479
|
+
{
|
|
21480
|
+
title: `repos on installation @${payload.installation.accountLogin} (${payload.installation.repositorySelection})`,
|
|
21481
|
+
lines: payload.repositories.map(
|
|
21482
|
+
(repo) => `${repo.repoId} ${repo.fullName} (default: ${repo.defaultBranch}${repo.private ? ", private" : ""}${repo.fork ? ", fork" : ""})`
|
|
21483
|
+
)
|
|
21484
|
+
}
|
|
21485
|
+
]
|
|
21486
|
+
}
|
|
21487
|
+
},
|
|
21488
|
+
{ json: options.json }
|
|
21489
|
+
);
|
|
21490
|
+
}
|
|
21491
|
+
async function resolveRepoId(repo, installation) {
|
|
21492
|
+
if (/^\d+$/.test(repo)) return Number(repo);
|
|
21493
|
+
const { http } = getAuthedHttpClient();
|
|
21494
|
+
const query = installation ? `?installationId=${encodeURIComponent(installation)}` : "";
|
|
21495
|
+
const payload = await http.get(
|
|
21496
|
+
`/api/v2/github/repos${query}`
|
|
21497
|
+
);
|
|
21498
|
+
const match = payload.repositories.find(
|
|
21499
|
+
(entry) => entry.fullName.toLowerCase() === repo.toLowerCase()
|
|
21500
|
+
);
|
|
21501
|
+
if (!match) {
|
|
21502
|
+
throw new Error(
|
|
21503
|
+
`Repo "${repo}" is not accessible to the workspace's GitHub installation. Run \`deepline git repos\` to list what is.`
|
|
21504
|
+
);
|
|
21505
|
+
}
|
|
21506
|
+
return match.repoId;
|
|
21507
|
+
}
|
|
21508
|
+
async function handleLink(repo, options) {
|
|
21509
|
+
const repoId = await resolveRepoId(repo, options.installation);
|
|
21510
|
+
const { http } = getAuthedHttpClient();
|
|
21511
|
+
const payload = await http.post("/api/v2/play-projects", {
|
|
21512
|
+
repoId,
|
|
21513
|
+
...options.installation !== void 0 ? { installationId: options.installation } : {},
|
|
21514
|
+
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
21515
|
+
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
21516
|
+
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
21517
|
+
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {}
|
|
21518
|
+
});
|
|
21519
|
+
printCommandEnvelope(
|
|
21520
|
+
{
|
|
21521
|
+
project: payload.project,
|
|
21522
|
+
render: {
|
|
21523
|
+
sections: [
|
|
21524
|
+
{
|
|
21525
|
+
title: "linked",
|
|
21526
|
+
lines: [
|
|
21527
|
+
renderProject(payload.project),
|
|
21528
|
+
...(payload.warnings ?? []).map(
|
|
21529
|
+
(warning) => `WARNING: ${warning}`
|
|
21530
|
+
),
|
|
21531
|
+
"Pushes to the production branch now register and promote changed plays.",
|
|
21532
|
+
"Anyone who can push to this repo can change what runs in this workspace."
|
|
21533
|
+
]
|
|
21534
|
+
}
|
|
21535
|
+
]
|
|
21536
|
+
}
|
|
21537
|
+
},
|
|
21538
|
+
{ json: options.json }
|
|
21539
|
+
);
|
|
21540
|
+
}
|
|
21541
|
+
async function handleGet(id, options) {
|
|
21542
|
+
const { http } = getAuthedHttpClient();
|
|
21543
|
+
const payload = await http.get(
|
|
21544
|
+
`/api/v2/play-projects/${encodeURIComponent(id)}`
|
|
21545
|
+
);
|
|
21546
|
+
printCommandEnvelope(
|
|
21547
|
+
{
|
|
21548
|
+
project: payload.project,
|
|
21549
|
+
render: {
|
|
21550
|
+
sections: [
|
|
21551
|
+
{
|
|
21552
|
+
title: "linked repository",
|
|
21553
|
+
lines: [renderProject(payload.project)]
|
|
21554
|
+
}
|
|
21555
|
+
]
|
|
21556
|
+
}
|
|
21557
|
+
},
|
|
21558
|
+
{ json: options.json }
|
|
21559
|
+
);
|
|
21560
|
+
}
|
|
21561
|
+
async function handleSet(id, options) {
|
|
21562
|
+
const { http } = getAuthedHttpClient();
|
|
21563
|
+
const payload = await http.patch(
|
|
21564
|
+
`/api/v2/play-projects/${encodeURIComponent(id)}`,
|
|
21565
|
+
{
|
|
21566
|
+
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
21567
|
+
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
21568
|
+
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
21569
|
+
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {},
|
|
21570
|
+
...options.disabled !== void 0 ? { disabled: options.disabled } : {}
|
|
21571
|
+
}
|
|
21572
|
+
);
|
|
21573
|
+
printCommandEnvelope(
|
|
21574
|
+
{
|
|
21575
|
+
project: payload.project,
|
|
21576
|
+
render: {
|
|
21577
|
+
sections: [
|
|
21578
|
+
{ title: "updated", lines: [renderProject(payload.project)] }
|
|
21579
|
+
]
|
|
21580
|
+
}
|
|
21581
|
+
},
|
|
21582
|
+
{ json: options.json }
|
|
21583
|
+
);
|
|
21584
|
+
}
|
|
21585
|
+
async function handleUnlink(id, options) {
|
|
21586
|
+
const { http } = getAuthedHttpClient();
|
|
21587
|
+
await http.delete(`/api/v2/play-projects/${encodeURIComponent(id)}`);
|
|
21588
|
+
printCommandEnvelope(
|
|
21589
|
+
{
|
|
21590
|
+
ok: true,
|
|
21591
|
+
id,
|
|
21592
|
+
render: {
|
|
21593
|
+
sections: [
|
|
21594
|
+
{
|
|
21595
|
+
title: "unlinked",
|
|
21596
|
+
lines: [
|
|
21597
|
+
`Repository link ${id} removed. Deployments stop immediately and in-flight deploy credentials die; live plays keep running.`
|
|
21598
|
+
]
|
|
21599
|
+
}
|
|
21600
|
+
]
|
|
21601
|
+
}
|
|
21602
|
+
},
|
|
21603
|
+
{ json: options.json }
|
|
21604
|
+
);
|
|
21605
|
+
}
|
|
21606
|
+
async function handleConnect(options) {
|
|
21607
|
+
const baseUrl = resolveBaseUrlOnly();
|
|
21608
|
+
const connectUrl = `${baseUrl.replace(/\/$/, "")}/api/v2/github/connect`;
|
|
21609
|
+
const opened = openInBrowser(connectUrl);
|
|
21610
|
+
printCommandEnvelope(
|
|
21611
|
+
{
|
|
21612
|
+
connectUrl,
|
|
21613
|
+
browser: opened,
|
|
21614
|
+
render: {
|
|
21615
|
+
sections: [
|
|
21616
|
+
{
|
|
21617
|
+
title: "connect GitHub",
|
|
21618
|
+
lines: [
|
|
21619
|
+
opened === "opened" ? `Opened ${connectUrl} in your browser.` : `Open ${connectUrl} in your browser.`,
|
|
21620
|
+
"Sign in as a workspace admin if prompted, approve the GitHub",
|
|
21621
|
+
"installation, then return here and run `deepline git repos`."
|
|
21622
|
+
]
|
|
21623
|
+
}
|
|
21624
|
+
]
|
|
21625
|
+
}
|
|
21626
|
+
},
|
|
21627
|
+
{ json: options.json }
|
|
21628
|
+
);
|
|
21629
|
+
}
|
|
21630
|
+
async function handleDeploymentsList(options) {
|
|
21631
|
+
const { http } = getAuthedHttpClient();
|
|
21632
|
+
const query = new URLSearchParams();
|
|
21633
|
+
if (options.repo) query.set("projectId", options.repo);
|
|
21634
|
+
if (options.limit) query.set("limit", options.limit);
|
|
21635
|
+
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
21636
|
+
const payload = await http.get(
|
|
21637
|
+
`/api/v2/deployments${suffix}`
|
|
21638
|
+
);
|
|
21639
|
+
printCommandEnvelope(
|
|
21640
|
+
{
|
|
21641
|
+
deployments: payload.deployments,
|
|
21642
|
+
count: payload.deployments.length,
|
|
21643
|
+
render: {
|
|
21644
|
+
sections: [
|
|
21645
|
+
{
|
|
21646
|
+
title: "deployments",
|
|
21647
|
+
lines: payload.deployments.length ? payload.deployments.map(renderDeployment) : [
|
|
21648
|
+
"No deployments yet. Push to a linked repository, or run `deepline plays deploy`."
|
|
21649
|
+
]
|
|
21650
|
+
}
|
|
21651
|
+
]
|
|
21652
|
+
}
|
|
21653
|
+
},
|
|
21654
|
+
{ json: options.json }
|
|
21655
|
+
);
|
|
21656
|
+
}
|
|
21657
|
+
function renderDeploymentPlayLines(results) {
|
|
21658
|
+
const plays = results?.plays;
|
|
21659
|
+
if (!Array.isArray(plays)) return [];
|
|
21660
|
+
return plays.flatMap((play) => {
|
|
21661
|
+
const version = play.version === void 0 ? "" : play.previousVersion === void 0 ? ` v${play.version}` : ` v${play.previousVersion} -> v${play.version}`;
|
|
21662
|
+
const file = play.file ? ` (${play.file})` : "";
|
|
21663
|
+
return [
|
|
21664
|
+
`${play.name ?? "?"}${file} - ${play.status ?? "?"}${version}`,
|
|
21665
|
+
...play.error ? [` error: ${play.error}`] : [],
|
|
21666
|
+
...play.warning ? [` warning: ${play.warning}`] : []
|
|
21667
|
+
];
|
|
21668
|
+
});
|
|
21669
|
+
}
|
|
21670
|
+
async function handleDeploymentGet(id, options) {
|
|
21671
|
+
const { http } = getAuthedHttpClient();
|
|
21672
|
+
const payload = await http.get(`/api/v2/deployments/${encodeURIComponent(id)}`);
|
|
21673
|
+
const playLines = renderDeploymentPlayLines(payload.deployment.results);
|
|
21674
|
+
const repository = payload.project?.repoFullName ?? payload.deployment.repoFullName;
|
|
21675
|
+
printCommandEnvelope(
|
|
21676
|
+
{
|
|
21677
|
+
deployment: payload.deployment,
|
|
21678
|
+
project: payload.project,
|
|
21679
|
+
render: {
|
|
21680
|
+
sections: [
|
|
21681
|
+
{
|
|
21682
|
+
title: `deployment ${payload.deployment.id}${repository ? ` (${repository})` : ""}`,
|
|
21683
|
+
lines: [renderDeployment(payload.deployment)]
|
|
21684
|
+
},
|
|
21685
|
+
...playLines.length ? [{ title: "plays", lines: playLines }] : []
|
|
21686
|
+
]
|
|
21687
|
+
}
|
|
21688
|
+
},
|
|
21689
|
+
{ json: options.json }
|
|
21690
|
+
);
|
|
21691
|
+
}
|
|
21692
|
+
async function handleDeploymentCancel(id, options) {
|
|
21693
|
+
const { http } = getAuthedHttpClient();
|
|
21694
|
+
const payload = await http.post(`/api/v2/deployments/${encodeURIComponent(id)}/cancel`, {});
|
|
21695
|
+
printCommandEnvelope(
|
|
21696
|
+
{
|
|
21697
|
+
cancelled: payload.cancelled,
|
|
21698
|
+
deployment: payload.deployment,
|
|
21699
|
+
render: {
|
|
21700
|
+
sections: [
|
|
21701
|
+
{
|
|
21702
|
+
title: payload.cancelled ? "cancelled" : "already cancelled",
|
|
21703
|
+
lines: [
|
|
21704
|
+
payload.deployment ? renderDeployment(payload.deployment) : `Deployment ${id} cancelled.`,
|
|
21705
|
+
"The build stops at its next step and nothing from it goes live."
|
|
21706
|
+
]
|
|
21707
|
+
}
|
|
21708
|
+
]
|
|
21709
|
+
}
|
|
21710
|
+
},
|
|
21711
|
+
{ json: options.json }
|
|
21712
|
+
);
|
|
21713
|
+
}
|
|
21714
|
+
function registerGitCommands(program) {
|
|
21715
|
+
const git = program.command("git", { hidden: !cliFeatureEnabled(GIT_DEPLOY_FEATURE) }).alias("projects").description(
|
|
21716
|
+
"Git deploys: link repositories to this workspace and deploy plays on push."
|
|
21717
|
+
).addHelpText(
|
|
21718
|
+
"after",
|
|
21719
|
+
`
|
|
21720
|
+
Examples:
|
|
21721
|
+
deepline git connect
|
|
21722
|
+
deepline git repos
|
|
21723
|
+
deepline git link acme/growth --branch main
|
|
21724
|
+
deepline git list
|
|
21725
|
+
deepline git set <id> --branch release
|
|
21726
|
+
deepline git unlink <id>
|
|
21727
|
+
deepline git deployments --repo <id>
|
|
21728
|
+
deepline git cancel <deployment-id>
|
|
21729
|
+
`
|
|
21730
|
+
);
|
|
21731
|
+
git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
|
|
21732
|
+
git.command("status").description(
|
|
21733
|
+
"Show the workspace's GitHub installation and whether it is still usable."
|
|
21734
|
+
).option("--json", "Emit JSON output").action(async (options) => handleStatus2(options));
|
|
21735
|
+
git.command("repos").description("List repos the workspace's GitHub installation can reach.").option(
|
|
21736
|
+
"--installation <id>",
|
|
21737
|
+
"GitHub installation id (required when several are connected)"
|
|
21738
|
+
).option("--json", "Emit JSON output").action(
|
|
21739
|
+
async (options) => handleRepos(options)
|
|
21740
|
+
);
|
|
21741
|
+
git.command("list").description("List linked repositories.").option("--all", "Include unlinked repositories").option("--json", "Emit JSON output").action(
|
|
21742
|
+
async (options) => handleList(options)
|
|
21743
|
+
);
|
|
21744
|
+
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(
|
|
21745
|
+
"--manifest <file>",
|
|
21746
|
+
"Manifest file name under the base path (default: deepline.json)"
|
|
21747
|
+
).option(
|
|
21748
|
+
"--installation <id>",
|
|
21749
|
+
"GitHub installation id (required when several are connected)"
|
|
21750
|
+
).option("--no-pr-checks", "Skip Check Runs on pull requests").option("--json", "Emit JSON output").action(
|
|
21751
|
+
async (repo, options) => handleLink(repo, options)
|
|
21752
|
+
);
|
|
21753
|
+
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));
|
|
21754
|
+
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(
|
|
21755
|
+
"--manifest <file>",
|
|
21756
|
+
"Manifest file name under the base path (default: deepline.json)"
|
|
21757
|
+
).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(
|
|
21758
|
+
async (id, options) => handleSet(id, {
|
|
21759
|
+
...options,
|
|
21760
|
+
disabled: options.enabled === true ? false : options.disabled === true ? true : void 0
|
|
21761
|
+
})
|
|
21762
|
+
);
|
|
21763
|
+
git.command("unlink").description("Unlink a repository (live plays keep running).").argument("<id>", "Repository link id").option("--json", "Emit JSON output").action(
|
|
21764
|
+
async (id, options) => handleUnlink(id, options)
|
|
21765
|
+
);
|
|
21766
|
+
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(
|
|
21767
|
+
async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
|
|
21768
|
+
);
|
|
21769
|
+
git.command("cancel").description(
|
|
21770
|
+
"Cancel a queued or running deployment before its plays go live (admin)."
|
|
21771
|
+
).argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
|
|
21772
|
+
async (id, options) => handleDeploymentCancel(id, options)
|
|
21773
|
+
);
|
|
21774
|
+
const deployments = program.command("deployments", { hidden: true });
|
|
21775
|
+
deployments.command("list").option("--project <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
|
|
21776
|
+
async (options) => handleDeploymentsList({ ...options, repo: options.project })
|
|
21777
|
+
);
|
|
21778
|
+
deployments.command("get").argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
|
|
21779
|
+
async (id, options) => handleDeploymentGet(id, options)
|
|
21780
|
+
);
|
|
21781
|
+
}
|
|
21782
|
+
|
|
21314
21783
|
// src/cli/commands/play.ts
|
|
21315
21784
|
var PLAY_BUNDLER_MODULE_PATHS = [
|
|
21316
21785
|
// Built CLI bundle: dist/cli/index.mjs -> dist/plays/bundle-play-file.mjs.
|
|
@@ -21657,7 +22126,7 @@ function rankPlayReferenceSuggestions(input2) {
|
|
|
21657
22126
|
function searchQueryForMissingPlayReference(target) {
|
|
21658
22127
|
return parseReferencedPlayTarget2(target).unqualifiedPlayName.replace(/[-_./]+/g, " ").replace(/\s+/g, " ").trim();
|
|
21659
22128
|
}
|
|
21660
|
-
function
|
|
22129
|
+
function shellQuote3(value) {
|
|
21661
22130
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
21662
22131
|
}
|
|
21663
22132
|
function buildPlayReferenceNotFoundMessage(input2) {
|
|
@@ -21690,7 +22159,7 @@ function buildPlayReferenceNotFoundMessage(input2) {
|
|
|
21690
22159
|
lines.push(
|
|
21691
22160
|
"",
|
|
21692
22161
|
"Search visible plays:",
|
|
21693
|
-
` deepline plays search ${
|
|
22162
|
+
` deepline plays search ${shellQuote3(searchQuery)} --all --json`
|
|
21694
22163
|
);
|
|
21695
22164
|
}
|
|
21696
22165
|
return lines.join("\n");
|
|
@@ -26450,7 +26919,7 @@ function printPlayCheckOutcome(outcome, target, prefix) {
|
|
|
26450
26919
|
printPlayCheckLimits(result.limits);
|
|
26451
26920
|
if (result.artifactHash && outcome.exportName === PLAY_DEFAULT_EXPORT) {
|
|
26452
26921
|
console.log(
|
|
26453
|
-
` publish: deepline plays publish ${
|
|
26922
|
+
` publish: deepline plays publish ${shellQuote3(target)} --expected-artifact ${result.artifactHash}`
|
|
26454
26923
|
);
|
|
26455
26924
|
}
|
|
26456
26925
|
printPlayTriggers(result.triggers);
|
|
@@ -27083,7 +27552,7 @@ async function handleRunsList(args) {
|
|
|
27083
27552
|
return lines2.join("\n");
|
|
27084
27553
|
});
|
|
27085
27554
|
const nextOffset = (page.offset ?? offset ?? 0) + runs.length;
|
|
27086
|
-
const nextPage = page.hasMore && playName ? `deepline runs list --play ${
|
|
27555
|
+
const nextPage = page.hasMore && playName ? `deepline runs list --play ${shellQuote3(playName)}${statusFilter ? ` --status ${shellQuote3(statusFilter)}` : ""} --limit ${page.limit ?? limit ?? 20} --offset ${nextOffset} --json` : null;
|
|
27087
27556
|
if (page.hasMore) {
|
|
27088
27557
|
lines.push("List truncated \u2014 more runs match this filter.");
|
|
27089
27558
|
lines.push(
|
|
@@ -27844,7 +28313,7 @@ async function handlePlayList(args) {
|
|
|
27844
28313
|
cursor
|
|
27845
28314
|
});
|
|
27846
28315
|
const plays = page.plays;
|
|
27847
|
-
const nextPage = page.hasMore && page.cursor ? `deepline plays list${categories ? ` --categories ${
|
|
28316
|
+
const nextPage = page.hasMore && page.cursor ? `deepline plays list${categories ? ` --categories ${shellQuote3(categories)}` : ""}${limit ? ` --limit ${limit}` : ""}${showCost ? " --show-cost" : ""} --cursor ${shellQuote3(page.cursor)} --json` : null;
|
|
27848
28317
|
if (page.hasMore && !nextPage) {
|
|
27849
28318
|
throw new Error(
|
|
27850
28319
|
"Play list reported more results without a continuation cursor"
|
|
@@ -28265,7 +28734,7 @@ async function handlePlaySave(args) {
|
|
|
28265
28734
|
message: "Refusing to save: the local file no longer produces the artifact checked earlier.",
|
|
28266
28735
|
expectedArtifactHash: options.expectedArtifactHash,
|
|
28267
28736
|
currentArtifactHash: artifactHash,
|
|
28268
|
-
next: `deepline plays check ${
|
|
28737
|
+
next: `deepline plays check ${shellQuote3(options.target)}`
|
|
28269
28738
|
};
|
|
28270
28739
|
if (options.jsonOutput) {
|
|
28271
28740
|
printCompactJson(result);
|
|
@@ -28330,7 +28799,7 @@ async function handlePlaySave(args) {
|
|
|
28330
28799
|
graphHash: graph.root.artifact.graphHash,
|
|
28331
28800
|
artifactStorageKey: saved.artifactStorageKey,
|
|
28332
28801
|
next: {
|
|
28333
|
-
publish: `deepline plays publish ${
|
|
28802
|
+
publish: `deepline plays publish ${shellQuote3(options.target)} --expected-artifact ${artifactHash}`,
|
|
28334
28803
|
get: `deepline plays get ${playName} --source --out ./${playName}/ --working`
|
|
28335
28804
|
}
|
|
28336
28805
|
};
|
|
@@ -28390,7 +28859,7 @@ async function handlePlayPublish(args) {
|
|
|
28390
28859
|
message: "Refusing to publish: the local file no longer produces the artifact checked earlier.",
|
|
28391
28860
|
expectedArtifactHash: options.expectedArtifactHash,
|
|
28392
28861
|
currentArtifactHash: artifactHash,
|
|
28393
|
-
next: `deepline plays check ${
|
|
28862
|
+
next: `deepline plays check ${shellQuote3(playName)}`
|
|
28394
28863
|
};
|
|
28395
28864
|
if (options.jsonOutput) {
|
|
28396
28865
|
printCompactJson(result3);
|
|
@@ -29158,6 +29627,22 @@ Examples:
|
|
|
29158
29627
|
).option("--repo <owner/name>", "Repository to record on the deployment").option("--ref <ref>", "Branch or ref to record on the deployment").option("--commit <sha>", "Commit to record on the deployment").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(
|
|
29159
29628
|
async (directory, options) => handlePlaysDeploy(directory, options)
|
|
29160
29629
|
);
|
|
29630
|
+
play.command("deployments [id]").description(
|
|
29631
|
+
"Deployment history for this workspace; pass an id for one deployment and its plays."
|
|
29632
|
+
).addHelpText(
|
|
29633
|
+
"after",
|
|
29634
|
+
`
|
|
29635
|
+
Notes:
|
|
29636
|
+
Lists every deployment, whether \`deepline plays deploy\` or a linked
|
|
29637
|
+
repository's push made it. The same views as \`deepline git deployments\`.
|
|
29638
|
+
|
|
29639
|
+
Examples:
|
|
29640
|
+
deepline plays deployments
|
|
29641
|
+
deepline plays deployments <deployment-id>
|
|
29642
|
+
`
|
|
29643
|
+
).option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(
|
|
29644
|
+
async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
|
|
29645
|
+
);
|
|
29161
29646
|
addPublishHelp(
|
|
29162
29647
|
play.command("publish <target>").description(
|
|
29163
29648
|
"Promote a saved play revision or publish a local play file."
|
|
@@ -37571,6 +38056,7 @@ function renderMonitorJob(payload) {
|
|
|
37571
38056
|
if (!job) return void 0;
|
|
37572
38057
|
const id = asString(job.id) ?? "<unknown>";
|
|
37573
38058
|
const state = asString(job.state) ?? "unknown";
|
|
38059
|
+
const outcome = asString(job.outcome);
|
|
37574
38060
|
const phase = asString(job.phase);
|
|
37575
38061
|
const counts = asRecord2(job.counts);
|
|
37576
38062
|
const reconciliation = asRecord2(job.reconciliation);
|
|
@@ -37578,6 +38064,9 @@ function renderMonitorJob(payload) {
|
|
|
37578
38064
|
`Monitor job: ${id}`,
|
|
37579
38065
|
`State: ${state}${phase ? ` (${phase})` : ""}`
|
|
37580
38066
|
];
|
|
38067
|
+
if (outcome) lines.push(`Outcome: ${outcome}`);
|
|
38068
|
+
const operationId = asString(job.operation_id);
|
|
38069
|
+
if (operationId) lines.push(`Operation: ${operationId}`);
|
|
37581
38070
|
if (counts) {
|
|
37582
38071
|
lines.push(
|
|
37583
38072
|
`Counts: requested ${asFiniteNumber(counts.requested) ?? 0}, created ${asFiniteNumber(counts.created) ?? 0}, updated ${asFiniteNumber(counts.updated) ?? 0}, removed ${asFiniteNumber(counts.removed) ?? 0}, unchanged ${asFiniteNumber(counts.unchanged) ?? 0}, verified ${asFiniteNumber(counts.verified) ?? 0}, failed ${asFiniteNumber(counts.failed) ?? 0}`
|
|
@@ -40767,448 +41256,6 @@ Examples:
|
|
|
40767
41256
|
);
|
|
40768
41257
|
}
|
|
40769
41258
|
|
|
40770
|
-
// src/cli/commands/git.ts
|
|
40771
|
-
var GIT_DEPLOY_FEATURE = "github-deploy";
|
|
40772
|
-
function shellQuote3(value) {
|
|
40773
|
-
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
40774
|
-
}
|
|
40775
|
-
function renderProject(project) {
|
|
40776
|
-
const root = project.rootDirectory ? ` (${project.rootDirectory})` : "";
|
|
40777
|
-
const flags = [
|
|
40778
|
-
project.disabled ? "unlinked" : "linked",
|
|
40779
|
-
`deploys ${project.productionBranch}`,
|
|
40780
|
-
project.checkOnPullRequest ? "PR checks on" : "PR checks off"
|
|
40781
|
-
].join(", ");
|
|
40782
|
-
return `${project.id} ${project.repoFullName}${root} - ${flags}`;
|
|
40783
|
-
}
|
|
40784
|
-
function renderDeployment(deployment) {
|
|
40785
|
-
const kind = deployment.isProduction ? "production" : deployment.trigger === "pull_request" ? `pr #${deployment.pullRequestNumber ?? "?"}` : deployment.trigger;
|
|
40786
|
-
const suffix = deployment.error ? ` - ${deployment.error.slice(0, 80)}` : "";
|
|
40787
|
-
const source = [
|
|
40788
|
-
deployment.commitSha?.slice(0, 10),
|
|
40789
|
-
deployment.ref?.replace("refs/heads/", "") ?? deployment.repoFullName
|
|
40790
|
-
].filter(Boolean).join(" ") || "directory";
|
|
40791
|
-
return `${deployment.id} ${source} (${kind}) - ${deployment.status}${suffix}`;
|
|
40792
|
-
}
|
|
40793
|
-
async function handleList(options) {
|
|
40794
|
-
const { http } = getAuthedHttpClient();
|
|
40795
|
-
const payload = await http.get(
|
|
40796
|
-
`/api/v2/play-projects${options.all ? "?includeDisabled=1" : ""}`
|
|
40797
|
-
);
|
|
40798
|
-
printCommandEnvelope(
|
|
40799
|
-
{
|
|
40800
|
-
projects: payload.projects,
|
|
40801
|
-
count: payload.projects.length,
|
|
40802
|
-
render: {
|
|
40803
|
-
sections: [
|
|
40804
|
-
{
|
|
40805
|
-
title: "linked repositories",
|
|
40806
|
-
lines: payload.projects.length ? payload.projects.map(renderProject) : [
|
|
40807
|
-
"No repositories are linked. Run `deepline git repos` to see what the GitHub installation can reach, then `deepline git link`."
|
|
40808
|
-
]
|
|
40809
|
-
}
|
|
40810
|
-
]
|
|
40811
|
-
}
|
|
40812
|
-
},
|
|
40813
|
-
{ json: options.json }
|
|
40814
|
-
);
|
|
40815
|
-
}
|
|
40816
|
-
function describeInstallationStatus(installation) {
|
|
40817
|
-
switch (installation.status) {
|
|
40818
|
-
case "active":
|
|
40819
|
-
return [
|
|
40820
|
-
`Connected to ${installation.accountLogin} (installation ${installation.installationId}).`
|
|
40821
|
-
];
|
|
40822
|
-
case "uninstalled":
|
|
40823
|
-
return [
|
|
40824
|
-
`The Deepline GitHub App was uninstalled from ${installation.accountLogin}${installation.uninstalledAt ? ` at ${new Date(installation.uninstalledAt).toISOString()}` : ""}.`,
|
|
40825
|
-
"Deploys are paused for every linked repository. Run `deepline git connect`, then `deepline git link <owner/repo>` again for each repository; links from the old installation cannot be resumed."
|
|
40826
|
-
];
|
|
40827
|
-
case "suspended":
|
|
40828
|
-
return [
|
|
40829
|
-
`GitHub suspended the Deepline App on ${installation.accountLogin}${installation.suspendedAt ? ` at ${new Date(installation.suspendedAt).toISOString()}` : ""}.`,
|
|
40830
|
-
"Pushes are not delivered while it is suspended; unsuspend it in GitHub settings."
|
|
40831
|
-
];
|
|
40832
|
-
}
|
|
40833
|
-
}
|
|
40834
|
-
async function handleStatus2(options) {
|
|
40835
|
-
const { http } = getAuthedHttpClient();
|
|
40836
|
-
const payload = await http.get("/api/v2/github/installation");
|
|
40837
|
-
const installation = payload.installation;
|
|
40838
|
-
const others = (payload.installations ?? []).filter(
|
|
40839
|
-
(row) => row.installationId !== installation?.installationId
|
|
40840
|
-
);
|
|
40841
|
-
const lines = installation ? describeInstallationStatus(installation) : [
|
|
40842
|
-
"No GitHub installation is connected to this workspace. Run `deepline git connect`."
|
|
40843
|
-
];
|
|
40844
|
-
for (const other of others) {
|
|
40845
|
-
lines.push(
|
|
40846
|
-
`Also: ${other.accountLogin} (installation ${other.installationId}) is ${other.status}.`
|
|
40847
|
-
);
|
|
40848
|
-
}
|
|
40849
|
-
const byId = new Map(
|
|
40850
|
-
(payload.installations ?? []).map((row) => [row.installationId, row])
|
|
40851
|
-
);
|
|
40852
|
-
const { projects } = await http.get(
|
|
40853
|
-
"/api/v2/play-projects?includeDisabled=1"
|
|
40854
|
-
);
|
|
40855
|
-
const affected_links = projects.map((project) => {
|
|
40856
|
-
const own = byId.get(project.installationId);
|
|
40857
|
-
const verdict = !own ? "unknown" : own.status === "active" ? null : own.status;
|
|
40858
|
-
return verdict ? {
|
|
40859
|
-
id: project.id,
|
|
40860
|
-
repoId: project.repoId,
|
|
40861
|
-
repoFullName: project.repoFullName,
|
|
40862
|
-
rootDirectory: project.rootDirectory,
|
|
40863
|
-
productionBranch: project.productionBranch,
|
|
40864
|
-
manifestPath: project.manifestPath,
|
|
40865
|
-
checkOnPullRequest: project.checkOnPullRequest,
|
|
40866
|
-
disabled: project.disabled,
|
|
40867
|
-
installationId: project.installationId,
|
|
40868
|
-
installationStatus: verdict
|
|
40869
|
-
} : null;
|
|
40870
|
-
}).filter((row) => row !== null);
|
|
40871
|
-
const activeInstallations = (payload.installations ?? []).filter(
|
|
40872
|
-
(row) => row.status === "active"
|
|
40873
|
-
);
|
|
40874
|
-
const relinkCommand = (link2) => [
|
|
40875
|
-
// The numeric repo id, not the name: a repository renamed while the
|
|
40876
|
-
// App was gone keeps a stale name here, and `git link` accepts the id.
|
|
40877
|
-
`deepline git link ${link2.repoId}`,
|
|
40878
|
-
// Stored values are admin-controlled text and this line is
|
|
40879
|
-
// copy-pasted into a shell by whoever reads it, so every
|
|
40880
|
-
// interpolated value below is quoted.
|
|
40881
|
-
`--branch ${shellQuote3(link2.productionBranch)}`,
|
|
40882
|
-
link2.rootDirectory ? `--root-dir ${shellQuote3(link2.rootDirectory)}` : "",
|
|
40883
|
-
link2.manifestPath && link2.manifestPath !== "deepline.json" ? `--manifest ${shellQuote3(link2.manifestPath)}` : "",
|
|
40884
|
-
link2.checkOnPullRequest ? "" : "--no-pr-checks",
|
|
40885
|
-
// With several active installations no id is guessed: the reader picks.
|
|
40886
|
-
activeInstallations.length > 1 ? "--installation <id>" : ""
|
|
40887
|
-
].filter(Boolean).join(" ");
|
|
40888
|
-
for (const link2 of affected_links) {
|
|
40889
|
-
const label = `${link2.repoFullName}${link2.rootDirectory ? ` (${link2.rootDirectory})` : ""}`;
|
|
40890
|
-
lines.push(
|
|
40891
|
-
link2.installationStatus !== "suspended" ? `Link again: ${label} \u2014 its installation ${link2.installationId} is ${link2.installationStatus}; run \`${relinkCommand(link2)}\`${activeInstallations.length > 1 ? ` with <id> being the installation that reaches this repo: ${activeInstallations.map((row) => `${row.installationId} (${row.accountLogin})`).join(", ")}` : ""}.` : (
|
|
40892
|
-
// A link disabled during the suspension stays disabled; only an
|
|
40893
|
-
// enabled one picks up again on its own when GitHub unsuspends.
|
|
40894
|
-
link2.disabled ? `Paused and disabled: ${label} \u2014 its installation is suspended, and the link stays disabled after GitHub unsuspends it until you run \`deepline git set ${link2.id} --enabled\`.` : `Paused: ${label} \u2014 its installation is suspended; pushes resume when GitHub unsuspends it.`
|
|
40895
|
-
)
|
|
40896
|
-
);
|
|
40897
|
-
}
|
|
40898
|
-
printCommandEnvelope(
|
|
40899
|
-
{
|
|
40900
|
-
installation,
|
|
40901
|
-
installations: payload.installations ?? [],
|
|
40902
|
-
affected_links,
|
|
40903
|
-
render: { sections: [{ title: "github installation", lines }] }
|
|
40904
|
-
},
|
|
40905
|
-
{ json: options.json }
|
|
40906
|
-
);
|
|
40907
|
-
}
|
|
40908
|
-
async function handleRepos(options) {
|
|
40909
|
-
const { http } = getAuthedHttpClient();
|
|
40910
|
-
const query = options.installation ? `?installationId=${encodeURIComponent(options.installation)}` : "";
|
|
40911
|
-
const payload = await http.get(`/api/v2/github/repos${query}`);
|
|
40912
|
-
printCommandEnvelope(
|
|
40913
|
-
{
|
|
40914
|
-
installation: payload.installation,
|
|
40915
|
-
repositories: payload.repositories,
|
|
40916
|
-
count: payload.repositories.length,
|
|
40917
|
-
render: {
|
|
40918
|
-
sections: [
|
|
40919
|
-
{
|
|
40920
|
-
title: `repos on installation @${payload.installation.accountLogin} (${payload.installation.repositorySelection})`,
|
|
40921
|
-
lines: payload.repositories.map(
|
|
40922
|
-
(repo) => `${repo.repoId} ${repo.fullName} (default: ${repo.defaultBranch}${repo.private ? ", private" : ""}${repo.fork ? ", fork" : ""})`
|
|
40923
|
-
)
|
|
40924
|
-
}
|
|
40925
|
-
]
|
|
40926
|
-
}
|
|
40927
|
-
},
|
|
40928
|
-
{ json: options.json }
|
|
40929
|
-
);
|
|
40930
|
-
}
|
|
40931
|
-
async function resolveRepoId(repo, installation) {
|
|
40932
|
-
if (/^\d+$/.test(repo)) return Number(repo);
|
|
40933
|
-
const { http } = getAuthedHttpClient();
|
|
40934
|
-
const query = installation ? `?installationId=${encodeURIComponent(installation)}` : "";
|
|
40935
|
-
const payload = await http.get(
|
|
40936
|
-
`/api/v2/github/repos${query}`
|
|
40937
|
-
);
|
|
40938
|
-
const match = payload.repositories.find(
|
|
40939
|
-
(entry) => entry.fullName.toLowerCase() === repo.toLowerCase()
|
|
40940
|
-
);
|
|
40941
|
-
if (!match) {
|
|
40942
|
-
throw new Error(
|
|
40943
|
-
`Repo "${repo}" is not accessible to the workspace's GitHub installation. Run \`deepline git repos\` to list what is.`
|
|
40944
|
-
);
|
|
40945
|
-
}
|
|
40946
|
-
return match.repoId;
|
|
40947
|
-
}
|
|
40948
|
-
async function handleLink(repo, options) {
|
|
40949
|
-
const repoId = await resolveRepoId(repo, options.installation);
|
|
40950
|
-
const { http } = getAuthedHttpClient();
|
|
40951
|
-
const payload = await http.post("/api/v2/play-projects", {
|
|
40952
|
-
repoId,
|
|
40953
|
-
...options.installation !== void 0 ? { installationId: options.installation } : {},
|
|
40954
|
-
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
40955
|
-
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
40956
|
-
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
40957
|
-
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {}
|
|
40958
|
-
});
|
|
40959
|
-
printCommandEnvelope(
|
|
40960
|
-
{
|
|
40961
|
-
project: payload.project,
|
|
40962
|
-
render: {
|
|
40963
|
-
sections: [
|
|
40964
|
-
{
|
|
40965
|
-
title: "linked",
|
|
40966
|
-
lines: [
|
|
40967
|
-
renderProject(payload.project),
|
|
40968
|
-
...(payload.warnings ?? []).map(
|
|
40969
|
-
(warning) => `WARNING: ${warning}`
|
|
40970
|
-
),
|
|
40971
|
-
"Pushes to the production branch now register and promote changed plays.",
|
|
40972
|
-
"Anyone who can push to this repo can change what runs in this workspace."
|
|
40973
|
-
]
|
|
40974
|
-
}
|
|
40975
|
-
]
|
|
40976
|
-
}
|
|
40977
|
-
},
|
|
40978
|
-
{ json: options.json }
|
|
40979
|
-
);
|
|
40980
|
-
}
|
|
40981
|
-
async function handleGet(id, options) {
|
|
40982
|
-
const { http } = getAuthedHttpClient();
|
|
40983
|
-
const payload = await http.get(
|
|
40984
|
-
`/api/v2/play-projects/${encodeURIComponent(id)}`
|
|
40985
|
-
);
|
|
40986
|
-
printCommandEnvelope(
|
|
40987
|
-
{
|
|
40988
|
-
project: payload.project,
|
|
40989
|
-
render: {
|
|
40990
|
-
sections: [
|
|
40991
|
-
{
|
|
40992
|
-
title: "linked repository",
|
|
40993
|
-
lines: [renderProject(payload.project)]
|
|
40994
|
-
}
|
|
40995
|
-
]
|
|
40996
|
-
}
|
|
40997
|
-
},
|
|
40998
|
-
{ json: options.json }
|
|
40999
|
-
);
|
|
41000
|
-
}
|
|
41001
|
-
async function handleSet(id, options) {
|
|
41002
|
-
const { http } = getAuthedHttpClient();
|
|
41003
|
-
const payload = await http.patch(
|
|
41004
|
-
`/api/v2/play-projects/${encodeURIComponent(id)}`,
|
|
41005
|
-
{
|
|
41006
|
-
...options.branch !== void 0 ? { productionBranch: options.branch } : {},
|
|
41007
|
-
...options.rootDir !== void 0 ? { rootDirectory: options.rootDir } : {},
|
|
41008
|
-
...options.manifest !== void 0 ? { manifestPath: options.manifest } : {},
|
|
41009
|
-
...options.prChecks !== void 0 ? { checkOnPullRequest: options.prChecks } : {},
|
|
41010
|
-
...options.disabled !== void 0 ? { disabled: options.disabled } : {}
|
|
41011
|
-
}
|
|
41012
|
-
);
|
|
41013
|
-
printCommandEnvelope(
|
|
41014
|
-
{
|
|
41015
|
-
project: payload.project,
|
|
41016
|
-
render: {
|
|
41017
|
-
sections: [
|
|
41018
|
-
{ title: "updated", lines: [renderProject(payload.project)] }
|
|
41019
|
-
]
|
|
41020
|
-
}
|
|
41021
|
-
},
|
|
41022
|
-
{ json: options.json }
|
|
41023
|
-
);
|
|
41024
|
-
}
|
|
41025
|
-
async function handleUnlink(id, options) {
|
|
41026
|
-
const { http } = getAuthedHttpClient();
|
|
41027
|
-
await http.delete(`/api/v2/play-projects/${encodeURIComponent(id)}`);
|
|
41028
|
-
printCommandEnvelope(
|
|
41029
|
-
{
|
|
41030
|
-
ok: true,
|
|
41031
|
-
id,
|
|
41032
|
-
render: {
|
|
41033
|
-
sections: [
|
|
41034
|
-
{
|
|
41035
|
-
title: "unlinked",
|
|
41036
|
-
lines: [
|
|
41037
|
-
`Repository link ${id} removed. Deployments stop immediately and in-flight deploy credentials die; live plays keep running.`
|
|
41038
|
-
]
|
|
41039
|
-
}
|
|
41040
|
-
]
|
|
41041
|
-
}
|
|
41042
|
-
},
|
|
41043
|
-
{ json: options.json }
|
|
41044
|
-
);
|
|
41045
|
-
}
|
|
41046
|
-
async function handleConnect(options) {
|
|
41047
|
-
const baseUrl = resolveBaseUrlOnly();
|
|
41048
|
-
const connectUrl = `${baseUrl.replace(/\/$/, "")}/api/v2/github/connect`;
|
|
41049
|
-
const opened = openInBrowser(connectUrl);
|
|
41050
|
-
printCommandEnvelope(
|
|
41051
|
-
{
|
|
41052
|
-
connectUrl,
|
|
41053
|
-
browser: opened,
|
|
41054
|
-
render: {
|
|
41055
|
-
sections: [
|
|
41056
|
-
{
|
|
41057
|
-
title: "connect GitHub",
|
|
41058
|
-
lines: [
|
|
41059
|
-
opened === "opened" ? `Opened ${connectUrl} in your browser.` : `Open ${connectUrl} in your browser.`,
|
|
41060
|
-
"Sign in as a workspace admin if prompted, approve the GitHub",
|
|
41061
|
-
"installation, then return here and run `deepline git repos`."
|
|
41062
|
-
]
|
|
41063
|
-
}
|
|
41064
|
-
]
|
|
41065
|
-
}
|
|
41066
|
-
},
|
|
41067
|
-
{ json: options.json }
|
|
41068
|
-
);
|
|
41069
|
-
}
|
|
41070
|
-
async function handleDeploymentsList(options) {
|
|
41071
|
-
const { http } = getAuthedHttpClient();
|
|
41072
|
-
const query = new URLSearchParams();
|
|
41073
|
-
if (options.repo) query.set("projectId", options.repo);
|
|
41074
|
-
if (options.limit) query.set("limit", options.limit);
|
|
41075
|
-
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
41076
|
-
const payload = await http.get(
|
|
41077
|
-
`/api/v2/deployments${suffix}`
|
|
41078
|
-
);
|
|
41079
|
-
printCommandEnvelope(
|
|
41080
|
-
{
|
|
41081
|
-
deployments: payload.deployments,
|
|
41082
|
-
count: payload.deployments.length,
|
|
41083
|
-
render: {
|
|
41084
|
-
sections: [
|
|
41085
|
-
{
|
|
41086
|
-
title: "deployments",
|
|
41087
|
-
lines: payload.deployments.length ? payload.deployments.map(renderDeployment) : [
|
|
41088
|
-
"No deployments yet. Push to a linked repository to create one."
|
|
41089
|
-
]
|
|
41090
|
-
}
|
|
41091
|
-
]
|
|
41092
|
-
}
|
|
41093
|
-
},
|
|
41094
|
-
{ json: options.json }
|
|
41095
|
-
);
|
|
41096
|
-
}
|
|
41097
|
-
async function handleDeploymentGet(id, options) {
|
|
41098
|
-
const { http } = getAuthedHttpClient();
|
|
41099
|
-
const payload = await http.get(`/api/v2/deployments/${encodeURIComponent(id)}`);
|
|
41100
|
-
const results = payload.deployment.results;
|
|
41101
|
-
const playLines = Array.isArray(results?.plays) ? results.plays.map(
|
|
41102
|
-
(play) => `${play.name ?? "?"} - ${play.status ?? "?"}${play.error ? `: ${play.error}` : ""}`
|
|
41103
|
-
) : [];
|
|
41104
|
-
printCommandEnvelope(
|
|
41105
|
-
{
|
|
41106
|
-
deployment: payload.deployment,
|
|
41107
|
-
project: payload.project,
|
|
41108
|
-
render: {
|
|
41109
|
-
sections: [
|
|
41110
|
-
{
|
|
41111
|
-
title: `deployment ${payload.deployment.id}${payload.project ? ` (${payload.project.repoFullName})` : ""}`,
|
|
41112
|
-
lines: [renderDeployment(payload.deployment)]
|
|
41113
|
-
},
|
|
41114
|
-
...playLines.length ? [{ title: "plays", lines: playLines }] : []
|
|
41115
|
-
]
|
|
41116
|
-
}
|
|
41117
|
-
},
|
|
41118
|
-
{ json: options.json }
|
|
41119
|
-
);
|
|
41120
|
-
}
|
|
41121
|
-
async function handleDeploymentCancel(id, options) {
|
|
41122
|
-
const { http } = getAuthedHttpClient();
|
|
41123
|
-
const payload = await http.post(`/api/v2/deployments/${encodeURIComponent(id)}/cancel`, {});
|
|
41124
|
-
printCommandEnvelope(
|
|
41125
|
-
{
|
|
41126
|
-
cancelled: payload.cancelled,
|
|
41127
|
-
deployment: payload.deployment,
|
|
41128
|
-
render: {
|
|
41129
|
-
sections: [
|
|
41130
|
-
{
|
|
41131
|
-
title: payload.cancelled ? "cancelled" : "already cancelled",
|
|
41132
|
-
lines: [
|
|
41133
|
-
payload.deployment ? renderDeployment(payload.deployment) : `Deployment ${id} cancelled.`,
|
|
41134
|
-
"The build stops at its next step and nothing from it goes live."
|
|
41135
|
-
]
|
|
41136
|
-
}
|
|
41137
|
-
]
|
|
41138
|
-
}
|
|
41139
|
-
},
|
|
41140
|
-
{ json: options.json }
|
|
41141
|
-
);
|
|
41142
|
-
}
|
|
41143
|
-
function registerGitCommands(program) {
|
|
41144
|
-
const git = program.command("git", { hidden: !cliFeatureEnabled(GIT_DEPLOY_FEATURE) }).alias("projects").description(
|
|
41145
|
-
"Git deploys: link repositories to this workspace and deploy plays on push."
|
|
41146
|
-
).addHelpText(
|
|
41147
|
-
"after",
|
|
41148
|
-
`
|
|
41149
|
-
Examples:
|
|
41150
|
-
deepline git connect
|
|
41151
|
-
deepline git repos
|
|
41152
|
-
deepline git link acme/growth --branch main
|
|
41153
|
-
deepline git list
|
|
41154
|
-
deepline git set <id> --branch release
|
|
41155
|
-
deepline git unlink <id>
|
|
41156
|
-
deepline git deployments --repo <id>
|
|
41157
|
-
deepline git cancel <deployment-id>
|
|
41158
|
-
`
|
|
41159
|
-
);
|
|
41160
|
-
git.command("connect").description("Connect a GitHub installation (browser step).").option("--json", "Emit JSON output").action(async (options) => handleConnect(options));
|
|
41161
|
-
git.command("status").description(
|
|
41162
|
-
"Show the workspace's GitHub installation and whether it is still usable."
|
|
41163
|
-
).option("--json", "Emit JSON output").action(async (options) => handleStatus2(options));
|
|
41164
|
-
git.command("repos").description("List repos the workspace's GitHub installation can reach.").option(
|
|
41165
|
-
"--installation <id>",
|
|
41166
|
-
"GitHub installation id (required when several are connected)"
|
|
41167
|
-
).option("--json", "Emit JSON output").action(
|
|
41168
|
-
async (options) => handleRepos(options)
|
|
41169
|
-
);
|
|
41170
|
-
git.command("list").description("List linked repositories.").option("--all", "Include unlinked repositories").option("--json", "Emit JSON output").action(
|
|
41171
|
-
async (options) => handleList(options)
|
|
41172
|
-
);
|
|
41173
|
-
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(
|
|
41174
|
-
"--manifest <file>",
|
|
41175
|
-
"Manifest file name under the base path (default: deepline.json)"
|
|
41176
|
-
).option(
|
|
41177
|
-
"--installation <id>",
|
|
41178
|
-
"GitHub installation id (required when several are connected)"
|
|
41179
|
-
).option("--no-pr-checks", "Skip Check Runs on pull requests").option("--json", "Emit JSON output").action(
|
|
41180
|
-
async (repo, options) => handleLink(repo, options)
|
|
41181
|
-
);
|
|
41182
|
-
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));
|
|
41183
|
-
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(
|
|
41184
|
-
"--manifest <file>",
|
|
41185
|
-
"Manifest file name under the base path (default: deepline.json)"
|
|
41186
|
-
).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(
|
|
41187
|
-
async (id, options) => handleSet(id, {
|
|
41188
|
-
...options,
|
|
41189
|
-
disabled: options.enabled === true ? false : options.disabled === true ? true : void 0
|
|
41190
|
-
})
|
|
41191
|
-
);
|
|
41192
|
-
git.command("unlink").description("Unlink a repository (live plays keep running).").argument("<id>", "Repository link id").option("--json", "Emit JSON output").action(
|
|
41193
|
-
async (id, options) => handleUnlink(id, options)
|
|
41194
|
-
);
|
|
41195
|
-
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(
|
|
41196
|
-
async (id, options) => id ? handleDeploymentGet(id, options) : handleDeploymentsList(options)
|
|
41197
|
-
);
|
|
41198
|
-
git.command("cancel").description(
|
|
41199
|
-
"Cancel a queued or running deployment before its plays go live (admin)."
|
|
41200
|
-
).argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
|
|
41201
|
-
async (id, options) => handleDeploymentCancel(id, options)
|
|
41202
|
-
);
|
|
41203
|
-
const deployments = program.command("deployments", { hidden: true });
|
|
41204
|
-
deployments.command("list").option("--project <id>", "Filter to one repository link").option("--limit <n>", "Max rows (default 50)").option("--json", "Emit JSON output").action(
|
|
41205
|
-
async (options) => handleDeploymentsList({ ...options, repo: options.project })
|
|
41206
|
-
);
|
|
41207
|
-
deployments.command("get").argument("<id>", "Deployment id").option("--json", "Emit JSON output").action(
|
|
41208
|
-
async (id, options) => handleDeploymentGet(id, options)
|
|
41209
|
-
);
|
|
41210
|
-
}
|
|
41211
|
-
|
|
41212
41259
|
// src/cli/getting-started.ts
|
|
41213
41260
|
var DEEPLINE_GTM_SKILL = "/deepline-gtm";
|
|
41214
41261
|
var DEEPLINE_GTM_STARTER_PROMPTS = [
|
|
@@ -41303,6 +41350,33 @@ function normalizeSecretName(value) {
|
|
|
41303
41350
|
}
|
|
41304
41351
|
return normalized;
|
|
41305
41352
|
}
|
|
41353
|
+
function normalizePlaySelector(value) {
|
|
41354
|
+
const normalized = value?.trim();
|
|
41355
|
+
if (value !== void 0 && !normalized) {
|
|
41356
|
+
throw new Error("--play requires a bare Play name.");
|
|
41357
|
+
}
|
|
41358
|
+
if (!normalized) return void 0;
|
|
41359
|
+
if (normalized.includes("/")) {
|
|
41360
|
+
throw new Error(
|
|
41361
|
+
"--play expects the bare Play name, not an org-qualified name."
|
|
41362
|
+
);
|
|
41363
|
+
}
|
|
41364
|
+
return normalized;
|
|
41365
|
+
}
|
|
41366
|
+
function resolveSecretWriteScope(options) {
|
|
41367
|
+
const playName = normalizePlaySelector(options.play);
|
|
41368
|
+
if (options.scope && options.scope !== "org" && options.scope !== "play") {
|
|
41369
|
+
throw new Error("--scope must be either org or play.");
|
|
41370
|
+
}
|
|
41371
|
+
const scope = options.scope === void 0 ? playName ? "play" : "org" : options.scope;
|
|
41372
|
+
if (scope === "play" && !playName) {
|
|
41373
|
+
throw new Error("--play <name> is required when --scope play is used.");
|
|
41374
|
+
}
|
|
41375
|
+
if (scope === "org" && playName) {
|
|
41376
|
+
throw new Error("--play can only be used with --scope play.");
|
|
41377
|
+
}
|
|
41378
|
+
return scope === "play" ? { scope, playName } : { scope };
|
|
41379
|
+
}
|
|
41306
41380
|
function renderSecret(secret) {
|
|
41307
41381
|
const scope = secret.scope === "play" && secret.playName ? `play:${secret.playName}` : secret.scope;
|
|
41308
41382
|
const added = new Date(secret.createdAt).toISOString();
|
|
@@ -41472,7 +41546,8 @@ async function handleList2(options) {
|
|
|
41472
41546
|
async function handleCheck(nameInput, options) {
|
|
41473
41547
|
const name = normalizeSecretName(nameInput);
|
|
41474
41548
|
const client2 = new DeeplineClient();
|
|
41475
|
-
const
|
|
41549
|
+
const playName = options.play === void 0 ? void 0 : normalizePlaySelector(options.play);
|
|
41550
|
+
const check = playName !== void 0 ? await client2.inspectSecret(name, { playName }) : null;
|
|
41476
41551
|
const secret = check ? check.secret : await client2.checkSecret(name);
|
|
41477
41552
|
const ok = check ? check.ok : Boolean(secret);
|
|
41478
41553
|
const quotedPlay = `'${(options.play ?? "PLAY").replace(/'/g, `'"'"'`)}'`;
|
|
@@ -41503,11 +41578,7 @@ async function handleCheck(nameInput, options) {
|
|
|
41503
41578
|
async function handleSet2(nameInput, forbidden, options) {
|
|
41504
41579
|
preventShellHistoryLeak(forbidden);
|
|
41505
41580
|
const name = normalizeSecretName(nameInput);
|
|
41506
|
-
const
|
|
41507
|
-
const playName = options.play?.trim();
|
|
41508
|
-
if (scope === "play" && !playName) {
|
|
41509
|
-
throw new Error("--play <name> is required when --scope play is used.");
|
|
41510
|
-
}
|
|
41581
|
+
const { scope, playName } = resolveSecretWriteScope(options);
|
|
41511
41582
|
const value = await readSecretValueFromOptions(options);
|
|
41512
41583
|
const { http } = getAuthedHttpClient();
|
|
41513
41584
|
const response = await http.post(
|
|
@@ -41599,7 +41670,8 @@ Notes:
|
|
|
41599
41670
|
Secret values are never accepted as command arguments. Use the hidden prompt,
|
|
41600
41671
|
or one explicit non-argv source: --value-stdin, --from-env NAME, or
|
|
41601
41672
|
--from-file PATH. Values are never printed. secrets list shows only metadata,
|
|
41602
|
-
including any note you intentionally added.
|
|
41673
|
+
including any note you intentionally added. Supplying --play implies
|
|
41674
|
+
--scope play; --play expects the bare Play name in the current workspace.
|
|
41603
41675
|
|
|
41604
41676
|
Examples:
|
|
41605
41677
|
deepline secrets list
|
|
@@ -41625,7 +41697,7 @@ Examples:
|
|
|
41625
41697
|
).option("--json", "Emit JSON output").action(async (name, options) => {
|
|
41626
41698
|
await handleCheck(name, options);
|
|
41627
41699
|
});
|
|
41628
|
-
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
|
|
41700
|
+
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; --play implies play").option("--play <name>", "Play name for play-scoped secrets").option(
|
|
41629
41701
|
"--note <note>",
|
|
41630
41702
|
"Optional non-sensitive memo (maximum 500 characters)"
|
|
41631
41703
|
).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(
|
|
@@ -42240,7 +42312,7 @@ async function maybeReportSdkCliFailure(input2) {
|
|
|
42240
42312
|
// src/cli/skills-sync.ts
|
|
42241
42313
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
42242
42314
|
function shouldSkipSkillsSync() {
|
|
42243
|
-
if (detectAgentRuntime() === "claude_cowork") {
|
|
42315
|
+
if (detectAgentRuntime() === "claude_cowork" || isCiEnvironment()) {
|
|
42244
42316
|
return true;
|
|
42245
42317
|
}
|
|
42246
42318
|
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
@@ -49667,11 +49739,8 @@ function envTruthy(name) {
|
|
|
49667
49739
|
const value = process.env[name]?.trim().toLowerCase();
|
|
49668
49740
|
return value === "1" || value === "true" || value === "yes";
|
|
49669
49741
|
}
|
|
49670
|
-
function isCi() {
|
|
49671
|
-
return envTruthy("CI") || envTruthy("GITHUB_ACTIONS");
|
|
49672
|
-
}
|
|
49673
49742
|
function shouldSkipSelfUpdate() {
|
|
49674
|
-
return envTruthy("DEEPLINE_SKIP_SELF_UPDATE") || envTruthy("DEEPLINE_NO_AUTO_UPDATE") || envTruthy("DEEPLINE_SKIP_SDK_AUTO_UPDATE") || envTruthy("DEEPLINE_DISABLE_AUTO_UPDATE") || !shouldRunCliAutoUpdate() ||
|
|
49743
|
+
return envTruthy("DEEPLINE_SKIP_SELF_UPDATE") || envTruthy("DEEPLINE_NO_AUTO_UPDATE") || envTruthy("DEEPLINE_SKIP_SDK_AUTO_UPDATE") || envTruthy("DEEPLINE_DISABLE_AUTO_UPDATE") || !shouldRunCliAutoUpdate() || isCiEnvironment();
|
|
49675
49744
|
}
|
|
49676
49745
|
function parseSemver(version) {
|
|
49677
49746
|
const trimmed = version?.trim();
|