@contextecf/guardian-cli 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -14
- package/dist/packages/guardian-cli/src/bin.js +2430 -115
- package/dist/packages/guardian-cli/src/index.js +662 -83
- package/dist/packages/guardian-cli/src/runtime.d.ts +49 -4
- package/package.json +1 -1
|
@@ -16275,7 +16275,7 @@ function cloneList(values) {
|
|
|
16275
16275
|
}
|
|
16276
16276
|
|
|
16277
16277
|
// packages/guardian-cli/src/runtime.ts
|
|
16278
|
-
var GUARDIAN_CLI_VERSION = "0.1.
|
|
16278
|
+
var GUARDIAN_CLI_VERSION = "0.1.8";
|
|
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/";
|
|
@@ -16283,8 +16283,17 @@ var GUARDIAN_GLOBAL_INSTALL_COMMAND = `npm install -g ${GUARDIAN_NPM_PACKAGE_NAM
|
|
|
16283
16283
|
var GUARDIAN_NPX_SETUP_COMMAND = `npx ${GUARDIAN_NPM_PACKAGE_NAME}@latest setup`;
|
|
16284
16284
|
var GUARDIAN_FIRST_RUN_COMMAND = "guardian setup";
|
|
16285
16285
|
var GUARDIAN_OPEN_CONTROL_TOWER_COMMAND = "guardian open";
|
|
16286
|
+
var GUARDIAN_HALO_CHROME_EXTENSION_ID = "dopkdppbiakhbglhgjfacfdhpheejkck";
|
|
16287
|
+
var GUARDIAN_HALO_CHROME_WEB_STORE_LISTING_URL = `https://chromewebstore.google.com/detail/contextecf-halo/${GUARDIAN_HALO_CHROME_EXTENSION_ID}`;
|
|
16286
16288
|
var GUARDIAN_RELEASE_DISPATCH_WORKFLOW = "guardian-release-dispatch.yml";
|
|
16287
16289
|
var GUARDIAN_RELEASE_REPOSITORY = "Intelligent-Context-AI-Inc/ContextECF-GITHUB";
|
|
16290
|
+
var GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES = [
|
|
16291
|
+
"CHROME_WEB_STORE_CLIENT_ID",
|
|
16292
|
+
"CHROME_WEB_STORE_CLIENT_SECRET",
|
|
16293
|
+
"CHROME_WEB_STORE_REFRESH_TOKEN",
|
|
16294
|
+
"CHROME_WEB_STORE_PUBLISHER_ID",
|
|
16295
|
+
"CHROME_WEB_STORE_EXTENSION_ID"
|
|
16296
|
+
];
|
|
16288
16297
|
var GUARDIAN_CONTROL_TOWER_URL_ENV = "GUARDIAN_CONTROL_TOWER_URL";
|
|
16289
16298
|
var GUARDIAN_DEFAULT_CONTROL_TOWER_URL = "http://127.0.0.1:4317/control-tower";
|
|
16290
16299
|
var GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ENV = "GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY";
|
|
@@ -16301,6 +16310,195 @@ var GUARDIAN_WINDOWS_NATIVE_HOST_REGISTRY_PROOF_SCHEMA_VERSION = "contextecf/pro
|
|
|
16301
16310
|
var PERSONAL_FABRIC_CONTRACTS_SCHEMA_VERSION2 = "contextecf/personal-fabric-contracts/v1";
|
|
16302
16311
|
var PROMPT_COACH_MODES = ["off", "quiet", "balanced", "hands_on"];
|
|
16303
16312
|
var DEFAULT_PROMPT_COACH_DAILY_SOFT_CARD_LIMIT = 6;
|
|
16313
|
+
var GUARDIAN_PROMPT_CARD_OPTIONS_CATALOG = [
|
|
16314
|
+
{
|
|
16315
|
+
disposition: "allow",
|
|
16316
|
+
cardStyle: "No visible card",
|
|
16317
|
+
whenShown: "Local Guardian approves the prompt before it leaves the browser.",
|
|
16318
|
+
actions: [
|
|
16319
|
+
{
|
|
16320
|
+
id: "auto-send",
|
|
16321
|
+
label: "Send prompt",
|
|
16322
|
+
role: "none",
|
|
16323
|
+
sendsPrompt: true,
|
|
16324
|
+
sendsRevisedPrompt: false,
|
|
16325
|
+
requiresConfirmation: false,
|
|
16326
|
+
visibleToUser: false
|
|
16327
|
+
}
|
|
16328
|
+
],
|
|
16329
|
+
sendAsIsAllowed: true,
|
|
16330
|
+
hardBlock: false,
|
|
16331
|
+
receiptExpected: true
|
|
16332
|
+
},
|
|
16333
|
+
{
|
|
16334
|
+
disposition: "warn",
|
|
16335
|
+
cardStyle: "Quick check",
|
|
16336
|
+
whenShown: "Guardian found a low or medium-risk concern, but policy still allows the user to continue.",
|
|
16337
|
+
actions: [
|
|
16338
|
+
{
|
|
16339
|
+
id: "send-as-is",
|
|
16340
|
+
label: "Send as-is",
|
|
16341
|
+
role: "allowed_override",
|
|
16342
|
+
sendsPrompt: true,
|
|
16343
|
+
sendsRevisedPrompt: false,
|
|
16344
|
+
requiresConfirmation: false,
|
|
16345
|
+
visibleToUser: true
|
|
16346
|
+
},
|
|
16347
|
+
{
|
|
16348
|
+
id: "edit-prompt",
|
|
16349
|
+
label: "Edit prompt",
|
|
16350
|
+
role: "safe_escape",
|
|
16351
|
+
sendsPrompt: false,
|
|
16352
|
+
sendsRevisedPrompt: false,
|
|
16353
|
+
requiresConfirmation: false,
|
|
16354
|
+
visibleToUser: true
|
|
16355
|
+
}
|
|
16356
|
+
],
|
|
16357
|
+
sendAsIsAllowed: true,
|
|
16358
|
+
hardBlock: false,
|
|
16359
|
+
receiptExpected: true
|
|
16360
|
+
},
|
|
16361
|
+
{
|
|
16362
|
+
disposition: "rewrite",
|
|
16363
|
+
cardStyle: "Safer version ready",
|
|
16364
|
+
whenShown: "Guardian prepared a safer prompt, usually by masking sensitive text or narrowing scope.",
|
|
16365
|
+
actions: [
|
|
16366
|
+
{
|
|
16367
|
+
id: "send-revised-prompt",
|
|
16368
|
+
label: "Send revised prompt",
|
|
16369
|
+
role: "recommended",
|
|
16370
|
+
sendsPrompt: true,
|
|
16371
|
+
sendsRevisedPrompt: true,
|
|
16372
|
+
requiresConfirmation: false,
|
|
16373
|
+
visibleToUser: true
|
|
16374
|
+
},
|
|
16375
|
+
{
|
|
16376
|
+
id: "send-as-is",
|
|
16377
|
+
label: "Send as-is",
|
|
16378
|
+
role: "allowed_override",
|
|
16379
|
+
sendsPrompt: true,
|
|
16380
|
+
sendsRevisedPrompt: false,
|
|
16381
|
+
requiresConfirmation: false,
|
|
16382
|
+
visibleToUser: true
|
|
16383
|
+
},
|
|
16384
|
+
{
|
|
16385
|
+
id: "edit-prompt",
|
|
16386
|
+
label: "Edit prompt",
|
|
16387
|
+
role: "safe_escape",
|
|
16388
|
+
sendsPrompt: false,
|
|
16389
|
+
sendsRevisedPrompt: false,
|
|
16390
|
+
requiresConfirmation: false,
|
|
16391
|
+
visibleToUser: true
|
|
16392
|
+
}
|
|
16393
|
+
],
|
|
16394
|
+
sendAsIsAllowed: true,
|
|
16395
|
+
hardBlock: false,
|
|
16396
|
+
receiptExpected: true
|
|
16397
|
+
},
|
|
16398
|
+
{
|
|
16399
|
+
disposition: "confirm",
|
|
16400
|
+
cardStyle: "Review needed",
|
|
16401
|
+
whenShown: "Guardian needs deliberate approval before sending higher-risk content or action requests.",
|
|
16402
|
+
actions: [
|
|
16403
|
+
{
|
|
16404
|
+
id: "approve-and-send",
|
|
16405
|
+
label: "Approve and send",
|
|
16406
|
+
role: "recommended",
|
|
16407
|
+
sendsPrompt: true,
|
|
16408
|
+
sendsRevisedPrompt: false,
|
|
16409
|
+
requiresConfirmation: true,
|
|
16410
|
+
visibleToUser: true
|
|
16411
|
+
},
|
|
16412
|
+
{
|
|
16413
|
+
id: "edit-prompt",
|
|
16414
|
+
label: "Edit prompt",
|
|
16415
|
+
role: "safe_escape",
|
|
16416
|
+
sendsPrompt: false,
|
|
16417
|
+
sendsRevisedPrompt: false,
|
|
16418
|
+
requiresConfirmation: false,
|
|
16419
|
+
visibleToUser: true
|
|
16420
|
+
}
|
|
16421
|
+
],
|
|
16422
|
+
sendAsIsAllowed: false,
|
|
16423
|
+
hardBlock: false,
|
|
16424
|
+
receiptExpected: true
|
|
16425
|
+
},
|
|
16426
|
+
{
|
|
16427
|
+
disposition: "block",
|
|
16428
|
+
cardStyle: "Blocked",
|
|
16429
|
+
whenShown: "The prompt violates policy, contains protected secrets, or targets a denied destination.",
|
|
16430
|
+
actions: [
|
|
16431
|
+
{
|
|
16432
|
+
id: "edit-prompt",
|
|
16433
|
+
label: "Edit prompt",
|
|
16434
|
+
role: "safe_escape",
|
|
16435
|
+
sendsPrompt: false,
|
|
16436
|
+
sendsRevisedPrompt: false,
|
|
16437
|
+
requiresConfirmation: false,
|
|
16438
|
+
visibleToUser: true
|
|
16439
|
+
}
|
|
16440
|
+
],
|
|
16441
|
+
sendAsIsAllowed: false,
|
|
16442
|
+
hardBlock: true,
|
|
16443
|
+
receiptExpected: true
|
|
16444
|
+
},
|
|
16445
|
+
{
|
|
16446
|
+
disposition: "unavailable",
|
|
16447
|
+
cardStyle: "Setup needed",
|
|
16448
|
+
whenShown: "The browser cannot reach Local Guardian, so the prompt is held back.",
|
|
16449
|
+
actions: [
|
|
16450
|
+
{
|
|
16451
|
+
id: "edit-prompt",
|
|
16452
|
+
label: "Edit prompt",
|
|
16453
|
+
role: "safe_escape",
|
|
16454
|
+
sendsPrompt: false,
|
|
16455
|
+
sendsRevisedPrompt: false,
|
|
16456
|
+
requiresConfirmation: false,
|
|
16457
|
+
visibleToUser: true
|
|
16458
|
+
}
|
|
16459
|
+
],
|
|
16460
|
+
sendAsIsAllowed: false,
|
|
16461
|
+
hardBlock: false,
|
|
16462
|
+
receiptExpected: false
|
|
16463
|
+
},
|
|
16464
|
+
{
|
|
16465
|
+
disposition: "live_sensitive_warning",
|
|
16466
|
+
cardStyle: "Early heads-up",
|
|
16467
|
+
whenShown: "Guardian notices sensitive text while the user is typing, before the formal send-time check.",
|
|
16468
|
+
actions: [
|
|
16469
|
+
{
|
|
16470
|
+
id: "use-placeholder",
|
|
16471
|
+
label: "Use placeholder",
|
|
16472
|
+
role: "recommended",
|
|
16473
|
+
sendsPrompt: false,
|
|
16474
|
+
sendsRevisedPrompt: true,
|
|
16475
|
+
requiresConfirmation: false,
|
|
16476
|
+
visibleToUser: true
|
|
16477
|
+
},
|
|
16478
|
+
{
|
|
16479
|
+
id: "send-as-is",
|
|
16480
|
+
label: "Send as-is",
|
|
16481
|
+
role: "allowed_override",
|
|
16482
|
+
sendsPrompt: true,
|
|
16483
|
+
sendsRevisedPrompt: false,
|
|
16484
|
+
requiresConfirmation: false,
|
|
16485
|
+
visibleToUser: true
|
|
16486
|
+
},
|
|
16487
|
+
{
|
|
16488
|
+
id: "keep-drafting",
|
|
16489
|
+
label: "Keep drafting",
|
|
16490
|
+
role: "safe_escape",
|
|
16491
|
+
sendsPrompt: false,
|
|
16492
|
+
sendsRevisedPrompt: false,
|
|
16493
|
+
requiresConfirmation: false,
|
|
16494
|
+
visibleToUser: true
|
|
16495
|
+
}
|
|
16496
|
+
],
|
|
16497
|
+
sendAsIsAllowed: true,
|
|
16498
|
+
hardBlock: false,
|
|
16499
|
+
receiptExpected: false
|
|
16500
|
+
}
|
|
16501
|
+
];
|
|
16304
16502
|
var GUARDIAN_POSTURE_PROFILE_IDS = [
|
|
16305
16503
|
"calm",
|
|
16306
16504
|
"balanced",
|
|
@@ -16780,6 +16978,45 @@ var MCP_CLIENTS = ["generic", "codex", "claude-desktop", "cursor"];
|
|
|
16780
16978
|
var NATIVE_HOST_BROWSERS = ["chrome", "chromium", "edge"];
|
|
16781
16979
|
var HELP_TEXT = `guardian \u2014 Project Guardian Personal Context Fabric
|
|
16782
16980
|
|
|
16981
|
+
Global install:
|
|
16982
|
+
${GUARDIAN_GLOBAL_INSTALL_COMMAND}
|
|
16983
|
+
|
|
16984
|
+
First run:
|
|
16985
|
+
${GUARDIAN_FIRST_RUN_COMMAND}
|
|
16986
|
+
|
|
16987
|
+
No global install:
|
|
16988
|
+
${GUARDIAN_NPX_SETUP_COMMAND}
|
|
16989
|
+
|
|
16990
|
+
Open Control Tower:
|
|
16991
|
+
${GUARDIAN_OPEN_CONTROL_TOWER_COMMAND}
|
|
16992
|
+
start aliases: guardian launch, guardian tower, guardian control-tower
|
|
16993
|
+
|
|
16994
|
+
Everyday commands:
|
|
16995
|
+
guardian --version
|
|
16996
|
+
guardian setup
|
|
16997
|
+
guardian launch
|
|
16998
|
+
guardian open
|
|
16999
|
+
guardian status
|
|
17000
|
+
guardian doctor
|
|
17001
|
+
guardian connect
|
|
17002
|
+
guardian coach options
|
|
17003
|
+
guardian policy list
|
|
17004
|
+
guardian marketplace list
|
|
17005
|
+
guardian posture list
|
|
17006
|
+
guardian privacy show
|
|
17007
|
+
|
|
17008
|
+
Recommended first run:
|
|
17009
|
+
${GUARDIAN_GLOBAL_INSTALL_COMMAND}
|
|
17010
|
+
guardian setup
|
|
17011
|
+
Open ContextECF Halo and click Connect.
|
|
17012
|
+
guardian open
|
|
17013
|
+
|
|
17014
|
+
Support and developer commands:
|
|
17015
|
+
guardian help --advanced
|
|
17016
|
+
|
|
17017
|
+
Defaults are local-first: raw capture, cloud sync, learning graph, and app autopilot stay off.`;
|
|
17018
|
+
var ADVANCED_HELP_TEXT = `guardian \u2014 Project Guardian Personal Context Fabric
|
|
17019
|
+
|
|
16783
17020
|
Global install:
|
|
16784
17021
|
${GUARDIAN_GLOBAL_INSTALL_COMMAND}
|
|
16785
17022
|
|
|
@@ -16796,7 +17033,7 @@ Open Control Tower:
|
|
|
16796
17033
|
Usage:
|
|
16797
17034
|
guardian --version
|
|
16798
17035
|
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>]
|
|
17036
|
+
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
17037
|
guardian install [--json]
|
|
16801
17038
|
guardian doctor [--json]
|
|
16802
17039
|
guardian readiness [--json] [--strict]
|
|
@@ -16804,7 +17041,7 @@ Usage:
|
|
|
16804
17041
|
guardian release flow --version=<semver> [--json]
|
|
16805
17042
|
guardian release verify --version=<semver> [--json]
|
|
16806
17043
|
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]
|
|
17044
|
+
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
17045
|
guardian release secrets [--json]
|
|
16809
17046
|
guardian release browser-store [--json]
|
|
16810
17047
|
guardian open [--json] [--print] [--url=http://127.0.0.1:<port>]
|
|
@@ -16812,6 +17049,8 @@ Usage:
|
|
|
16812
17049
|
guardian start [--json] [--host=127.0.0.1] [--port=4317]
|
|
16813
17050
|
guardian launch|tower|control-tower [--json] [--open] [--print] [--host=127.0.0.1] [--port=4317]
|
|
16814
17051
|
guardian stop [--json] [--url=http://127.0.0.1:<port>/control-tower]
|
|
17052
|
+
guardian pair [--json]
|
|
17053
|
+
guardian connect [--json] [--browser=chrome|chromium|edge] [--extension-id=<chrome-extension-id>] [--host=127.0.0.1] [--port=4317]
|
|
16815
17054
|
guardian service install [--json] [--platform=auto|launchd|systemd|windows-task-scheduler] [--force]
|
|
16816
17055
|
guardian service status [--json]
|
|
16817
17056
|
guardian service uninstall [--yes] [--json]
|
|
@@ -16820,6 +17059,7 @@ Usage:
|
|
|
16820
17059
|
guardian key-store uninstall [--yes] [--json]
|
|
16821
17060
|
guardian daemon serve [--host=127.0.0.1] [--port=4317]
|
|
16822
17061
|
guardian daemon pair [--json]
|
|
17062
|
+
guardian extension connect [--json] [--browser=chrome|chromium|edge] [--extension-id=<chrome-extension-id>]
|
|
16823
17063
|
guardian extension open-setup [--json] [--print] [--url=http://127.0.0.1:<port>/control-tower] [--extension-id=<chrome-extension-id>]
|
|
16824
17064
|
guardian extension native-host install --extension-id=<chrome-extension-id> [--browser=chrome|chromium|edge] [--target=/path/to/manifest] [--force] [--write-registry --yes] [--json]
|
|
16825
17065
|
guardian extension native-host status [--browser=chrome|chromium|edge] [--target=/path/to/manifest] [--json]
|
|
@@ -16835,6 +17075,7 @@ Usage:
|
|
|
16835
17075
|
guardian privacy mode on [--json]
|
|
16836
17076
|
guardian mcp install [--json] [--client=generic|codex|claude-desktop|cursor|all] [--write] [--target=/path/to/config] [--force]
|
|
16837
17077
|
guardian mcp serve
|
|
17078
|
+
guardian coach options [--json]
|
|
16838
17079
|
guardian policy list [--json]
|
|
16839
17080
|
guardian policy enable <pack-id> [--json]
|
|
16840
17081
|
guardian policy disable <pack-id> [--json]
|
|
@@ -16887,6 +17128,8 @@ async function runGuardianCli(argv, options = {}) {
|
|
|
16887
17128
|
return runReleaseCommand(argv.slice(1), flags, options);
|
|
16888
17129
|
case "open":
|
|
16889
17130
|
return runControlTowerOpenCommand(flags, options);
|
|
17131
|
+
case "connect":
|
|
17132
|
+
return runExtensionConnectCommand(flags, options);
|
|
16890
17133
|
case "status":
|
|
16891
17134
|
write(stdout, await statusGuardian(flags, options));
|
|
16892
17135
|
return 0;
|
|
@@ -16898,6 +17141,14 @@ async function runGuardianCli(argv, options = {}) {
|
|
|
16898
17141
|
return runLaunchCommand(flags, options);
|
|
16899
17142
|
case "stop":
|
|
16900
17143
|
return runStopCommand(flags, options);
|
|
17144
|
+
case "pair": {
|
|
17145
|
+
if (!flags.has("json")) {
|
|
17146
|
+
return runExtensionConnectCommand(flags, options);
|
|
17147
|
+
}
|
|
17148
|
+
const result = await daemonPair(flags, options);
|
|
17149
|
+
write(result.exitCode === 0 ? stdout : stderr, result.message);
|
|
17150
|
+
return result.exitCode;
|
|
17151
|
+
}
|
|
16901
17152
|
case "daemon":
|
|
16902
17153
|
return runDaemonCommand(argv.slice(1), flags, options);
|
|
16903
17154
|
case "service":
|
|
@@ -16920,6 +17171,9 @@ async function runGuardianCli(argv, options = {}) {
|
|
|
16920
17171
|
return runPrivacyCommand(argv.slice(1), flags, options);
|
|
16921
17172
|
case "mcp":
|
|
16922
17173
|
return runMcpCommand(argv.slice(1), flags, options);
|
|
17174
|
+
case "coach":
|
|
17175
|
+
case "prompt-coach":
|
|
17176
|
+
return runCoachCommand(argv.slice(1), flags, options);
|
|
16923
17177
|
case "policy":
|
|
16924
17178
|
return runPolicyCommand(argv.slice(1), flags, options);
|
|
16925
17179
|
case "marketplace":
|
|
@@ -16942,7 +17196,7 @@ async function runGuardianCli(argv, options = {}) {
|
|
|
16942
17196
|
case "help":
|
|
16943
17197
|
case "--help":
|
|
16944
17198
|
case "-h":
|
|
16945
|
-
write(stdout, `${HELP_TEXT}
|
|
17199
|
+
write(stdout, `${flags.has("advanced") ? ADVANCED_HELP_TEXT : HELP_TEXT}
|
|
16946
17200
|
`);
|
|
16947
17201
|
return 0;
|
|
16948
17202
|
default:
|
|
@@ -17021,11 +17275,13 @@ async function installGuardian(flags, options = {}) {
|
|
|
17021
17275
|
"guardian start",
|
|
17022
17276
|
"guardian open",
|
|
17023
17277
|
"guardian mcp install",
|
|
17024
|
-
"guardian daemon pair --json",
|
|
17025
17278
|
"guardian service install",
|
|
17026
17279
|
"guardian key-store install --yes",
|
|
17027
|
-
"guardian
|
|
17028
|
-
|
|
17280
|
+
"guardian connect"
|
|
17281
|
+
],
|
|
17282
|
+
advancedCommands: [
|
|
17283
|
+
`guardian extension native-host install --extension-id=${GUARDIAN_HALO_CHROME_EXTENSION_ID}`,
|
|
17284
|
+
"guardian pair --json"
|
|
17029
17285
|
]
|
|
17030
17286
|
};
|
|
17031
17287
|
return flags.has("json") ? `${JSON.stringify(result, null, 2)}
|
|
@@ -17038,7 +17294,8 @@ async function installGuardian(flags, options = {}) {
|
|
|
17038
17294
|
`First run: ${GUARDIAN_FIRST_RUN_COMMAND}`,
|
|
17039
17295
|
`Open Control Tower: ${GUARDIAN_OPEN_CONTROL_TOWER_COMMAND}`,
|
|
17040
17296
|
`No global install: ${GUARDIAN_NPX_SETUP_COMMAND}`,
|
|
17041
|
-
"Next: guardian setup;
|
|
17297
|
+
"Next: guardian setup; open ContextECF Halo and click Connect; guardian open",
|
|
17298
|
+
"Help: run guardian doctor if setup needs attention."
|
|
17042
17299
|
].join("\n")}
|
|
17043
17300
|
`;
|
|
17044
17301
|
}
|
|
@@ -17046,8 +17303,9 @@ async function runSetupCommand(flags, options) {
|
|
|
17046
17303
|
const stdout = options.stdout ?? process.stdout;
|
|
17047
17304
|
const stderr = options.stderr ?? process.stderr;
|
|
17048
17305
|
const home = resolveGuardianHome(options.env, options.platform);
|
|
17049
|
-
const
|
|
17050
|
-
|
|
17306
|
+
const requestedExtensionId = stringFlag(flags, "extension-id") ?? stringFlag(flags, "id");
|
|
17307
|
+
const extensionId = requestedExtensionId ?? GUARDIAN_HALO_CHROME_EXTENSION_ID;
|
|
17308
|
+
if (requestedExtensionId && !isValidChromeExtensionId(requestedExtensionId)) {
|
|
17051
17309
|
write(
|
|
17052
17310
|
stderr,
|
|
17053
17311
|
"Invalid --extension-id. Chrome extension ids must be 32 lowercase letters from a-p.\n"
|
|
@@ -17103,10 +17361,80 @@ async function runSetupCommand(flags, options) {
|
|
|
17103
17361
|
}
|
|
17104
17362
|
launch = JSON.parse(launchOutput);
|
|
17105
17363
|
}
|
|
17364
|
+
const requestedHost = stringFlag(flags, "host") ?? "127.0.0.1";
|
|
17365
|
+
const requestedPort = numberFlag(flags, "port") ?? 4317;
|
|
17366
|
+
const requestedControlTowerUrl = `${formatDaemonBaseUrl(requestedHost, requestedPort)}/control-tower`;
|
|
17106
17367
|
const resolvedControlTowerUrl = resolveControlTowerUrl(/* @__PURE__ */ new Map(), options.env, profile);
|
|
17107
|
-
const controlTowerUrl = launch?.controlTowerUrl ?? (resolvedControlTowerUrl.ok ? resolvedControlTowerUrl.url : GUARDIAN_DEFAULT_CONTROL_TOWER_URL);
|
|
17368
|
+
const controlTowerUrl = launch?.controlTowerUrl ?? (flags.has("host") || flags.has("port") ? requestedControlTowerUrl : resolvedControlTowerUrl.ok ? resolvedControlTowerUrl.url : GUARDIAN_DEFAULT_CONTROL_TOWER_URL);
|
|
17369
|
+
if (!launch && (flags.has("host") || flags.has("port"))) {
|
|
17370
|
+
profile.control_tower = {
|
|
17371
|
+
url: controlTowerUrl,
|
|
17372
|
+
source: "env_or_flag"
|
|
17373
|
+
};
|
|
17374
|
+
await writeProfile(home, profile);
|
|
17375
|
+
}
|
|
17108
17376
|
const setupUrl = buildControlTowerSetupUrl(controlTowerUrl);
|
|
17109
|
-
const nativeHostCommand = `guardian extension native-host install --extension-id=${extensionId
|
|
17377
|
+
const nativeHostCommand = `guardian extension native-host install --extension-id=${extensionId}`;
|
|
17378
|
+
let browserHelper;
|
|
17379
|
+
if (flags.has("no-browser-connection") || flags.has("no-browser-helper")) {
|
|
17380
|
+
browserHelper = {
|
|
17381
|
+
success: false,
|
|
17382
|
+
skipped: true,
|
|
17383
|
+
tokenPrinted: false
|
|
17384
|
+
};
|
|
17385
|
+
} else {
|
|
17386
|
+
let nativeHostOutput = "";
|
|
17387
|
+
let nativeHostError = "";
|
|
17388
|
+
const nativeHostFlags = new Map([
|
|
17389
|
+
["json", true],
|
|
17390
|
+
["force", true],
|
|
17391
|
+
["extension-id", extensionId],
|
|
17392
|
+
...copyStringFlags(flags, ["browser", "target"])
|
|
17393
|
+
]);
|
|
17394
|
+
if ((options.platform ?? process.platform) === "win32") {
|
|
17395
|
+
nativeHostFlags.set("write-registry", true);
|
|
17396
|
+
nativeHostFlags.set("yes", true);
|
|
17397
|
+
}
|
|
17398
|
+
const nativeHostExitCode = await runExtensionCommand(
|
|
17399
|
+
["native-host", "install"],
|
|
17400
|
+
nativeHostFlags,
|
|
17401
|
+
{
|
|
17402
|
+
...options,
|
|
17403
|
+
stdout: {
|
|
17404
|
+
write: (chunk) => {
|
|
17405
|
+
nativeHostOutput += chunk.toString();
|
|
17406
|
+
return true;
|
|
17407
|
+
}
|
|
17408
|
+
},
|
|
17409
|
+
stderr: {
|
|
17410
|
+
write: (chunk) => {
|
|
17411
|
+
nativeHostError += chunk.toString();
|
|
17412
|
+
return true;
|
|
17413
|
+
}
|
|
17414
|
+
}
|
|
17415
|
+
}
|
|
17416
|
+
);
|
|
17417
|
+
if (nativeHostExitCode === 0) {
|
|
17418
|
+
const nativeHost = JSON.parse(nativeHostOutput);
|
|
17419
|
+
browserHelper = {
|
|
17420
|
+
success: true,
|
|
17421
|
+
skipped: false,
|
|
17422
|
+
browser: nativeHost.browser,
|
|
17423
|
+
hostName: nativeHost.hostName,
|
|
17424
|
+
manifestPath: nativeHost.manifestPath,
|
|
17425
|
+
allowedOrigins: nativeHost.allowedOrigins,
|
|
17426
|
+
tokenPrinted: nativeHost.tokenPrinted
|
|
17427
|
+
};
|
|
17428
|
+
} else {
|
|
17429
|
+
browserHelper = {
|
|
17430
|
+
success: false,
|
|
17431
|
+
skipped: false,
|
|
17432
|
+
error: nativeHostError.trim() || "Guardian browser connection setup failed.",
|
|
17433
|
+
exitCode: nativeHostExitCode,
|
|
17434
|
+
tokenPrinted: false
|
|
17435
|
+
};
|
|
17436
|
+
}
|
|
17437
|
+
}
|
|
17110
17438
|
const result = {
|
|
17111
17439
|
schema_version: "contextecf/project-guardian-setup/v1",
|
|
17112
17440
|
success: true,
|
|
@@ -17156,10 +17484,14 @@ async function runSetupCommand(flags, options) {
|
|
|
17156
17484
|
},
|
|
17157
17485
|
browserSetup: {
|
|
17158
17486
|
setupUrl,
|
|
17159
|
-
extensionId
|
|
17487
|
+
extensionId,
|
|
17488
|
+
defaultExtensionId: GUARDIAN_HALO_CHROME_EXTENSION_ID,
|
|
17160
17489
|
opened: false,
|
|
17161
17490
|
tokenPrinted: false,
|
|
17162
|
-
nativeHostCommand
|
|
17491
|
+
nativeHostCommand,
|
|
17492
|
+
connectInstruction: "Open ContextECF Halo and click Connect. No setup code is needed.",
|
|
17493
|
+
manualFallbackCommand: "guardian pair --json",
|
|
17494
|
+
nativeHost: browserHelper
|
|
17163
17495
|
},
|
|
17164
17496
|
nextCommands: [
|
|
17165
17497
|
"guardian status",
|
|
@@ -17168,12 +17500,10 @@ async function runSetupCommand(flags, options) {
|
|
|
17168
17500
|
"guardian policy list",
|
|
17169
17501
|
"guardian posture list",
|
|
17170
17502
|
"guardian preferences show",
|
|
17171
|
-
"guardian extension open-setup",
|
|
17172
|
-
"guardian daemon pair --json",
|
|
17173
17503
|
"guardian service install",
|
|
17174
|
-
"guardian key-store install --yes"
|
|
17175
|
-
|
|
17176
|
-
]
|
|
17504
|
+
"guardian key-store install --yes"
|
|
17505
|
+
],
|
|
17506
|
+
advancedCommands: ["guardian extension connect", nativeHostCommand, "guardian pair --json"]
|
|
17177
17507
|
};
|
|
17178
17508
|
write(
|
|
17179
17509
|
stdout,
|
|
@@ -17186,8 +17516,11 @@ async function runSetupCommand(flags, options) {
|
|
|
17186
17516
|
result.launch.opened ? `Opening: ${result.launch.controlTowerUrl}` : void 0,
|
|
17187
17517
|
`MCP artifacts: ${result.mcp.writtenFiles.length > 0 ? result.mcp.writtenFiles.join(", ") : "skipped" in result.mcp && result.mcp.skipped ? "skipped" : "none"}`,
|
|
17188
17518
|
`Browser setup: ${result.browserSetup.setupUrl}`,
|
|
17519
|
+
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})` : ""}`,
|
|
17520
|
+
"Extension setup: open ContextECF Halo and click Connect. No setup code needed.",
|
|
17189
17521
|
"Token printed: no",
|
|
17190
|
-
`Next: ${result.nextCommands.join("; ")}
|
|
17522
|
+
`Next: ${result.nextCommands.join("; ")}`,
|
|
17523
|
+
"Help: run guardian connect if the browser says Local Guardian is not connected."
|
|
17191
17524
|
].filter(Boolean).join("\n")}
|
|
17192
17525
|
`
|
|
17193
17526
|
);
|
|
@@ -17262,8 +17595,8 @@ function buildGuardianDistributionReadiness(npmPreviewReady) {
|
|
|
17262
17595
|
},
|
|
17263
17596
|
aiToolIntegration: {
|
|
17264
17597
|
mcpInstallCommand: "guardian mcp install --client=all --write",
|
|
17265
|
-
browserSetupCommand: "guardian
|
|
17266
|
-
nativeHostInstallCommand:
|
|
17598
|
+
browserSetupCommand: "guardian connect",
|
|
17599
|
+
nativeHostInstallCommand: `guardian extension native-host install --extension-id=${GUARDIAN_HALO_CHROME_EXTENSION_ID}`
|
|
17267
17600
|
},
|
|
17268
17601
|
browserStoreHandoff: {
|
|
17269
17602
|
status: npmPreviewReady ? "operator_handoff_ready_not_submitted" : "blocked_until_preview_ready",
|
|
@@ -17287,7 +17620,7 @@ function buildGuardianDistributionReadiness(npmPreviewReady) {
|
|
|
17287
17620
|
boundaries: [
|
|
17288
17621
|
"Use dry_run=true before public publication.",
|
|
17289
17622
|
"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
|
|
17623
|
+
"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
17624
|
"GitHub Actions OIDC/provenance applies to CI release context; manual local publishes are recorded separately and should not claim CI provenance."
|
|
17292
17625
|
]
|
|
17293
17626
|
},
|
|
@@ -17308,12 +17641,16 @@ function buildGuardianReleaseDispatchCommand(dryRun) {
|
|
|
17308
17641
|
});
|
|
17309
17642
|
}
|
|
17310
17643
|
function buildGuardianReleaseDispatchCommandFor(input) {
|
|
17644
|
+
const publishAuth = input.publishAuth ?? "token";
|
|
17645
|
+
const browserStorePublish = input.browserStorePublish ?? "manual";
|
|
17311
17646
|
return [
|
|
17312
17647
|
`gh workflow run ${GUARDIAN_RELEASE_DISPATCH_WORKFLOW} \\`,
|
|
17313
17648
|
` -f release_version=${input.releaseVersion} \\`,
|
|
17314
17649
|
` -f channels=${input.channels} \\`,
|
|
17315
17650
|
` -f dry_run=${input.dryRun ? "true" : "false"} \\`,
|
|
17316
|
-
` -f run_docker_smoke=${input.runDockerSmoke ? "true" : "false"}
|
|
17651
|
+
` -f run_docker_smoke=${input.runDockerSmoke ? "true" : "false"} \\`,
|
|
17652
|
+
` -f publish_auth=${publishAuth} \\`,
|
|
17653
|
+
` -f browser_store_publish=${browserStorePublish}`
|
|
17317
17654
|
].join("\n");
|
|
17318
17655
|
}
|
|
17319
17656
|
async function runReleaseCommand(argv, flags, options) {
|
|
@@ -17420,11 +17757,23 @@ async function runReleaseCommand(argv, flags, options) {
|
|
|
17420
17757
|
}
|
|
17421
17758
|
const dryRun = flags.has("publish") ? false : booleanFlag(flags, "dry-run", true);
|
|
17422
17759
|
const runDockerSmoke = booleanFlag(flags, "run-docker-smoke", true);
|
|
17760
|
+
const publishAuth = stringFlag(flags, "publish-auth") ?? "token";
|
|
17761
|
+
if (!isValidReleasePublishAuth(publishAuth)) {
|
|
17762
|
+
write(stderr, "Invalid --publish-auth. Expected one of: token, trusted_publisher.\n");
|
|
17763
|
+
return 1;
|
|
17764
|
+
}
|
|
17765
|
+
const browserStorePublish = stringFlag(flags, "browser-store-publish") ?? "manual";
|
|
17766
|
+
if (!isValidBrowserStorePublish(browserStorePublish)) {
|
|
17767
|
+
write(stderr, "Invalid --browser-store-publish. Expected one of: manual, api.\n");
|
|
17768
|
+
return 1;
|
|
17769
|
+
}
|
|
17423
17770
|
const result = buildGuardianReleaseDispatchCommandResult({
|
|
17424
17771
|
releaseVersion,
|
|
17425
17772
|
channels,
|
|
17426
17773
|
dryRun,
|
|
17427
|
-
runDockerSmoke
|
|
17774
|
+
runDockerSmoke,
|
|
17775
|
+
publishAuth,
|
|
17776
|
+
browserStorePublish
|
|
17428
17777
|
});
|
|
17429
17778
|
write(stdout, renderGuardianReleaseDispatchCommand(result, flags));
|
|
17430
17779
|
return 0;
|
|
@@ -17492,6 +17841,7 @@ function renderGuardianReleaseHelp(result, flags) {
|
|
|
17492
17841
|
`;
|
|
17493
17842
|
}
|
|
17494
17843
|
function buildGuardianReleaseDispatchCommandResult(input) {
|
|
17844
|
+
const npmLaneSelected = input.channels === "all" || input.channels === "npm";
|
|
17495
17845
|
return {
|
|
17496
17846
|
schema_version: "contextecf/project-guardian-release-dispatch-command/v1",
|
|
17497
17847
|
cli_version: GUARDIAN_CLI_VERSION,
|
|
@@ -17500,13 +17850,21 @@ function buildGuardianReleaseDispatchCommandResult(input) {
|
|
|
17500
17850
|
channels: input.channels,
|
|
17501
17851
|
dryRun: input.dryRun,
|
|
17502
17852
|
runDockerSmoke: input.runDockerSmoke,
|
|
17853
|
+
publishAuth: input.publishAuth,
|
|
17854
|
+
browserStorePublish: input.browserStorePublish,
|
|
17503
17855
|
command: buildGuardianReleaseDispatchCommandFor(input),
|
|
17504
|
-
...input.dryRun ? {} : { requiredPublishCredentialName: "NPM_TOKEN" },
|
|
17856
|
+
...input.dryRun || input.publishAuth === "trusted_publisher" || !npmLaneSelected ? {} : { requiredPublishCredentialName: "NPM_TOKEN" },
|
|
17857
|
+
...input.browserStorePublish === "api" && !input.dryRun ? {
|
|
17858
|
+
requiredBrowserStoreCredentialNames: [...GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES]
|
|
17859
|
+
} : {},
|
|
17505
17860
|
provenance: "github_actions_oidc_supported",
|
|
17506
17861
|
boundaries: [
|
|
17507
17862
|
"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
|
-
"
|
|
17863
|
+
"dry_run=false with publish_auth=token requires the repository secret NPM_TOKEN and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17864
|
+
"dry_run=false with publish_auth=trusted_publisher requires npm Trusted Publishing to be configured for this GitHub Actions workflow and package.",
|
|
17865
|
+
"browser_store_publish=manual keeps Chrome Web Store upload as an operator ZIP handoff.",
|
|
17866
|
+
"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.",
|
|
17867
|
+
"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
17868
|
"A release-dispatch command is operator guidance, not production-gate proof."
|
|
17511
17869
|
],
|
|
17512
17870
|
tokenPrinted: false,
|
|
@@ -17525,7 +17883,10 @@ function renderGuardianReleaseDispatchCommand(result, flags) {
|
|
|
17525
17883
|
`Workflow: ${result.workflow}`,
|
|
17526
17884
|
`Channels: ${result.channels}`,
|
|
17527
17885
|
`Docker smoke: ${result.runDockerSmoke ? "yes" : "no"}`,
|
|
17886
|
+
`Publish auth: ${result.publishAuth}`,
|
|
17887
|
+
`Browser store publish: ${result.browserStorePublish}`,
|
|
17528
17888
|
result.requiredPublishCredentialName ? `Required repository secret: ${result.requiredPublishCredentialName}` : "Required repository secret: not needed for dry run",
|
|
17889
|
+
result.requiredBrowserStoreCredentialNames ? `Required browser-store secrets: ${result.requiredBrowserStoreCredentialNames.join(", ")}` : "Required browser-store secrets: not needed for manual browser handoff",
|
|
17529
17890
|
"Command:",
|
|
17530
17891
|
result.command,
|
|
17531
17892
|
"Boundaries:",
|
|
@@ -17540,6 +17901,7 @@ function buildGuardianBrowserStoreHandoffCommandResult() {
|
|
|
17540
17901
|
cli_version: GUARDIAN_CLI_VERSION,
|
|
17541
17902
|
status: "chrome_distribution_proven_next_submission_pack_ready",
|
|
17542
17903
|
primaryStore: "chrome_web_store",
|
|
17904
|
+
publicListingUrl: GUARDIAN_HALO_CHROME_WEB_STORE_LISTING_URL,
|
|
17543
17905
|
productionGate: {
|
|
17544
17906
|
id: "browser-store-distribution",
|
|
17545
17907
|
status: "proven",
|
|
@@ -17606,6 +17968,7 @@ function renderGuardianBrowserStoreHandoffCommand(result, flags) {
|
|
|
17606
17968
|
"Project Guardian Browser Store Handoff",
|
|
17607
17969
|
`Status: ${result.status}`,
|
|
17608
17970
|
`Primary store: ${result.primaryStore}`,
|
|
17971
|
+
`Public listing: ${result.publicListingUrl}`,
|
|
17609
17972
|
`Production gate: ${result.productionGate.id} (${result.productionGate.status})`,
|
|
17610
17973
|
"1. Build submission pack:",
|
|
17611
17974
|
result.commands.submissionPack,
|
|
@@ -17626,15 +17989,23 @@ function renderGuardianBrowserStoreHandoffCommand(result, flags) {
|
|
|
17626
17989
|
`;
|
|
17627
17990
|
}
|
|
17628
17991
|
function buildGuardianReleaseSecretSetup() {
|
|
17992
|
+
const chromeWebStoreSecretMatcher = GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES.join("|");
|
|
17629
17993
|
return {
|
|
17630
17994
|
schema_version: "contextecf/project-guardian-release-secret-setup/v1",
|
|
17631
17995
|
cli_version: GUARDIAN_CLI_VERSION,
|
|
17632
17996
|
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17633
17997
|
requiredForPublish: "NPM_TOKEN",
|
|
17998
|
+
requiredForBrowserStoreApi: GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES,
|
|
17634
17999
|
githubActionsSecretUrl: `https://github.com/${GUARDIAN_RELEASE_REPOSITORY}/settings/secrets/actions/new`,
|
|
17635
18000
|
commands: {
|
|
17636
18001
|
setNpmToken: `gh secret set NPM_TOKEN --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
|
|
18002
|
+
setChromeWebStoreClientId: `gh secret set CHROME_WEB_STORE_CLIENT_ID --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
|
|
18003
|
+
setChromeWebStoreClientSecret: `gh secret set CHROME_WEB_STORE_CLIENT_SECRET --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
|
|
18004
|
+
setChromeWebStoreRefreshToken: `gh secret set CHROME_WEB_STORE_REFRESH_TOKEN --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
|
|
18005
|
+
setChromeWebStorePublisherId: `gh secret set CHROME_WEB_STORE_PUBLISHER_ID --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
|
|
18006
|
+
setChromeWebStoreExtensionId: `gh secret set CHROME_WEB_STORE_EXTENSION_ID --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
|
|
17637
18007
|
verifyNpmTokenPresence: `gh secret list --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions | rg '^NPM_TOKEN\\b'`,
|
|
18008
|
+
verifyChromeWebStoreSecretsPresence: `gh secret list --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions | rg '^(${chromeWebStoreSecretMatcher})\\b'`,
|
|
17638
18009
|
dryRunDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17639
18010
|
dryRun: true,
|
|
17640
18011
|
releaseVersion: "<version>",
|
|
@@ -17646,13 +18017,23 @@ function buildGuardianReleaseSecretSetup() {
|
|
|
17646
18017
|
releaseVersion: "<version>",
|
|
17647
18018
|
channels: "all",
|
|
17648
18019
|
runDockerSmoke: true
|
|
18020
|
+
}),
|
|
18021
|
+
browserStoreApiPublishDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
18022
|
+
dryRun: false,
|
|
18023
|
+
releaseVersion: "<version>",
|
|
18024
|
+
channels: "browser",
|
|
18025
|
+
runDockerSmoke: true,
|
|
18026
|
+
publishAuth: "trusted_publisher",
|
|
18027
|
+
browserStorePublish: "api"
|
|
17649
18028
|
})
|
|
17650
18029
|
},
|
|
17651
18030
|
boundaries: [
|
|
17652
18031
|
"NPM_TOKEN belongs only in GitHub Actions repository secrets for guarded dry_run=false npm publication.",
|
|
18032
|
+
"Chrome Web Store API OAuth values belong only in GitHub Actions repository secrets for guarded browser_store_publish=api upload/submission.",
|
|
17653
18033
|
"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
18034
|
"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."
|
|
18035
|
+
"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.",
|
|
18036
|
+
"Chrome Web Store API secrets enable browser update upload/submission only; official review approval evidence is still required for production browser-store claims."
|
|
17656
18037
|
],
|
|
17657
18038
|
tokenPrinted: false,
|
|
17658
18039
|
rawContentIncluded: false
|
|
@@ -17666,16 +18047,27 @@ function renderGuardianReleaseSecretSetup(result, flags) {
|
|
|
17666
18047
|
return `${[
|
|
17667
18048
|
"Project Guardian Release Secret Setup",
|
|
17668
18049
|
`Repository: ${result.repository}`,
|
|
17669
|
-
`Required for publish: ${result.requiredForPublish}`,
|
|
18050
|
+
`Required for npm publish: ${result.requiredForPublish}`,
|
|
18051
|
+
`Required for Chrome Web Store API: ${result.requiredForBrowserStoreApi.join(", ")}`,
|
|
17670
18052
|
`GitHub Actions secret page: ${result.githubActionsSecretUrl}`,
|
|
17671
|
-
"
|
|
18053
|
+
"NPM publish secret:",
|
|
17672
18054
|
result.commands.setNpmToken,
|
|
17673
|
-
"Verify secret presence:",
|
|
18055
|
+
"Verify npm secret presence:",
|
|
17674
18056
|
result.commands.verifyNpmTokenPresence,
|
|
18057
|
+
"Chrome Web Store API secrets:",
|
|
18058
|
+
result.commands.setChromeWebStoreClientId,
|
|
18059
|
+
result.commands.setChromeWebStoreClientSecret,
|
|
18060
|
+
result.commands.setChromeWebStoreRefreshToken,
|
|
18061
|
+
result.commands.setChromeWebStorePublisherId,
|
|
18062
|
+
result.commands.setChromeWebStoreExtensionId,
|
|
18063
|
+
"Verify Chrome Web Store API secret presence:",
|
|
18064
|
+
result.commands.verifyChromeWebStoreSecretsPresence,
|
|
17675
18065
|
"Dry-run release command:",
|
|
17676
18066
|
result.commands.dryRunDispatch,
|
|
17677
|
-
"
|
|
18067
|
+
"Default publish command with manual browser-store upload:",
|
|
17678
18068
|
result.commands.publishDispatch,
|
|
18069
|
+
"Browser-store API publish command:",
|
|
18070
|
+
result.commands.browserStoreApiPublishDispatch,
|
|
17679
18071
|
"Boundaries:",
|
|
17680
18072
|
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17681
18073
|
"Token printed: no"
|
|
@@ -17896,9 +18288,9 @@ function buildGuardianReleaseVerify(releaseVersion) {
|
|
|
17896
18288
|
commands: {
|
|
17897
18289
|
registryVersion: `npm view ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion} version --registry=${GUARDIAN_NPM_REGISTRY}`,
|
|
17898
18290
|
publicInstall: `npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion}`,
|
|
18291
|
+
chromeWebStoreListing: GUARDIAN_HALO_CHROME_WEB_STORE_LISTING_URL,
|
|
17899
18292
|
installedVersion: "guardian --version",
|
|
17900
18293
|
setup: "guardian setup",
|
|
17901
|
-
launch: "guardian launch",
|
|
17902
18294
|
status: "guardian status",
|
|
17903
18295
|
openControlTower: "guardian open",
|
|
17904
18296
|
copyPasteLocalSmoke,
|
|
@@ -17927,9 +18319,8 @@ function buildGuardianReleasePaste(releaseVersion) {
|
|
|
17927
18319
|
"guardian --version",
|
|
17928
18320
|
"guardian stop",
|
|
17929
18321
|
"guardian setup",
|
|
17930
|
-
"guardian
|
|
17931
|
-
"guardian open"
|
|
17932
|
-
"guardian status"
|
|
18322
|
+
"guardian status",
|
|
18323
|
+
"guardian open"
|
|
17933
18324
|
];
|
|
17934
18325
|
return {
|
|
17935
18326
|
schema_version: "contextecf/project-guardian-release-paste/v1",
|
|
@@ -17940,9 +18331,9 @@ function buildGuardianReleasePaste(releaseVersion) {
|
|
|
17940
18331
|
command: commands.join("\n"),
|
|
17941
18332
|
commands,
|
|
17942
18333
|
boundaries: [
|
|
17943
|
-
"This paste block verifies public npm visibility, global install, first-run setup,
|
|
18334
|
+
"This paste block verifies public npm visibility, global install, stale-process cleanup, first-run setup, Local Guardian status, and Control Tower open.",
|
|
17944
18335
|
"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
|
|
18336
|
+
"guardian stop is included before setup so stale Local Guardian processes or local token mismatches are cleared before setup relaunches the local service."
|
|
17946
18337
|
],
|
|
17947
18338
|
tokenPrinted: false,
|
|
17948
18339
|
rawContentIncluded: false
|
|
@@ -17969,18 +18360,19 @@ function renderGuardianReleaseVerify(result, flags) {
|
|
|
17969
18360
|
`Status: ${result.status}`,
|
|
17970
18361
|
"1. Confirm registry visibility:",
|
|
17971
18362
|
result.commands.registryVersion,
|
|
17972
|
-
"2.
|
|
18363
|
+
"2. Confirm public Chrome Web Store listing:",
|
|
18364
|
+
result.commands.chromeWebStoreListing,
|
|
18365
|
+
"3. Install the published version:",
|
|
17973
18366
|
result.commands.publicInstall,
|
|
17974
|
-
"
|
|
18367
|
+
"4. Confirm installed CLI version:",
|
|
17975
18368
|
result.commands.installedVersion,
|
|
17976
|
-
"
|
|
18369
|
+
"5. Run first-use smoke:",
|
|
17977
18370
|
result.commands.setup,
|
|
17978
|
-
result.commands.launch,
|
|
17979
18371
|
result.commands.status,
|
|
17980
18372
|
result.commands.openControlTower,
|
|
17981
|
-
"
|
|
18373
|
+
"6. Copy-paste local smoke block:",
|
|
17982
18374
|
result.commands.copyPasteLocalSmoke,
|
|
17983
|
-
"
|
|
18375
|
+
"7. Verify release evidence:",
|
|
17984
18376
|
result.commands.publishStatusVerification,
|
|
17985
18377
|
result.commands.finishLineStatus,
|
|
17986
18378
|
"Evidence outputs:",
|
|
@@ -17997,6 +18389,12 @@ function isValidReleaseVersion(value) {
|
|
|
17997
18389
|
function isValidReleaseChannels(value) {
|
|
17998
18390
|
return ["all", "npm", "browser", "evidence"].includes(value);
|
|
17999
18391
|
}
|
|
18392
|
+
function isValidReleasePublishAuth(value) {
|
|
18393
|
+
return value === "token" || value === "trusted_publisher";
|
|
18394
|
+
}
|
|
18395
|
+
function isValidBrowserStorePublish(value) {
|
|
18396
|
+
return value === "manual" || value === "api";
|
|
18397
|
+
}
|
|
18000
18398
|
function renderGuardianProductionReadiness(result, flags) {
|
|
18001
18399
|
if (flags.has("json")) {
|
|
18002
18400
|
return `${JSON.stringify(result, null, 2)}
|
|
@@ -18099,9 +18497,9 @@ async function statusGuardian(flags, options) {
|
|
|
18099
18497
|
`Profile: ${home}`,
|
|
18100
18498
|
`Runtime profile: ${result.runtime.profileDaemonStatus}`,
|
|
18101
18499
|
`Control Tower: ${result.controlTowerUrl ?? "not configured"}`,
|
|
18102
|
-
`
|
|
18103
|
-
result.daemon.error ? `
|
|
18104
|
-
result.daemonVersionMismatch ? `
|
|
18500
|
+
`Local Guardian: ${result.daemon.status}${result.daemon.statusCode ? ` (HTTP ${result.daemon.statusCode})` : ""}`,
|
|
18501
|
+
result.daemon.error ? `Connection detail: ${result.daemon.error}` : void 0,
|
|
18502
|
+
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
18503
|
`MCP stdio: ${result.runtime.mcpStdioAvailable ? "available" : "unavailable"}`,
|
|
18106
18504
|
`Posture Profile: ${result.postureProfile.selected}`,
|
|
18107
18505
|
`Prompt Coach: ${result.preferences.promptCoachMode}`,
|
|
@@ -18208,7 +18606,7 @@ async function runLaunchCommand(flags, options) {
|
|
|
18208
18606
|
nextCommands: [
|
|
18209
18607
|
"guardian open",
|
|
18210
18608
|
"guardian status",
|
|
18211
|
-
"
|
|
18609
|
+
"Open ContextECF Halo and click Connect",
|
|
18212
18610
|
"guardian policy list"
|
|
18213
18611
|
]
|
|
18214
18612
|
};
|
|
@@ -18217,7 +18615,7 @@ async function runLaunchCommand(flags, options) {
|
|
|
18217
18615
|
flags.has("json") ? `${JSON.stringify(result, null, 2)}
|
|
18218
18616
|
` : `${[
|
|
18219
18617
|
"Project Guardian launched.",
|
|
18220
|
-
`
|
|
18618
|
+
`Local Guardian: ${result.daemonUrl}${result.reusedExistingDaemon ? " (already running)" : ""}`,
|
|
18221
18619
|
`Control Tower: ${result.controlTowerUrl}`,
|
|
18222
18620
|
shouldOpen ? `Opening: ${result.controlTowerUrl}` : void 0,
|
|
18223
18621
|
"Next: guardian open; guardian status"
|
|
@@ -18328,14 +18726,14 @@ async function runStartCommand(flags, options) {
|
|
|
18328
18726
|
controlTowerUrl: requestedControlTowerUrl,
|
|
18329
18727
|
healthUrl,
|
|
18330
18728
|
healthStatus: "reachable",
|
|
18331
|
-
nextCommands: ["guardian open", "guardian status", "
|
|
18729
|
+
nextCommands: ["guardian open", "guardian status", "Open ContextECF Halo and click Connect"]
|
|
18332
18730
|
};
|
|
18333
18731
|
write(
|
|
18334
18732
|
stdout,
|
|
18335
18733
|
flags.has("json") ? `${JSON.stringify(result2, null, 2)}
|
|
18336
18734
|
` : `${[
|
|
18337
|
-
"Guardian
|
|
18338
|
-
`
|
|
18735
|
+
"Local Guardian already running.",
|
|
18736
|
+
`Local Guardian: ${requestedDaemonUrl}`,
|
|
18339
18737
|
`Control Tower: ${requestedControlTowerUrl}`,
|
|
18340
18738
|
"Next: guardian open"
|
|
18341
18739
|
].join("\n")}
|
|
@@ -18344,7 +18742,7 @@ async function runStartCommand(flags, options) {
|
|
|
18344
18742
|
return 0;
|
|
18345
18743
|
}
|
|
18346
18744
|
if (!options.startDetachedDaemon) {
|
|
18347
|
-
write(stderr, "Guardian
|
|
18745
|
+
write(stderr, "Guardian local background launcher is unavailable in this runtime.\n");
|
|
18348
18746
|
return 1;
|
|
18349
18747
|
}
|
|
18350
18748
|
const started = await options.startDetachedDaemon({ home, host, port: selected.port });
|
|
@@ -18365,14 +18763,14 @@ async function runStartCommand(flags, options) {
|
|
|
18365
18763
|
pid: started.pid,
|
|
18366
18764
|
healthUrl,
|
|
18367
18765
|
healthStatus: existing.error ? "unreachable" : "not_reachable",
|
|
18368
|
-
nextCommands: ["guardian open", "guardian status", "
|
|
18766
|
+
nextCommands: ["guardian open", "guardian status", "Open ContextECF Halo and click Connect"]
|
|
18369
18767
|
};
|
|
18370
18768
|
write(
|
|
18371
18769
|
stdout,
|
|
18372
18770
|
flags.has("json") ? `${JSON.stringify(result, null, 2)}
|
|
18373
18771
|
` : `${[
|
|
18374
|
-
"Guardian
|
|
18375
|
-
`
|
|
18772
|
+
"Local Guardian start requested.",
|
|
18773
|
+
`Local Guardian: ${daemonUrl}`,
|
|
18376
18774
|
`Control Tower: ${controlTowerUrl}`,
|
|
18377
18775
|
started.pid ? `PID: ${started.pid}` : void 0,
|
|
18378
18776
|
"Next: guardian open"
|
|
@@ -18383,8 +18781,8 @@ async function runStartCommand(flags, options) {
|
|
|
18383
18781
|
}
|
|
18384
18782
|
function renderDaemonTokenMismatchMessage(requestedDaemonUrl, port) {
|
|
18385
18783
|
return [
|
|
18386
|
-
`Guardian found another
|
|
18387
|
-
"This usually means an older Guardian
|
|
18784
|
+
`Guardian found another local service or container at ${requestedDaemonUrl}, but it rejected this profile's local connection token.`,
|
|
18785
|
+
"This usually means an older Guardian background service or Docker demo is still using the port.",
|
|
18388
18786
|
`Recovery: stop the other process/container, or run Guardian on a different port with guardian launch --port=${port + 1}.`,
|
|
18389
18787
|
`Diagnostics: guardian status; docker ps --filter publish=${port}`,
|
|
18390
18788
|
""
|
|
@@ -18417,7 +18815,7 @@ async function runStopCommand(flags, options) {
|
|
|
18417
18815
|
if (!stopped.ok) {
|
|
18418
18816
|
write(
|
|
18419
18817
|
stderr,
|
|
18420
|
-
`Guardian
|
|
18818
|
+
`Local Guardian did not stop cleanly${stopped.statusCode ? ` (HTTP ${stopped.statusCode})` : ""}: ${stopped.error ?? "unknown_error"}
|
|
18421
18819
|
`
|
|
18422
18820
|
);
|
|
18423
18821
|
return 1;
|
|
@@ -18428,12 +18826,12 @@ async function runStopCommand(flags, options) {
|
|
|
18428
18826
|
success: true,
|
|
18429
18827
|
daemonStatus: profile.runtime.daemon_status,
|
|
18430
18828
|
stopUrl: stopUrl.url,
|
|
18431
|
-
note: "Guardian
|
|
18829
|
+
note: "Local Guardian stop requested."
|
|
18432
18830
|
};
|
|
18433
18831
|
write(
|
|
18434
18832
|
stdout,
|
|
18435
18833
|
flags.has("json") ? `${JSON.stringify(result, null, 2)}
|
|
18436
|
-
` : `${["Guardian
|
|
18834
|
+
` : `${["Local Guardian stop requested.", "Status: not_started_mvp"].join("\n")}
|
|
18437
18835
|
`
|
|
18438
18836
|
);
|
|
18439
18837
|
return 0;
|
|
@@ -18505,7 +18903,7 @@ Proof: ${result2.proofPath}
|
|
|
18505
18903
|
}
|
|
18506
18904
|
const host = stringFlag(flags, "host") ?? "127.0.0.1";
|
|
18507
18905
|
if (!isLoopbackHost(host)) {
|
|
18508
|
-
write(stderr, "Guardian service supervision only accepts loopback
|
|
18906
|
+
write(stderr, "Guardian service supervision only accepts loopback Local Guardian hosts.\n");
|
|
18509
18907
|
return 1;
|
|
18510
18908
|
}
|
|
18511
18909
|
const port = numberFlag(flags, "port") ?? 4317;
|
|
@@ -18762,7 +19160,7 @@ async function daemonPair(flags, options) {
|
|
|
18762
19160
|
[GUARDIAN_BRIDGE_CONFIG_STORAGE_KEY]: bridgeConfig,
|
|
18763
19161
|
[GUARDIAN_BRIDGE_TOKEN_STORAGE_KEY]: token
|
|
18764
19162
|
},
|
|
18765
|
-
note: "
|
|
19163
|
+
note: "Advanced fallback only. Most users should run guardian setup, open ContextECF Halo, and click Connect."
|
|
18766
19164
|
};
|
|
18767
19165
|
if (flags.has("json")) {
|
|
18768
19166
|
return { exitCode: 0, message: `${JSON.stringify(pairing, null, 2)}
|
|
@@ -18771,13 +19169,10 @@ async function daemonPair(flags, options) {
|
|
|
18771
19169
|
return {
|
|
18772
19170
|
exitCode: 0,
|
|
18773
19171
|
message: `${[
|
|
18774
|
-
"Guardian browser
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
`Native host: ${pairing.nativeHostName}`,
|
|
18779
|
-
`Token: ${pairing.token}`,
|
|
18780
|
-
pairing.note
|
|
19172
|
+
"Guardian browser connection uses one-click setup now.",
|
|
19173
|
+
"Run guardian connect, then open ContextECF Halo and click Connect.",
|
|
19174
|
+
"Support setup codes are only printed by guardian pair --json.",
|
|
19175
|
+
"Token printed: no"
|
|
18781
19176
|
].join("\n")}
|
|
18782
19177
|
`
|
|
18783
19178
|
};
|
|
@@ -18786,6 +19181,9 @@ async function runExtensionCommand(argv, flags, options) {
|
|
|
18786
19181
|
const subcommand = argv[0] ?? "native-host";
|
|
18787
19182
|
const stdout = options.stdout ?? process.stdout;
|
|
18788
19183
|
const stderr = options.stderr ?? process.stderr;
|
|
19184
|
+
if (subcommand === "connect") {
|
|
19185
|
+
return runExtensionConnectCommand(flags, options);
|
|
19186
|
+
}
|
|
18789
19187
|
if (subcommand === "open-setup") {
|
|
18790
19188
|
return runExtensionOpenSetupCommand(flags, options);
|
|
18791
19189
|
}
|
|
@@ -18973,13 +19371,18 @@ Re-run with --force to replace it.
|
|
|
18973
19371
|
registryMutationRequested: writeRegistry,
|
|
18974
19372
|
registryProofPath,
|
|
18975
19373
|
tokenPrinted: false,
|
|
18976
|
-
nextCommands: [
|
|
19374
|
+
nextCommands: [
|
|
19375
|
+
"guardian launch",
|
|
19376
|
+
"Open ContextECF Halo and click Connect",
|
|
19377
|
+
"guardian extension native-host status"
|
|
19378
|
+
],
|
|
19379
|
+
advancedCommands: ["guardian pair --json"]
|
|
18977
19380
|
};
|
|
18978
19381
|
write(
|
|
18979
19382
|
stdout,
|
|
18980
19383
|
flags.has("json") ? `${JSON.stringify(result, null, 2)}
|
|
18981
19384
|
` : `${[
|
|
18982
|
-
"Guardian
|
|
19385
|
+
"Guardian browser connection installed.",
|
|
18983
19386
|
`Browser: ${browser}`,
|
|
18984
19387
|
`Host: ${plan.hostName}`,
|
|
18985
19388
|
`Manifest: ${plan.manifestPath}`,
|
|
@@ -18994,6 +19397,121 @@ Re-run with --force to replace it.
|
|
|
18994
19397
|
);
|
|
18995
19398
|
return 0;
|
|
18996
19399
|
}
|
|
19400
|
+
async function runExtensionConnectCommand(flags, options) {
|
|
19401
|
+
const stdout = options.stdout ?? process.stdout;
|
|
19402
|
+
const stderr = options.stderr ?? process.stderr;
|
|
19403
|
+
const requestedExtensionId = stringFlag(flags, "extension-id") ?? stringFlag(flags, "id");
|
|
19404
|
+
const extensionId = requestedExtensionId ?? GUARDIAN_HALO_CHROME_EXTENSION_ID;
|
|
19405
|
+
if (requestedExtensionId && !isValidChromeExtensionId(requestedExtensionId)) {
|
|
19406
|
+
write(
|
|
19407
|
+
stderr,
|
|
19408
|
+
"Invalid --extension-id. Chrome extension ids must be 32 lowercase letters from a-p.\n"
|
|
19409
|
+
);
|
|
19410
|
+
return 1;
|
|
19411
|
+
}
|
|
19412
|
+
const install = JSON.parse(await installGuardian(/* @__PURE__ */ new Map([["json", true]]), options));
|
|
19413
|
+
let launchOutput = "";
|
|
19414
|
+
const launchFlags = new Map([
|
|
19415
|
+
["json", true],
|
|
19416
|
+
["print", true],
|
|
19417
|
+
...copyStringFlags(flags, ["host", "port"])
|
|
19418
|
+
]);
|
|
19419
|
+
const launchExitCode = await runLaunchCommand(launchFlags, {
|
|
19420
|
+
...options,
|
|
19421
|
+
stdout: {
|
|
19422
|
+
write: (chunk) => {
|
|
19423
|
+
launchOutput += chunk.toString();
|
|
19424
|
+
return true;
|
|
19425
|
+
}
|
|
19426
|
+
},
|
|
19427
|
+
stderr
|
|
19428
|
+
});
|
|
19429
|
+
if (launchExitCode !== 0) {
|
|
19430
|
+
return launchExitCode;
|
|
19431
|
+
}
|
|
19432
|
+
const launch = JSON.parse(launchOutput);
|
|
19433
|
+
const helperFlags = new Map([
|
|
19434
|
+
["json", true],
|
|
19435
|
+
["force", true],
|
|
19436
|
+
["extension-id", extensionId],
|
|
19437
|
+
...copyStringFlags(flags, ["browser", "target"])
|
|
19438
|
+
]);
|
|
19439
|
+
if ((options.platform ?? process.platform) === "win32") {
|
|
19440
|
+
helperFlags.set("write-registry", true);
|
|
19441
|
+
helperFlags.set("yes", true);
|
|
19442
|
+
}
|
|
19443
|
+
let helperOutput = "";
|
|
19444
|
+
let helperError = "";
|
|
19445
|
+
const helperExitCode = await runExtensionCommand(["native-host", "install"], helperFlags, {
|
|
19446
|
+
...options,
|
|
19447
|
+
stdout: {
|
|
19448
|
+
write: (chunk) => {
|
|
19449
|
+
helperOutput += chunk.toString();
|
|
19450
|
+
return true;
|
|
19451
|
+
}
|
|
19452
|
+
},
|
|
19453
|
+
stderr: {
|
|
19454
|
+
write: (chunk) => {
|
|
19455
|
+
helperError += chunk.toString();
|
|
19456
|
+
return true;
|
|
19457
|
+
}
|
|
19458
|
+
}
|
|
19459
|
+
});
|
|
19460
|
+
if (helperExitCode !== 0) {
|
|
19461
|
+
write(
|
|
19462
|
+
stderr,
|
|
19463
|
+
helperError.trim() ? `${helperError.trim()}
|
|
19464
|
+
` : "Guardian could not prepare the browser connection. Run guardian setup, then try again.\n"
|
|
19465
|
+
);
|
|
19466
|
+
return helperExitCode;
|
|
19467
|
+
}
|
|
19468
|
+
const helper = JSON.parse(helperOutput);
|
|
19469
|
+
const result = {
|
|
19470
|
+
schema_version: "contextecf/project-guardian-browser-connect/v1",
|
|
19471
|
+
success: true,
|
|
19472
|
+
extensionId,
|
|
19473
|
+
defaultExtensionId: GUARDIAN_HALO_CHROME_EXTENSION_ID,
|
|
19474
|
+
install: {
|
|
19475
|
+
profileDir: install.profileDir,
|
|
19476
|
+
tokenCreated: install.tokenCreated,
|
|
19477
|
+
tokenPrinted: false
|
|
19478
|
+
},
|
|
19479
|
+
localGuardian: {
|
|
19480
|
+
running: true,
|
|
19481
|
+
opened: launch.opened,
|
|
19482
|
+
reusedExistingDaemon: launch.reusedExistingDaemon,
|
|
19483
|
+
daemonUrl: launch.daemonUrl,
|
|
19484
|
+
controlTowerUrl: launch.controlTowerUrl,
|
|
19485
|
+
pid: launch.pid,
|
|
19486
|
+
healthStatus: launch.healthStatus
|
|
19487
|
+
},
|
|
19488
|
+
browser: helper.browser,
|
|
19489
|
+
helperInstalled: true,
|
|
19490
|
+
helperStatus: {
|
|
19491
|
+
hostName: helper.hostName,
|
|
19492
|
+
manifestPath: helper.manifestPath,
|
|
19493
|
+
allowedOrigins: helper.allowedOrigins,
|
|
19494
|
+
tokenPrinted: helper.tokenPrinted
|
|
19495
|
+
},
|
|
19496
|
+
tokenPrinted: false,
|
|
19497
|
+
nextCommands: ["Open ContextECF Halo and click Connect", "guardian open", "guardian status"],
|
|
19498
|
+
supportCommands: ["guardian extension open-setup --print", "guardian pair --json"]
|
|
19499
|
+
};
|
|
19500
|
+
write(
|
|
19501
|
+
stdout,
|
|
19502
|
+
flags.has("json") ? `${JSON.stringify(result, null, 2)}
|
|
19503
|
+
` : `${[
|
|
19504
|
+
"Guardian browser connection is ready.",
|
|
19505
|
+
`Local Guardian: ${result.localGuardian.daemonUrl}${result.localGuardian.reusedExistingDaemon ? " (already running)" : ""}`,
|
|
19506
|
+
`Browser: ${result.browser}`,
|
|
19507
|
+
"Next: open ContextECF Halo and click Connect.",
|
|
19508
|
+
"No setup code needed.",
|
|
19509
|
+
"Token printed: no"
|
|
19510
|
+
].join("\n")}
|
|
19511
|
+
`
|
|
19512
|
+
);
|
|
19513
|
+
return 0;
|
|
19514
|
+
}
|
|
18997
19515
|
async function runExtensionOpenSetupCommand(flags, options) {
|
|
18998
19516
|
const stdout = options.stdout ?? process.stdout;
|
|
18999
19517
|
const stderr = options.stderr ?? process.stderr;
|
|
@@ -19003,8 +19521,9 @@ async function runExtensionOpenSetupCommand(flags, options) {
|
|
|
19003
19521
|
write(stderr, "Guardian is not installed. Run guardian install first.\n");
|
|
19004
19522
|
return 1;
|
|
19005
19523
|
}
|
|
19006
|
-
const
|
|
19007
|
-
|
|
19524
|
+
const requestedExtensionId = stringFlag(flags, "extension-id") ?? stringFlag(flags, "id");
|
|
19525
|
+
const extensionId = requestedExtensionId ?? GUARDIAN_HALO_CHROME_EXTENSION_ID;
|
|
19526
|
+
if (requestedExtensionId && !isValidChromeExtensionId(requestedExtensionId)) {
|
|
19008
19527
|
write(
|
|
19009
19528
|
stderr,
|
|
19010
19529
|
"Invalid --extension-id. Chrome extension ids must be 32 lowercase letters from a-p.\n"
|
|
@@ -19018,22 +19537,24 @@ async function runExtensionOpenSetupCommand(flags, options) {
|
|
|
19018
19537
|
return 1;
|
|
19019
19538
|
}
|
|
19020
19539
|
const setupUrl = buildControlTowerSetupUrl(resolved.url);
|
|
19021
|
-
const nativeHostCommand = `guardian extension native-host install --extension-id=${extensionId
|
|
19540
|
+
const nativeHostCommand = `guardian extension native-host install --extension-id=${extensionId}`;
|
|
19022
19541
|
const result = {
|
|
19023
19542
|
schema_version: "contextecf/project-guardian-extension-setup/v1",
|
|
19024
19543
|
success: true,
|
|
19025
19544
|
opened: !flags.has("print"),
|
|
19026
19545
|
controlTowerUrl: resolved.url,
|
|
19027
19546
|
setupUrl,
|
|
19028
|
-
extensionId
|
|
19547
|
+
extensionId,
|
|
19548
|
+
defaultExtensionId: GUARDIAN_HALO_CHROME_EXTENSION_ID,
|
|
19029
19549
|
tokenPrinted: false,
|
|
19030
19550
|
nextCommands: [
|
|
19031
19551
|
"guardian launch",
|
|
19032
|
-
"guardian daemon pair --json",
|
|
19033
19552
|
nativeHostCommand,
|
|
19034
|
-
"guardian extension native-host status"
|
|
19553
|
+
"guardian extension native-host status",
|
|
19554
|
+
"Open ContextECF Halo and click Connect"
|
|
19035
19555
|
],
|
|
19036
|
-
|
|
19556
|
+
advancedCommands: ["guardian pair --json"],
|
|
19557
|
+
note: extensionId ? "Guardian browser setup opened for ContextECF Halo." : "Guardian browser setup opened."
|
|
19037
19558
|
};
|
|
19038
19559
|
if (result.opened) {
|
|
19039
19560
|
const opener = options.openUrl ?? ((url2) => openUrlInDefaultBrowser(url2, options));
|
|
@@ -19045,7 +19566,8 @@ async function runExtensionOpenSetupCommand(flags, options) {
|
|
|
19045
19566
|
` : `${[
|
|
19046
19567
|
result.opened ? `Opening Guardian browser setup: ${setupUrl}` : `Guardian browser setup: ${setupUrl}`,
|
|
19047
19568
|
"Token printed: no",
|
|
19048
|
-
`Next: ${result.nextCommands.join("; ")}
|
|
19569
|
+
`Next: ${result.nextCommands.join("; ")}`,
|
|
19570
|
+
`Advanced fallback: ${result.advancedCommands.join("; ")}`
|
|
19049
19571
|
].join("\n")}
|
|
19050
19572
|
`
|
|
19051
19573
|
);
|
|
@@ -19572,7 +20094,7 @@ function buildGuardianServiceArtifact(input) {
|
|
|
19572
20094
|
if (input.platform === "systemd") {
|
|
19573
20095
|
return `${[
|
|
19574
20096
|
"[Unit]",
|
|
19575
|
-
"Description=Project Guardian
|
|
20097
|
+
"Description=Project Guardian Local Guardian background service",
|
|
19576
20098
|
"After=network.target",
|
|
19577
20099
|
"",
|
|
19578
20100
|
"[Service]",
|
|
@@ -19591,7 +20113,7 @@ function buildGuardianServiceArtifact(input) {
|
|
|
19591
20113
|
'<?xml version="1.0" encoding="UTF-16"?>',
|
|
19592
20114
|
'<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">',
|
|
19593
20115
|
" <RegistrationInfo>",
|
|
19594
|
-
" <Description>Project Guardian
|
|
20116
|
+
" <Description>Project Guardian Local Guardian background service</Description>",
|
|
19595
20117
|
" </RegistrationInfo>",
|
|
19596
20118
|
" <Triggers>",
|
|
19597
20119
|
" <LogonTrigger><Enabled>true</Enabled></LogonTrigger>",
|
|
@@ -20573,6 +21095,59 @@ async function runReceiptsCommand(argv, flags, options) {
|
|
|
20573
21095
|
write(stdout, await verifyReceipts(flags, options));
|
|
20574
21096
|
return 0;
|
|
20575
21097
|
}
|
|
21098
|
+
async function runCoachCommand(argv, flags, options) {
|
|
21099
|
+
const subcommand = argv[0] ?? "options";
|
|
21100
|
+
const stdout = options.stdout ?? process.stdout;
|
|
21101
|
+
const stderr = options.stderr ?? process.stderr;
|
|
21102
|
+
if (subcommand === "options" || subcommand === "catalog") {
|
|
21103
|
+
write(stdout, renderGuardianPromptCardOptions(buildGuardianPromptCardOptions(), flags));
|
|
21104
|
+
return 0;
|
|
21105
|
+
}
|
|
21106
|
+
write(stderr, `Unknown Guardian coach command: ${subcommand}
|
|
21107
|
+
`);
|
|
21108
|
+
return 1;
|
|
21109
|
+
}
|
|
21110
|
+
function buildGuardianPromptCardOptions() {
|
|
21111
|
+
return {
|
|
21112
|
+
schema_version: "contextecf/project-guardian-prompt-card-options/v1",
|
|
21113
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
21114
|
+
status: "catalog_ready",
|
|
21115
|
+
summary: "Guardian prompt cards keep the user in control: warnings and safer rewrites can be sent as-is, while hard blocks cannot.",
|
|
21116
|
+
catalog: GUARDIAN_PROMPT_CARD_OPTIONS_CATALOG,
|
|
21117
|
+
rules: [
|
|
21118
|
+
"Show a clear reason before asking the user to decide.",
|
|
21119
|
+
"Offer Send as-is for warnings and safer rewrites when policy allows override.",
|
|
21120
|
+
"Never offer Send as-is for hard blocks or unavailable Local Guardian checks.",
|
|
21121
|
+
"Keep Edit prompt available as the safe path for every visible send-time card.",
|
|
21122
|
+
"Do not store raw sensitive prompt text in this catalog or CLI output."
|
|
21123
|
+
],
|
|
21124
|
+
tokenPrinted: false,
|
|
21125
|
+
rawContentIncluded: false
|
|
21126
|
+
};
|
|
21127
|
+
}
|
|
21128
|
+
function renderGuardianPromptCardOptions(result, flags) {
|
|
21129
|
+
if (flags.has("json")) {
|
|
21130
|
+
return `${JSON.stringify(result, null, 2)}
|
|
21131
|
+
`;
|
|
21132
|
+
}
|
|
21133
|
+
return `${[
|
|
21134
|
+
"Guardian Prompt Card Options",
|
|
21135
|
+
result.summary,
|
|
21136
|
+
"",
|
|
21137
|
+
"Programmed cards:",
|
|
21138
|
+
...result.catalog.map((entry) => {
|
|
21139
|
+
const visibleActions = entry.actions.filter((action) => action.visibleToUser).map((action) => action.label);
|
|
21140
|
+
const labels = visibleActions.length > 0 ? visibleActions.join(", ") : "Prompt sends automatically";
|
|
21141
|
+
return `- ${entry.cardStyle}: ${labels}`;
|
|
21142
|
+
}),
|
|
21143
|
+
"",
|
|
21144
|
+
"Rules:",
|
|
21145
|
+
...result.rules.map((rule) => `- ${rule}`),
|
|
21146
|
+
"Token printed: no",
|
|
21147
|
+
"Raw prompt content included: no"
|
|
21148
|
+
].join("\n")}
|
|
21149
|
+
`;
|
|
21150
|
+
}
|
|
20576
21151
|
async function runPolicyCommand(argv, flags, options) {
|
|
20577
21152
|
const subcommand = argv[0] ?? "list";
|
|
20578
21153
|
const stdout = options.stdout ?? process.stdout;
|
|
@@ -23003,6 +23578,7 @@ function openUrlInDefaultBrowser(url2, options = {}) {
|
|
|
23003
23578
|
});
|
|
23004
23579
|
}
|
|
23005
23580
|
export {
|
|
23581
|
+
GUARDIAN_CHROME_WEB_STORE_API_SECRET_NAMES,
|
|
23006
23582
|
GUARDIAN_CLI_VERSION,
|
|
23007
23583
|
GUARDIAN_CONTROL_TOWER_URL_ENV,
|
|
23008
23584
|
GUARDIAN_DEFAULT_CONTROL_TOWER_URL,
|
|
@@ -23012,6 +23588,8 @@ export {
|
|
|
23012
23588
|
GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_VERSION,
|
|
23013
23589
|
GUARDIAN_FIRST_RUN_COMMAND,
|
|
23014
23590
|
GUARDIAN_GLOBAL_INSTALL_COMMAND,
|
|
23591
|
+
GUARDIAN_HALO_CHROME_EXTENSION_ID,
|
|
23592
|
+
GUARDIAN_HALO_CHROME_WEB_STORE_LISTING_URL,
|
|
23015
23593
|
GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ENV,
|
|
23016
23594
|
GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ID_ENV,
|
|
23017
23595
|
GUARDIAN_NOT_PROVEN_PRODUCTION_GATES,
|
|
@@ -23024,6 +23602,7 @@ export {
|
|
|
23024
23602
|
GUARDIAN_POSTURE_PROFILE_CATALOG,
|
|
23025
23603
|
GUARDIAN_POSTURE_PROFILE_IDS,
|
|
23026
23604
|
GUARDIAN_PROFILE_SCHEMA_VERSION,
|
|
23605
|
+
GUARDIAN_PROMPT_CARD_OPTIONS_CATALOG,
|
|
23027
23606
|
GUARDIAN_PROVIDER_IDS,
|
|
23028
23607
|
GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
|
|
23029
23608
|
GUARDIAN_RELEASE_REPOSITORY,
|