@contextecf/guardian-cli 0.1.3 → 0.1.5
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/README.md +93 -15
- package/dist/packages/guardian-cli/src/bin.js +1036 -43
- package/dist/packages/guardian-cli/src/index.js +882 -39
- package/dist/packages/guardian-cli/src/runtime.d.ts +214 -2
- package/package.json +2 -2
|
@@ -16275,13 +16275,16 @@ function cloneList(values) {
|
|
|
16275
16275
|
}
|
|
16276
16276
|
|
|
16277
16277
|
// packages/guardian-cli/src/runtime.ts
|
|
16278
|
-
var GUARDIAN_CLI_VERSION = "0.1.
|
|
16278
|
+
var GUARDIAN_CLI_VERSION = "0.1.5";
|
|
16279
16279
|
var GUARDIAN_PROFILE_SCHEMA_VERSION = "contextecf/project-guardian-profile/v1";
|
|
16280
16280
|
var GUARDIAN_NPM_PACKAGE_NAME = "@contextecf/guardian-cli";
|
|
16281
|
+
var GUARDIAN_NPM_REGISTRY = "https://registry.npmjs.org/";
|
|
16281
16282
|
var GUARDIAN_GLOBAL_INSTALL_COMMAND = `npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}`;
|
|
16282
16283
|
var GUARDIAN_NPX_SETUP_COMMAND = `npx ${GUARDIAN_NPM_PACKAGE_NAME}@latest setup`;
|
|
16283
16284
|
var GUARDIAN_FIRST_RUN_COMMAND = "guardian setup";
|
|
16284
|
-
var GUARDIAN_OPEN_CONTROL_TOWER_COMMAND = "guardian
|
|
16285
|
+
var GUARDIAN_OPEN_CONTROL_TOWER_COMMAND = "guardian open";
|
|
16286
|
+
var GUARDIAN_RELEASE_DISPATCH_WORKFLOW = "guardian-release-dispatch.yml";
|
|
16287
|
+
var GUARDIAN_RELEASE_REPOSITORY = "Intelligent-Context-AI-Inc/ContextECF-GITHUB";
|
|
16285
16288
|
var GUARDIAN_CONTROL_TOWER_URL_ENV = "GUARDIAN_CONTROL_TOWER_URL";
|
|
16286
16289
|
var GUARDIAN_DEFAULT_CONTROL_TOWER_URL = "http://127.0.0.1:4317/control-tower";
|
|
16287
16290
|
var GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ENV = "GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY";
|
|
@@ -16708,28 +16711,6 @@ var GUARDIAN_NOT_PROVEN_PRODUCTION_GATES = [
|
|
|
16708
16711
|
"Release evidence includes artifact digests without signing secrets."
|
|
16709
16712
|
]
|
|
16710
16713
|
},
|
|
16711
|
-
{
|
|
16712
|
-
id: "browser-store-distribution",
|
|
16713
|
-
label: "Browser store distribution",
|
|
16714
|
-
boundary: "Pending store submission, review, and release evidence.",
|
|
16715
|
-
owner: "browser-release",
|
|
16716
|
-
runtimeBoundary: "Pending store submission, review, and release evidence.",
|
|
16717
|
-
releaseBoundary: "Browser store approval and listing evidence are not yet proven.",
|
|
16718
|
-
evidencePacket: "browser-store-distribution",
|
|
16719
|
-
evidenceRequiredFields: [
|
|
16720
|
-
"stores",
|
|
16721
|
-
"submitted_versions",
|
|
16722
|
-
"review_status",
|
|
16723
|
-
"package_digest_matches_release",
|
|
16724
|
-
"listing_boundary_proof"
|
|
16725
|
-
],
|
|
16726
|
-
closesWhen: [
|
|
16727
|
-
"Chrome Web Store package id, version, and approval state are recorded.",
|
|
16728
|
-
"Any claimed Edge or Firefox store distribution has matching approval evidence.",
|
|
16729
|
-
"Store package digest matches the validated MV3 release artifact.",
|
|
16730
|
-
"Store listing text uses the same proven/not-proven boundary."
|
|
16731
|
-
]
|
|
16732
|
-
},
|
|
16733
16714
|
{
|
|
16734
16715
|
id: "high-risk-desktop-action-execution",
|
|
16735
16716
|
label: "High-risk desktop action execution after authorization",
|
|
@@ -16810,19 +16791,26 @@ No global install:
|
|
|
16810
16791
|
|
|
16811
16792
|
Open Control Tower:
|
|
16812
16793
|
${GUARDIAN_OPEN_CONTROL_TOWER_COMMAND}
|
|
16813
|
-
aliases: guardian tower, guardian control-tower
|
|
16794
|
+
start aliases: guardian launch, guardian tower, guardian control-tower
|
|
16814
16795
|
|
|
16815
16796
|
Usage:
|
|
16816
16797
|
guardian --version
|
|
16817
16798
|
guardian version [--json]
|
|
16818
|
-
guardian setup [--json] [--print] [--host=127.0.0.1] [--port=4317] [--no-launch] [--no-mcp] [--extension-id=<chrome-extension-id>]
|
|
16799
|
+
guardian setup [--json] [--open] [--print] [--host=127.0.0.1] [--port=4317] [--no-launch] [--no-mcp] [--extension-id=<chrome-extension-id>]
|
|
16819
16800
|
guardian install [--json]
|
|
16820
16801
|
guardian doctor [--json]
|
|
16821
16802
|
guardian readiness [--json] [--strict]
|
|
16803
|
+
guardian release checklist --version=<semver> [--json]
|
|
16804
|
+
guardian release flow --version=<semver> [--json]
|
|
16805
|
+
guardian release verify --version=<semver> [--json]
|
|
16806
|
+
guardian release paste --version=<semver> [--json]
|
|
16807
|
+
guardian release command --version=<semver> [--publish|--dry-run=false] [--channels=all|npm|browser|evidence] [--run-docker-smoke=true|false] [--json]
|
|
16808
|
+
guardian release secrets [--json]
|
|
16809
|
+
guardian release browser-store [--json]
|
|
16822
16810
|
guardian open [--json] [--print] [--url=http://127.0.0.1:<port>]
|
|
16823
16811
|
guardian status [--json]
|
|
16824
16812
|
guardian start [--json] [--host=127.0.0.1] [--port=4317]
|
|
16825
|
-
guardian launch|tower|control-tower [--json] [--print] [--host=127.0.0.1] [--port=4317]
|
|
16813
|
+
guardian launch|tower|control-tower [--json] [--open] [--print] [--host=127.0.0.1] [--port=4317]
|
|
16826
16814
|
guardian stop [--json] [--url=http://127.0.0.1:<port>/control-tower]
|
|
16827
16815
|
guardian service install [--json] [--platform=auto|launchd|systemd|windows-task-scheduler] [--force]
|
|
16828
16816
|
guardian service status [--json]
|
|
@@ -16895,6 +16883,8 @@ async function runGuardianCli(argv, options = {}) {
|
|
|
16895
16883
|
write(stdout, renderGuardianProductionReadiness(readiness, flags));
|
|
16896
16884
|
return flags.has("strict") && (readiness.npmPreview.status !== "ready" || readiness.fullProduction.status !== "ready") ? 1 : 0;
|
|
16897
16885
|
}
|
|
16886
|
+
case "release":
|
|
16887
|
+
return runReleaseCommand(argv.slice(1), flags, options);
|
|
16898
16888
|
case "open":
|
|
16899
16889
|
return runControlTowerOpenCommand(flags, options);
|
|
16900
16890
|
case "status":
|
|
@@ -17048,7 +17038,7 @@ async function installGuardian(flags, options = {}) {
|
|
|
17048
17038
|
`First run: ${GUARDIAN_FIRST_RUN_COMMAND}`,
|
|
17049
17039
|
`Open Control Tower: ${GUARDIAN_OPEN_CONTROL_TOWER_COMMAND}`,
|
|
17050
17040
|
`No global install: ${GUARDIAN_NPX_SETUP_COMMAND}`,
|
|
17051
|
-
"Next: guardian setup; guardian doctor; guardian readiness; guardian launch; guardian mcp install; guardian extension open-setup; guardian daemon pair --json; guardian extension native-host install --extension-id=<browser-extension-id>"
|
|
17041
|
+
"Next: guardian setup; guardian doctor; guardian readiness; guardian launch; guardian open; guardian mcp install; guardian extension open-setup; guardian daemon pair --json; guardian extension native-host install --extension-id=<browser-extension-id>"
|
|
17052
17042
|
].join("\n")}
|
|
17053
17043
|
`;
|
|
17054
17044
|
}
|
|
@@ -17095,7 +17085,7 @@ async function runSetupCommand(flags, options) {
|
|
|
17095
17085
|
["json", true],
|
|
17096
17086
|
...copyStringFlags(flags, ["host", "port"])
|
|
17097
17087
|
]);
|
|
17098
|
-
if (flags.has("print")) {
|
|
17088
|
+
if (!flags.has("open") || flags.has("print")) {
|
|
17099
17089
|
launchFlags.set("print", true);
|
|
17100
17090
|
}
|
|
17101
17091
|
const launchExitCode = await runLaunchCommand(launchFlags, {
|
|
@@ -17174,6 +17164,7 @@ async function runSetupCommand(flags, options) {
|
|
|
17174
17164
|
nextCommands: [
|
|
17175
17165
|
"guardian status",
|
|
17176
17166
|
"guardian readiness",
|
|
17167
|
+
"guardian open",
|
|
17177
17168
|
"guardian policy list",
|
|
17178
17169
|
"guardian posture list",
|
|
17179
17170
|
"guardian preferences show",
|
|
@@ -17251,10 +17242,761 @@ async function buildGuardianProductionReadinessStatus(home, profile, env = proce
|
|
|
17251
17242
|
productionGateEvidenceStatus: protectedEvidence.productionGateEvidence?.status ?? "not_recorded",
|
|
17252
17243
|
productionGateEvidencePath: protectedEvidence.productionGateEvidence?.evidencePath
|
|
17253
17244
|
},
|
|
17245
|
+
distribution: buildGuardianDistributionReadiness(npmPreviewReady),
|
|
17246
|
+
tokenPrinted: false,
|
|
17247
|
+
rawContentIncluded: false
|
|
17248
|
+
};
|
|
17249
|
+
}
|
|
17250
|
+
function buildGuardianDistributionReadiness(npmPreviewReady) {
|
|
17251
|
+
return {
|
|
17252
|
+
status: npmPreviewReady ? "preview_install_ready" : "setup_or_release_evidence_required",
|
|
17253
|
+
oneLineInstallCommand: GUARDIAN_GLOBAL_INSTALL_COMMAND,
|
|
17254
|
+
oneLineTryCommand: GUARDIAN_NPX_SETUP_COMMAND,
|
|
17255
|
+
openControlTowerCommand: GUARDIAN_OPEN_CONTROL_TOWER_COMMAND,
|
|
17256
|
+
localUserCommands: {
|
|
17257
|
+
setup: GUARDIAN_FIRST_RUN_COMMAND,
|
|
17258
|
+
launch: "guardian launch",
|
|
17259
|
+
open: "guardian open",
|
|
17260
|
+
status: "guardian status",
|
|
17261
|
+
readiness: "guardian readiness"
|
|
17262
|
+
},
|
|
17263
|
+
aiToolIntegration: {
|
|
17264
|
+
mcpInstallCommand: "guardian mcp install --client=all --write",
|
|
17265
|
+
browserSetupCommand: "guardian extension open-setup",
|
|
17266
|
+
nativeHostInstallCommand: "guardian extension native-host install --extension-id=<browser-extension-id>"
|
|
17267
|
+
},
|
|
17268
|
+
browserStoreHandoff: {
|
|
17269
|
+
status: npmPreviewReady ? "operator_handoff_ready_not_submitted" : "blocked_until_preview_ready",
|
|
17270
|
+
submissionPackCommand: "npm run guardian:browser-store:submission-pack",
|
|
17271
|
+
closeoutChecklistPath: "release/evidence/guardian-browser-store-submission-pack/browser-store-closeout-checklist.json",
|
|
17272
|
+
productionGateStatus: "not_proven"
|
|
17273
|
+
},
|
|
17274
|
+
enterpriseDeployment: {
|
|
17275
|
+
status: "managed_rollout_ready_for_customer_pack",
|
|
17276
|
+
note: "Use enterprise policy packs, managed browser deployment, and customer evidence as a separate company or school-district rollout lane; it does not prove public browser-store distribution."
|
|
17277
|
+
},
|
|
17278
|
+
releaseAutomation: {
|
|
17279
|
+
workflow: GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
|
|
17280
|
+
dryRunCommand: buildGuardianReleaseDispatchCommand(true),
|
|
17281
|
+
publishCommand: buildGuardianReleaseDispatchCommand(false),
|
|
17282
|
+
requiredPublishCredentialName: "NPM_TOKEN",
|
|
17283
|
+
channels: ["all", "npm", "browser", "evidence"],
|
|
17284
|
+
defaultDockerSmoke: true,
|
|
17285
|
+
provenance: "github_actions_oidc_supported",
|
|
17286
|
+
status: npmPreviewReady ? "ready_for_dispatch_after_preview_evidence" : "blocked_until_preview_release_evidence_passes",
|
|
17287
|
+
boundaries: [
|
|
17288
|
+
"Use dry_run=true before public publication.",
|
|
17289
|
+
"dry_run=false requires the repository secret NPM_TOKEN and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17290
|
+
"The workflow can publish the npm preview package, upload evidence, and run public install smokes; it does not sign native installers or approve future browser-store listings.",
|
|
17291
|
+
"GitHub Actions OIDC/provenance applies to CI release context; manual local publishes are recorded separately and should not claim CI provenance."
|
|
17292
|
+
]
|
|
17293
|
+
},
|
|
17294
|
+
boundaries: [
|
|
17295
|
+
"One-line npm install and Control Tower launch prove preview distribution only.",
|
|
17296
|
+
"Chrome Web Store distribution is proven for the evidenced ContextECF Halo listing; future store submissions still require fresh official review evidence.",
|
|
17297
|
+
"Enterprise managed deployment can support company or school-district rollout but remains a separate rollout lane.",
|
|
17298
|
+
"MCP and browser setup commands must not print runtime tokens, raw prompts, raw responses, source archives, source maps, credentials, or private policy packs."
|
|
17299
|
+
]
|
|
17300
|
+
};
|
|
17301
|
+
}
|
|
17302
|
+
function buildGuardianReleaseDispatchCommand(dryRun) {
|
|
17303
|
+
return buildGuardianReleaseDispatchCommandFor({
|
|
17304
|
+
dryRun,
|
|
17305
|
+
releaseVersion: "<version>",
|
|
17306
|
+
channels: "all",
|
|
17307
|
+
runDockerSmoke: true
|
|
17308
|
+
});
|
|
17309
|
+
}
|
|
17310
|
+
function buildGuardianReleaseDispatchCommandFor(input) {
|
|
17311
|
+
return [
|
|
17312
|
+
`gh workflow run ${GUARDIAN_RELEASE_DISPATCH_WORKFLOW} \\`,
|
|
17313
|
+
` -f release_version=${input.releaseVersion} \\`,
|
|
17314
|
+
` -f channels=${input.channels} \\`,
|
|
17315
|
+
` -f dry_run=${input.dryRun ? "true" : "false"} \\`,
|
|
17316
|
+
` -f run_docker_smoke=${input.runDockerSmoke ? "true" : "false"}`
|
|
17317
|
+
].join("\n");
|
|
17318
|
+
}
|
|
17319
|
+
async function runReleaseCommand(argv, flags, options) {
|
|
17320
|
+
const subcommand = argv[0];
|
|
17321
|
+
const stdout = options.stdout ?? process.stdout;
|
|
17322
|
+
const stderr = options.stderr ?? process.stderr;
|
|
17323
|
+
if (!subcommand || subcommand === "help" || subcommand === "quickstart") {
|
|
17324
|
+
write(stdout, renderGuardianReleaseHelp(buildGuardianReleaseHelp(), flags));
|
|
17325
|
+
return 0;
|
|
17326
|
+
}
|
|
17327
|
+
if (subcommand === "browser-store" || subcommand === "browser-store-handoff" || subcommand === "store") {
|
|
17328
|
+
write(
|
|
17329
|
+
stdout,
|
|
17330
|
+
renderGuardianBrowserStoreHandoffCommand(
|
|
17331
|
+
buildGuardianBrowserStoreHandoffCommandResult(),
|
|
17332
|
+
flags
|
|
17333
|
+
)
|
|
17334
|
+
);
|
|
17335
|
+
return 0;
|
|
17336
|
+
}
|
|
17337
|
+
if (subcommand === "secrets" || subcommand === "secret-setup" || subcommand === "npm-token") {
|
|
17338
|
+
write(stdout, renderGuardianReleaseSecretSetup(buildGuardianReleaseSecretSetup(), flags));
|
|
17339
|
+
return 0;
|
|
17340
|
+
}
|
|
17341
|
+
if (subcommand === "checklist" || subcommand === "plan") {
|
|
17342
|
+
const releaseVersion2 = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17343
|
+
if (!releaseVersion2) {
|
|
17344
|
+
write(
|
|
17345
|
+
stderr,
|
|
17346
|
+
"Missing release version. Usage: guardian release checklist --version=<semver>\n"
|
|
17347
|
+
);
|
|
17348
|
+
return 1;
|
|
17349
|
+
}
|
|
17350
|
+
if (!isValidReleaseVersion(releaseVersion2)) {
|
|
17351
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17352
|
+
return 1;
|
|
17353
|
+
}
|
|
17354
|
+
write(
|
|
17355
|
+
stdout,
|
|
17356
|
+
renderGuardianReleaseChecklist(buildGuardianReleaseChecklist(releaseVersion2), flags)
|
|
17357
|
+
);
|
|
17358
|
+
return 0;
|
|
17359
|
+
}
|
|
17360
|
+
if (subcommand === "flow" || subcommand === "train" || subcommand === "next") {
|
|
17361
|
+
const releaseVersion2 = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17362
|
+
if (!releaseVersion2) {
|
|
17363
|
+
write(stderr, "Missing release version. Usage: guardian release flow --version=<semver>\n");
|
|
17364
|
+
return 1;
|
|
17365
|
+
}
|
|
17366
|
+
if (!isValidReleaseVersion(releaseVersion2)) {
|
|
17367
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17368
|
+
return 1;
|
|
17369
|
+
}
|
|
17370
|
+
write(stdout, renderGuardianReleaseFlow(buildGuardianReleaseFlow(releaseVersion2), flags));
|
|
17371
|
+
return 0;
|
|
17372
|
+
}
|
|
17373
|
+
if (subcommand === "verify" || subcommand === "post-release") {
|
|
17374
|
+
const releaseVersion2 = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17375
|
+
if (!releaseVersion2) {
|
|
17376
|
+
write(stderr, "Missing release version. Usage: guardian release verify --version=<semver>\n");
|
|
17377
|
+
return 1;
|
|
17378
|
+
}
|
|
17379
|
+
if (!isValidReleaseVersion(releaseVersion2)) {
|
|
17380
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17381
|
+
return 1;
|
|
17382
|
+
}
|
|
17383
|
+
write(stdout, renderGuardianReleaseVerify(buildGuardianReleaseVerify(releaseVersion2), flags));
|
|
17384
|
+
return 0;
|
|
17385
|
+
}
|
|
17386
|
+
if (subcommand === "paste" || subcommand === "smoke" || subcommand === "install-smoke") {
|
|
17387
|
+
const releaseVersion2 = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17388
|
+
if (!releaseVersion2) {
|
|
17389
|
+
write(stderr, "Missing release version. Usage: guardian release paste --version=<semver>\n");
|
|
17390
|
+
return 1;
|
|
17391
|
+
}
|
|
17392
|
+
if (!isValidReleaseVersion(releaseVersion2)) {
|
|
17393
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17394
|
+
return 1;
|
|
17395
|
+
}
|
|
17396
|
+
write(stdout, renderGuardianReleasePaste(buildGuardianReleasePaste(releaseVersion2), flags));
|
|
17397
|
+
return 0;
|
|
17398
|
+
}
|
|
17399
|
+
if (subcommand !== "command" && subcommand !== "dispatch") {
|
|
17400
|
+
write(stderr, `Unknown Guardian release command: ${subcommand}
|
|
17401
|
+
`);
|
|
17402
|
+
return 1;
|
|
17403
|
+
}
|
|
17404
|
+
const releaseVersion = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17405
|
+
if (!releaseVersion) {
|
|
17406
|
+
write(
|
|
17407
|
+
stderr,
|
|
17408
|
+
"Missing release version. Usage: guardian release command --version=<semver> [--publish|--dry-run=false]\n"
|
|
17409
|
+
);
|
|
17410
|
+
return 1;
|
|
17411
|
+
}
|
|
17412
|
+
if (!isValidReleaseVersion(releaseVersion)) {
|
|
17413
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17414
|
+
return 1;
|
|
17415
|
+
}
|
|
17416
|
+
const channels = stringFlag(flags, "channels") ?? "all";
|
|
17417
|
+
if (!isValidReleaseChannels(channels)) {
|
|
17418
|
+
write(stderr, "Invalid --channels. Expected one of: all, npm, browser, evidence.\n");
|
|
17419
|
+
return 1;
|
|
17420
|
+
}
|
|
17421
|
+
const dryRun = flags.has("publish") ? false : booleanFlag(flags, "dry-run", true);
|
|
17422
|
+
const runDockerSmoke = booleanFlag(flags, "run-docker-smoke", true);
|
|
17423
|
+
const result = buildGuardianReleaseDispatchCommandResult({
|
|
17424
|
+
releaseVersion,
|
|
17425
|
+
channels,
|
|
17426
|
+
dryRun,
|
|
17427
|
+
runDockerSmoke
|
|
17428
|
+
});
|
|
17429
|
+
write(stdout, renderGuardianReleaseDispatchCommand(result, flags));
|
|
17430
|
+
return 0;
|
|
17431
|
+
}
|
|
17432
|
+
function buildGuardianReleaseHelp() {
|
|
17433
|
+
return {
|
|
17434
|
+
schema_version: "contextecf/project-guardian-release-help/v1",
|
|
17435
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17436
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17437
|
+
status: "release_owner_quickstart",
|
|
17438
|
+
commands: {
|
|
17439
|
+
checklist: "guardian release checklist --version=<version>",
|
|
17440
|
+
flow: "guardian release flow --version=<version>",
|
|
17441
|
+
secrets: "guardian release secrets",
|
|
17442
|
+
dryRunDispatch: "guardian release command --version=<version>",
|
|
17443
|
+
publishDispatch: "guardian release command --version=<version> --publish",
|
|
17444
|
+
verifyPublishedVersion: "guardian release verify --version=<version>",
|
|
17445
|
+
pasteLocalSmoke: "guardian release paste --version=<version>",
|
|
17446
|
+
browserStoreHandoff: "guardian release browser-store",
|
|
17447
|
+
readiness: "guardian readiness"
|
|
17448
|
+
},
|
|
17449
|
+
suggestedOrder: [
|
|
17450
|
+
"Run the checklist for the target version.",
|
|
17451
|
+
"Set or verify the repository publish credential if this is a public npm release.",
|
|
17452
|
+
"Run the dry-run dispatch before any publish dispatch.",
|
|
17453
|
+
"Run the publish dispatch only after dry-run evidence passes.",
|
|
17454
|
+
"Verify the published version and refresh release evidence.",
|
|
17455
|
+
"Use browser-store handoff only for submission/review evidence; it does not upload or approve listings."
|
|
17456
|
+
],
|
|
17457
|
+
boundaries: [
|
|
17458
|
+
"Release quickstart output is operator guidance only, not release evidence or production-gate proof.",
|
|
17459
|
+
"Do not paste npm tokens, OTP values, .npmrc contents, signing keys, browser-store credentials, raw prompts, raw responses, private policy packs, or customer content into release commands, chat, PR bodies, or evidence.",
|
|
17460
|
+
"Public npm preview publication does not close signed-installer, browser-store, high-risk desktop action, or autonomous local app execution production gates.",
|
|
17461
|
+
"Full production claims remain blocked until every not-proven production gate has real validated external evidence."
|
|
17462
|
+
],
|
|
17463
|
+
tokenPrinted: false,
|
|
17464
|
+
rawContentIncluded: false
|
|
17465
|
+
};
|
|
17466
|
+
}
|
|
17467
|
+
function renderGuardianReleaseHelp(result, flags) {
|
|
17468
|
+
if (flags.has("json")) {
|
|
17469
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17470
|
+
`;
|
|
17471
|
+
}
|
|
17472
|
+
return `${[
|
|
17473
|
+
"Project Guardian Release Quickstart",
|
|
17474
|
+
`Repository: ${result.repository}`,
|
|
17475
|
+
`Status: ${result.status}`,
|
|
17476
|
+
"Commands:",
|
|
17477
|
+
`- Checklist: ${result.commands.checklist}`,
|
|
17478
|
+
`- Flow: ${result.commands.flow}`,
|
|
17479
|
+
`- Secrets: ${result.commands.secrets}`,
|
|
17480
|
+
`- Dry run: ${result.commands.dryRunDispatch}`,
|
|
17481
|
+
`- Publish: ${result.commands.publishDispatch}`,
|
|
17482
|
+
`- Verify published version: ${result.commands.verifyPublishedVersion}`,
|
|
17483
|
+
`- Copy-paste local smoke: ${result.commands.pasteLocalSmoke}`,
|
|
17484
|
+
`- Browser-store handoff: ${result.commands.browserStoreHandoff}`,
|
|
17485
|
+
`- Readiness: ${result.commands.readiness}`,
|
|
17486
|
+
"Suggested order:",
|
|
17487
|
+
...result.suggestedOrder.map((step, index) => `${index + 1}. ${step}`),
|
|
17488
|
+
"Boundaries:",
|
|
17489
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17490
|
+
"Token printed: no"
|
|
17491
|
+
].join("\n")}
|
|
17492
|
+
`;
|
|
17493
|
+
}
|
|
17494
|
+
function buildGuardianReleaseDispatchCommandResult(input) {
|
|
17495
|
+
return {
|
|
17496
|
+
schema_version: "contextecf/project-guardian-release-dispatch-command/v1",
|
|
17497
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17498
|
+
workflow: GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
|
|
17499
|
+
releaseVersion: input.releaseVersion,
|
|
17500
|
+
channels: input.channels,
|
|
17501
|
+
dryRun: input.dryRun,
|
|
17502
|
+
runDockerSmoke: input.runDockerSmoke,
|
|
17503
|
+
command: buildGuardianReleaseDispatchCommandFor(input),
|
|
17504
|
+
...input.dryRun ? {} : { requiredPublishCredentialName: "NPM_TOKEN" },
|
|
17505
|
+
provenance: "github_actions_oidc_supported",
|
|
17506
|
+
boundaries: [
|
|
17507
|
+
"Use dry_run=true before public publication.",
|
|
17508
|
+
"dry_run=false requires the repository secret NPM_TOKEN and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17509
|
+
"This dispatch can publish the npm preview package, upload evidence, and run public install smokes; it does not sign native installers or approve future browser-store listings.",
|
|
17510
|
+
"A release-dispatch command is operator guidance, not production-gate proof."
|
|
17511
|
+
],
|
|
17512
|
+
tokenPrinted: false,
|
|
17513
|
+
rawContentIncluded: false
|
|
17514
|
+
};
|
|
17515
|
+
}
|
|
17516
|
+
function renderGuardianReleaseDispatchCommand(result, flags) {
|
|
17517
|
+
if (flags.has("json")) {
|
|
17518
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17519
|
+
`;
|
|
17520
|
+
}
|
|
17521
|
+
return `${[
|
|
17522
|
+
"Project Guardian Release Dispatch Command",
|
|
17523
|
+
`Release: ${result.releaseVersion}`,
|
|
17524
|
+
`Mode: ${result.dryRun ? "dry run" : "publish"}`,
|
|
17525
|
+
`Workflow: ${result.workflow}`,
|
|
17526
|
+
`Channels: ${result.channels}`,
|
|
17527
|
+
`Docker smoke: ${result.runDockerSmoke ? "yes" : "no"}`,
|
|
17528
|
+
result.requiredPublishCredentialName ? `Required repository secret: ${result.requiredPublishCredentialName}` : "Required repository secret: not needed for dry run",
|
|
17529
|
+
"Command:",
|
|
17530
|
+
result.command,
|
|
17531
|
+
"Boundaries:",
|
|
17532
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17533
|
+
"Token printed: no"
|
|
17534
|
+
].join("\n")}
|
|
17535
|
+
`;
|
|
17536
|
+
}
|
|
17537
|
+
function buildGuardianBrowserStoreHandoffCommandResult() {
|
|
17538
|
+
return {
|
|
17539
|
+
schema_version: "contextecf/project-guardian-browser-store-handoff-command/v1",
|
|
17540
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17541
|
+
status: "chrome_distribution_proven_next_submission_pack_ready",
|
|
17542
|
+
primaryStore: "chrome_web_store",
|
|
17543
|
+
productionGate: {
|
|
17544
|
+
id: "browser-store-distribution",
|
|
17545
|
+
status: "proven",
|
|
17546
|
+
nextSubmissionRequiresFreshOfficialReviewEvidence: true
|
|
17547
|
+
},
|
|
17548
|
+
commands: {
|
|
17549
|
+
submissionPack: "npm run guardian:browser-store:submission-pack -- --json --output-dir release/evidence/guardian-browser-store-submission-pack",
|
|
17550
|
+
preSubmissionSmoke: "GUARDIAN_BROWSER_STORE_SMOKE_WORKSPACE=/tmp/guardian-browser-store-pre-submission-smoke bash release/evidence/guardian-browser-store-submission-pack/run-pre-submission-readiness-smoke.sh",
|
|
17551
|
+
preSubmissionReadiness: [
|
|
17552
|
+
"npm run guardian:browser-store:readiness:collect -- \\",
|
|
17553
|
+
" --package artifacts/guardian-browser-store/guardian-browser-extension-<version>.zip \\",
|
|
17554
|
+
" --assert-pre-submission-only \\",
|
|
17555
|
+
" --assert-mv3-validation-passed \\",
|
|
17556
|
+
" --assert-source-archive-excluded \\",
|
|
17557
|
+
" --assert-store-credentials-excluded \\",
|
|
17558
|
+
" --output release/evidence/guardian-browser-store-submission-pack/pre-submission-readiness.json"
|
|
17559
|
+
].join("\n"),
|
|
17560
|
+
reviewPreflightAfterApproval: [
|
|
17561
|
+
"npm run guardian:browser-store:review-preflight -- \\",
|
|
17562
|
+
" --store-evidence release/evidence/guardian-browser-store-submission-pack/browser-store-evidence-input.json \\",
|
|
17563
|
+
" --assert-metadata-only \\",
|
|
17564
|
+
" --assert-no-store-credentials \\",
|
|
17565
|
+
" --assert-approved-review-status \\",
|
|
17566
|
+
" --assert-public-listing-url \\",
|
|
17567
|
+
" --output release/evidence/guardian-browser-store-submission-pack/browser-store-review-preflight.json"
|
|
17568
|
+
].join("\n"),
|
|
17569
|
+
collectorAfterApproval: [
|
|
17570
|
+
"npm run guardian:production-gates:collect:browser-store -- \\",
|
|
17571
|
+
" --store-evidence release/evidence/guardian-browser-store-submission-pack/browser-store-evidence-input.json \\",
|
|
17572
|
+
" --review-preflight-summary release/evidence/guardian-browser-store-submission-pack/browser-store-review-preflight.json \\",
|
|
17573
|
+
" --assert-no-source-archives \\",
|
|
17574
|
+
" --assert-package-digest-matches-release \\",
|
|
17575
|
+
" --assert-listing-matches-release-boundary \\",
|
|
17576
|
+
" --assert-listing-names-not-proven-gates \\",
|
|
17577
|
+
" --assert-production-claim-absent \\",
|
|
17578
|
+
" --output release/evidence/guardian-production-gates/browser-store-distribution.json"
|
|
17579
|
+
].join("\n"),
|
|
17580
|
+
finalGateValidation: "npm run validate:guardian-production-gates -- --claim production"
|
|
17581
|
+
},
|
|
17582
|
+
evidence: {
|
|
17583
|
+
submissionPackDir: "release/evidence/guardian-browser-store-submission-pack",
|
|
17584
|
+
closeoutChecklistPath: "release/evidence/guardian-browser-store-submission-pack/browser-store-closeout-checklist.json",
|
|
17585
|
+
preSubmissionChecklistPath: "docs/project-guardian/browser-store-pre-submission-checklist.md",
|
|
17586
|
+
readinessOutput: "release/evidence/guardian-browser-store-submission-pack/pre-submission-readiness.json",
|
|
17587
|
+
reviewPreflightOutput: "release/evidence/guardian-browser-store-submission-pack/browser-store-review-preflight.json",
|
|
17588
|
+
productionGatePacket: "release/evidence/guardian-production-gates/browser-store-distribution.json"
|
|
17589
|
+
},
|
|
17590
|
+
boundaries: [
|
|
17591
|
+
"This command surface prepares browser-store submission handoff for future extension versions; it does not upload, submit, approve, or distribute the extension.",
|
|
17592
|
+
"Chrome Web Store distribution is proven for the evidenced ContextECF Halo listing; each future extension package still needs fresh review/submission evidence before updating that proof.",
|
|
17593
|
+
"Do not place browser-store credentials, dashboard cookies, source archives, source maps, runtime tokens, private policy packs, raw prompts, raw responses, or customer content in browser-store evidence.",
|
|
17594
|
+
"Enterprise managed browser deployment is a separate customer rollout lane and does not replace public store review evidence for public listings."
|
|
17595
|
+
],
|
|
17596
|
+
tokenPrinted: false,
|
|
17597
|
+
rawContentIncluded: false
|
|
17598
|
+
};
|
|
17599
|
+
}
|
|
17600
|
+
function renderGuardianBrowserStoreHandoffCommand(result, flags) {
|
|
17601
|
+
if (flags.has("json")) {
|
|
17602
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17603
|
+
`;
|
|
17604
|
+
}
|
|
17605
|
+
return `${[
|
|
17606
|
+
"Project Guardian Browser Store Handoff",
|
|
17607
|
+
`Status: ${result.status}`,
|
|
17608
|
+
`Primary store: ${result.primaryStore}`,
|
|
17609
|
+
`Production gate: ${result.productionGate.id} (${result.productionGate.status})`,
|
|
17610
|
+
"1. Build submission pack:",
|
|
17611
|
+
result.commands.submissionPack,
|
|
17612
|
+
"2. Run pre-submission smoke:",
|
|
17613
|
+
result.commands.preSubmissionSmoke,
|
|
17614
|
+
"3. Record pre-submission readiness:",
|
|
17615
|
+
result.commands.preSubmissionReadiness,
|
|
17616
|
+
"4. After official approval, run review preflight:",
|
|
17617
|
+
result.commands.reviewPreflightAfterApproval,
|
|
17618
|
+
"5. After official approval, collect production-gate evidence:",
|
|
17619
|
+
result.commands.collectorAfterApproval,
|
|
17620
|
+
`Closeout checklist: ${result.evidence.closeoutChecklistPath}`,
|
|
17621
|
+
`Pre-submission checklist: ${result.evidence.preSubmissionChecklistPath}`,
|
|
17622
|
+
"Boundaries:",
|
|
17623
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17624
|
+
"Token printed: no"
|
|
17625
|
+
].join("\n")}
|
|
17626
|
+
`;
|
|
17627
|
+
}
|
|
17628
|
+
function buildGuardianReleaseSecretSetup() {
|
|
17629
|
+
return {
|
|
17630
|
+
schema_version: "contextecf/project-guardian-release-secret-setup/v1",
|
|
17631
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17632
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17633
|
+
requiredForPublish: "NPM_TOKEN",
|
|
17634
|
+
githubActionsSecretUrl: `https://github.com/${GUARDIAN_RELEASE_REPOSITORY}/settings/secrets/actions/new`,
|
|
17635
|
+
commands: {
|
|
17636
|
+
setNpmToken: `gh secret set NPM_TOKEN --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
|
|
17637
|
+
verifyNpmTokenPresence: `gh secret list --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions | rg '^NPM_TOKEN\\b'`,
|
|
17638
|
+
dryRunDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17639
|
+
dryRun: true,
|
|
17640
|
+
releaseVersion: "<version>",
|
|
17641
|
+
channels: "all",
|
|
17642
|
+
runDockerSmoke: true
|
|
17643
|
+
}),
|
|
17644
|
+
publishDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17645
|
+
dryRun: false,
|
|
17646
|
+
releaseVersion: "<version>",
|
|
17647
|
+
channels: "all",
|
|
17648
|
+
runDockerSmoke: true
|
|
17649
|
+
})
|
|
17650
|
+
},
|
|
17651
|
+
boundaries: [
|
|
17652
|
+
"NPM_TOKEN belongs only in GitHub Actions repository secrets for guarded dry_run=false npm publication.",
|
|
17653
|
+
"Do not paste npm tokens, OTP values, .npmrc contents, signing keys, browser-store credentials, raw prompts, raw responses, private policy packs, or customer content into chat, PR bodies, release evidence, or CLI output.",
|
|
17654
|
+
"Use dry_run=true before dry_run=false; dry-run dispatch does not require NPM_TOKEN.",
|
|
17655
|
+
"Adding NPM_TOKEN enables the npm preview publish lane only; it does not close signed-installer, browser-store, high-risk desktop, or autonomous app production gates."
|
|
17656
|
+
],
|
|
17657
|
+
tokenPrinted: false,
|
|
17658
|
+
rawContentIncluded: false
|
|
17659
|
+
};
|
|
17660
|
+
}
|
|
17661
|
+
function renderGuardianReleaseSecretSetup(result, flags) {
|
|
17662
|
+
if (flags.has("json")) {
|
|
17663
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17664
|
+
`;
|
|
17665
|
+
}
|
|
17666
|
+
return `${[
|
|
17667
|
+
"Project Guardian Release Secret Setup",
|
|
17668
|
+
`Repository: ${result.repository}`,
|
|
17669
|
+
`Required for publish: ${result.requiredForPublish}`,
|
|
17670
|
+
`GitHub Actions secret page: ${result.githubActionsSecretUrl}`,
|
|
17671
|
+
"Set secret:",
|
|
17672
|
+
result.commands.setNpmToken,
|
|
17673
|
+
"Verify secret presence:",
|
|
17674
|
+
result.commands.verifyNpmTokenPresence,
|
|
17675
|
+
"Dry-run release command:",
|
|
17676
|
+
result.commands.dryRunDispatch,
|
|
17677
|
+
"Publish release command:",
|
|
17678
|
+
result.commands.publishDispatch,
|
|
17679
|
+
"Boundaries:",
|
|
17680
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17681
|
+
"Token printed: no"
|
|
17682
|
+
].join("\n")}
|
|
17683
|
+
`;
|
|
17684
|
+
}
|
|
17685
|
+
function buildGuardianReleaseChecklist(releaseVersion) {
|
|
17686
|
+
return {
|
|
17687
|
+
schema_version: "contextecf/project-guardian-release-checklist/v1",
|
|
17688
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17689
|
+
releaseVersion,
|
|
17690
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17691
|
+
status: "preview_release_operator_ready_full_production_blocked",
|
|
17692
|
+
operatorCommands: {
|
|
17693
|
+
secretSetup: "guardian release secrets",
|
|
17694
|
+
dryRunDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17695
|
+
dryRun: true,
|
|
17696
|
+
releaseVersion,
|
|
17697
|
+
channels: "all",
|
|
17698
|
+
runDockerSmoke: true
|
|
17699
|
+
}),
|
|
17700
|
+
publishDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17701
|
+
dryRun: false,
|
|
17702
|
+
releaseVersion,
|
|
17703
|
+
channels: "all",
|
|
17704
|
+
runDockerSmoke: true
|
|
17705
|
+
}),
|
|
17706
|
+
browserStoreHandoff: "guardian release browser-store",
|
|
17707
|
+
readiness: "guardian readiness"
|
|
17708
|
+
},
|
|
17709
|
+
requiredRepositoryCredentialName: "NPM_TOKEN",
|
|
17710
|
+
evidenceOutputs: [
|
|
17711
|
+
"release/evidence/guardian-release-dispatch-summary.json",
|
|
17712
|
+
"release/evidence/guardian-npm-publish-execution-summary.json",
|
|
17713
|
+
"release/evidence/guardian-npm-publish-status-verification.json",
|
|
17714
|
+
"release/evidence/guardian-browser-store-submission-pack/browser-store-closeout-checklist.json",
|
|
17715
|
+
"release/evidence/guardian-finish-line-status.json"
|
|
17716
|
+
],
|
|
17717
|
+
notProvenProductionGates: GUARDIAN_NOT_PROVEN_PRODUCTION_GATES.map((gate) => ({
|
|
17718
|
+
id: gate.id,
|
|
17719
|
+
label: gate.label,
|
|
17720
|
+
owner: gate.owner,
|
|
17721
|
+
releaseBoundary: gate.releaseBoundary
|
|
17722
|
+
})),
|
|
17723
|
+
boundaries: [
|
|
17724
|
+
"This checklist is an operator command surface for Guardian preview releases; it is not production-gate proof.",
|
|
17725
|
+
"Run the dry-run dispatch before any dry_run=false publish dispatch.",
|
|
17726
|
+
"dry_run=false requires NPM_TOKEN in GitHub Actions repository secrets and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17727
|
+
"The checklist does not sign native installers, submit browser-store packages, execute high-risk desktop actions, or enable autonomous local app execution.",
|
|
17728
|
+
"Full production claims remain blocked until every not-proven production gate has real validated external evidence."
|
|
17729
|
+
],
|
|
17254
17730
|
tokenPrinted: false,
|
|
17255
17731
|
rawContentIncluded: false
|
|
17256
17732
|
};
|
|
17257
17733
|
}
|
|
17734
|
+
function buildGuardianReleaseFlow(releaseVersion) {
|
|
17735
|
+
const checklist = buildGuardianReleaseChecklist(releaseVersion);
|
|
17736
|
+
const verify = buildGuardianReleaseVerify(releaseVersion);
|
|
17737
|
+
const dryRunDispatch = buildGuardianReleaseDispatchCommandFor({
|
|
17738
|
+
dryRun: true,
|
|
17739
|
+
releaseVersion,
|
|
17740
|
+
channels: "all",
|
|
17741
|
+
runDockerSmoke: true
|
|
17742
|
+
});
|
|
17743
|
+
const publishDispatch = buildGuardianReleaseDispatchCommandFor({
|
|
17744
|
+
dryRun: false,
|
|
17745
|
+
releaseVersion,
|
|
17746
|
+
channels: "all",
|
|
17747
|
+
runDockerSmoke: true
|
|
17748
|
+
});
|
|
17749
|
+
return {
|
|
17750
|
+
schema_version: "contextecf/project-guardian-release-flow/v1",
|
|
17751
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17752
|
+
releaseVersion,
|
|
17753
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17754
|
+
status: "release_owner_flow_ready_full_production_blocked",
|
|
17755
|
+
steps: [
|
|
17756
|
+
{
|
|
17757
|
+
id: "review-checklist",
|
|
17758
|
+
label: "Review the release checklist",
|
|
17759
|
+
command: `guardian release checklist --version=${releaseVersion}`,
|
|
17760
|
+
credentialRequired: false
|
|
17761
|
+
},
|
|
17762
|
+
{
|
|
17763
|
+
id: "verify-secrets",
|
|
17764
|
+
label: "Verify npm publish secret setup",
|
|
17765
|
+
command: "guardian release secrets",
|
|
17766
|
+
credentialRequired: false
|
|
17767
|
+
},
|
|
17768
|
+
{
|
|
17769
|
+
id: "dry-run-dispatch",
|
|
17770
|
+
label: "Run the GitHub Actions dry run",
|
|
17771
|
+
command: dryRunDispatch,
|
|
17772
|
+
credentialRequired: false
|
|
17773
|
+
},
|
|
17774
|
+
{
|
|
17775
|
+
id: "publish-dispatch",
|
|
17776
|
+
label: "Run the guarded publish dispatch after dry-run evidence passes",
|
|
17777
|
+
command: publishDispatch,
|
|
17778
|
+
credentialRequired: true
|
|
17779
|
+
},
|
|
17780
|
+
{
|
|
17781
|
+
id: "verify-public-release",
|
|
17782
|
+
label: "Verify the published package and local install smoke",
|
|
17783
|
+
command: `guardian release verify --version=${releaseVersion}`,
|
|
17784
|
+
credentialRequired: false
|
|
17785
|
+
},
|
|
17786
|
+
{
|
|
17787
|
+
id: "copy-paste-local-smoke",
|
|
17788
|
+
label: "Copy-paste the local end-user smoke block",
|
|
17789
|
+
command: `guardian release paste --version=${releaseVersion}`,
|
|
17790
|
+
credentialRequired: false
|
|
17791
|
+
},
|
|
17792
|
+
{
|
|
17793
|
+
id: "browser-store-handoff",
|
|
17794
|
+
label: "Prepare browser-store submission handoff",
|
|
17795
|
+
command: "guardian release browser-store",
|
|
17796
|
+
credentialRequired: false
|
|
17797
|
+
}
|
|
17798
|
+
],
|
|
17799
|
+
copyPasteLocalSmoke: verify.commands.copyPasteLocalSmoke,
|
|
17800
|
+
evidenceOutputs: Array.from(
|
|
17801
|
+
/* @__PURE__ */ new Set([
|
|
17802
|
+
...checklist.evidenceOutputs,
|
|
17803
|
+
...verify.evidenceOutputs,
|
|
17804
|
+
"release/evidence/guardian-browser-store-submission-pack/browser-store-closeout-checklist.json"
|
|
17805
|
+
])
|
|
17806
|
+
),
|
|
17807
|
+
notProvenProductionGates: checklist.notProvenProductionGates.map((gate) => ({
|
|
17808
|
+
id: gate.id,
|
|
17809
|
+
label: gate.label,
|
|
17810
|
+
releaseBoundary: gate.releaseBoundary
|
|
17811
|
+
})),
|
|
17812
|
+
boundaries: [
|
|
17813
|
+
"This release flow is copy-paste operator guidance only; it is not release evidence or production-gate proof.",
|
|
17814
|
+
"Publish dispatch requires NPM_TOKEN in GitHub Actions repository secrets and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17815
|
+
"Run the dry-run dispatch before the guarded dry_run=false publish dispatch.",
|
|
17816
|
+
"Public npm preview publication and local install smoke prove the CLI preview lane only.",
|
|
17817
|
+
"Signed native installers, high-risk desktop action execution, and autonomous local app execution remain separate not-proven production gates until real external evidence is collected and validated."
|
|
17818
|
+
],
|
|
17819
|
+
tokenPrinted: false,
|
|
17820
|
+
rawContentIncluded: false
|
|
17821
|
+
};
|
|
17822
|
+
}
|
|
17823
|
+
function renderGuardianReleaseFlow(result, flags) {
|
|
17824
|
+
if (flags.has("json")) {
|
|
17825
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17826
|
+
`;
|
|
17827
|
+
}
|
|
17828
|
+
const lines = [
|
|
17829
|
+
"Project Guardian Release Flow",
|
|
17830
|
+
`Release: ${result.releaseVersion}`,
|
|
17831
|
+
`Repository: ${result.repository}`,
|
|
17832
|
+
`Status: ${result.status}`,
|
|
17833
|
+
"Steps:",
|
|
17834
|
+
...result.steps.flatMap((step, index) => [
|
|
17835
|
+
`${index + 1}. ${step.label}${step.credentialRequired ? " (requires NPM_TOKEN secret)" : ""}:`,
|
|
17836
|
+
step.command
|
|
17837
|
+
]),
|
|
17838
|
+
"Post-publish copy-paste local smoke:",
|
|
17839
|
+
result.copyPasteLocalSmoke,
|
|
17840
|
+
"Evidence outputs:",
|
|
17841
|
+
...result.evidenceOutputs.map((output) => `- ${output}`),
|
|
17842
|
+
"Not-proven production gates:",
|
|
17843
|
+
...result.notProvenProductionGates.map(
|
|
17844
|
+
(gate) => `- ${gate.label}: ${gate.releaseBoundary ?? "not proven"}`
|
|
17845
|
+
),
|
|
17846
|
+
"Boundaries:",
|
|
17847
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17848
|
+
"Token printed: no"
|
|
17849
|
+
];
|
|
17850
|
+
return `${lines.join("\n")}
|
|
17851
|
+
`;
|
|
17852
|
+
}
|
|
17853
|
+
function renderGuardianReleaseChecklist(result, flags) {
|
|
17854
|
+
if (flags.has("json")) {
|
|
17855
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17856
|
+
`;
|
|
17857
|
+
}
|
|
17858
|
+
return `${[
|
|
17859
|
+
"Project Guardian Release Checklist",
|
|
17860
|
+
`Release: ${result.releaseVersion}`,
|
|
17861
|
+
`Repository: ${result.repository}`,
|
|
17862
|
+
`Status: ${result.status}`,
|
|
17863
|
+
`Required repository credential: ${result.requiredRepositoryCredentialName}`,
|
|
17864
|
+
"1. Secret setup:",
|
|
17865
|
+
result.operatorCommands.secretSetup,
|
|
17866
|
+
"2. Dry-run dispatch:",
|
|
17867
|
+
result.operatorCommands.dryRunDispatch,
|
|
17868
|
+
"3. Publish dispatch:",
|
|
17869
|
+
result.operatorCommands.publishDispatch,
|
|
17870
|
+
"4. Browser-store handoff:",
|
|
17871
|
+
result.operatorCommands.browserStoreHandoff,
|
|
17872
|
+
"5. Readiness check:",
|
|
17873
|
+
result.operatorCommands.readiness,
|
|
17874
|
+
"Evidence outputs:",
|
|
17875
|
+
...result.evidenceOutputs.map((output) => `- ${output}`),
|
|
17876
|
+
"Not-proven production gates:",
|
|
17877
|
+
...result.notProvenProductionGates.map(
|
|
17878
|
+
(gate) => `- ${gate.label}: ${gate.releaseBoundary ?? "not proven"}`
|
|
17879
|
+
),
|
|
17880
|
+
"Boundaries:",
|
|
17881
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17882
|
+
"Token printed: no"
|
|
17883
|
+
].join("\n")}
|
|
17884
|
+
`;
|
|
17885
|
+
}
|
|
17886
|
+
function buildGuardianReleaseVerify(releaseVersion) {
|
|
17887
|
+
const copyPasteLocalSmoke = buildGuardianReleasePaste(releaseVersion).command;
|
|
17888
|
+
return {
|
|
17889
|
+
schema_version: "contextecf/project-guardian-release-verify/v1",
|
|
17890
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17891
|
+
releaseVersion,
|
|
17892
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17893
|
+
packageName: GUARDIAN_NPM_PACKAGE_NAME,
|
|
17894
|
+
registry: GUARDIAN_NPM_REGISTRY,
|
|
17895
|
+
status: "post_release_verification_required",
|
|
17896
|
+
commands: {
|
|
17897
|
+
registryVersion: `npm view ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion} version --registry=${GUARDIAN_NPM_REGISTRY}`,
|
|
17898
|
+
publicInstall: `npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion}`,
|
|
17899
|
+
installedVersion: "guardian --version",
|
|
17900
|
+
setup: "guardian setup",
|
|
17901
|
+
launch: "guardian launch",
|
|
17902
|
+
status: "guardian status",
|
|
17903
|
+
openControlTower: "guardian open",
|
|
17904
|
+
copyPasteLocalSmoke,
|
|
17905
|
+
publishStatusVerification: "npm run guardian:npm:publish:verify-status -- --status release/evidence/guardian-npm-publish-status.json --assert-ready --verify-artifacts --output release/evidence/guardian-npm-publish-status-verification.json",
|
|
17906
|
+
finishLineStatus: "npm run guardian:finish-line:status -- --npm-publish-status release/evidence/guardian-npm-publish-status.json --json --output release/evidence/guardian-finish-line-status.json"
|
|
17907
|
+
},
|
|
17908
|
+
evidenceOutputs: [
|
|
17909
|
+
"release/evidence/guardian-npm-publish-status.json",
|
|
17910
|
+
"release/evidence/guardian-npm-publish-status-verification.json",
|
|
17911
|
+
"release/evidence/guardian-finish-line-status.json"
|
|
17912
|
+
],
|
|
17913
|
+
boundaries: [
|
|
17914
|
+
"This command surface verifies public preview release visibility and installability; it does not publish to npm.",
|
|
17915
|
+
"Do not print npm tokens, OTP values, .npmrc contents, signing keys, browser-store credentials, raw prompts, raw responses, private policy packs, or customer content in release verification evidence.",
|
|
17916
|
+
"A passing public npm install smoke proves the CLI preview lane only; signed installers, high-risk desktop action execution, and autonomous app execution remain separate production gates.",
|
|
17917
|
+
"Full production claims remain blocked until every not-proven production gate has real validated external evidence."
|
|
17918
|
+
],
|
|
17919
|
+
tokenPrinted: false,
|
|
17920
|
+
rawContentIncluded: false
|
|
17921
|
+
};
|
|
17922
|
+
}
|
|
17923
|
+
function buildGuardianReleasePaste(releaseVersion) {
|
|
17924
|
+
const commands = [
|
|
17925
|
+
`npm view ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion} version --registry=${GUARDIAN_NPM_REGISTRY}`,
|
|
17926
|
+
`npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion}`,
|
|
17927
|
+
"guardian --version",
|
|
17928
|
+
"guardian stop",
|
|
17929
|
+
"guardian setup",
|
|
17930
|
+
"guardian launch",
|
|
17931
|
+
"guardian open",
|
|
17932
|
+
"guardian status"
|
|
17933
|
+
];
|
|
17934
|
+
return {
|
|
17935
|
+
schema_version: "contextecf/project-guardian-release-paste/v1",
|
|
17936
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17937
|
+
releaseVersion,
|
|
17938
|
+
packageName: GUARDIAN_NPM_PACKAGE_NAME,
|
|
17939
|
+
registry: GUARDIAN_NPM_REGISTRY,
|
|
17940
|
+
command: commands.join("\n"),
|
|
17941
|
+
commands,
|
|
17942
|
+
boundaries: [
|
|
17943
|
+
"This paste block verifies public npm visibility, global install, first-run setup, daemon launch, Control Tower open, and status.",
|
|
17944
|
+
"It does not publish to npm and must not include npm tokens, OTP values, .npmrc contents, signing keys, browser-store credentials, raw prompts, raw responses, private policy packs, or customer content.",
|
|
17945
|
+
"guardian stop is included before setup so stale local daemons or local token mismatches are cleared before launch."
|
|
17946
|
+
],
|
|
17947
|
+
tokenPrinted: false,
|
|
17948
|
+
rawContentIncluded: false
|
|
17949
|
+
};
|
|
17950
|
+
}
|
|
17951
|
+
function renderGuardianReleasePaste(result, flags) {
|
|
17952
|
+
if (flags.has("json")) {
|
|
17953
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17954
|
+
`;
|
|
17955
|
+
}
|
|
17956
|
+
return `${result.command}
|
|
17957
|
+
`;
|
|
17958
|
+
}
|
|
17959
|
+
function renderGuardianReleaseVerify(result, flags) {
|
|
17960
|
+
if (flags.has("json")) {
|
|
17961
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17962
|
+
`;
|
|
17963
|
+
}
|
|
17964
|
+
return `${[
|
|
17965
|
+
"Project Guardian Release Verification",
|
|
17966
|
+
`Release: ${result.releaseVersion}`,
|
|
17967
|
+
`Package: ${result.packageName}`,
|
|
17968
|
+
`Registry: ${result.registry}`,
|
|
17969
|
+
`Status: ${result.status}`,
|
|
17970
|
+
"1. Confirm registry visibility:",
|
|
17971
|
+
result.commands.registryVersion,
|
|
17972
|
+
"2. Install the published version:",
|
|
17973
|
+
result.commands.publicInstall,
|
|
17974
|
+
"3. Confirm installed CLI version:",
|
|
17975
|
+
result.commands.installedVersion,
|
|
17976
|
+
"4. Run first-use smoke:",
|
|
17977
|
+
result.commands.setup,
|
|
17978
|
+
result.commands.launch,
|
|
17979
|
+
result.commands.status,
|
|
17980
|
+
result.commands.openControlTower,
|
|
17981
|
+
"5. Copy-paste local smoke block:",
|
|
17982
|
+
result.commands.copyPasteLocalSmoke,
|
|
17983
|
+
"6. Verify release evidence:",
|
|
17984
|
+
result.commands.publishStatusVerification,
|
|
17985
|
+
result.commands.finishLineStatus,
|
|
17986
|
+
"Evidence outputs:",
|
|
17987
|
+
...result.evidenceOutputs.map((output) => `- ${output}`),
|
|
17988
|
+
"Boundaries:",
|
|
17989
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17990
|
+
"Token printed: no"
|
|
17991
|
+
].join("\n")}
|
|
17992
|
+
`;
|
|
17993
|
+
}
|
|
17994
|
+
function isValidReleaseVersion(value) {
|
|
17995
|
+
return /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(value);
|
|
17996
|
+
}
|
|
17997
|
+
function isValidReleaseChannels(value) {
|
|
17998
|
+
return ["all", "npm", "browser", "evidence"].includes(value);
|
|
17999
|
+
}
|
|
17258
18000
|
function renderGuardianProductionReadiness(result, flags) {
|
|
17259
18001
|
if (flags.has("json")) {
|
|
17260
18002
|
return `${JSON.stringify(result, null, 2)}
|
|
@@ -17267,6 +18009,18 @@ function renderGuardianProductionReadiness(result, flags) {
|
|
|
17267
18009
|
`Doctor: ${result.doctorOverall.toUpperCase()}`,
|
|
17268
18010
|
`NPM preview install: ${result.npmPreview.status.toUpperCase()} - ${result.npmPreview.reason}`,
|
|
17269
18011
|
result.npmPreview.publishCommand ? `NPM publish command: ${result.npmPreview.publishCommand}` : "NPM publish command: not available until publish dry-run evidence passes",
|
|
18012
|
+
`Distribution: ${result.distribution.status}`,
|
|
18013
|
+
`Install: ${result.distribution.oneLineInstallCommand}`,
|
|
18014
|
+
`Try without global install: ${result.distribution.oneLineTryCommand}`,
|
|
18015
|
+
`Open Control Tower: ${result.distribution.openControlTowerCommand}`,
|
|
18016
|
+
`AI tool setup: ${result.distribution.aiToolIntegration.mcpInstallCommand}; ${result.distribution.aiToolIntegration.browserSetupCommand}`,
|
|
18017
|
+
`Browser-store handoff: ${result.distribution.browserStoreHandoff.status}; gate ${result.distribution.browserStoreHandoff.productionGateStatus}`,
|
|
18018
|
+
`Browser-store checklist: ${result.distribution.browserStoreHandoff.closeoutChecklistPath}`,
|
|
18019
|
+
`Release workflow: ${result.distribution.releaseAutomation.workflow}; status=${result.distribution.releaseAutomation.status}`,
|
|
18020
|
+
`Release dry run:
|
|
18021
|
+
${result.distribution.releaseAutomation.dryRunCommand}`,
|
|
18022
|
+
`Release publish:
|
|
18023
|
+
${result.distribution.releaseAutomation.publishCommand}`,
|
|
17270
18024
|
`Full production release: ${result.fullProduction.status.toUpperCase()} - ${result.fullProduction.reason}`,
|
|
17271
18025
|
`Production gate evidence: ${result.fullProduction.productionGateEvidenceStatus}`,
|
|
17272
18026
|
`Blocked production gates: ${result.fullProduction.blockedGateCount}`,
|
|
@@ -17295,6 +18049,10 @@ async function statusGuardian(flags, options) {
|
|
|
17295
18049
|
installed: profile !== void 0,
|
|
17296
18050
|
daemonStatus: daemonHealth.daemon.status
|
|
17297
18051
|
});
|
|
18052
|
+
const daemonVersionMismatch = daemonHealth.daemon.status === "reachable" && daemonHealth.daemon.version !== void 0 && daemonHealth.daemon.version !== GUARDIAN_CLI_VERSION ? { cliVersion: GUARDIAN_CLI_VERSION, daemonVersion: daemonHealth.daemon.version } : null;
|
|
18053
|
+
if (daemonVersionMismatch) {
|
|
18054
|
+
nextCommands.push("guardian stop", "guardian launch");
|
|
18055
|
+
}
|
|
17298
18056
|
const result = {
|
|
17299
18057
|
schema_version: "contextecf/project-guardian-status/v1",
|
|
17300
18058
|
cli_version: GUARDIAN_CLI_VERSION,
|
|
@@ -17328,6 +18086,7 @@ async function statusGuardian(flags, options) {
|
|
|
17328
18086
|
serviceSupervision,
|
|
17329
18087
|
osKeyStorage,
|
|
17330
18088
|
notProvenProductionGates: GUARDIAN_NOT_PROVEN_PRODUCTION_GATES,
|
|
18089
|
+
daemonVersionMismatch,
|
|
17331
18090
|
nextCommands
|
|
17332
18091
|
};
|
|
17333
18092
|
if (flags.has("json")) {
|
|
@@ -17342,6 +18101,7 @@ async function statusGuardian(flags, options) {
|
|
|
17342
18101
|
`Control Tower: ${result.controlTowerUrl ?? "not configured"}`,
|
|
17343
18102
|
`Daemon health: ${result.daemon.status}${result.daemon.statusCode ? ` (HTTP ${result.daemon.statusCode})` : ""}`,
|
|
17344
18103
|
result.daemon.error ? `Daemon detail: ${result.daemon.error}` : void 0,
|
|
18104
|
+
result.daemonVersionMismatch ? `Daemon version: ${result.daemonVersionMismatch.daemonVersion} (this CLI is ${result.daemonVersionMismatch.cliVersion} \u2014 versions differ, likely because the CLI was reinstalled or changed version while this daemon kept running; run guardian stop && guardian launch to restart it on the current version)` : void 0,
|
|
17345
18105
|
`MCP stdio: ${result.runtime.mcpStdioAvailable ? "available" : "unavailable"}`,
|
|
17346
18106
|
`Posture Profile: ${result.postureProfile.selected}`,
|
|
17347
18107
|
`Prompt Coach: ${result.preferences.promptCoachMode}`,
|
|
@@ -17431,7 +18191,7 @@ async function runLaunchCommand(flags, options) {
|
|
|
17431
18191
|
return startExitCode;
|
|
17432
18192
|
}
|
|
17433
18193
|
const start = JSON.parse(startOutput);
|
|
17434
|
-
const shouldOpen = !flags.has("print");
|
|
18194
|
+
const shouldOpen = flags.has("open") && !flags.has("print");
|
|
17435
18195
|
if (shouldOpen) {
|
|
17436
18196
|
const opener = options.openUrl ?? ((url2) => openUrlInDefaultBrowser(url2, options));
|
|
17437
18197
|
await opener(start.controlTowerUrl);
|
|
@@ -17445,7 +18205,12 @@ async function runLaunchCommand(flags, options) {
|
|
|
17445
18205
|
controlTowerUrl: start.controlTowerUrl,
|
|
17446
18206
|
pid: start.pid,
|
|
17447
18207
|
healthStatus: start.healthStatus,
|
|
17448
|
-
nextCommands: [
|
|
18208
|
+
nextCommands: [
|
|
18209
|
+
"guardian open",
|
|
18210
|
+
"guardian status",
|
|
18211
|
+
"guardian daemon pair --json",
|
|
18212
|
+
"guardian policy list"
|
|
18213
|
+
]
|
|
17449
18214
|
};
|
|
17450
18215
|
write(
|
|
17451
18216
|
stdout,
|
|
@@ -17455,7 +18220,7 @@ async function runLaunchCommand(flags, options) {
|
|
|
17455
18220
|
`Daemon: ${result.daemonUrl}${result.reusedExistingDaemon ? " (already running)" : ""}`,
|
|
17456
18221
|
`Control Tower: ${result.controlTowerUrl}`,
|
|
17457
18222
|
shouldOpen ? `Opening: ${result.controlTowerUrl}` : void 0,
|
|
17458
|
-
"Next: guardian status"
|
|
18223
|
+
"Next: guardian open; guardian status"
|
|
17459
18224
|
].filter(Boolean).join("\n")}
|
|
17460
18225
|
`
|
|
17461
18226
|
);
|
|
@@ -17879,6 +18644,7 @@ function requestGuardianDaemonHealth(request) {
|
|
|
17879
18644
|
const parsedBody = parseJsonObject(body);
|
|
17880
18645
|
const service = typeof parsedBody?.service === "string" ? parsedBody.service : void 0;
|
|
17881
18646
|
const rawContentPersistence = typeof parsedBody?.rawContentPersistence === "boolean" ? parsedBody.rawContentPersistence : void 0;
|
|
18647
|
+
const version2 = typeof parsedBody?.version === "string" ? parsedBody.version : void 0;
|
|
17882
18648
|
const error51 = typeof parsedBody?.error === "string" ? parsedBody.error : void 0;
|
|
17883
18649
|
const ok = typeof statusCode === "number" && statusCode >= 200 && statusCode < 300;
|
|
17884
18650
|
resolve({
|
|
@@ -17887,6 +18653,7 @@ function requestGuardianDaemonHealth(request) {
|
|
|
17887
18653
|
statusCode,
|
|
17888
18654
|
service,
|
|
17889
18655
|
rawContentPersistence,
|
|
18656
|
+
version: version2,
|
|
17890
18657
|
error: ok ? void 0 : error51 ?? "daemon_health_failed"
|
|
17891
18658
|
});
|
|
17892
18659
|
});
|
|
@@ -19675,7 +20442,7 @@ function drainMessages() {
|
|
|
19675
20442
|
|
|
19676
20443
|
async function handleNativeMessage(raw) {
|
|
19677
20444
|
const message = JSON.parse(raw);
|
|
19678
|
-
if (!message || message.
|
|
20445
|
+
if (!message || message.adapter !== 'browser_mv3') {
|
|
19679
20446
|
sendNativeMessage({ ok: false, error: 'Unsupported Guardian native message.' });
|
|
19680
20447
|
return;
|
|
19681
20448
|
}
|
|
@@ -19686,12 +20453,44 @@ async function handleNativeMessage(raw) {
|
|
|
19686
20453
|
return;
|
|
19687
20454
|
}
|
|
19688
20455
|
const token = readRuntimeToken();
|
|
19689
|
-
|
|
19690
|
-
|
|
19691
|
-
|
|
19692
|
-
|
|
19693
|
-
|
|
19694
|
-
|
|
20456
|
+
|
|
20457
|
+
if (message.type === 'GUARDIAN_BRIDGE_DISCOVER') {
|
|
20458
|
+
sendNativeMessage({
|
|
20459
|
+
ok: true,
|
|
20460
|
+
bridgeConfig: {
|
|
20461
|
+
schema_version: 'contextecf/project-guardian-browser-bridge/v1',
|
|
20462
|
+
loopbackBaseUrl,
|
|
20463
|
+
token,
|
|
20464
|
+
pairedAt: new Date().toISOString(),
|
|
20465
|
+
source: 'native-host-discovery',
|
|
20466
|
+
transport: 'native_then_loopback',
|
|
20467
|
+
nativeHostName: 'com.contextecf.guardian',
|
|
20468
|
+
},
|
|
20469
|
+
});
|
|
20470
|
+
return;
|
|
20471
|
+
}
|
|
20472
|
+
|
|
20473
|
+
if (message.type === 'GUARDIAN_PROMPT_CHECK') {
|
|
20474
|
+
const response = await postJson(
|
|
20475
|
+
loopbackBaseUrl + '/v1/guardian/process-prompt',
|
|
20476
|
+
JSON.stringify({ adapter: 'browser_mv3', request: message.request }),
|
|
20477
|
+
token
|
|
20478
|
+
);
|
|
20479
|
+
sendNativeMessage(response);
|
|
20480
|
+
return;
|
|
20481
|
+
}
|
|
20482
|
+
|
|
20483
|
+
if (message.type === 'GUARDIAN_LIVE_COACH_EVENT') {
|
|
20484
|
+
const response = await postJson(
|
|
20485
|
+
loopbackBaseUrl + '/v1/guardian/live-coach-event',
|
|
20486
|
+
JSON.stringify({ adapter: 'browser_mv3', request: message.request }),
|
|
20487
|
+
token
|
|
20488
|
+
);
|
|
20489
|
+
sendNativeMessage(response);
|
|
20490
|
+
return;
|
|
20491
|
+
}
|
|
20492
|
+
|
|
20493
|
+
sendNativeMessage({ ok: false, error: 'Unsupported Guardian native message.' });
|
|
19695
20494
|
}
|
|
19696
20495
|
|
|
19697
20496
|
function readRuntimeToken() {
|
|
@@ -21594,6 +22393,7 @@ async function buildDaemonHealthStatus(home, flags, options, profile) {
|
|
|
21594
22393
|
statusCode: checked.statusCode,
|
|
21595
22394
|
service: checked.service,
|
|
21596
22395
|
rawContentPersistence: checked.rawContentPersistence,
|
|
22396
|
+
version: checked.version,
|
|
21597
22397
|
error: checked.error
|
|
21598
22398
|
}
|
|
21599
22399
|
};
|
|
@@ -21906,6 +22706,19 @@ async function buildGuardianDoctorStatus(home, profile, env = process.env) {
|
|
|
21906
22706
|
rawContentIncluded: false
|
|
21907
22707
|
};
|
|
21908
22708
|
}
|
|
22709
|
+
var GUARDIAN_MIN_SUPPORTED_NODE_VERSION = [20, 20, 0];
|
|
22710
|
+
function isGuardianSupportedNodeVersion(nodeVersion) {
|
|
22711
|
+
const parts = nodeVersion.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10));
|
|
22712
|
+
const [major = 0, minor = 0, patch = 0] = parts;
|
|
22713
|
+
const [minMajor, minMinor, minPatch] = GUARDIAN_MIN_SUPPORTED_NODE_VERSION;
|
|
22714
|
+
if (major !== minMajor) {
|
|
22715
|
+
return major > minMajor;
|
|
22716
|
+
}
|
|
22717
|
+
if (minor !== minMinor) {
|
|
22718
|
+
return minor > minMinor;
|
|
22719
|
+
}
|
|
22720
|
+
return patch >= minPatch;
|
|
22721
|
+
}
|
|
21909
22722
|
async function buildDoctorChecks(home, profile, env = process.env) {
|
|
21910
22723
|
const encryption = buildGuardianLocalDataEncryptionStatus(
|
|
21911
22724
|
env,
|
|
@@ -21915,6 +22728,12 @@ async function buildDoctorChecks(home, profile, env = process.env) {
|
|
|
21915
22728
|
const serviceSupervision = await buildGuardianServiceSupervisionStatus(home);
|
|
21916
22729
|
const osKeyStorage = await buildGuardianOsKeyStorageStatus(home);
|
|
21917
22730
|
return [
|
|
22731
|
+
{
|
|
22732
|
+
id: "node-runtime",
|
|
22733
|
+
label: "Node.js runtime",
|
|
22734
|
+
status: isGuardianSupportedNodeVersion(process.version) ? "pass" : "warn",
|
|
22735
|
+
detail: isGuardianSupportedNodeVersion(process.version) ? `Node ${process.version} meets the >=20.20.0 floor` : `Node ${process.version} is below the supported >=20.20.0 floor; upgrade to Node 20.20+ or 22 LTS`
|
|
22736
|
+
},
|
|
21918
22737
|
{
|
|
21919
22738
|
id: "profile",
|
|
21920
22739
|
label: "Guardian profile",
|
|
@@ -22016,6 +22835,26 @@ function stringFlag(flags, key) {
|
|
|
22016
22835
|
const value = flags.get(key);
|
|
22017
22836
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
22018
22837
|
}
|
|
22838
|
+
function booleanFlag(flags, key, defaultValue) {
|
|
22839
|
+
const value = flags.get(key);
|
|
22840
|
+
if (value === void 0) {
|
|
22841
|
+
return defaultValue;
|
|
22842
|
+
}
|
|
22843
|
+
if (value === true) {
|
|
22844
|
+
return true;
|
|
22845
|
+
}
|
|
22846
|
+
if (typeof value !== "string") {
|
|
22847
|
+
return defaultValue;
|
|
22848
|
+
}
|
|
22849
|
+
const normalized = value.trim().toLowerCase();
|
|
22850
|
+
if (["1", "true", "yes", "on"].includes(normalized)) {
|
|
22851
|
+
return true;
|
|
22852
|
+
}
|
|
22853
|
+
if (["0", "false", "no", "off"].includes(normalized)) {
|
|
22854
|
+
return false;
|
|
22855
|
+
}
|
|
22856
|
+
return defaultValue;
|
|
22857
|
+
}
|
|
22019
22858
|
function copyStringFlags(flags, keys) {
|
|
22020
22859
|
return keys.flatMap((key) => {
|
|
22021
22860
|
const value = stringFlag(flags, key);
|
|
@@ -22177,6 +23016,7 @@ export {
|
|
|
22177
23016
|
GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ID_ENV,
|
|
22178
23017
|
GUARDIAN_NOT_PROVEN_PRODUCTION_GATES,
|
|
22179
23018
|
GUARDIAN_NPM_PACKAGE_NAME,
|
|
23019
|
+
GUARDIAN_NPM_REGISTRY,
|
|
22180
23020
|
GUARDIAN_NPX_SETUP_COMMAND,
|
|
22181
23021
|
GUARDIAN_OPEN_CONTROL_TOWER_COMMAND,
|
|
22182
23022
|
GUARDIAN_OS_KEY_STORAGE_PROOF_SCHEMA_VERSION,
|
|
@@ -22185,6 +23025,8 @@ export {
|
|
|
22185
23025
|
GUARDIAN_POSTURE_PROFILE_IDS,
|
|
22186
23026
|
GUARDIAN_PROFILE_SCHEMA_VERSION,
|
|
22187
23027
|
GUARDIAN_PROVIDER_IDS,
|
|
23028
|
+
GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
|
|
23029
|
+
GUARDIAN_RELEASE_REPOSITORY,
|
|
22188
23030
|
GUARDIAN_SERVICE_PROOF_SCHEMA_VERSION,
|
|
22189
23031
|
GUARDIAN_SOURCE_TYPES,
|
|
22190
23032
|
GUARDIAN_SQLITE_PAGE_ENCRYPTION_KEY_ENV,
|
|
@@ -22201,6 +23043,7 @@ export {
|
|
|
22201
23043
|
executeGuardianDesktopActionPlan,
|
|
22202
23044
|
exportGuardianDataSnapshot,
|
|
22203
23045
|
installGuardian,
|
|
23046
|
+
isGuardianSupportedNodeVersion,
|
|
22204
23047
|
normalizeGuardianProfile,
|
|
22205
23048
|
requestGuardianDaemonHealth,
|
|
22206
23049
|
requestGuardianDaemonStop,
|