@contextecf/guardian-cli 0.1.6 → 0.1.9

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.
@@ -16275,16 +16275,26 @@ function cloneList(values) {
16275
16275
  }
16276
16276
 
16277
16277
  // packages/guardian-cli/src/runtime.ts
16278
- var GUARDIAN_CLI_VERSION = "0.1.6";
16278
+ var GUARDIAN_CLI_VERSION = "0.1.9";
16279
16279
  var GUARDIAN_PROFILE_SCHEMA_VERSION = "contextecf/project-guardian-profile/v1";
16280
16280
  var GUARDIAN_NPM_PACKAGE_NAME = "@contextecf/guardian-cli";
16281
16281
  var GUARDIAN_NPM_REGISTRY = "https://registry.npmjs.org/";
16282
+ var GUARDIAN_DEFAULT_NPM_PUBLISH_AUTH = "trusted_publisher";
16282
16283
  var GUARDIAN_GLOBAL_INSTALL_COMMAND = `npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}`;
16283
16284
  var GUARDIAN_NPX_SETUP_COMMAND = `npx ${GUARDIAN_NPM_PACKAGE_NAME}@latest setup`;
16284
16285
  var GUARDIAN_FIRST_RUN_COMMAND = "guardian setup";
16285
16286
  var GUARDIAN_OPEN_CONTROL_TOWER_COMMAND = "guardian open";
16287
+ var GUARDIAN_HALO_CHROME_EXTENSION_ID = "dopkdppbiakhbglhgjfacfdhpheejkck";
16288
+ var GUARDIAN_HALO_CHROME_WEB_STORE_LISTING_URL = `https://chromewebstore.google.com/detail/contextecf-halo/${GUARDIAN_HALO_CHROME_EXTENSION_ID}`;
16286
16289
  var GUARDIAN_RELEASE_DISPATCH_WORKFLOW = "guardian-release-dispatch.yml";
16287
16290
  var GUARDIAN_RELEASE_REPOSITORY = "Intelligent-Context-AI-Inc/ContextECF-GITHUB";
16291
+ var GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES = [
16292
+ "CHROME_WEB_STORE_CLIENT_ID",
16293
+ "CHROME_WEB_STORE_CLIENT_SECRET",
16294
+ "CHROME_WEB_STORE_REFRESH_TOKEN",
16295
+ "CHROME_WEB_STORE_PUBLISHER_ID",
16296
+ "CHROME_WEB_STORE_EXTENSION_ID"
16297
+ ];
16288
16298
  var GUARDIAN_CONTROL_TOWER_URL_ENV = "GUARDIAN_CONTROL_TOWER_URL";
16289
16299
  var GUARDIAN_DEFAULT_CONTROL_TOWER_URL = "http://127.0.0.1:4317/control-tower";
16290
16300
  var GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ENV = "GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY";
@@ -16301,6 +16311,195 @@ var GUARDIAN_WINDOWS_NATIVE_HOST_REGISTRY_PROOF_SCHEMA_VERSION = "contextecf/pro
16301
16311
  var PERSONAL_FABRIC_CONTRACTS_SCHEMA_VERSION2 = "contextecf/personal-fabric-contracts/v1";
16302
16312
  var PROMPT_COACH_MODES = ["off", "quiet", "balanced", "hands_on"];
16303
16313
  var DEFAULT_PROMPT_COACH_DAILY_SOFT_CARD_LIMIT = 6;
