@contextecf/guardian-cli 0.1.2 → 0.1.4

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.
@@ -593,7 +593,7 @@ function $constructor(name, initializer3, params) {
593
593
  Object.defineProperty(_, "name", { value: name });
594
594
  return _;
595
595
  }
596
- var $brand = Symbol("zod_brand");
596
+ var $brand = /* @__PURE__ */ Symbol("zod_brand");
597
597
  var $ZodAsyncError = class extends Error {
598
598
  constructor() {
599
599
  super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);
@@ -10336,8 +10336,8 @@ function yo_default() {
10336
10336
 
10337
10337
  // node_modules/zod/v4/core/registries.js
10338
10338
  var _a2;
10339
- var $output = Symbol("ZodOutput");
10340
- var $input = Symbol("ZodInput");
10339
+ var $output = /* @__PURE__ */ Symbol("ZodOutput");
10340
+ var $input = /* @__PURE__ */ Symbol("ZodInput");
10341
10341
  var $ZodRegistry = class {
10342
10342
  constructor() {
10343
10343
  this._map = /* @__PURE__ */ new WeakMap();
@@ -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.2";
16278
+ var GUARDIAN_CLI_VERSION = "0.1.4";
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 launch";
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
+ ],
17730
+ tokenPrinted: false,
17731
+ rawContentIncluded: false
17732
+ };
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
+ ],
17254
17947
  tokenPrinted: false,
17255
17948
  rawContentIncluded: false
17256
17949
  };
17257
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}`,
@@ -17286,6 +18040,19 @@ async function statusGuardian(flags, options) {
17286
18040
  const releaseEvidence = await buildGuardianReleaseEvidenceStatus(home);
17287
18041
  const serviceSupervision = await buildGuardianServiceSupervisionStatus(home);
17288
18042
  const osKeyStorage = await buildGuardianOsKeyStorageStatus(home);
18043
+ const privacy = {
18044
+ rawContentCaptureEnabled: profile?.privacy.raw_content_capture_enabled ?? false,
18045
+ cloudSyncEnabled: profile?.privacy.cloud_sync_enabled ?? false,
18046
+ localAppAutopilotEnabled: profile?.privacy.local_app_autopilot_enabled ?? false
18047
+ };
18048
+ const nextCommands = buildGuardianStatusNextCommands({
18049
+ installed: profile !== void 0,
18050
+ daemonStatus: daemonHealth.daemon.status
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
+ }
17289
18056
  const result = {
17290
18057
  schema_version: "contextecf/project-guardian-status/v1",
17291
18058
  cli_version: GUARDIAN_CLI_VERSION,
@@ -17299,11 +18066,7 @@ async function statusGuardian(flags, options) {
17299
18066
  controlTowerUrl: daemonHealth.controlTowerUrl,
17300
18067
  controlTowerUrlSource: profile?.control_tower?.source ?? "default_loopback",
17301
18068
  daemon: daemonHealth.daemon,
17302
- privacy: {
17303
- rawContentCaptureEnabled: profile?.privacy.raw_content_capture_enabled ?? false,
17304
- cloudSyncEnabled: profile?.privacy.cloud_sync_enabled ?? false,
17305
- localAppAutopilotEnabled: profile?.privacy.local_app_autopilot_enabled ?? false
17306
- },
18069
+ privacy,
17307
18070
  preferences: {
17308
18071
  promptCoachMode: profile?.prompt_coach_mode ?? "not_installed",
17309
18072
  learningGraphEnabled: profile?.learning_graph.enabled ?? false
@@ -17322,7 +18085,9 @@ async function statusGuardian(flags, options) {
17322
18085
  releaseEvidence,
17323
18086
  serviceSupervision,
17324
18087
  osKeyStorage,
17325
- notProvenProductionGates: GUARDIAN_NOT_PROVEN_PRODUCTION_GATES
18088
+ notProvenProductionGates: GUARDIAN_NOT_PROVEN_PRODUCTION_GATES,
18089
+ daemonVersionMismatch,
18090
+ nextCommands
17326
18091
  };
17327
18092
  if (flags.has("json")) {
17328
18093
  return `${JSON.stringify(result, null, 2)}
@@ -17336,6 +18101,7 @@ async function statusGuardian(flags, options) {
17336
18101
  `Control Tower: ${result.controlTowerUrl ?? "not configured"}`,
17337
18102
  `Daemon health: ${result.daemon.status}${result.daemon.statusCode ? ` (HTTP ${result.daemon.statusCode})` : ""}`,
17338
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,
17339
18105
  `MCP stdio: ${result.runtime.mcpStdioAvailable ? "available" : "unavailable"}`,
17340
18106
  `Posture Profile: ${result.postureProfile.selected}`,
17341
18107
  `Prompt Coach: ${result.preferences.promptCoachMode}`,
@@ -17345,11 +18111,36 @@ async function statusGuardian(flags, options) {
17345
18111
  `Service supervision: ${result.serviceSupervision.status}`,
17346
18112
  `OS key storage: ${result.osKeyStorage.status}`,
17347
18113
  `Not-proven production gates: ${result.notProvenProductionGates.length}`,
17348
- "Privacy: raw capture off, cloud sync off, local app autopilot off",
17349
- result.installed ? "Next: guardian launch" : "Next: guardian install"
18114
+ formatGuardianPrivacyStatus(result.privacy),
18115
+ `Next: ${result.nextCommands.join("; ")}`
17350
18116
  ].filter(Boolean).join("\n")}