16314
+ var GUARDIAN_PROMPT_CARD_OPTIONS_CATALOG = [
16315
+ {
16316
+ disposition: "allow",
16317
+ cardStyle: "No visible card",
16318
+ whenShown: "Local Guardian approves the prompt before it leaves the browser.",
16319
+ actions: [
16320
+ {
16321
+ id: "auto-send",
16322
+ label: "Send prompt",
16323
+ role: "none",
16324
+ sendsPrompt: true,
16325
+ sendsRevisedPrompt: false,
16326
+ requiresConfirmation: false,
16327
+ visibleToUser: false
16328
+ }
16329
+ ],
16330
+ sendAsIsAllowed: true,
16331
+ hardBlock: false,
16332
+ receiptExpected: true
16333
+ },
16334
+ {
16335
+ disposition: "warn",
16336
+ cardStyle: "Quick check",
16337
+ whenShown: "Guardian found a low or medium-risk concern, but policy still allows the user to continue.",
16338
+ actions: [
16339
+ {
16340
+ id: "send-as-is",
16341
+ label: "Send as-is",
16342
+ role: "allowed_override",
16343
+ sendsPrompt: true,
16344
+ sendsRevisedPrompt: false,
16345
+ requiresConfirmation: false,
16346
+ visibleToUser: true
16347
+ },
16348
+ {
16349
+ id: "edit-prompt",
16350
+ label: "Edit prompt",
16351
+ role: "safe_escape",
16352
+ sendsPrompt: false,
16353
+ sendsRevisedPrompt: false,
16354
+ requiresConfirmation: false,
16355
+ visibleToUser: true
16356
+ }
16357
+ ],
16358
+ sendAsIsAllowed: true,
16359
+ hardBlock: false,
16360
+ receiptExpected: true
16361
+ },
16362
+ {
16363
+ disposition: "rewrite",
16364
+ cardStyle: "Safer version ready",
16365
+ whenShown: "Guardian prepared a safer prompt, usually by masking sensitive text or narrowing scope.",
16366
+ actions: [
16367
+ {
16368
+ id: "send-revised-prompt",
16369
+ label: "Send revised prompt",
16370
+ role: "recommended",
16371
+ sendsPrompt: true,
16372
+ sendsRevisedPrompt: true,
16373
+ requiresConfirmation: false,
16374
+ visibleToUser: true
16375
+ },
16376
+ {
16377
+ id: "send-as-is",
16378
+ label: "Send as-is",
16379
+ role: "allowed_override",
16380
+ sendsPrompt: true,
16381
+ sendsRevisedPrompt: false,
16382
+ requiresConfirmation: false,
16383
+ visibleToUser: true
16384
+ },
16385
+ {
16386
+ id: "edit-prompt",
16387
+ label: "Edit prompt",
16388
+ role: "safe_escape",
16389
+ sendsPrompt: false,
16390
+ sendsRevisedPrompt: false,
16391
+ requiresConfirmation: false,
16392
+ visibleToUser: true
16393
+ }
16394
+ ],
16395
+ sendAsIsAllowed: true,
16396
+ hardBlock: false,
16397
+ receiptExpected: true
16398
+ },
16399
+ {
16400
+ disposition: "confirm",
16401
+ cardStyle: "Review needed",
16402
+ whenShown: "Guardian needs deliberate approval before sending higher-risk content or action requests.",
16403
+ actions: [
16404
+ {
16405
+ id: "approve-and-send",
16406
+ label: "Approve and send",
16407
+ role: "recommended",
16408
+ sendsPrompt: true,
16409
+ sendsRevisedPrompt: false,
16410
+ requiresConfirmation: true,
16411
+ visibleToUser: true
16412
+ },
16413
+ {
16414
+ id: "edit-prompt",
16415
+ label: "Edit prompt",
16416
+ role: "safe_escape",
16417
+ sendsPrompt: false,
16418
+ sendsRevisedPrompt: false,
16419
+ requiresConfirmation: false,
16420
+ visibleToUser: true
16421
+ }
16422
+ ],
16423
+ sendAsIsAllowed: false,
16424
+ hardBlock: false,
16425
+ receiptExpected: true
16426
+ },
16427
+ {
16428
+ disposition: "block",
16429
+ cardStyle: "Blocked",
16430
+ whenShown: "The prompt violates policy, contains protected secrets, or targets a denied destination.",
16431
+ actions: [
16432
+ {
16433
+ id: "edit-prompt",
16434
+ label: "Edit prompt",
16435
+ role: "safe_escape",
16436
+ sendsPrompt: false,
16437
+ sendsRevisedPrompt: false,
16438
+ requiresConfirmation: false,
16439
+ visibleToUser: true
16440
+ }
16441
+ ],
16442
+ sendAsIsAllowed: false,
16443
+ hardBlock: true,
16444
+ receiptExpected: true
16445
+ },
16446
+ {
16447
+ disposition: "unavailable",
16448
+ cardStyle: "Setup needed",
16449
+ whenShown: "The browser cannot reach Local Guardian, so the prompt is held back.",
16450
+ actions: [
16451
+ {
16452
+ id: "edit-prompt",
16453
+ label: "Edit prompt",
16454
+ role: "safe_escape",
16455
+ sendsPrompt: false,
16456
+ sendsRevisedPrompt: false,
16457
+ requiresConfirmation: false,
16458
+ visibleToUser: true
16459
+ }
16460
+ ],
16461
+ sendAsIsAllowed: false,
16462
+ hardBlock: false,
16463
+ receiptExpected: false
16464
+ },
16465
+ {
16466
+ disposition: "live_sensitive_warning",
16467
+ cardStyle: "Early heads-up",
16468
+ whenShown: "Guardian notices sensitive text while the user is typing, before the formal send-time check.",
16469
+ actions: [
16470
+ {
16471
+ id: "use-placeholder",
16472
+ label: "Use placeholder",
16473
+ role: "recommended",
16474
+ sendsPrompt: false,
16475
+ sendsRevisedPrompt: true,
16476
+ requiresConfirmation: false,
16477
+ visibleToUser: true
16478
+ },
16479
+ {
16480
+ id: "send-as-is",
16481
+ label: "Send as-is",
16482
+ role: "allowed_override",
16483
+ sendsPrompt: true,
16484
+ sendsRevisedPrompt: false,
16485
+ requiresConfirmation: false,
16486
+ visibleToUser: true
16487
+ },
16488
+ {
16489
+ id: "keep-drafting",
16490
+ label: "Keep drafting",
16491
+ role: "safe_escape",
16492
+ sendsPrompt: false,
16493
+ sendsRevisedPrompt: false,
16494
+ requiresConfirmation: false,
16495
+ visibleToUser: true
16496
+ }
16497
+ ],
16498
+ sendAsIsAllowed: true,
16499
+ hardBlock: false,
16500
+ receiptExpected: false
16501
+ }
16502
+ ];
16304
16503
  var GUARDIAN_POSTURE_PROFILE_IDS = [
16305
16504
  "calm",
16306
16505
  "balanced",
@@ -16780,6 +16979,45 @@ var MCP_CLIENTS = ["generic", "codex", "claude-desktop", "cursor"];
16780
16979
  var NATIVE_HOST_BROWSERS = ["chrome", "chromium", "edge"];
16781
16980
  var HELP_TEXT = `guardian \u2014 Project Guardian Personal Context Fabric
16782
16981
 
16982
+ Global install:
16983
+ ${GUARDIAN_GLOBAL_INSTALL_COMMAND}
16984
+
16985
+ First run:
16986
+ ${GUARDIAN_FIRST_RUN_COMMAND}
16987
+
16988
+ No global install:
16989
+ ${GUARDIAN_NPX_SETUP_COMMAND}
16990
+
16991
+ Open Control Tower:
16992
+ ${GUARDIAN_OPEN_CONTROL_TOWER_COMMAND}
16993
+ start aliases: guardian launch, guardian tower, guardian control-tower
16994
+
16995
+ Everyday commands:
16996
+ guardian --version
16997
+ guardian setup
16998
+ guardian launch
16999
+ guardian open
17000
+ guardian status
17001
+ guardian doctor
17002
+ guardian connect
17003
+ guardian coach options
17004
+ guardian policy list
17005
+ guardian marketplace list
17006
+ guardian posture list
17007
+ guardian privacy show
17008
+
17009
+ Recommended first run:
17010
+ ${GUARDIAN_GLOBAL_INSTALL_COMMAND}
17011
+ guardian setup
17012
+ Open ContextECF Halo and click Connect.
17013
+ guardian open
17014
+
17015
+ Support and developer commands:
17016
+ guardian help --advanced
17017
+
17018
+ Defaults are local-first: raw capture, cloud sync, learning graph, and app autopilot stay off.`;
17019
+ var ADVANCED_HELP_TEXT = `guardian \u2014 Project Guardian Personal Context Fabric
17020
+
16783
17021
  Global install:
16784
17022
  ${GUARDIAN_GLOBAL_INSTALL_COMMAND}
16785
17023
 
@@ -16796,7 +17034,7 @@ Open Control Tower:
16796
17034
  Usage:
16797
17035
  guardian --version
16798
17036
  guardian version [--json]
16799
- guardian setup [--json] [--open] [--print] [--host=127.0.0.1] [--port=4317] [--no-launch] [--no-mcp] [--extension-id=<chrome-extension-id>]
17037
+ guardian setup [--json] [--open] [--print] [--host=127.0.0.1] [--port=4317] [--no-launch] [--no-mcp] [--no-browser-connection] [--extension-id=<chrome-extension-id>]
16800
17038
  guardian install [--json]
16801
17039
  guardian doctor [--json]
16802
17040
  guardian readiness [--json] [--strict]
@@ -16804,7 +17042,7 @@ Usage:
16804
17042
  guardian release flow --version=<semver> [--json]
16805
17043
  guardian release verify --version=<semver> [--json]
16806
17044
  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]
17045
+ guardian release command --version=<semver> [--publish|--dry-run=false] [--channels=all|npm|browser|evidence] [--run-docker-smoke=true|false] [--publish-auth=token|trusted_publisher] [--browser-store-publish=manual|api] [--json]
16808
17046
  guardian release secrets [--json]
16809
17047
  guardian release browser-store [--json]
16810
17048
  guardian open [--json] [--print] [--url=http://127.0.0.1:<port>]
@@ -16812,6 +17050,8 @@ Usage:
16812
17050
  guardian start [--json] [--host=127.0.0.1] [--port=4317]
16813
17051
  guardian launch|tower|control-tower [--json] [--open] [--print] [--host=127.0.0.1] [--port=4317]
16814
17052
  guardian stop [--json] [--url=http://127.0.0.1:<port>/control-tower]
17053
+ guardian pair [--json]
17054
+ guardian connect [--json] [--browser=chrome|chromium|edge] [--extension-id=<chrome-extension-id>] [--host=127.0.0.1] [--port=4317]
16815
17055
  guardian service install [--json] [--platform=auto|launchd|systemd|windows-task-scheduler] [--force]
16816
17056
  guardian service status [--json]
16817
17057
  guardian service uninstall [--yes] [--json]
@@ -16820,6 +17060,7 @@ Usage:
16820
17060
  guardian key-store uninstall [--yes] [--json]
16821
17061
  guardian daemon serve [--host=127.0.0.1] [--port=4317]
16822
17062
  guardian daemon pair [--json]
17063
+ guardian extension connect [--json] [--browser=chrome|chromium|edge] [--extension-id=<chrome-extension-id>]
16823
17064
  guardian extension open-setup [--json] [--print] [--url=http://127.0.0.1:<port>/control-tower] [--extension-id=<chrome-extension-id>]
16824
17065
  guardian extension native-host install --extension-id=<chrome-extension-id> [--browser=chrome|chromium|edge] [--target=/path/to/manifest] [--force] [--write-registry --yes] [--json]
16825
17066
  guardian extension native-host status [--browser=chrome|chromium|edge] [--target=/path/to/manifest] [--json]
@@ -16835,6 +17076,7 @@ Usage:
16835
17076
  guardian privacy mode on [--json]
16836
17077
  guardian mcp install [--json] [--client=generic|codex|claude-desktop|cursor|all] [--write] [--target=/path/to/config] [--force]
16837
17078
  guardian mcp serve
17079
+ guardian coach options [--json]
16838
17080
  guardian policy list [--json]
16839
17081
  guardian policy enable <pack-id> [--json]
16840
17082
  guardian policy disable <pack-id> [--json]
@@ -16887,6 +17129,8 @@ async function runGuardianCli(argv, options = {}) {
16887
17129
  return runReleaseCommand(argv.slice(1), flags, options);
16888
17130
  case "open":
16889
17131
  return runControlTowerOpenCommand(flags, options);
17132
+ case "connect":
17133
+ return runExtensionConnectCommand(flags, options);
16890
17134
  case "status":
16891
17135
  write(stdout, await statusGuardian(flags, options));
16892
17136
  return 0;
@@ -16898,6 +17142,14 @@ async function runGuardianCli(argv, options = {}) {
16898
17142
  return runLaunchCommand(flags, options);
16899
17143
  case "stop":
16900
17144
  return runStopCommand(flags, options);
17145
+ case "pair": {
17146
+ if (!flags.has("json")) {
17147
+ return runExtensionConnectCommand(flags, options);
17148
+ }
17149
+ const result = await daemonPair(flags, options);
17150
+ write(result.exitCode === 0 ? stdout : stderr, result.message);
17151
+ return result.exitCode;
17152
+ }
16901
17153
  case "daemon":
16902
17154
  return runDaemonCommand(argv.slice(1), flags, options);
16903
17155
  case "service":
@@ -16920,6 +17172,9 @@ async function runGuardianCli(argv, options = {}) {
16920
17172
  return runPrivacyCommand(argv.slice(1), flags, options);
16921
17173
  case "mcp":
16922
17174
  return runMcpCommand(argv.slice(1), flags, options);
17175
+ case "coach":
17176
+ case "prompt-coach":
17177
+ return runCoachCommand(argv.slice(1), flags, options);
16923
17178
  case "policy":
16924
17179
  return runPolicyCommand(argv.slice(1), flags, options);
16925
17180
  case "marketplace":
@@ -16942,7 +17197,7 @@ async function runGuardianCli(argv, options = {}) {
16942
17197
  case "help":
16943
17198
  case "--help":
16944
17199
  case "-h":
16945
- write(stdout, `${HELP_TEXT}
17200
+ write(stdout, `${flags.has("advanced") ? ADVANCED_HELP_TEXT : HELP_TEXT}
16946
17201
  `);
16947
17202
  return 0;
16948
17203
  default:
@@ -17021,11 +17276,13 @@ async function installGuardian(flags, options = {}) {
17021
17276
  "guardian start",
17022
17277
  "guardian open",
17023
17278
  "guardian mcp install",
17024
- "guardian daemon pair --json",
17025
17279
  "guardian service install",
17026
17280
  "guardian key-store install --yes",
17027
- "guardian extension open-setup",
17028
- "guardian extension native-host install --extension-id=<browser-extension-id>"
17281
+ "guardian connect"
17282
+ ],
17283
+ advancedCommands: [
17284
+ `guardian extension native-host install --extension-id=${GUARDIAN_HALO_CHROME_EXTENSION_ID}`,
17285
+ "guardian pair --json"
17029
17286
  ]
17030
17287
  };
17031
17288
  return flags.has("json") ? `${JSON.stringify(result, null, 2)}
@@ -17038,7 +17295,8 @@ async function installGuardian(flags, options = {}) {
17038
17295
  `First run: ${GUARDIAN_FIRST_RUN_COMMAND}`,
17039
17296
  `Open Control Tower: ${GUARDIAN_OPEN_CONTROL_TOWER_COMMAND}`,
17040
17297
  `No global install: ${GUARDIAN_NPX_SETUP_COMMAND}`,
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>"
17298
+ "Next: guardian setup; open ContextECF Halo and click Connect; guardian open",
17299
+ "Help: run guardian doctor if setup needs attention."
17042
17300
  ].join("\n")}
17043
17301
  `;
17044
17302
  }
@@ -17046,8 +17304,9 @@ async function runSetupCommand(flags, options) {
17046
17304
  const stdout = options.stdout ?? process.stdout;
17047
17305
  const stderr = options.stderr ?? process.stderr;
17048
17306
  const home = resolveGuardianHome(options.env, options.platform);
17049
- const extensionId = stringFlag(flags, "extension-id") ?? stringFlag(flags, "id");
17050
- if (extensionId && !isValidChromeExtensionId(extensionId)) {
17307
+ const requestedExtensionId = stringFlag(flags, "extension-id") ?? stringFlag(flags, "id");
17308
+ const extensionId = requestedExtensionId ?? GUARDIAN_HALO_CHROME_EXTENSION_ID;
17309
+ if (requestedExtensionId && !isValidChromeExtensionId(requestedExtensionId)) {
17051
17310
  write(
17052
17311
  stderr,
17053
17312
  "Invalid --extension-id. Chrome extension ids must be 32 lowercase letters from a-p.\n"
@@ -17103,10 +17362,80 @@ async function runSetupCommand(flags, options) {
17103
17362
  }
17104
17363
  launch = JSON.parse(launchOutput);
17105
17364
  }
17365
+ const requestedHost = stringFlag(flags, "host") ?? "127.0.0.1";
17366
+ const requestedPort = numberFlag(flags, "port") ?? 4317;
17367
+ const requestedControlTowerUrl = `${formatDaemonBaseUrl(requestedHost, requestedPort)}/control-tower`;
17106
17368
  const resolvedControlTowerUrl = resolveControlTowerUrl(/* @__PURE__ */ new Map(), options.env, profile);
17107
- const controlTowerUrl = launch?.controlTowerUrl ?? (resolvedControlTowerUrl.ok ? resolvedControlTowerUrl.url : GUARDIAN_DEFAULT_CONTROL_TOWER_URL);
17369
+ const controlTowerUrl = launch?.controlTowerUrl ?? (flags.has("host") || flags.has("port") ? requestedControlTowerUrl : resolvedControlTowerUrl.ok ? resolvedControlTowerUrl.url : GUARDIAN_DEFAULT_CONTROL_TOWER_URL);
17370
+ if (!launch && (flags.has("host") || flags.has("port"))) {
17371
+ profile.control_tower = {
17372
+ url: controlTowerUrl,
17373
+ source: "env_or_flag"
17374
+ };
17375
+ await writeProfile(home, profile);
17376
+ }
17108
17377
  const setupUrl = buildControlTowerSetupUrl(controlTowerUrl);
17109
- const nativeHostCommand = `guardian extension native-host install --extension-id=${extensionId ?? "<browser-extension-id>"}`;
17378
+ const nativeHostCommand = `guardian extension native-host install --extension-id=${extensionId}`;
17379
+ let browserHelper;
17380
+ if (flags.has("no-browser-connection") || flags.has("no-browser-helper")) {
17381
+ browserHelper = {
17382
+ success: false,
17383
+ skipped: true,
17384
+ tokenPrinted: false
17385
+ };
17386
+ } else {
17387
+ let nativeHostOutput = "";
17388
+ let nativeHostError = "";
17389
+ const nativeHostFlags = new Map([
17390
+ ["json", true],
17391
+ ["force", true],
17392
+ ["extension-id", extensionId],
17393
+ ...copyStringFlags(flags, ["browser", "target"])
17394
+ ]);
17395
+ if ((options.platform ?? process.platform) === "win32") {
17396
+ nativeHostFlags.set("write-registry", true);
17397
+ nativeHostFlags.set("yes", true);
17398
+ }
17399
+ const nativeHostExitCode = await runExtensionCommand(
17400
+ ["native-host", "install"],
17401
+ nativeHostFlags,
17402
+ {
17403
+ ...options,
17404
+ stdout: {
17405
+ write: (chunk) => {
17406
+ nativeHostOutput += chunk.toString();
17407
+ return true;
17408
+ }
17409
+ },
17410
+ stderr: {
17411
+ write: (chunk) => {
17412
+ nativeHostError += chunk.toString();
17413
+ return true;
17414
+ }
17415
+ }
17416
+ }
17417
+ );
17418
+ if (nativeHostExitCode === 0) {
17419
+ const nativeHost = JSON.parse(nativeHostOutput);
17420
+ browserHelper = {
17421
+ success: true,
17422
+ skipped: false,
17423
+ browser: nativeHost.browser,
17424
+ hostName: nativeHost.hostName,
17425
+ manifestPath: nativeHost.manifestPath,
17426
+ allowedOrigins: nativeHost.allowedOrigins,
17427
+ tokenPrinted: nativeHost.tokenPrinted
17428
+ };
17429
+ } else {
17430
+ browserHelper = {
17431
+ success: false,
17432
+ skipped: false,
17433
+ error: nativeHostError.trim() || "Guardian browser connection setup failed.",
17434
+ exitCode: nativeHostExitCode,
17435
+ tokenPrinted: false
17436
+ };
17437
+ }
17438
+ }
17110
17439
  const result = {
17111
17440
  schema_version: "contextecf/project-guardian-setup/v1",
17112
17441
  success: true,
@@ -17156,10 +17485,14 @@ async function runSetupCommand(flags, options) {
17156
17485
  },
17157
17486
  browserSetup: {
17158
17487
  setupUrl,
17159
- extensionId: extensionId ?? null,
17488
+ extensionId,
17489
+ defaultExtensionId: GUARDIAN_HALO_CHROME_EXTENSION_ID,
17160
17490
  opened: false,
17161
17491
  tokenPrinted: false,
17162
- nativeHostCommand
17492
+ nativeHostCommand,
17493
+ connectInstruction: "Open ContextECF Halo and click Connect. No setup code is needed.",
17494
+ manualFallbackCommand: "guardian pair --json",
17495
+ nativeHost: browserHelper
17163
17496
  },
17164
17497
  nextCommands: [
17165
17498
  "guardian status",
@@ -17168,12 +17501,10 @@ async function runSetupCommand(flags, options) {
17168
17501
  "guardian policy list",
17169
17502
  "guardian posture list",
17170
17503
  "guardian preferences show",
17171
- "guardian extension open-setup",
17172
- "guardian daemon pair --json",
17173
17504
  "guardian service install",
17174
- "guardian key-store install --yes",
17175
- nativeHostCommand
17176
- ]
17505
+ "guardian key-store install --yes"
17506
+ ],
17507
+ advancedCommands: ["guardian extension connect", nativeHostCommand, "guardian pair --json"]
17177
17508
  };
17178
17509
  write(
17179
17510
  stdout,
@@ -17186,8 +17517,11 @@ async function runSetupCommand(flags, options) {
17186
17517
  result.launch.opened ? `Opening: ${result.launch.controlTowerUrl}` : void 0,
17187
17518
  `MCP artifacts: ${result.mcp.writtenFiles.length > 0 ? result.mcp.writtenFiles.join(", ") : "skipped" in result.mcp && result.mcp.skipped ? "skipped" : "none"}`,
17188
17519
  `Browser setup: ${result.browserSetup.setupUrl}`,
17520
+ result.browserSetup.nativeHost.success ? `Browser connection: ready for ContextECF Halo (${result.browserSetup.extensionId})` : result.browserSetup.nativeHost.skipped ? "Browser connection: skipped" : `Browser connection: needs attention${result.browserSetup.nativeHost.error ? ` (${result.browserSetup.nativeHost.error})` : ""}`,
17521
+ "Extension setup: open ContextECF Halo and click Connect. No setup code needed.",
17189
17522
  "Token printed: no",
17190
- `Next: ${result.nextCommands.join("; ")}`
17523
+ `Next: ${result.nextCommands.join("; ")}`,
17524
+ "Help: run guardian connect if the browser says Local Guardian is not connected."
17191
17525
  ].filter(Boolean).join("\n")}
17192
17526
  `
17193
17527
  );
@@ -17262,8 +17596,8 @@ function buildGuardianDistributionReadiness(npmPreviewReady) {
17262
17596
  },
17263
17597
  aiToolIntegration: {
17264
17598
  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>"
17599
+ browserSetupCommand: "guardian connect",
17600
+ nativeHostInstallCommand: `guardian extension native-host install --extension-id=${GUARDIAN_HALO_CHROME_EXTENSION_ID}`
17267
17601
  },
17268
17602
  browserStoreHandoff: {
17269
17603
  status: npmPreviewReady ? "operator_handoff_ready_not_submitted" : "blocked_until_preview_ready",
@@ -17279,15 +17613,17 @@ function buildGuardianDistributionReadiness(npmPreviewReady) {
17279
17613
  workflow: GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
17280
17614
  dryRunCommand: buildGuardianReleaseDispatchCommand(true),
17281
17615
  publishCommand: buildGuardianReleaseDispatchCommand(false),
17282
- requiredPublishCredentialName: "NPM_TOKEN",
17616
+ defaultPublishAuth: GUARDIAN_DEFAULT_NPM_PUBLISH_AUTH,
17617
+ tokenFallbackCredentialName: "NPM_TOKEN",
17283
17618
  channels: ["all", "npm", "browser", "evidence"],
17284
17619
  defaultDockerSmoke: true,
17285
17620
  provenance: "github_actions_oidc_supported",
17286
17621
  status: npmPreviewReady ? "ready_for_dispatch_after_preview_evidence" : "blocked_until_preview_release_evidence_passes",
17287
17622
  boundaries: [
17288
17623
  "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.",
17624
+ "dry_run=false defaults to npm Trusted Publishing and must not print npm tokens, OTP values, or .npmrc contents.",
17625
+ "The token fallback route remains available with publish_auth=token and requires the repository secret NPM_TOKEN.",
17626
+ "The workflow can publish the npm preview package, upload evidence, submit future Chrome Web Store updates for review when browser_store_publish=api, and run public install smokes; it does not sign native installers or prove future browser-store approval.",
17291
17627
  "GitHub Actions OIDC/provenance applies to CI release context; manual local publishes are recorded separately and should not claim CI provenance."
17292
17628
  ]
17293
17629
  },
@@ -17308,12 +17644,16 @@ function buildGuardianReleaseDispatchCommand(dryRun) {
17308
17644
  });
17309
17645
  }
17310
17646
  function buildGuardianReleaseDispatchCommandFor(input) {
17647
+ const publishAuth = input.publishAuth ?? GUARDIAN_DEFAULT_NPM_PUBLISH_AUTH;
17648
+ const browserStorePublish = input.browserStorePublish ?? "manual";
17311
17649
  return [
17312
17650
  `gh workflow run ${GUARDIAN_RELEASE_DISPATCH_WORKFLOW} \\`,
17313
17651
  ` -f release_version=${input.releaseVersion} \\`,
17314
17652
  ` -f channels=${input.channels} \\`,
17315
17653
  ` -f dry_run=${input.dryRun ? "true" : "false"} \\`,
17316
- ` -f run_docker_smoke=${input.runDockerSmoke ? "true" : "false"}`
17654
+ ` -f run_docker_smoke=${input.runDockerSmoke ? "true" : "false"} \\`,
17655
+ ` -f publish_auth=${publishAuth} \\`,
17656
+ ` -f browser_store_publish=${browserStorePublish}`
17317
17657
  ].join("\n");
17318
17658
  }
17319
17659
  async function runReleaseCommand(argv, flags, options) {
@@ -17420,11 +17760,23 @@ async function runReleaseCommand(argv, flags, options) {
17420
17760
  }
17421
17761
  const dryRun = flags.has("publish") ? false : booleanFlag(flags, "dry-run", true);
17422
17762
  const runDockerSmoke = booleanFlag(flags, "run-docker-smoke", true);
17763
+ const publishAuth = stringFlag(flags, "publish-auth") ?? GUARDIAN_DEFAULT_NPM_PUBLISH_AUTH;
17764
+ if (!isValidReleasePublishAuth(publishAuth)) {
17765
+ write(stderr, "Invalid --publish-auth. Expected one of: token, trusted_publisher.\n");
17766
+ return 1;
17767
+ }
17768
+ const browserStorePublish = stringFlag(flags, "browser-store-publish") ?? "manual";
17769
+ if (!isValidBrowserStorePublish(browserStorePublish)) {
17770
+ write(stderr, "Invalid --browser-store-publish. Expected one of: manual, api.\n");
17771
+ return 1;
17772
+ }
17423
17773
  const result = buildGuardianReleaseDispatchCommandResult({
17424
17774
  releaseVersion,
17425
17775
  channels,
17426
17776
  dryRun,
17427
- runDockerSmoke
17777
+ runDockerSmoke,
17778
+ publishAuth,
17779
+ browserStorePublish
17428
17780
  });
17429
17781
  write(stdout, renderGuardianReleaseDispatchCommand(result, flags));
17430
17782
  return 0;
@@ -17492,6 +17844,7 @@ function renderGuardianReleaseHelp(result, flags) {
17492
17844
  `;
17493
17845
  }
17494
17846
  function buildGuardianReleaseDispatchCommandResult(input) {
17847
+ const npmLaneSelected = input.channels === "all" || input.channels === "npm";
17495
17848
  return {
17496
17849
  schema_version: "contextecf/project-guardian-release-dispatch-command/v1",
17497
17850
  cli_version: GUARDIAN_CLI_VERSION,
@@ -17500,13 +17853,21 @@ function buildGuardianReleaseDispatchCommandResult(input) {
17500
17853
  channels: input.channels,
17501
17854
  dryRun: input.dryRun,
17502
17855
  runDockerSmoke: input.runDockerSmoke,
17856
+ publishAuth: input.publishAuth,
17857
+ browserStorePublish: input.browserStorePublish,
17503
17858
  command: buildGuardianReleaseDispatchCommandFor(input),
17504
- ...input.dryRun ? {} : { requiredPublishCredentialName: "NPM_TOKEN" },
17859
+ ...input.dryRun || input.publishAuth === "trusted_publisher" || !npmLaneSelected ? {} : { requiredPublishCredentialName: "NPM_TOKEN" },
17860
+ ...input.browserStorePublish === "api" && !input.dryRun ? {
17861
+ requiredBrowserStoreCredentialNames: [...GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES]
17862
+ } : {},
17505
17863
  provenance: "github_actions_oidc_supported",
17506
17864
  boundaries: [
17507
17865
  "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.",
17866
+ "dry_run=false with publish_auth=token requires the repository secret NPM_TOKEN and must not print npm tokens, OTP values, or .npmrc contents.",
17867
+ "dry_run=false with publish_auth=trusted_publisher requires npm Trusted Publishing to be configured for this GitHub Actions workflow and package.",
17868
+ "browser_store_publish=manual keeps Chrome Web Store upload as an operator ZIP handoff.",
17869
+ "browser_store_publish=api uploads an existing Chrome Web Store item update and submits it for review when Chrome Web Store API secrets are configured.",
17870
+ "This dispatch can publish the npm preview package, upload evidence, submit future Chrome Web Store updates for review, and run public install smokes; it does not sign native installers or prove future browser-store approval.",
17510
17871
  "A release-dispatch command is operator guidance, not production-gate proof."
17511
17872
  ],
17512
17873
  tokenPrinted: false,
@@ -17525,7 +17886,10 @@ function renderGuardianReleaseDispatchCommand(result, flags) {
17525
17886
  `Workflow: ${result.workflow}`,
17526
17887
  `Channels: ${result.channels}`,
17527
17888
  `Docker smoke: ${result.runDockerSmoke ? "yes" : "no"}`,
17528
- result.requiredPublishCredentialName ? `Required repository secret: ${result.requiredPublishCredentialName}` : "Required repository secret: not needed for dry run",
17889
+ `Publish auth: ${result.publishAuth}`,
17890
+ `Browser store publish: ${result.browserStorePublish}`,
17891
+ result.requiredPublishCredentialName ? `Required repository secret: ${result.requiredPublishCredentialName}` : result.publishAuth === "trusted_publisher" && !result.dryRun ? "Required npm setup: Trusted Publisher connection" : "Required repository secret: not needed for dry run",
17892
+ result.requiredBrowserStoreCredentialNames ? `Required browser-store secrets: ${result.requiredBrowserStoreCredentialNames.join(", ")}` : "Required browser-store secrets: not needed for manual browser handoff",
17529
17893
  "Command:",
17530
17894
  result.command,
17531
17895
  "Boundaries:",
@@ -17540,6 +17904,7 @@ function buildGuardianBrowserStoreHandoffCommandResult() {
17540
17904
  cli_version: GUARDIAN_CLI_VERSION,
17541
17905
  status: "chrome_distribution_proven_next_submission_pack_ready",
17542
17906
  primaryStore: "chrome_web_store",
17907
+ publicListingUrl: GUARDIAN_HALO_CHROME_WEB_STORE_LISTING_URL,
17543
17908
  productionGate: {
17544
17909
  id: "browser-store-distribution",
17545
17910
  status: "proven",
@@ -17606,6 +17971,7 @@ function renderGuardianBrowserStoreHandoffCommand(result, flags) {
17606
17971
  "Project Guardian Browser Store Handoff",
17607
17972
  `Status: ${result.status}`,
17608
17973
  `Primary store: ${result.primaryStore}`,
17974
+ `Public listing: ${result.publicListingUrl}`,
17609
17975
  `Production gate: ${result.productionGate.id} (${result.productionGate.status})`,
17610
17976
  "1. Build submission pack:",
17611
17977
  result.commands.submissionPack,
@@ -17626,15 +17992,25 @@ function renderGuardianBrowserStoreHandoffCommand(result, flags) {
17626
17992
  `;
17627
17993
  }
17628
17994
  function buildGuardianReleaseSecretSetup() {
17995
+ const chromeWebStoreSecretMatcher = GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES.join("|");
17629
17996
  return {
17630
17997
  schema_version: "contextecf/project-guardian-release-secret-setup/v1",
17631
17998
  cli_version: GUARDIAN_CLI_VERSION,
17632
17999
  repository: GUARDIAN_RELEASE_REPOSITORY,
17633
- requiredForPublish: "NPM_TOKEN",
18000
+ defaultPublishAuth: GUARDIAN_DEFAULT_NPM_PUBLISH_AUTH,
18001
+ requiredForPublish: "npm_trusted_publisher_connection",
18002
+ tokenFallbackCredentialName: "NPM_TOKEN",
18003
+ requiredForBrowserStoreApi: GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES,
17634
18004
  githubActionsSecretUrl: `https://github.com/${GUARDIAN_RELEASE_REPOSITORY}/settings/secrets/actions/new`,
17635
18005
  commands: {
17636
18006
  setNpmToken: `gh secret set NPM_TOKEN --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
18007
+ setChromeWebStoreClientId: `gh secret set CHROME_WEB_STORE_CLIENT_ID --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
18008
+ setChromeWebStoreClientSecret: `gh secret set CHROME_WEB_STORE_CLIENT_SECRET --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
18009
+ setChromeWebStoreRefreshToken: `gh secret set CHROME_WEB_STORE_REFRESH_TOKEN --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
18010
+ setChromeWebStorePublisherId: `gh secret set CHROME_WEB_STORE_PUBLISHER_ID --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
18011
+ setChromeWebStoreExtensionId: `gh secret set CHROME_WEB_STORE_EXTENSION_ID --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
17637
18012
  verifyNpmTokenPresence: `gh secret list --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions | rg '^NPM_TOKEN\\b'`,
18013
+ verifyChromeWebStoreSecretsPresence: `gh secret list --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions | rg '^(${chromeWebStoreSecretMatcher})\\b'`,
17638
18014
  dryRunDispatch: buildGuardianReleaseDispatchCommandFor({
17639
18015
  dryRun: true,
17640
18016
  releaseVersion: "<version>",
@@ -17646,13 +18022,24 @@ function buildGuardianReleaseSecretSetup() {
17646
18022
  releaseVersion: "<version>",
17647
18023
  channels: "all",
17648
18024
  runDockerSmoke: true
18025
+ }),
18026
+ browserStoreApiPublishDispatch: buildGuardianReleaseDispatchCommandFor({
18027
+ dryRun: false,
18028
+ releaseVersion: "<version>",
18029
+ channels: "browser",
18030
+ runDockerSmoke: true,
18031
+ publishAuth: "trusted_publisher",
18032
+ browserStorePublish: "api"
17649
18033
  })
17650
18034
  },
17651
18035
  boundaries: [
17652
- "NPM_TOKEN belongs only in GitHub Actions repository secrets for guarded dry_run=false npm publication.",
18036
+ "npm Trusted Publishing is the default Guardian release path and uses this GitHub Actions workflow identity.",
18037
+ "NPM_TOKEN is a fallback credential only; when used, it belongs only in GitHub Actions repository secrets for guarded dry_run=false npm publication.",
18038
+ "Chrome Web Store API OAuth values belong only in GitHub Actions repository secrets for guarded browser_store_publish=api upload/submission.",
17653
18039
  "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."
18040
+ "Use dry_run=true before dry_run=false; dry-run dispatch does not require npm publish credentials.",
18041
+ "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.",
18042
+ "Chrome Web Store API secrets enable browser update upload/submission only; official review approval evidence is still required for production browser-store claims."
17656
18043
  ],
17657
18044
  tokenPrinted: false,
17658
18045
  rawContentIncluded: false
@@ -17666,16 +18053,28 @@ function renderGuardianReleaseSecretSetup(result, flags) {
17666
18053
  return `${[
17667
18054
  "Project Guardian Release Secret Setup",
17668
18055
  `Repository: ${result.repository}`,
17669
- `Required for publish: ${result.requiredForPublish}`,
18056
+ "Default npm publish setup: Trusted Publisher connection",
18057
+ `Fallback npm publish secret: ${result.tokenFallbackCredentialName}`,
18058
+ `Required for Chrome Web Store API: ${result.requiredForBrowserStoreApi.join(", ")}`,
17670
18059
  `GitHub Actions secret page: ${result.githubActionsSecretUrl}`,
17671
- "Set secret:",
18060
+ "NPM publish secret:",
17672
18061
  result.commands.setNpmToken,
17673
- "Verify secret presence:",
18062
+ "Verify npm secret presence:",
17674
18063
  result.commands.verifyNpmTokenPresence,
18064
+ "Chrome Web Store API secrets:",
18065
+ result.commands.setChromeWebStoreClientId,
18066
+ result.commands.setChromeWebStoreClientSecret,
18067
+ result.commands.setChromeWebStoreRefreshToken,
18068
+ result.commands.setChromeWebStorePublisherId,
18069
+ result.commands.setChromeWebStoreExtensionId,
18070
+ "Verify Chrome Web Store API secret presence:",
18071
+ result.commands.verifyChromeWebStoreSecretsPresence,
17675
18072
  "Dry-run release command:",
17676
18073
  result.commands.dryRunDispatch,
17677
- "Publish release command:",
18074
+ "Default publish command with manual browser-store upload:",
17678
18075
  result.commands.publishDispatch,
18076
+ "Browser-store API publish command:",
18077
+ result.commands.browserStoreApiPublishDispatch,
17679
18078
  "Boundaries:",
17680
18079
  ...result.boundaries.map((boundary) => `- ${boundary}`),
17681
18080
  "Token printed: no"
@@ -17706,7 +18105,8 @@ function buildGuardianReleaseChecklist(releaseVersion) {
17706
18105
  browserStoreHandoff: "guardian release browser-store",
17707
18106
  readiness: "guardian readiness"
17708
18107
  },
17709
- requiredRepositoryCredentialName: "NPM_TOKEN",
18108
+ defaultPublishAuth: GUARDIAN_DEFAULT_NPM_PUBLISH_AUTH,
18109
+ tokenFallbackCredentialName: "NPM_TOKEN",
17710
18110
  evidenceOutputs: [
17711
18111
  "release/evidence/guardian-release-dispatch-summary.json",
17712
18112
  "release/evidence/guardian-npm-publish-execution-summary.json",
@@ -17723,7 +18123,8 @@ function buildGuardianReleaseChecklist(releaseVersion) {
17723
18123
  boundaries: [
17724
18124
  "This checklist is an operator command surface for Guardian preview releases; it is not production-gate proof.",
17725
18125
  "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.",
18126
+ "dry_run=false defaults to npm Trusted Publishing and must not print npm tokens, OTP values, or .npmrc contents.",
18127
+ "The token fallback route remains available with publish_auth=token and requires NPM_TOKEN in GitHub Actions repository secrets.",
17727
18128
  "The checklist does not sign native installers, submit browser-store packages, execute high-risk desktop actions, or enable autonomous local app execution.",
17728
18129
  "Full production claims remain blocked until every not-proven production gate has real validated external evidence."
17729
18130
  ],
@@ -17761,7 +18162,7 @@ function buildGuardianReleaseFlow(releaseVersion) {
17761
18162
  },
17762
18163
  {
17763
18164
  id: "verify-secrets",
17764
- label: "Verify npm publish secret setup",
18165
+ label: "Verify npm Trusted Publisher setup or token fallback",
17765
18166
  command: "guardian release secrets",
17766
18167
  credentialRequired: false
17767
18168
  },
@@ -17775,7 +18176,7 @@ function buildGuardianReleaseFlow(releaseVersion) {
17775
18176
  id: "publish-dispatch",
17776
18177
  label: "Run the guarded publish dispatch after dry-run evidence passes",
17777
18178
  command: publishDispatch,
17778
- credentialRequired: true
18179
+ credentialRequired: false
17779
18180
  },
17780
18181
  {
17781
18182
  id: "verify-public-release",
@@ -17811,7 +18212,8 @@ function buildGuardianReleaseFlow(releaseVersion) {
17811
18212
  })),
17812
18213
  boundaries: [
17813
18214
  "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.",
18215
+ "Publish dispatch defaults to npm Trusted Publishing and must not print npm tokens, OTP values, or .npmrc contents.",
18216
+ "The token fallback route remains available with publish_auth=token and requires NPM_TOKEN in GitHub Actions repository secrets.",
17815
18217
  "Run the dry-run dispatch before the guarded dry_run=false publish dispatch.",
17816
18218
  "Public npm preview publication and local install smoke prove the CLI preview lane only.",
17817
18219
  "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."
@@ -17860,7 +18262,8 @@ function renderGuardianReleaseChecklist(result, flags) {
17860
18262
  `Release: ${result.releaseVersion}`,
17861
18263
  `Repository: ${result.repository}`,
17862
18264
  `Status: ${result.status}`,
17863
- `Required repository credential: ${result.requiredRepositoryCredentialName}`,
18265
+ "Default npm publish setup: Trusted Publisher connection",
18266
+ `Fallback npm publish secret: ${result.tokenFallbackCredentialName}`,
17864
18267
  "1. Secret setup:",
17865
18268
  result.operatorCommands.secretSetup,
17866
18269
  "2. Dry-run dispatch:",
@@ -17896,9 +18299,9 @@ function buildGuardianReleaseVerify(releaseVersion) {
17896
18299
  commands: {
17897
18300
  registryVersion: `npm view ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion} version --registry=${GUARDIAN_NPM_REGISTRY}`,
17898
18301
  publicInstall: `npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion}`,
18302
+ chromeWebStoreListing: GUARDIAN_HALO_CHROME_WEB_STORE_LISTING_URL,
17899
18303
  installedVersion: "guardian --version",
17900
18304
  setup: "guardian setup",
17901
- launch: "guardian launch",
17902
18305
  status: "guardian status",
17903
18306
  openControlTower: "guardian open",
17904
18307
  copyPasteLocalSmoke,
@@ -17927,9 +18330,8 @@ function buildGuardianReleasePaste(releaseVersion) {
17927
18330
  "guardian --version",
17928
18331
  "guardian stop",
17929
18332
  "guardian setup",
17930
- "guardian launch",
17931
- "guardian open",
17932
- "guardian status"
18333
+ "guardian status",
18334
+ "guardian open"
17933
18335
  ];
17934
18336
  return {
17935
18337
  schema_version: "contextecf/project-guardian-release-paste/v1",
@@ -17940,9 +18342,9 @@ function buildGuardianReleasePaste(releaseVersion) {
17940
18342
  command: commands.join("\n"),
17941
18343
  commands,
17942
18344
  boundaries: [
17943
- "This paste block verifies public npm visibility, global install, first-run setup, daemon launch, Control Tower open, and status.",
18345
+ "This paste block verifies public npm visibility, global install, stale-process cleanup, first-run setup, Local Guardian status, and Control Tower open.",
17944
18346
  "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."
18347
+ "guardian stop is included before setup so stale Local Guardian processes or local token mismatches are cleared before setup relaunches the local service."
17946
18348
  ],
17947
18349
  tokenPrinted: false,
17948
18350
  rawContentIncluded: false
@@ -17969,18 +18371,19 @@ function renderGuardianReleaseVerify(result, flags) {
17969
18371
  `Status: ${result.status}`,
17970
18372
  "1. Confirm registry visibility:",
17971
18373
  result.commands.registryVersion,
17972
- "2. Install the published version:",
18374
+ "2. Confirm public Chrome Web Store listing:",
18375
+ result.commands.chromeWebStoreListing,
18376
+ "3. Install the published version:",
17973
18377
  result.commands.publicInstall,
17974
- "3. Confirm installed CLI version:",
18378
+ "4. Confirm installed CLI version:",
17975
18379
  result.commands.installedVersion,
17976
- "4. Run first-use smoke:",
18380
+ "5. Run first-use smoke:",
17977
18381
  result.commands.setup,
17978
- result.commands.launch,
17979
18382
  result.commands.status,
17980
18383
  result.commands.openControlTower,
17981
- "5. Copy-paste local smoke block:",
18384
+ "6. Copy-paste local smoke block:",
17982
18385
  result.commands.copyPasteLocalSmoke,
17983
- "6. Verify release evidence:",
18386
+ "7. Verify release evidence:",
17984
18387
  result.commands.publishStatusVerification,
17985
18388
  result.commands.finishLineStatus,
17986
18389
  "Evidence outputs:",
@@ -17997,6 +18400,12 @@ function isValidReleaseVersion(value) {
17997
18400
  function isValidReleaseChannels(value) {
17998
18401
  return ["all", "npm", "browser", "evidence"].includes(value);
17999
18402
  }
18403
+ function isValidReleasePublishAuth(value) {
18404
+ return value === "token" || value === "trusted_publisher";
18405
+ }
18406
+ function isValidBrowserStorePublish(value) {
18407
+ return value === "manual" || value === "api";
18408
+ }
18000
18409
  function renderGuardianProductionReadiness(result, flags) {
18001
18410
  if (flags.has("json")) {
18002
18411
  return `${JSON.stringify(result, null, 2)}
@@ -18099,9 +18508,9 @@ async function statusGuardian(flags, options) {
18099
18508
  `Profile: ${home}`,
18100
18509
  `Runtime profile: ${result.runtime.profileDaemonStatus}`,
18101
18510
  `Control Tower: ${result.controlTowerUrl ?? "not configured"}`,
18102
- `Daemon health: ${result.daemon.status}${result.daemon.statusCode ? ` (HTTP ${result.daemon.statusCode})` : ""}`,
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,
18511
+ `Local Guardian: ${result.daemon.status}${result.daemon.statusCode ? ` (HTTP ${result.daemon.statusCode})` : ""}`,
18512
+ result.daemon.error ? `Connection detail: ${result.daemon.error}` : void 0,
18513
+ result.daemonVersionMismatch ? `Local Guardian version: ${result.daemonVersionMismatch.daemonVersion} (this CLI is ${result.daemonVersionMismatch.cliVersion} \u2014 versions differ, likely because the CLI was reinstalled or changed version while Local Guardian kept running; run guardian stop && guardian launch to restart it on the current version)` : void 0,
18105
18514
  `MCP stdio: ${result.runtime.mcpStdioAvailable ? "available" : "unavailable"}`,
18106
18515
  `Posture Profile: ${result.postureProfile.selected}`,
18107
18516
  `Prompt Coach: ${result.preferences.promptCoachMode}`,
@@ -18208,7 +18617,7 @@ async function runLaunchCommand(flags, options) {
18208
18617
  nextCommands: [
18209
18618
  "guardian open",
18210
18619
  "guardian status",
18211
- "guardian daemon pair --json",
18620
+ "Open ContextECF Halo and click Connect",
18212
18621
  "guardian policy list"
18213
18622
  ]
18214
18623
  };
@@ -18217,7 +18626,7 @@ async function runLaunchCommand(flags, options) {
18217
18626
  flags.has("json") ? `${JSON.stringify(result, null, 2)}
18218
18627
  ` : `${[
18219
18628
  "Project Guardian launched.",
18220
- `Daemon: ${result.daemonUrl}${result.reusedExistingDaemon ? " (already running)" : ""}`,
18629
+ `Local Guardian: ${result.daemonUrl}${result.reusedExistingDaemon ? " (already running)" : ""}`,
18221
18630
  `Control Tower: ${result.controlTowerUrl}`,
18222
18631
  shouldOpen ? `Opening: ${result.controlTowerUrl}` : void 0,
18223
18632
  "Next: guardian open; guardian status"
@@ -18328,14 +18737,14 @@ async function runStartCommand(flags, options) {
18328
18737
  controlTowerUrl: requestedControlTowerUrl,
18329
18738
  healthUrl,
18330
18739
  healthStatus: "reachable",
18331
- nextCommands: ["guardian open", "guardian status", "guardian daemon pair --json"]
18740
+ nextCommands: ["guardian open", "guardian status", "Open ContextECF Halo and click Connect"]
18332
18741
  };
18333
18742
  write(
18334
18743
  stdout,
18335
18744
  flags.has("json") ? `${JSON.stringify(result2, null, 2)}
18336
18745
  ` : `${[
18337
- "Guardian daemon already running.",
18338
- `Daemon: ${requestedDaemonUrl}`,
18746
+ "Local Guardian already running.",
18747
+ `Local Guardian: ${requestedDaemonUrl}`,
18339
18748
  `Control Tower: ${requestedControlTowerUrl}`,
18340
18749
  "Next: guardian open"
18341
18750
  ].join("\n")}
@@ -18344,7 +18753,7 @@ async function runStartCommand(flags, options) {
18344
18753
  return 0;
18345
18754
  }
18346
18755
  if (!options.startDetachedDaemon) {
18347
- write(stderr, "Guardian detached daemon launcher is unavailable in this runtime.\n");
18756
+ write(stderr, "Guardian local background launcher is unavailable in this runtime.\n");
18348
18757
  return 1;
18349
18758
  }
18350
18759
  const started = await options.startDetachedDaemon({ home, host, port: selected.port });
@@ -18365,14 +18774,14 @@ async function runStartCommand(flags, options) {
18365
18774
  pid: started.pid,
18366
18775
  healthUrl,
18367
18776
  healthStatus: existing.error ? "unreachable" : "not_reachable",
18368
- nextCommands: ["guardian open", "guardian status", "guardian daemon pair --json"]
18777
+ nextCommands: ["guardian open", "guardian status", "Open ContextECF Halo and click Connect"]
18369
18778
  };
18370
18779
  write(
18371
18780
  stdout,
18372
18781
  flags.has("json") ? `${JSON.stringify(result, null, 2)}
18373
18782
  ` : `${[
18374
- "Guardian daemon start requested.",
18375
- `Daemon: ${daemonUrl}`,
18783
+ "Local Guardian start requested.",
18784
+ `Local Guardian: ${daemonUrl}`,
18376
18785
  `Control Tower: ${controlTowerUrl}`,
18377
18786
  started.pid ? `PID: ${started.pid}` : void 0,
18378
18787
  "Next: guardian open"
@@ -18383,8 +18792,8 @@ async function runStartCommand(flags, options) {
18383
18792
  }
18384
18793
  function renderDaemonTokenMismatchMessage(requestedDaemonUrl, port) {
18385
18794
  return [
18386
- `Guardian found another daemon or container at ${requestedDaemonUrl}, but it rejected this profile's local runtime token.`,
18387
- "This usually means an older Guardian daemon or Docker demo is still using the port.",
18795
+ `Guardian found another local service or container at ${requestedDaemonUrl}, but it rejected this profile's local connection token.`,
18796
+ "This usually means an older Guardian background service or Docker demo is still using the port.",
18388
18797
  `Recovery: stop the other process/container, or run Guardian on a different port with guardian launch --port=${port + 1}.`,
18389
18798
  `Diagnostics: guardian status; docker ps --filter publish=${port}`,
18390
18799
  ""
@@ -18417,7 +18826,7 @@ async function runStopCommand(flags, options) {
18417
18826
  if (!stopped.ok) {
18418
18827
  write(
18419
18828
  stderr,
18420
- `Guardian daemon did not stop cleanly${stopped.statusCode ? ` (HTTP ${stopped.statusCode})` : ""}: ${stopped.error ?? "unknown_error"}
18829
+ `Local Guardian did not stop cleanly${stopped.statusCode ? ` (HTTP ${stopped.statusCode})` : ""}: ${stopped.error ?? "unknown_error"}
18421
18830
  `
18422
18831
  );
18423
18832
  return 1;
@@ -18428,12 +18837,12 @@ async function runStopCommand(flags, options) {
18428
18837
  success: true,
18429
18838
  daemonStatus: profile.runtime.daemon_status,
18430
18839
  stopUrl: stopUrl.url,
18431
- note: "Guardian daemon stop requested."
18840
+ note: "Local Guardian stop requested."
18432
18841
  };
18433
18842
  write(
18434
18843
  stdout,
18435
18844
  flags.has("json") ? `${JSON.stringify(result, null, 2)}
18436
- ` : `${["Guardian daemon stop requested.", "Status: not_started_mvp"].join("\n")}
18845
+ ` : `${["Local Guardian stop requested.", "Status: not_started_mvp"].join("\n")}
18437
18846
  `
18438
18847
  );
18439
18848
  return 0;
@@ -18505,7 +18914,7 @@ Proof: ${result2.proofPath}
18505
18914
  }
18506
18915
  const host = stringFlag(flags, "host") ?? "127.0.0.1";
18507
18916
  if (!isLoopbackHost(host)) {
18508
- write(stderr, "Guardian service supervision only accepts loopback daemon hosts.\n");
18917
+ write(stderr, "Guardian service supervision only accepts loopback Local Guardian hosts.\n");
18509
18918
  return 1;
18510
18919
  }
18511
18920
  const port = numberFlag(flags, "port") ?? 4317;
@@ -18762,7 +19171,7 @@ async function daemonPair(flags, options) {
18762
19171
  [GUARDIAN_BRIDGE_CONFIG_STORAGE_KEY]: bridgeConfig,
18763
19172
  [GUARDIAN_BRIDGE_TOKEN_STORAGE_KEY]: token
18764
19173
  },
18765
- note: "Store this token in the Guardian browser extension local settings, then run guardian daemon serve."
19174
+ note: "Advanced fallback only. Most users should run guardian setup, open ContextECF Halo, and click Connect."
18766
19175
  };
18767
19176
  if (flags.has("json")) {
18768
19177
  return { exitCode: 0, message: `${JSON.stringify(pairing, null, 2)}
@@ -18771,13 +19180,10 @@ async function daemonPair(flags, options) {
18771
19180
  return {
18772
19181
  exitCode: 0,
18773
19182
  message: `${[
18774
- "Guardian browser bridge pairing",
18775
- `Storage key: ${pairing.storageKey}`,
18776
- `Loopback URL: ${pairing.loopbackBaseUrl}`,
18777
- `Transport: ${pairing.transport}`,
18778
- `Native host: ${pairing.nativeHostName}`,
18779
- `Token: ${pairing.token}`,
18780
- pairing.note
19183
+ "Guardian browser connection uses one-click setup now.",
19184
+ "Run guardian connect, then open ContextECF Halo and click Connect.",
19185
+ "Support setup codes are only printed by guardian pair --json.",
19186
+ "Token printed: no"
18781
19187
  ].join("\n")}
18782
19188
  `
18783
19189
  };
@@ -18786,6 +19192,9 @@ async function runExtensionCommand(argv, flags, options) {
18786
19192
  const subcommand = argv[0] ?? "native-host";
18787
19193
  const stdout = options.stdout ?? process.stdout;
18788
19194
  const stderr = options.stderr ?? process.stderr;
19195
+ if (subcommand === "connect") {
19196
+ return runExtensionConnectCommand(flags, options);
19197
+ }
18789
19198
  if (subcommand === "open-setup") {
18790
19199
  return runExtensionOpenSetupCommand(flags, options);
18791
19200
  }
@@ -18973,13 +19382,18 @@ Re-run with --force to replace it.
18973
19382
  registryMutationRequested: writeRegistry,
18974
19383
  registryProofPath,
18975
19384
  tokenPrinted: false,
18976
- nextCommands: ["guardian launch", "guardian daemon pair --json"]
19385
+ nextCommands: [
19386
+ "guardian launch",
19387
+ "Open ContextECF Halo and click Connect",
19388
+ "guardian extension native-host status"
19389
+ ],
19390
+ advancedCommands: ["guardian pair --json"]
18977
19391
  };
18978
19392
  write(
18979
19393
  stdout,
18980
19394
  flags.has("json") ? `${JSON.stringify(result, null, 2)}
18981
19395
  ` : `${[
18982
- "Guardian native host installed.",
19396
+ "Guardian browser connection installed.",
18983
19397
  `Browser: ${browser}`,
18984
19398
  `Host: ${plan.hostName}`,
18985
19399
  `Manifest: ${plan.manifestPath}`,
@@ -18994,6 +19408,121 @@ Re-run with --force to replace it.
18994
19408
  );
18995
19409
  return 0;
18996
19410
  }
19411
+ async function runExtensionConnectCommand(flags, options) {
19412
+ const stdout = options.stdout ?? process.stdout;
19413
+ const stderr = options.stderr ?? process.stderr;
19414
+ const requestedExtensionId = stringFlag(flags, "extension-id") ?? stringFlag(flags, "id");
19415
+ const extensionId = requestedExtensionId ?? GUARDIAN_HALO_CHROME_EXTENSION_ID;
19416
+ if (requestedExtensionId && !isValidChromeExtensionId(requestedExtensionId)) {
19417
+ write(
19418
+ stderr,
19419
+ "Invalid --extension-id. Chrome extension ids must be 32 lowercase letters from a-p.\n"
19420
+ );
19421
+ return 1;
19422
+ }
19423
+ const install = JSON.parse(await installGuardian(/* @__PURE__ */ new Map([["json", true]]), options));
19424
+ let launchOutput = "";
19425
+ const launchFlags = new Map([
19426
+ ["json", true],
19427
+ ["print", true],
19428
+ ...copyStringFlags(flags, ["host", "port"])
19429
+ ]);
19430
+ const launchExitCode = await runLaunchCommand(launchFlags, {
19431
+ ...options,
19432
+ stdout: {
19433
+ write: (chunk) => {
19434
+ launchOutput += chunk.toString();
19435
+ return true;
19436
+ }
19437
+ },
19438
+ stderr
19439
+ });
19440
+ if (launchExitCode !== 0) {
19441
+ return launchExitCode;
19442
+ }
19443
+ const launch = JSON.parse(launchOutput);
19444
+ const helperFlags = new Map([
19445
+ ["json", true],
19446
+ ["force", true],
19447
+ ["extension-id", extensionId],
19448
+ ...copyStringFlags(flags, ["browser", "target"])
19449
+ ]);
19450
+ if ((options.platform ?? process.platform) === "win32") {
19451
+ helperFlags.set("write-registry", true);
19452
+ helperFlags.set("yes", true);
19453
+ }
19454
+ let helperOutput = "";
19455
+ let helperError = "";
19456
+ const helperExitCode = await runExtensionCommand(["native-host", "install"], helperFlags, {
19457
+ ...options,
19458
+ stdout: {
19459
+ write: (chunk) => {
19460
+ helperOutput += chunk.toString();
19461
+ return true;
19462
+ }
19463
+ },
19464
+ stderr: {
19465
+ write: (chunk) => {
19466
+ helperError += chunk.toString();
19467
+ return true;
19468
+ }
19469
+ }
19470
+ });
19471
+ if (helperExitCode !== 0) {
19472
+ write(
19473
+ stderr,
19474
+ helperError.trim() ? `${helperError.trim()}
19475
+ ` : "Guardian could not prepare the browser connection. Run guardian setup, then try again.\n"
19476
+ );
19477
+ return helperExitCode;
19478
+ }
19479
+ const helper = JSON.parse(helperOutput);
19480
+ const result = {
19481
+ schema_version: "contextecf/project-guardian-browser-connect/v1",
19482
+ success: true,
19483
+ extensionId,
19484
+ defaultExtensionId: GUARDIAN_HALO_CHROME_EXTENSION_ID,
19485
+ install: {
19486
+ profileDir: install.profileDir,
19487
+ tokenCreated: install.tokenCreated,
19488
+ tokenPrinted: false
19489
+ },
19490
+ localGuardian: {
19491
+ running: true,
19492
+ opened: launch.opened,
19493
+ reusedExistingDaemon: launch.reusedExistingDaemon,
19494
+ daemonUrl: launch.daemonUrl,
19495
+ controlTowerUrl: launch.controlTowerUrl,
19496
+ pid: launch.pid,
19497
+ healthStatus: launch.healthStatus
19498
+ },
19499
+ browser: helper.browser,
19500
+ helperInstalled: true,
19501
+ helperStatus: {
19502
+ hostName: helper.hostName,
19503
+ manifestPath: helper.manifestPath,
19504
+ allowedOrigins: helper.allowedOrigins,
19505
+ tokenPrinted: helper.tokenPrinted
19506
+ },
19507
+ tokenPrinted: false,
19508
+ nextCommands: ["Open ContextECF Halo and click Connect", "guardian open", "guardian status"],
19509
+ supportCommands: ["guardian extension open-setup --print", "guardian pair --json"]
19510
+ };
19511
+ write(
19512
+ stdout,
19513
+ flags.has("json") ? `${JSON.stringify(result, null, 2)}
19514
+ ` : `${[
19515
+ "Guardian browser connection is ready.",
19516
+ `Local Guardian: ${result.localGuardian.daemonUrl}${result.localGuardian.reusedExistingDaemon ? " (already running)" : ""}`,
19517
+ `Browser: ${result.browser}`,
19518
+ "Next: open ContextECF Halo and click Connect.",
19519
+ "No setup code needed.",
19520
+ "Token printed: no"
19521
+ ].join("\n")}
19522
+ `
19523
+ );
19524
+ return 0;
19525
+ }
18997
19526
  async function runExtensionOpenSetupCommand(flags, options) {
18998
19527
  const stdout = options.stdout ?? process.stdout;
18999
19528
  const stderr = options.stderr ?? process.stderr;
@@ -19003,8 +19532,9 @@ async function runExtensionOpenSetupCommand(flags, options) {
19003
19532
  write(stderr, "Guardian is not installed. Run guardian install first.\n");
19004
19533
  return 1;
19005
19534
  }
19006
- const extensionId = stringFlag(flags, "extension-id") ?? stringFlag(flags, "id");
19007
- if (extensionId && !isValidChromeExtensionId(extensionId)) {
19535
+ const requestedExtensionId = stringFlag(flags, "extension-id") ?? stringFlag(flags, "id");
19536
+ const extensionId = requestedExtensionId ?? GUARDIAN_HALO_CHROME_EXTENSION_ID;
19537
+ if (requestedExtensionId && !isValidChromeExtensionId(requestedExtensionId)) {
19008
19538
  write(
19009
19539
  stderr,
19010
19540
  "Invalid --extension-id. Chrome extension ids must be 32 lowercase letters from a-p.\n"
@@ -19018,22 +19548,24 @@ async function runExtensionOpenSetupCommand(flags, options) {
19018
19548
  return 1;
19019
19549
  }
19020
19550
  const setupUrl = buildControlTowerSetupUrl(resolved.url);
19021
- const nativeHostCommand = `guardian extension native-host install --extension-id=${extensionId ?? "<browser-extension-id>"}`;
19551
+ const nativeHostCommand = `guardian extension native-host install --extension-id=${extensionId}`;
19022
19552
  const result = {
19023
19553
  schema_version: "contextecf/project-guardian-extension-setup/v1",
19024
19554
  success: true,
19025
19555
  opened: !flags.has("print"),
19026
19556
  controlTowerUrl: resolved.url,
19027
19557
  setupUrl,
19028
- extensionId: extensionId ?? null,
19558
+ extensionId,
19559
+ defaultExtensionId: GUARDIAN_HALO_CHROME_EXTENSION_ID,
19029
19560
  tokenPrinted: false,
19030
19561
  nextCommands: [
19031
19562
  "guardian launch",
19032
- "guardian daemon pair --json",
19033
19563
  nativeHostCommand,
19034
- "guardian extension native-host status"
19564
+ "guardian extension native-host status",
19565
+ "Open ContextECF Halo and click Connect"
19035
19566
  ],
19036
- note: extensionId ? "Guardian browser setup opened with a concrete native host install command." : "Guardian browser setup opened with placeholder extension-id guidance."
19567
+ advancedCommands: ["guardian pair --json"],
19568
+ note: extensionId ? "Guardian browser setup opened for ContextECF Halo." : "Guardian browser setup opened."
19037
19569
  };
19038
19570
  if (result.opened) {
19039
19571
  const opener = options.openUrl ?? ((url2) => openUrlInDefaultBrowser(url2, options));
@@ -19045,7 +19577,8 @@ async function runExtensionOpenSetupCommand(flags, options) {
19045
19577
  ` : `${[
19046
19578
  result.opened ? `Opening Guardian browser setup: ${setupUrl}` : `Guardian browser setup: ${setupUrl}`,
19047
19579
  "Token printed: no",
19048
- `Next: ${result.nextCommands.join("; ")}`
19580
+ `Next: ${result.nextCommands.join("; ")}`,
19581
+ `Advanced fallback: ${result.advancedCommands.join("; ")}`
19049
19582
  ].join("\n")}
19050
19583
  `
19051
19584
  );
@@ -19572,7 +20105,7 @@ function buildGuardianServiceArtifact(input) {
19572
20105
  if (input.platform === "systemd") {
19573
20106
  return `${[
19574
20107
  "[Unit]",
19575
- "Description=Project Guardian local daemon",
20108
+ "Description=Project Guardian Local Guardian background service",
19576
20109
  "After=network.target",
19577
20110
  "",
19578
20111
  "[Service]",
@@ -19591,7 +20124,7 @@ function buildGuardianServiceArtifact(input) {
19591
20124
  '<?xml version="1.0" encoding="UTF-16"?>',
19592
20125
  '<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">',
19593
20126
  " <RegistrationInfo>",
19594
- " <Description>Project Guardian local daemon</Description>",
20127
+ " <Description>Project Guardian Local Guardian background service</Description>",
19595
20128
  " </RegistrationInfo>",
19596
20129
  " <Triggers>",
19597
20130
  " <LogonTrigger><Enabled>true</Enabled></LogonTrigger>",
@@ -20573,6 +21106,59 @@ async function runReceiptsCommand(argv, flags, options) {
20573
21106
  write(stdout, await verifyReceipts(flags, options));
20574
21107
  return 0;
20575
21108
  }
21109
+ async function runCoachCommand(argv, flags, options) {
21110
+ const subcommand = argv[0] ?? "options";
21111
+ const stdout = options.stdout ?? process.stdout;
21112
+ const stderr = options.stderr ?? process.stderr;
21113
+ if (subcommand === "options" || subcommand === "catalog") {
21114
+ write(stdout, renderGuardianPromptCardOptions(buildGuardianPromptCardOptions(), flags));
21115
+ return 0;
21116
+ }
21117
+ write(stderr, `Unknown Guardian coach command: ${subcommand}
21118
+ `);
21119
+ return 1;
21120
+ }
21121
+ function buildGuardianPromptCardOptions() {
21122
+ return {
21123
+ schema_version: "contextecf/project-guardian-prompt-card-options/v1",
21124
+ cli_version: GUARDIAN_CLI_VERSION,
21125
+ status: "catalog_ready",
21126
+ summary: "Guardian prompt cards keep the user in control: warnings and safer rewrites can be sent as-is, while hard blocks cannot.",
21127
+ catalog: GUARDIAN_PROMPT_CARD_OPTIONS_CATALOG,
21128
+ rules: [
21129
+ "Show a clear reason before asking the user to decide.",
21130
+ "Offer Send as-is for warnings and safer rewrites when policy allows override.",
21131
+ "Never offer Send as-is for hard blocks or unavailable Local Guardian checks.",
21132
+ "Keep Edit prompt available as the safe path for every visible send-time card.",
21133
+ "Do not store raw sensitive prompt text in this catalog or CLI output."
21134
+ ],
21135
+ tokenPrinted: false,
21136
+ rawContentIncluded: false
21137
+ };
21138
+ }
21139
+ function renderGuardianPromptCardOptions(result, flags) {
21140
+ if (flags.has("json")) {
21141
+ return `${JSON.stringify(result, null, 2)}
21142
+ `;
21143
+ }
21144
+ return `${[
21145
+ "Guardian Prompt Card Options",
21146
+ result.summary,
21147
+ "",
21148
+ "Programmed cards:",
21149
+ ...result.catalog.map((entry) => {
21150
+ const visibleActions = entry.actions.filter((action) => action.visibleToUser).map((action) => action.label);
21151
+ const labels = visibleActions.length > 0 ? visibleActions.join(", ") : "Prompt sends automatically";
21152
+ return `- ${entry.cardStyle}: ${labels}`;
21153
+ }),
21154
+ "",
21155
+ "Rules:",
21156
+ ...result.rules.map((rule) => `- ${rule}`),
21157
+ "Token printed: no",
21158
+ "Raw prompt content included: no"
21159
+ ].join("\n")}
21160
+ `;
21161
+ }
20576
21162
  async function runPolicyCommand(argv, flags, options) {
20577
21163
  const subcommand = argv[0] ?? "list";
20578
21164
  const stdout = options.stdout ?? process.stdout;
@@ -23003,15 +23589,19 @@ function openUrlInDefaultBrowser(url2, options = {}) {
23003
23589
  });
23004
23590
  }
23005
23591
  export {
23592
+ GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES,
23006
23593
  GUARDIAN_CLI_VERSION,
23007
23594
  GUARDIAN_CONTROL_TOWER_URL_ENV,
23008
23595
  GUARDIAN_DEFAULT_CONTROL_TOWER_URL,
23596
+ GUARDIAN_DEFAULT_NPM_PUBLISH_AUTH,
23009
23597
  GUARDIAN_DESKTOP_ADAPTER_SIMULATE_OPEN_ENV,
23010
23598
  GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_ID,
23011
23599
  GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_PROOF_SCHEMA_VERSION,
23012
23600
  GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_VERSION,
23013
23601
  GUARDIAN_FIRST_RUN_COMMAND,
23014
23602
  GUARDIAN_GLOBAL_INSTALL_COMMAND,
23603
+ GUARDIAN_HALO_CHROME_EXTENSION_ID,
23604
+ GUARDIAN_HALO_CHROME_WEB_STORE_LISTING_URL,
23015
23605
  GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ENV,
23016
23606
  GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ID_ENV,
23017
23607
  GUARDIAN_NOT_PROVEN_PRODUCTION_GATES,
@@ -23024,6 +23614,7 @@ export {
23024
23614
  GUARDIAN_POSTURE_PROFILE_CATALOG,
23025
23615
  GUARDIAN_POSTURE_PROFILE_IDS,
23026
23616
  GUARDIAN_PROFILE_SCHEMA_VERSION,
23617
+ GUARDIAN_PROMPT_CARD_OPTIONS_CATALOG,
23027
23618
  GUARDIAN_PROVIDER_IDS,
23028
23619
  GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
23029
23620
  GUARDIAN_RELEASE_REPOSITORY,