17351
18117
  `;
17352
18118
  }
18119
+ function buildGuardianStatusNextCommands(input) {
18120
+ if (!input.installed) {
18121
+ return ["guardian install"];
18122
+ }
18123
+ if (input.daemonStatus === "reachable") {
18124
+ return ["guardian open", "guardian readiness", "guardian extension open-setup"];
18125
+ }
18126
+ if (input.daemonStatus === "unauthorized") {
18127
+ return ["guardian stop", "guardian launch --port=4322", "guardian status"];
18128
+ }
18129
+ if (input.daemonStatus === "token_missing" || input.daemonStatus === "invalid_control_tower_url") {
18130
+ return ["guardian setup", "guardian launch", "guardian status"];
18131
+ }
18132
+ return ["guardian launch", "guardian status"];
18133
+ }
18134
+ function formatGuardianPrivacyStatus(input) {
18135
+ return [
18136
+ `Privacy: raw capture ${formatOnOff(input.rawContentCaptureEnabled)}`,
18137
+ `cloud sync ${formatOnOff(input.cloudSyncEnabled)}`,
18138
+ `local app autopilot ${formatOnOff(input.localAppAutopilotEnabled)}`
18139
+ ].join(", ");
18140
+ }
18141
+ function formatOnOff(enabled) {
18142
+ return enabled ? "on" : "off";
18143
+ }
17353
18144
  async function runControlTowerOpenCommand(flags, options) {
17354
18145
  const stdout = options.stdout ?? process.stdout;
17355
18146
  const stderr = options.stderr ?? process.stderr;
@@ -17400,7 +18191,7 @@ async function runLaunchCommand(flags, options) {
17400
18191
  return startExitCode;
17401
18192
  }
17402
18193
  const start = JSON.parse(startOutput);
17403
- const shouldOpen = !flags.has("print");
18194
+ const shouldOpen = flags.has("open") && !flags.has("print");
17404
18195
  if (shouldOpen) {
17405
18196
  const opener = options.openUrl ?? ((url2) => openUrlInDefaultBrowser(url2, options));
17406
18197
  await opener(start.controlTowerUrl);
@@ -17414,7 +18205,12 @@ async function runLaunchCommand(flags, options) {
17414
18205
  controlTowerUrl: start.controlTowerUrl,
17415
18206
  pid: start.pid,
17416
18207
  healthStatus: start.healthStatus,
17417
- nextCommands: ["guardian status", "guardian daemon pair --json", "guardian policy list"]
18208
+ nextCommands: [
18209
+ "guardian open",
18210
+ "guardian status",
18211
+ "guardian daemon pair --json",
18212
+ "guardian policy list"
18213
+ ]
17418
18214
  };
17419
18215
  write(
17420
18216
  stdout,
@@ -17424,7 +18220,7 @@ async function runLaunchCommand(flags, options) {
17424
18220
  `Daemon: ${result.daemonUrl}${result.reusedExistingDaemon ? " (already running)" : ""}`,
17425
18221
  `Control Tower: ${result.controlTowerUrl}`,
17426
18222
  shouldOpen ? `Opening: ${result.controlTowerUrl}` : void 0,
17427
- "Next: guardian status"
18223
+ "Next: guardian open; guardian status"
17428
18224
  ].filter(Boolean).join("\n")}
17429
18225
  `
17430
18226
  );
@@ -17848,6 +18644,7 @@ function requestGuardianDaemonHealth(request) {
17848
18644
  const parsedBody = parseJsonObject(body);
17849
18645
  const service = typeof parsedBody?.service === "string" ? parsedBody.service : void 0;
17850
18646
  const rawContentPersistence = typeof parsedBody?.rawContentPersistence === "boolean" ? parsedBody.rawContentPersistence : void 0;
18647
+ const version2 = typeof parsedBody?.version === "string" ? parsedBody.version : void 0;
17851
18648
  const error51 = typeof parsedBody?.error === "string" ? parsedBody.error : void 0;
17852
18649
  const ok = typeof statusCode === "number" && statusCode >= 200 && statusCode < 300;
17853
18650
  resolve({
@@ -17856,6 +18653,7 @@ function requestGuardianDaemonHealth(request) {
17856
18653
  statusCode,
17857
18654
  service,
17858
18655
  rawContentPersistence,
18656
+ version: version2,
17859
18657
  error: ok ? void 0 : error51 ?? "daemon_health_failed"
17860
18658
  });
17861
18659
  });
@@ -21563,6 +22361,7 @@ async function buildDaemonHealthStatus(home, flags, options, profile) {
21563
22361
  statusCode: checked.statusCode,
21564
22362
  service: checked.service,
21565
22363
  rawContentPersistence: checked.rawContentPersistence,
22364
+ version: checked.version,
21566
22365
  error: checked.error
21567
22366
  }
21568
22367
  };
@@ -21875,6 +22674,19 @@ async function buildGuardianDoctorStatus(home, profile, env = process.env) {
21875
22674
  rawContentIncluded: false
21876
22675
  };
21877
22676
  }
22677
+ var GUARDIAN_MIN_SUPPORTED_NODE_VERSION = [20, 20, 0];
22678
+ function isGuardianSupportedNodeVersion(nodeVersion) {
22679
+ const parts = nodeVersion.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10));
22680
+ const [major = 0, minor = 0, patch = 0] = parts;
22681
+ const [minMajor, minMinor, minPatch] = GUARDIAN_MIN_SUPPORTED_NODE_VERSION;
22682
+ if (major !== minMajor) {
22683
+ return major > minMajor;
22684
+ }
22685
+ if (minor !== minMinor) {
22686
+ return minor > minMinor;
22687
+ }
22688
+ return patch >= minPatch;
22689
+ }
21878
22690
  async function buildDoctorChecks(home, profile, env = process.env) {
21879
22691
  const encryption = buildGuardianLocalDataEncryptionStatus(
21880
22692
  env,
@@ -21884,6 +22696,12 @@ async function buildDoctorChecks(home, profile, env = process.env) {
21884
22696
  const serviceSupervision = await buildGuardianServiceSupervisionStatus(home);
21885
22697
  const osKeyStorage = await buildGuardianOsKeyStorageStatus(home);
21886
22698
  return [
22699
+ {
22700
+ id: "node-runtime",
22701
+ label: "Node.js runtime",
22702
+ status: isGuardianSupportedNodeVersion(process.version) ? "pass" : "warn",
22703
+ 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`
22704
+ },
21887
22705
  {
21888
22706
  id: "profile",
21889
22707
  label: "Guardian profile",
@@ -21985,6 +22803,26 @@ function stringFlag(flags, key) {
21985
22803
  const value = flags.get(key);
21986
22804
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
21987
22805
  }
22806
+ function booleanFlag(flags, key, defaultValue) {
22807
+ const value = flags.get(key);
22808
+ if (value === void 0) {
22809
+ return defaultValue;
22810
+ }
22811
+ if (value === true) {
22812
+ return true;
22813
+ }
22814
+ if (typeof value !== "string") {
22815
+ return defaultValue;
22816
+ }
22817
+ const normalized = value.trim().toLowerCase();
22818
+ if (["1", "true", "yes", "on"].includes(normalized)) {
22819
+ return true;
22820
+ }
22821
+ if (["0", "false", "no", "off"].includes(normalized)) {
22822
+ return false;
22823
+ }
22824
+ return defaultValue;
22825
+ }
21988
22826
  function copyStringFlags(flags, keys) {
21989
22827
  return keys.flatMap((key) => {
21990
22828
  const value = stringFlag(flags, key);
@@ -22146,6 +22984,7 @@ export {
22146
22984
  GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ID_ENV,
22147
22985
  GUARDIAN_NOT_PROVEN_PRODUCTION_GATES,
22148
22986
  GUARDIAN_NPM_PACKAGE_NAME,
22987
+ GUARDIAN_NPM_REGISTRY,
22149
22988
  GUARDIAN_NPX_SETUP_COMMAND,
22150
22989
  GUARDIAN_OPEN_CONTROL_TOWER_COMMAND,
22151
22990
  GUARDIAN_OS_KEY_STORAGE_PROOF_SCHEMA_VERSION,
@@ -22154,6 +22993,8 @@ export {
22154
22993
  GUARDIAN_POSTURE_PROFILE_IDS,
22155
22994
  GUARDIAN_PROFILE_SCHEMA_VERSION,
22156
22995
  GUARDIAN_PROVIDER_IDS,
22996
+ GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
22997
+ GUARDIAN_RELEASE_REPOSITORY,
22157
22998
  GUARDIAN_SERVICE_PROOF_SCHEMA_VERSION,
22158
22999
  GUARDIAN_SOURCE_TYPES,
22159
23000
  GUARDIAN_SQLITE_PAGE_ENCRYPTION_KEY_ENV,
@@ -22170,6 +23011,7 @@ export {
22170
23011
  executeGuardianDesktopActionPlan,
22171
23012
  exportGuardianDataSnapshot,
22172
23013
  installGuardian,
23014
+ isGuardianSupportedNodeVersion,
22173
23015
  normalizeGuardianProfile,
22174
23016
  requestGuardianDaemonHealth,
22175
23017
  requestGuardianDaemonStop,