@astrasyncai/verification-gateway 5.18.0 → 5.19.0
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/CHANGELOG.md +178 -0
- package/README.md +168 -4
- package/dist/adapters/express.d.mts +9 -1
- package/dist/adapters/express.d.ts +9 -1
- package/dist/adapters/express.js +96 -37
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +96 -37
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/http-pdlss.d.mts +7 -1
- package/dist/adapters/http-pdlss.d.ts +7 -1
- package/dist/adapters/http-pdlss.js +18 -2
- package/dist/adapters/http-pdlss.js.map +1 -1
- package/dist/adapters/http-pdlss.mjs +16 -1
- package/dist/adapters/http-pdlss.mjs.map +1 -1
- package/dist/adapters/kit-express.d.mts +93 -1
- package/dist/adapters/kit-express.d.ts +93 -1
- package/dist/adapters/kit-express.js +181 -2
- package/dist/adapters/kit-express.js.map +1 -1
- package/dist/adapters/kit-express.mjs +180 -2
- package/dist/adapters/kit-express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +80 -9
- package/dist/adapters/mcp.d.ts +80 -9
- package/dist/adapters/mcp.js +153 -5
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +151 -5
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +1 -1
- package/dist/adapters/nextjs.d.ts +1 -1
- package/dist/adapters/nextjs.js +41 -4
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +41 -4
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +44 -1
- package/dist/adapters/sdk.d.ts +44 -1
- package/dist/adapters/sdk.js +76 -2
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +76 -2
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +46 -6
- package/dist/bin/astrasync-codex-hook.js +46 -6
- package/dist/bin/astrasync-guard.js +375 -117
- package/dist/bin/astrasync.js +417 -117
- package/dist/browser/background.js +46 -6
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +46 -6
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +46 -6
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +46 -6
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +46 -6
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +46 -6
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/edge-config.js +1 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +1 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +1 -1
- package/dist/edge-core/index.d.ts +1 -1
- package/dist/edge-core/index.js +21 -2
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +21 -2
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +46 -6
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +46 -6
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +1 -1
- package/dist/git-trigger/git-hooks.d.ts +1 -1
- package/dist/index.d.mts +542 -30
- package/dist/index.d.ts +542 -30
- package/dist/index.js +1171 -183
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1157 -173
- package/dist/index.mjs.map +1 -1
- package/dist/registration/index.d.mts +1 -1
- package/dist/registration/index.d.ts +1 -1
- package/dist/registration/index.js +1 -1
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +1 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/transport/index.js +3 -2
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +3 -2
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-3ObBpsnf.d.mts → types-BoGjyon0.d.mts} +81 -2
- package/dist/{types-Cns4l8gX.d.mts → types-DqWPkiYl.d.mts} +90 -12
- package/dist/{types-Cns4l8gX.d.ts → types-DqWPkiYl.d.ts} +90 -12
- package/dist/{types-BoxZEYPS.d.ts → types-eWyZuz-3.d.ts} +81 -2
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +23 -2
- package/dist/verify.d.ts +23 -2
- package/dist/verify.js +23 -4
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +23 -4
- package/dist/verify.mjs.map +1 -1
- package/dist/webhooks.d.mts +16 -3
- package/dist/webhooks.d.ts +16 -3
- package/dist/webhooks.js +24 -13
- package/dist/webhooks.js.map +1 -1
- package/dist/webhooks.mjs +24 -13
- package/dist/webhooks.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bin/astrasync.js
CHANGED
|
@@ -36,7 +36,7 @@ var SDK_VERSION;
|
|
|
36
36
|
var init_version = __esm({
|
|
37
37
|
"src/version.ts"() {
|
|
38
38
|
"use strict";
|
|
39
|
-
SDK_VERSION = "5.
|
|
39
|
+
SDK_VERSION = "5.19.0";
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -3474,115 +3474,115 @@ function validatePolicy(policy) {
|
|
|
3474
3474
|
}
|
|
3475
3475
|
return { valid: errors.length === 0, errors };
|
|
3476
3476
|
}
|
|
3477
|
-
function validatePurpose(purpose,
|
|
3477
|
+
function validatePurpose(purpose, path3) {
|
|
3478
3478
|
const errors = [];
|
|
3479
3479
|
if (!purpose || typeof purpose !== "object") {
|
|
3480
|
-
return [{ path:
|
|
3480
|
+
return [{ path: path3, message: "purpose must be an object" }];
|
|
3481
3481
|
}
|
|
3482
3482
|
const p = purpose;
|
|
3483
3483
|
if (typeof p.id !== "string" || !p.id) {
|
|
3484
|
-
errors.push({ path: `${
|
|
3484
|
+
errors.push({ path: `${path3}.id`, message: "id is required and must be a non-empty string" });
|
|
3485
3485
|
}
|
|
3486
3486
|
if (typeof p.allowed !== "boolean") {
|
|
3487
|
-
errors.push({ path: `${
|
|
3487
|
+
errors.push({ path: `${path3}.allowed`, message: "allowed is required and must be a boolean" });
|
|
3488
3488
|
}
|
|
3489
3489
|
if (p.targets !== void 0 && !isStringArray(p.targets)) {
|
|
3490
|
-
errors.push({ path: `${
|
|
3490
|
+
errors.push({ path: `${path3}.targets`, message: "targets must be an array of strings" });
|
|
3491
3491
|
}
|
|
3492
3492
|
if (p.blockedPatterns !== void 0 && !isStringArray(p.blockedPatterns)) {
|
|
3493
3493
|
errors.push({
|
|
3494
|
-
path: `${
|
|
3494
|
+
path: `${path3}.blockedPatterns`,
|
|
3495
3495
|
message: "blockedPatterns must be an array of strings"
|
|
3496
3496
|
});
|
|
3497
3497
|
}
|
|
3498
3498
|
if (p.requiresApproval !== void 0 && typeof p.requiresApproval !== "boolean") {
|
|
3499
3499
|
errors.push({
|
|
3500
|
-
path: `${
|
|
3500
|
+
path: `${path3}.requiresApproval`,
|
|
3501
3501
|
message: "requiresApproval must be a boolean"
|
|
3502
3502
|
});
|
|
3503
3503
|
}
|
|
3504
3504
|
return errors;
|
|
3505
3505
|
}
|
|
3506
|
-
function validateScope(scope,
|
|
3506
|
+
function validateScope(scope, path3) {
|
|
3507
3507
|
const errors = [];
|
|
3508
3508
|
if (typeof scope !== "object" || scope === null) {
|
|
3509
|
-
return [{ path:
|
|
3509
|
+
return [{ path: path3, message: "scope must be an object" }];
|
|
3510
3510
|
}
|
|
3511
3511
|
const s = scope;
|
|
3512
3512
|
for (const field of ["allowedDomains", "blockedDomains", "blockedResources"]) {
|
|
3513
3513
|
if (s[field] !== void 0 && !isStringArray(s[field])) {
|
|
3514
|
-
errors.push({ path: `${
|
|
3514
|
+
errors.push({ path: `${path3}.${field}`, message: `${field} must be an array of strings` });
|
|
3515
3515
|
}
|
|
3516
3516
|
}
|
|
3517
3517
|
return errors;
|
|
3518
3518
|
}
|
|
3519
|
-
function validateLimits(limits,
|
|
3519
|
+
function validateLimits(limits, path3) {
|
|
3520
3520
|
const errors = [];
|
|
3521
3521
|
if (typeof limits !== "object" || limits === null) {
|
|
3522
|
-
return [{ path:
|
|
3522
|
+
return [{ path: path3, message: "limits must be an object" }];
|
|
3523
3523
|
}
|
|
3524
3524
|
const l = limits;
|
|
3525
3525
|
if (l.autonomousThreshold !== void 0 && typeof l.autonomousThreshold !== "number") {
|
|
3526
3526
|
errors.push({
|
|
3527
|
-
path: `${
|
|
3527
|
+
path: `${path3}.autonomousThreshold`,
|
|
3528
3528
|
message: "autonomousThreshold must be a number"
|
|
3529
3529
|
});
|
|
3530
3530
|
}
|
|
3531
3531
|
if (l.maxTransactionAmount !== void 0 && typeof l.maxTransactionAmount !== "number") {
|
|
3532
3532
|
errors.push({
|
|
3533
|
-
path: `${
|
|
3533
|
+
path: `${path3}.maxTransactionAmount`,
|
|
3534
3534
|
message: "maxTransactionAmount must be a number"
|
|
3535
3535
|
});
|
|
3536
3536
|
}
|
|
3537
3537
|
if (typeof l.autonomousThreshold === "number" && typeof l.maxTransactionAmount === "number" && l.autonomousThreshold > l.maxTransactionAmount) {
|
|
3538
3538
|
errors.push({
|
|
3539
|
-
path: `${
|
|
3539
|
+
path: `${path3}.autonomousThreshold`,
|
|
3540
3540
|
message: "autonomousThreshold (Autonomous Limit) must be <= maxTransactionAmount (Hard Limit)"
|
|
3541
3541
|
});
|
|
3542
3542
|
}
|
|
3543
3543
|
if (l.maxRequestsPerHour !== void 0 && typeof l.maxRequestsPerHour !== "number") {
|
|
3544
3544
|
errors.push({
|
|
3545
|
-
path: `${
|
|
3545
|
+
path: `${path3}.maxRequestsPerHour`,
|
|
3546
3546
|
message: "maxRequestsPerHour must be a number"
|
|
3547
3547
|
});
|
|
3548
3548
|
}
|
|
3549
3549
|
if (l.currency !== void 0 && typeof l.currency !== "string") {
|
|
3550
|
-
errors.push({ path: `${
|
|
3550
|
+
errors.push({ path: `${path3}.currency`, message: "currency must be a string" });
|
|
3551
3551
|
}
|
|
3552
3552
|
return errors;
|
|
3553
3553
|
}
|
|
3554
|
-
function validateRiskThresholds(thresholds,
|
|
3554
|
+
function validateRiskThresholds(thresholds, path3) {
|
|
3555
3555
|
const errors = [];
|
|
3556
3556
|
if (typeof thresholds !== "object" || thresholds === null) {
|
|
3557
|
-
return [{ path:
|
|
3557
|
+
return [{ path: path3, message: "riskThresholds must be an object" }];
|
|
3558
3558
|
}
|
|
3559
3559
|
const t = thresholds;
|
|
3560
3560
|
for (const range of ["autoAllow", "requireApproval", "autoBlock"]) {
|
|
3561
3561
|
if (!t[range] || typeof t[range] !== "object") {
|
|
3562
3562
|
errors.push({
|
|
3563
|
-
path: `${
|
|
3563
|
+
path: `${path3}.${range}`,
|
|
3564
3564
|
message: `${range} is required and must be an object with min and max`
|
|
3565
3565
|
});
|
|
3566
3566
|
continue;
|
|
3567
3567
|
}
|
|
3568
3568
|
const r = t[range];
|
|
3569
3569
|
if (typeof r.min !== "number" || typeof r.max !== "number") {
|
|
3570
|
-
errors.push({ path: `${
|
|
3570
|
+
errors.push({ path: `${path3}.${range}`, message: `${range} must have numeric min and max` });
|
|
3571
3571
|
} else if (r.min > r.max) {
|
|
3572
|
-
errors.push({ path: `${
|
|
3572
|
+
errors.push({ path: `${path3}.${range}`, message: `${range}.min must be <= ${range}.max` });
|
|
3573
3573
|
}
|
|
3574
3574
|
}
|
|
3575
3575
|
if (isValidThresholdShape(t)) {
|
|
3576
3576
|
const thresholdObj = t;
|
|
3577
3577
|
if (thresholdObj.autoAllow.max + 1 !== thresholdObj.requireApproval.min) {
|
|
3578
3578
|
errors.push({
|
|
3579
|
-
path: `${
|
|
3579
|
+
path: `${path3}`,
|
|
3580
3580
|
message: `Gap between autoAllow.max (${thresholdObj.autoAllow.max}) and requireApproval.min (${thresholdObj.requireApproval.min}). Ranges must be contiguous.`
|
|
3581
3581
|
});
|
|
3582
3582
|
}
|
|
3583
3583
|
if (thresholdObj.requireApproval.max + 1 !== thresholdObj.autoBlock.min) {
|
|
3584
3584
|
errors.push({
|
|
3585
|
-
path: `${
|
|
3585
|
+
path: `${path3}`,
|
|
3586
3586
|
message: `Gap between requireApproval.max (${thresholdObj.requireApproval.max}) and autoBlock.min (${thresholdObj.autoBlock.min}). Ranges must be contiguous.`
|
|
3587
3587
|
});
|
|
3588
3588
|
}
|
|
@@ -3962,8 +3962,8 @@ ${category.label}
|
|
|
3962
3962
|
async runAndSave(outputPath) {
|
|
3963
3963
|
const policy = await this.run();
|
|
3964
3964
|
const yaml2 = toYaml(policy);
|
|
3965
|
-
const
|
|
3966
|
-
|
|
3965
|
+
const fs3 = await import("fs");
|
|
3966
|
+
fs3.writeFileSync(outputPath, yaml2, "utf-8");
|
|
3967
3967
|
this.print(`
|
|
3968
3968
|
Policy saved to ${outputPath}`);
|
|
3969
3969
|
this.print(" AstraSync Local Guard is now protecting your agent.\n");
|
|
@@ -5186,7 +5186,12 @@ function getCacheKey(request2, counterpartyId) {
|
|
|
5186
5186
|
// its start_checkout quote was served the cached quote-leg grant (no
|
|
5187
5187
|
// settlementOutcome) and never reached the backend. Same F-A1-07 bug class.
|
|
5188
5188
|
request2.commercePhase || "",
|
|
5189
|
-
request2.checkoutSessionId || ""
|
|
5189
|
+
request2.checkoutSessionId || "",
|
|
5190
|
+
// 5.19.0: a route_config purpose claim is checked server-side against
|
|
5191
|
+
// the stored rule for this method + path, so it changes the verdict.
|
|
5192
|
+
request2.purposeSource || "",
|
|
5193
|
+
request2.requestMethod || "",
|
|
5194
|
+
request2.requestPath || ""
|
|
5190
5195
|
].join("|");
|
|
5191
5196
|
}
|
|
5192
5197
|
function getCachedResult(request2, counterpartyId) {
|
|
@@ -5358,6 +5363,11 @@ async function callVerifyAccessAPI(config, request2) {
|
|
|
5358
5363
|
if (requestData.buyerEmail) body.buyerEmail = requestData.buyerEmail;
|
|
5359
5364
|
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
5360
5365
|
if (requestData.attemptId) body.attemptId = requestData.attemptId;
|
|
5366
|
+
if (requestData.purposeSource) body.purposeSource = requestData.purposeSource;
|
|
5367
|
+
if (requestData.agentArtifacts) body.agentArtifacts = requestData.agentArtifacts;
|
|
5368
|
+
if (requestData.metadata) body.metadata = requestData.metadata;
|
|
5369
|
+
if (requestData.requestMethod) body.requestMethod = requestData.requestMethod;
|
|
5370
|
+
if (requestData.requestPath) body.requestPath = requestData.requestPath;
|
|
5361
5371
|
if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
|
|
5362
5372
|
body.sdkVersion = SDK_VERSION;
|
|
5363
5373
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
@@ -5547,9 +5557,18 @@ async function verify(config, request2, options) {
|
|
|
5547
5557
|
if (!apiResponse.access?.allowed) {
|
|
5548
5558
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
5549
5559
|
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
|
|
5560
|
+
const denyAgent = idVerifiedFromBackend && apiResponse.agent ? {
|
|
5561
|
+
astraId: apiResponse.agent.astraId,
|
|
5562
|
+
name: apiResponse.agent.name,
|
|
5563
|
+
trustScore: apiResponse.agent.trustScore,
|
|
5564
|
+
trustLevel: getTrustLevel(apiResponse.agent.trustScore),
|
|
5565
|
+
blockchainAnchored: apiResponse.agent.blockchainStatus === "anchored",
|
|
5566
|
+
status: apiResponse.agent.agentStatus
|
|
5567
|
+
} : void 0;
|
|
5550
5568
|
const result2 = {
|
|
5551
5569
|
identityVerified: idVerifiedFromBackend,
|
|
5552
5570
|
policyAllowed: false,
|
|
5571
|
+
...denyAgent && { agent: denyAgent },
|
|
5553
5572
|
// 3.6.0: the server now emits top-level denialReasons on every deny
|
|
5554
5573
|
// path — prefer it verbatim; the failure-message reconstruction remains
|
|
5555
5574
|
// as the fallback for older backends.
|
|
@@ -5772,6 +5791,16 @@ var init_commerce_detect = __esm({
|
|
|
5772
5791
|
}
|
|
5773
5792
|
});
|
|
5774
5793
|
|
|
5794
|
+
// src/adapters/routes-cache.ts
|
|
5795
|
+
var DEFAULT_ROUTES_REFRESH_MS;
|
|
5796
|
+
var init_routes_cache = __esm({
|
|
5797
|
+
"src/adapters/routes-cache.ts"() {
|
|
5798
|
+
"use strict";
|
|
5799
|
+
init_verify();
|
|
5800
|
+
DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
5801
|
+
}
|
|
5802
|
+
});
|
|
5803
|
+
|
|
5775
5804
|
// src/transport/http.ts
|
|
5776
5805
|
var init_http2 = __esm({
|
|
5777
5806
|
"src/transport/http.ts"() {
|
|
@@ -6101,7 +6130,6 @@ var init_anonymous_beacon = __esm({
|
|
|
6101
6130
|
});
|
|
6102
6131
|
|
|
6103
6132
|
// src/adapters/express.ts
|
|
6104
|
-
var DEFAULT_ROUTES_REFRESH_MS;
|
|
6105
6133
|
var init_express = __esm({
|
|
6106
6134
|
"src/adapters/express.ts"() {
|
|
6107
6135
|
"use strict";
|
|
@@ -6109,6 +6137,7 @@ var init_express = __esm({
|
|
|
6109
6137
|
init_types2();
|
|
6110
6138
|
init_stepup_poll();
|
|
6111
6139
|
init_verify();
|
|
6140
|
+
init_routes_cache();
|
|
6112
6141
|
init_http2();
|
|
6113
6142
|
init_verified_hop();
|
|
6114
6143
|
init_http_pdlss();
|
|
@@ -6119,7 +6148,6 @@ var init_express = __esm({
|
|
|
6119
6148
|
init_anonymous_beacon();
|
|
6120
6149
|
init_failure_posture();
|
|
6121
6150
|
init_route_pattern();
|
|
6122
|
-
DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
6123
6151
|
}
|
|
6124
6152
|
});
|
|
6125
6153
|
|
|
@@ -6460,6 +6488,7 @@ var init_mcp2 = __esm({
|
|
|
6460
6488
|
init_approval_gate();
|
|
6461
6489
|
init_stepup_poll();
|
|
6462
6490
|
init_well_known();
|
|
6491
|
+
init_routes_cache();
|
|
6463
6492
|
init_failure_posture();
|
|
6464
6493
|
init_mcp_server();
|
|
6465
6494
|
}
|
|
@@ -6648,6 +6677,7 @@ var init_report_amount = __esm({
|
|
|
6648
6677
|
var init_kit_shared = __esm({
|
|
6649
6678
|
"src/ucp/kit-shared.ts"() {
|
|
6650
6679
|
"use strict";
|
|
6680
|
+
init_sign();
|
|
6651
6681
|
}
|
|
6652
6682
|
});
|
|
6653
6683
|
|
|
@@ -6667,6 +6697,41 @@ var init_checkout_kit = __esm({
|
|
|
6667
6697
|
init_signatures();
|
|
6668
6698
|
init_report_amount();
|
|
6669
6699
|
init_kit_shared();
|
|
6700
|
+
init_errors();
|
|
6701
|
+
init_stepup_poll();
|
|
6702
|
+
}
|
|
6703
|
+
});
|
|
6704
|
+
|
|
6705
|
+
// src/webhooks.ts
|
|
6706
|
+
var init_webhooks = __esm({
|
|
6707
|
+
"src/webhooks.ts"() {
|
|
6708
|
+
"use strict";
|
|
6709
|
+
}
|
|
6710
|
+
});
|
|
6711
|
+
|
|
6712
|
+
// src/ucp/approval-events.ts
|
|
6713
|
+
var MemorySeenEvents, defaultSeen;
|
|
6714
|
+
var init_approval_events = __esm({
|
|
6715
|
+
"src/ucp/approval-events.ts"() {
|
|
6716
|
+
"use strict";
|
|
6717
|
+
init_webhooks();
|
|
6718
|
+
MemorySeenEvents = class {
|
|
6719
|
+
constructor(max = 1e4) {
|
|
6720
|
+
this.max = max;
|
|
6721
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
6722
|
+
}
|
|
6723
|
+
async has(eventId) {
|
|
6724
|
+
return this.ids.has(eventId);
|
|
6725
|
+
}
|
|
6726
|
+
async add(eventId) {
|
|
6727
|
+
if (this.ids.size >= this.max) {
|
|
6728
|
+
const first = this.ids.values().next().value;
|
|
6729
|
+
if (first !== void 0) this.ids.delete(first);
|
|
6730
|
+
}
|
|
6731
|
+
this.ids.add(eventId);
|
|
6732
|
+
}
|
|
6733
|
+
};
|
|
6734
|
+
defaultSeen = new MemorySeenEvents();
|
|
6670
6735
|
}
|
|
6671
6736
|
});
|
|
6672
6737
|
|
|
@@ -6681,6 +6746,7 @@ var init_ucp2 = __esm({
|
|
|
6681
6746
|
init_signatures();
|
|
6682
6747
|
init_checkout_kit();
|
|
6683
6748
|
init_jcs();
|
|
6749
|
+
init_approval_events();
|
|
6684
6750
|
}
|
|
6685
6751
|
});
|
|
6686
6752
|
|
|
@@ -6742,6 +6808,8 @@ var init_checkout_kit2 = __esm({
|
|
|
6742
6808
|
init_idempotency();
|
|
6743
6809
|
init_report_amount();
|
|
6744
6810
|
init_kit_shared();
|
|
6811
|
+
init_errors();
|
|
6812
|
+
init_stepup_poll();
|
|
6745
6813
|
}
|
|
6746
6814
|
});
|
|
6747
6815
|
|
|
@@ -6750,6 +6818,7 @@ var init_acp2 = __esm({
|
|
|
6750
6818
|
"src/acp/index.ts"() {
|
|
6751
6819
|
"use strict";
|
|
6752
6820
|
init_checkout_kit2();
|
|
6821
|
+
init_approval_events();
|
|
6753
6822
|
}
|
|
6754
6823
|
});
|
|
6755
6824
|
|
|
@@ -6758,6 +6827,7 @@ var init_kit_express = __esm({
|
|
|
6758
6827
|
"src/adapters/kit-express.ts"() {
|
|
6759
6828
|
"use strict";
|
|
6760
6829
|
init_kit_shared();
|
|
6830
|
+
init_approval_events();
|
|
6761
6831
|
}
|
|
6762
6832
|
});
|
|
6763
6833
|
|
|
@@ -6846,7 +6916,9 @@ function toDecision(result) {
|
|
|
6846
6916
|
if (result.identityVerified && result.policyAllowed) {
|
|
6847
6917
|
return {
|
|
6848
6918
|
recommendation: "ALLOW",
|
|
6849
|
-
|
|
6919
|
+
// 5.19.0: the score is on `trustScore` for the merchant; `reason` is
|
|
6920
|
+
// text a merchant may relay to the agent, so it never embeds the number.
|
|
6921
|
+
reason: "Verified",
|
|
6850
6922
|
trustScore: result.agent?.trustScore,
|
|
6851
6923
|
sessionId: "sessionId" in result ? result.sessionId : void 0
|
|
6852
6924
|
};
|
|
@@ -7825,29 +7897,29 @@ function loadEnrolment(paths) {
|
|
|
7825
7897
|
[paths.machineDevice, "machine"],
|
|
7826
7898
|
[paths.userDevice, "user"]
|
|
7827
7899
|
];
|
|
7828
|
-
for (const [
|
|
7829
|
-
if (!(0, import_fs6.existsSync)(
|
|
7900
|
+
for (const [path3, scope] of candidates) {
|
|
7901
|
+
if (!(0, import_fs6.existsSync)(path3)) continue;
|
|
7830
7902
|
try {
|
|
7831
|
-
const parsed = JSON.parse((0, import_fs6.readFileSync)(
|
|
7903
|
+
const parsed = JSON.parse((0, import_fs6.readFileSync)(path3, "utf-8"));
|
|
7832
7904
|
if (isEnrolment(parsed)) return { enrolment: parsed, scope };
|
|
7833
7905
|
} catch {
|
|
7834
7906
|
}
|
|
7835
|
-
return { corrupt: true, path:
|
|
7907
|
+
return { corrupt: true, path: path3 };
|
|
7836
7908
|
}
|
|
7837
7909
|
return null;
|
|
7838
7910
|
}
|
|
7839
|
-
function writeFileMode(
|
|
7840
|
-
(0, import_fs6.mkdirSync)((0, import_path5.dirname)(
|
|
7841
|
-
(0, import_fs6.writeFileSync)(
|
|
7911
|
+
function writeFileMode(path3, content, mode) {
|
|
7912
|
+
(0, import_fs6.mkdirSync)((0, import_path5.dirname)(path3), { recursive: true, mode: 448 });
|
|
7913
|
+
(0, import_fs6.writeFileSync)(path3, content, { encoding: "utf-8", mode });
|
|
7842
7914
|
try {
|
|
7843
|
-
(0, import_fs6.chmodSync)(
|
|
7915
|
+
(0, import_fs6.chmodSync)(path3, mode);
|
|
7844
7916
|
} catch {
|
|
7845
7917
|
}
|
|
7846
7918
|
}
|
|
7847
7919
|
function saveEnrolment(paths, enrolment, scope) {
|
|
7848
|
-
const
|
|
7849
|
-
writeFileMode(
|
|
7850
|
-
return
|
|
7920
|
+
const path3 = scope === "machine" ? paths.machineDevice : paths.userDevice;
|
|
7921
|
+
writeFileMode(path3, JSON.stringify(enrolment, null, 2), scope === "machine" ? 420 : 384);
|
|
7922
|
+
return path3;
|
|
7851
7923
|
}
|
|
7852
7924
|
function readCachedPolicies(paths) {
|
|
7853
7925
|
const out = [];
|
|
@@ -8175,12 +8247,12 @@ function formatFleetStatus(status) {
|
|
|
8175
8247
|
if (status.lastError) lines.push(` Last sync error: ${status.lastError}`);
|
|
8176
8248
|
return lines;
|
|
8177
8249
|
}
|
|
8178
|
-
function managedHookCommand(target,
|
|
8250
|
+
function managedHookCommand(target, os3) {
|
|
8179
8251
|
const bin = target === "claude" ? "astrasync-claude-hook" : "astrasync-codex-hook";
|
|
8180
|
-
if (
|
|
8252
|
+
if (os3 === "win32") return `"C:\\Program Files\\nodejs\\${bin}.cmd"`;
|
|
8181
8253
|
return `/usr/local/bin/${bin}`;
|
|
8182
8254
|
}
|
|
8183
|
-
function buildClaudeManagedSettings(
|
|
8255
|
+
function buildClaudeManagedSettings(os3) {
|
|
8184
8256
|
return {
|
|
8185
8257
|
allowManagedHooksOnly: true,
|
|
8186
8258
|
env: { ASTRASYNC_FLEET_REQUIRED: "1" },
|
|
@@ -8188,7 +8260,7 @@ function buildClaudeManagedSettings(os2) {
|
|
|
8188
8260
|
PreToolUse: [
|
|
8189
8261
|
{
|
|
8190
8262
|
matcher: HOOK_MATCHER,
|
|
8191
|
-
hooks: [{ type: "command", command: managedHookCommand("claude",
|
|
8263
|
+
hooks: [{ type: "command", command: managedHookCommand("claude", os3), timeout: 10 }]
|
|
8192
8264
|
}
|
|
8193
8265
|
]
|
|
8194
8266
|
},
|
|
@@ -8198,11 +8270,11 @@ function buildClaudeManagedSettings(os2) {
|
|
|
8198
8270
|
function tomlString(value) {
|
|
8199
8271
|
return JSON.stringify(value);
|
|
8200
8272
|
}
|
|
8201
|
-
function buildCodexRequirementsToml(
|
|
8202
|
-
const command =
|
|
8273
|
+
function buildCodexRequirementsToml(os3) {
|
|
8274
|
+
const command = os3 === "win32" ? `set ASTRASYNC_FLEET_REQUIRED=1&& ${managedHookCommand("codex", os3)}` : `ASTRASYNC_FLEET_REQUIRED=1 ${managedHookCommand("codex", os3)}`;
|
|
8203
8275
|
return [
|
|
8204
8276
|
"# AstraSync Local Guard \u2014 managed hook (generated by `astrasync guard managed-settings --codex`)",
|
|
8205
|
-
`# Install at: ${MANAGED_SETTINGS_LOCATIONS.codex[
|
|
8277
|
+
`# Install at: ${MANAGED_SETTINGS_LOCATIONS.codex[os3]}`,
|
|
8206
8278
|
"allow_managed_hooks_only = true",
|
|
8207
8279
|
"",
|
|
8208
8280
|
"[features]",
|
|
@@ -8222,14 +8294,14 @@ function buildCodexRequirementsToml(os2) {
|
|
|
8222
8294
|
function buildManagedSettingsFiles(targets) {
|
|
8223
8295
|
const out = [];
|
|
8224
8296
|
for (const target of targets) {
|
|
8225
|
-
for (const
|
|
8226
|
-
const content = target === "claude" ? `${JSON.stringify(buildClaudeManagedSettings(
|
|
8227
|
-
` : buildCodexRequirementsToml(
|
|
8297
|
+
for (const os3 of ["darwin", "linux", "win32"]) {
|
|
8298
|
+
const content = target === "claude" ? `${JSON.stringify(buildClaudeManagedSettings(os3), null, 2)}
|
|
8299
|
+
` : buildCodexRequirementsToml(os3);
|
|
8228
8300
|
out.push({
|
|
8229
8301
|
target,
|
|
8230
|
-
os:
|
|
8231
|
-
installPath: MANAGED_SETTINGS_LOCATIONS[target][
|
|
8232
|
-
fileName: `${target}-${
|
|
8302
|
+
os: os3,
|
|
8303
|
+
installPath: MANAGED_SETTINGS_LOCATIONS[target][os3],
|
|
8304
|
+
fileName: `${target}-${os3}-${target === "claude" ? "managed-settings.json" : "requirements.toml"}`,
|
|
8233
8305
|
content
|
|
8234
8306
|
});
|
|
8235
8307
|
}
|
|
@@ -8435,7 +8507,8 @@ function createLocalCert(hosts, days = 30) {
|
|
|
8435
8507
|
${b64}
|
|
8436
8508
|
-----END CERTIFICATE-----
|
|
8437
8509
|
`,
|
|
8438
|
-
key: privateKey.export({ type: "pkcs8", format: "pem" }).toString()
|
|
8510
|
+
key: privateKey.export({ type: "pkcs8", format: "pem" }).toString(),
|
|
8511
|
+
spkiSha256: import_node_crypto5.default.createHash("sha256").update(spki).digest("base64")
|
|
8439
8512
|
};
|
|
8440
8513
|
}
|
|
8441
8514
|
var import_node_crypto5, tlv, seq2, set2, ctx, ECDSA_SHA256;
|
|
@@ -8451,16 +8524,204 @@ var init_local_cert = __esm({
|
|
|
8451
8524
|
}
|
|
8452
8525
|
});
|
|
8453
8526
|
|
|
8527
|
+
// src/fleet/open-browser.ts
|
|
8528
|
+
function isWsl(env = process.env, platform2 = process.platform, readVersion = () => import_node_fs.default.readFileSync("/proc/version", "utf8")) {
|
|
8529
|
+
if (platform2 !== "linux") return false;
|
|
8530
|
+
if (env.WSL_DISTRO_NAME) return true;
|
|
8531
|
+
try {
|
|
8532
|
+
return /microsoft/i.test(readVersion());
|
|
8533
|
+
} catch {
|
|
8534
|
+
return false;
|
|
8535
|
+
}
|
|
8536
|
+
}
|
|
8537
|
+
function findChromium(env = process.env, platform2 = process.platform, exists = (p) => import_node_fs.default.existsSync(p), wsl = isWsl(env, platform2), listDir = (dir) => import_node_fs.default.readdirSync(dir)) {
|
|
8538
|
+
let candidates;
|
|
8539
|
+
if (platform2 === "darwin") {
|
|
8540
|
+
candidates = MAC_PATHS;
|
|
8541
|
+
} else if (platform2 === "win32") {
|
|
8542
|
+
const bases = [
|
|
8543
|
+
env.ProgramFiles,
|
|
8544
|
+
env["ProgramFiles(x86)"],
|
|
8545
|
+
env.LOCALAPPDATA ?? env.LocalAppData
|
|
8546
|
+
].filter((b) => !!b);
|
|
8547
|
+
candidates = [
|
|
8548
|
+
...bases.map((b) => import_node_path.default.win32.join(b, "Google", "Chrome", "Application", "chrome.exe")),
|
|
8549
|
+
...bases.map((b) => import_node_path.default.win32.join(b, "Microsoft", "Edge", "Application", "msedge.exe"))
|
|
8550
|
+
];
|
|
8551
|
+
} else {
|
|
8552
|
+
const dirs = (env.PATH ?? "").split(":").filter(Boolean);
|
|
8553
|
+
candidates = LINUX_NAMES.flatMap((n) => dirs.map((d) => import_node_path.default.posix.join(d, n)));
|
|
8554
|
+
const cache2 = env.PLAYWRIGHT_BROWSERS_PATH ?? (env.HOME ? `${env.HOME}/.cache/ms-playwright` : "");
|
|
8555
|
+
if (cache2) {
|
|
8556
|
+
let builds = [];
|
|
8557
|
+
try {
|
|
8558
|
+
builds = listDir(cache2).filter((d) => /^chromium-\d+$/.test(d));
|
|
8559
|
+
} catch {
|
|
8560
|
+
}
|
|
8561
|
+
builds.sort((a, b) => Number(b.split("-")[1]) - Number(a.split("-")[1]));
|
|
8562
|
+
for (const b of builds)
|
|
8563
|
+
candidates.push(
|
|
8564
|
+
import_node_path.default.posix.join(cache2, b, "chrome-linux64", "chrome"),
|
|
8565
|
+
import_node_path.default.posix.join(cache2, b, "chrome-linux", "chrome")
|
|
8566
|
+
);
|
|
8567
|
+
}
|
|
8568
|
+
if (wsl) candidates = [...candidates, ...WSL_WINDOWS_PATHS];
|
|
8569
|
+
}
|
|
8570
|
+
return candidates.find((c) => exists(c)) ?? null;
|
|
8571
|
+
}
|
|
8572
|
+
function isWindowsExeFromWsl(browserPath) {
|
|
8573
|
+
return /^\/mnt\/[a-z]\//i.test(browserPath) && /\.exe$/i.test(browserPath);
|
|
8574
|
+
}
|
|
8575
|
+
function browserName(browserPath) {
|
|
8576
|
+
const b = browserPath.toLowerCase();
|
|
8577
|
+
if (b.includes("edge")) return "Edge";
|
|
8578
|
+
if (b.includes("chromium")) return "Chromium";
|
|
8579
|
+
return "Chrome";
|
|
8580
|
+
}
|
|
8581
|
+
function profileDirFor(proxyPort) {
|
|
8582
|
+
return import_node_path.default.join(import_node_os.default.tmpdir(), `astrasync-agent-browser-${proxyPort}`);
|
|
8583
|
+
}
|
|
8584
|
+
function windowsProfileDir(profileDir) {
|
|
8585
|
+
if (/^\/mnt\/[a-z]\//i.test(profileDir)) {
|
|
8586
|
+
try {
|
|
8587
|
+
return (0, import_node_child_process.execFileSync)("wslpath", ["-w", profileDir], { encoding: "utf8" }).trim();
|
|
8588
|
+
} catch {
|
|
8589
|
+
}
|
|
8590
|
+
}
|
|
8591
|
+
return `C:\\Temp\\${import_node_path.default.basename(profileDir)}`;
|
|
8592
|
+
}
|
|
8593
|
+
function certFlag(certSpki) {
|
|
8594
|
+
return `--ignore-certificate-errors-spki-list=${certSpki}`;
|
|
8595
|
+
}
|
|
8596
|
+
function launchBrowser(browserPath, proxyPort, url, certSpki, profileDir = profileDirFor(proxyPort), onError) {
|
|
8597
|
+
const dir = isWindowsExeFromWsl(browserPath) ? windowsProfileDir(profileDir) : profileDir;
|
|
8598
|
+
const child = (0, import_node_child_process.spawn)(
|
|
8599
|
+
browserPath,
|
|
8600
|
+
[
|
|
8601
|
+
`--proxy-server=http://127.0.0.1:${proxyPort}`,
|
|
8602
|
+
certFlag(certSpki),
|
|
8603
|
+
`--user-data-dir=${dir}`,
|
|
8604
|
+
"--no-first-run",
|
|
8605
|
+
"--new-window",
|
|
8606
|
+
url
|
|
8607
|
+
],
|
|
8608
|
+
{ detached: true, stdio: "ignore" }
|
|
8609
|
+
);
|
|
8610
|
+
child.on("error", (err) => onError?.(err));
|
|
8611
|
+
child.unref();
|
|
8612
|
+
return child;
|
|
8613
|
+
}
|
|
8614
|
+
function browserCommand(platform2, port, url, certSpki, wsl = false) {
|
|
8615
|
+
const proxy = `--proxy-server="http://127.0.0.1:${port}" ${certFlag(certSpki)}`;
|
|
8616
|
+
if (platform2 === "win32" || wsl) {
|
|
8617
|
+
return `& "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ${proxy} --user-data-dir="$env:TEMP\\astrasync-agent-${port}" '${url}'`;
|
|
8618
|
+
}
|
|
8619
|
+
const exe = platform2 === "darwin" ? '"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"' : "google-chrome";
|
|
8620
|
+
return `${exe} ${proxy} --user-data-dir="\${TMPDIR:-/tmp}/astrasync-agent-${port}" '${url}'`;
|
|
8621
|
+
}
|
|
8622
|
+
function browserCommandLines(platform2, port, url, certSpki, wsl = isWsl(process.env, platform2)) {
|
|
8623
|
+
if (wsl) {
|
|
8624
|
+
return [
|
|
8625
|
+
" In PowerShell (Windows):",
|
|
8626
|
+
` ${browserCommand("win32", port, url, certSpki)}`,
|
|
8627
|
+
" Or inside WSL (with Chromium installed):",
|
|
8628
|
+
` ${browserCommand("linux", port, url, certSpki)}`,
|
|
8629
|
+
` ${CERT_FLAG_NOTE}`
|
|
8630
|
+
];
|
|
8631
|
+
}
|
|
8632
|
+
return [` ${browserCommand(platform2, port, url, certSpki)}`, ` ${CERT_FLAG_NOTE}`];
|
|
8633
|
+
}
|
|
8634
|
+
function openThroughProxy(opts) {
|
|
8635
|
+
const log = opts.log ?? ((l) => console.log(l));
|
|
8636
|
+
const platform2 = opts.platform ?? process.platform;
|
|
8637
|
+
const env = opts.env ?? process.env;
|
|
8638
|
+
const wsl = opts.wsl ?? isWsl(env, platform2);
|
|
8639
|
+
const found = opts.find ? opts.find() : findChromium(env, platform2, void 0, wsl);
|
|
8640
|
+
if (!found) {
|
|
8641
|
+
log("No Chrome/Edge/Chromium found. Start one through the proxy with:");
|
|
8642
|
+
for (const l of browserCommandLines(platform2, opts.port, opts.url, opts.certSpki, wsl)) log(l);
|
|
8643
|
+
return false;
|
|
8644
|
+
}
|
|
8645
|
+
(opts.launch ?? launchBrowser)(
|
|
8646
|
+
found,
|
|
8647
|
+
opts.port,
|
|
8648
|
+
opts.url,
|
|
8649
|
+
opts.certSpki,
|
|
8650
|
+
profileDirFor(opts.port),
|
|
8651
|
+
(err) => log(`Couldn't start ${browserName(found)}: ${err.message}`)
|
|
8652
|
+
);
|
|
8653
|
+
log(`Opened ${browserName(found)} through the proxy.`);
|
|
8654
|
+
log(CERT_FLAG_NOTE);
|
|
8655
|
+
if (wsl && isWindowsExeFromWsl(found)) {
|
|
8656
|
+
log(
|
|
8657
|
+
"If the Windows browser can't reach the proxy, install Chromium inside WSL (e.g. npx playwright install chromium)."
|
|
8658
|
+
);
|
|
8659
|
+
}
|
|
8660
|
+
return true;
|
|
8661
|
+
}
|
|
8662
|
+
var import_node_child_process, import_node_fs, import_node_os, import_node_path, MAC_PATHS, LINUX_NAMES, WSL_WINDOWS_PATHS, CERT_FLAG_NOTE;
|
|
8663
|
+
var init_open_browser = __esm({
|
|
8664
|
+
"src/fleet/open-browser.ts"() {
|
|
8665
|
+
"use strict";
|
|
8666
|
+
import_node_child_process = require("child_process");
|
|
8667
|
+
import_node_fs = __toESM(require("fs"));
|
|
8668
|
+
import_node_os = __toESM(require("os"));
|
|
8669
|
+
import_node_path = __toESM(require("path"));
|
|
8670
|
+
MAC_PATHS = [
|
|
8671
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
8672
|
+
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
|
8673
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium"
|
|
8674
|
+
];
|
|
8675
|
+
LINUX_NAMES = [
|
|
8676
|
+
"google-chrome",
|
|
8677
|
+
"google-chrome-stable",
|
|
8678
|
+
"chromium",
|
|
8679
|
+
"chromium-browser",
|
|
8680
|
+
"microsoft-edge"
|
|
8681
|
+
];
|
|
8682
|
+
WSL_WINDOWS_PATHS = [
|
|
8683
|
+
"/mnt/c/Program Files/Google/Chrome/Application/chrome.exe",
|
|
8684
|
+
"/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
8685
|
+
"/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe",
|
|
8686
|
+
"/mnt/c/Program Files/Microsoft/Edge/Application/msedge.exe"
|
|
8687
|
+
];
|
|
8688
|
+
CERT_FLAG_NOTE = "Chrome shows a warning bar about the --ignore-certificate-errors-spki-list flag. That is expected (it trusts only this proxy's certificate); close the bar.";
|
|
8689
|
+
}
|
|
8690
|
+
});
|
|
8691
|
+
|
|
8454
8692
|
// src/fleet/browse-proxy.ts
|
|
8455
8693
|
function cleanHeaders(h) {
|
|
8456
8694
|
const out = {};
|
|
8457
8695
|
for (const [k, v] of Object.entries(h)) if (!HOP_BY_HOP.has(k) && v !== void 0) out[k] = v;
|
|
8458
8696
|
return out;
|
|
8459
8697
|
}
|
|
8698
|
+
function helpPage(port, certSpki) {
|
|
8699
|
+
const proxy = `http://127.0.0.1:${port}`;
|
|
8700
|
+
return `<!doctype html>
|
|
8701
|
+
<html lang="en"><head><meta charset="utf-8"><title>AstraSync device proxy</title>
|
|
8702
|
+
<style>body{font:16px/1.5 system-ui,sans-serif;max-width:40rem;margin:2rem auto;padding:0 1rem}code{background:#f2f2f2;padding:0 .25rem}</style>
|
|
8703
|
+
</head><body>
|
|
8704
|
+
<h1>AstraSync device proxy</h1>
|
|
8705
|
+
<p>This is AstraSync's Local Guard device proxy. It only works as a browser proxy — it isn't a page to open.</p>
|
|
8706
|
+
<h2>Open the sign-in link</h2>
|
|
8707
|
+
<ul>
|
|
8708
|
+
<li>Run <code>astrasync guard browse --open</code> — it opens a browser that goes through this proxy.</li>
|
|
8709
|
+
<li>Or start Chrome, Edge or Chromium with <code>--proxy-server=${proxy} ${certFlag(certSpki)}</code> and a separate profile (<code>--user-data-dir=<an empty folder></code>), then open the sign-in link in it.</li>
|
|
8710
|
+
</ul>
|
|
8711
|
+
<p>Chrome shows a warning bar about that flag. That is expected — it trusts only this proxy's certificate — so close the bar.</p>
|
|
8712
|
+
<p>Keep <code>astrasync guard browse</code> running while you use the session.</p>
|
|
8713
|
+
</body></html>
|
|
8714
|
+
`;
|
|
8715
|
+
}
|
|
8460
8716
|
async function startBrowseProxy(opts) {
|
|
8461
8717
|
const hosts = new Set(opts.hosts.map((h) => h.toLowerCase()));
|
|
8462
8718
|
const deviceHeader = `Device ${opts.deviceCredential}`;
|
|
8463
|
-
const { cert, key } = createLocalCert([...hosts]);
|
|
8719
|
+
const { cert, key, spkiSha256 } = createLocalCert([...hosts]);
|
|
8720
|
+
const sockets = /* @__PURE__ */ new Set();
|
|
8721
|
+
const track = (s) => {
|
|
8722
|
+
sockets.add(s);
|
|
8723
|
+
s.once("close", () => sockets.delete(s));
|
|
8724
|
+
};
|
|
8464
8725
|
function forward(req, res, target) {
|
|
8465
8726
|
const headers = cleanHeaders(req.headers);
|
|
8466
8727
|
headers["x-astra-device"] = deviceHeader;
|
|
@@ -8512,6 +8773,7 @@ async function startBrowseProxy(opts) {
|
|
|
8512
8773
|
},
|
|
8513
8774
|
onConnect
|
|
8514
8775
|
) : import_node_net.default.connect(target.port, target.host, onConnect);
|
|
8776
|
+
track(upstream);
|
|
8515
8777
|
upstream.on("error", () => socket.destroy());
|
|
8516
8778
|
socket.on("error", () => upstream.destroy());
|
|
8517
8779
|
}
|
|
@@ -8543,6 +8805,16 @@ async function startBrowseProxy(opts) {
|
|
|
8543
8805
|
});
|
|
8544
8806
|
});
|
|
8545
8807
|
const server = import_node_http.default.createServer((req, res) => {
|
|
8808
|
+
if ((req.url ?? "").startsWith("/")) {
|
|
8809
|
+
if (req.url === "/favicon.ico") {
|
|
8810
|
+
res.writeHead(404).end();
|
|
8811
|
+
return;
|
|
8812
|
+
}
|
|
8813
|
+
const listening = server.address()?.port ?? 0;
|
|
8814
|
+
res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
8815
|
+
res.end(helpPage(listening, spkiSha256));
|
|
8816
|
+
return;
|
|
8817
|
+
}
|
|
8546
8818
|
let url;
|
|
8547
8819
|
try {
|
|
8548
8820
|
url = new URL(req.url ?? "");
|
|
@@ -8635,18 +8907,22 @@ async function startBrowseProxy(opts) {
|
|
|
8635
8907
|
upstream.pipe(socket);
|
|
8636
8908
|
socket.pipe(upstream);
|
|
8637
8909
|
});
|
|
8910
|
+
track(upstream);
|
|
8638
8911
|
upstream.on("error", () => socket.destroy());
|
|
8639
8912
|
socket.on("error", () => upstream.destroy());
|
|
8640
8913
|
});
|
|
8914
|
+
server.on("connection", track);
|
|
8641
8915
|
await new Promise((resolve) => server.listen(opts.port ?? 0, "127.0.0.1", resolve));
|
|
8642
8916
|
const port = server.address().port;
|
|
8643
8917
|
return {
|
|
8644
8918
|
port,
|
|
8919
|
+
certSpki: spkiSha256,
|
|
8645
8920
|
close: () => new Promise((resolve) => {
|
|
8646
8921
|
inner.close();
|
|
8647
8922
|
plainInner.close();
|
|
8648
8923
|
server.close(() => resolve());
|
|
8649
8924
|
server.closeAllConnections?.();
|
|
8925
|
+
for (const s of sockets) s.destroy();
|
|
8650
8926
|
})
|
|
8651
8927
|
};
|
|
8652
8928
|
}
|
|
@@ -8659,6 +8935,7 @@ var init_browse_proxy = __esm({
|
|
|
8659
8935
|
import_node_net = __toESM(require("net"));
|
|
8660
8936
|
import_node_tls = __toESM(require("tls"));
|
|
8661
8937
|
init_local_cert();
|
|
8938
|
+
init_open_browser();
|
|
8662
8939
|
HOP_BY_HOP = /* @__PURE__ */ new Set([
|
|
8663
8940
|
"connection",
|
|
8664
8941
|
"proxy-connection",
|
|
@@ -8754,6 +9031,18 @@ async function runBrowse(paths, opts) {
|
|
|
8754
9031
|
log(
|
|
8755
9032
|
`Device proxy: http://127.0.0.1:${proxy.port} (adds this machine's credential for ${hosts.join(", ")})`
|
|
8756
9033
|
);
|
|
9034
|
+
if (!opts.open) {
|
|
9035
|
+
log("Open it in a browser through the proxy:");
|
|
9036
|
+
for (const l of browserCommandLines(
|
|
9037
|
+
opts.platform ?? process.platform,
|
|
9038
|
+
proxy.port,
|
|
9039
|
+
openUrl,
|
|
9040
|
+
proxy.certSpki,
|
|
9041
|
+
opts.wsl
|
|
9042
|
+
))
|
|
9043
|
+
log(l);
|
|
9044
|
+
log(" (or re-run with --open)");
|
|
9045
|
+
}
|
|
8757
9046
|
log("Playwright:");
|
|
8758
9047
|
log(
|
|
8759
9048
|
` chromium.launch({ proxy: { server: 'http://127.0.0.1:${proxy.port}' } }) + newContext({ ignoreHTTPSErrors: true })`
|
|
@@ -8770,6 +9059,7 @@ var init_browse = __esm({
|
|
|
8770
9059
|
"use strict";
|
|
8771
9060
|
init_enrolment_store();
|
|
8772
9061
|
init_browse_proxy();
|
|
9062
|
+
init_open_browser();
|
|
8773
9063
|
}
|
|
8774
9064
|
});
|
|
8775
9065
|
|
|
@@ -8799,7 +9089,7 @@ async function cmdSetup() {
|
|
|
8799
9089
|
}
|
|
8800
9090
|
async function cmdUpgrade() {
|
|
8801
9091
|
const policyPath = process.argv[4] || DEFAULT_POLICY_PATH;
|
|
8802
|
-
if (!
|
|
9092
|
+
if (!fs2.existsSync(policyPath)) {
|
|
8803
9093
|
console.error(`No policy file found at ${policyPath}`);
|
|
8804
9094
|
console.error('Run "astrasync guard setup" first to create a policy.');
|
|
8805
9095
|
process.exit(1);
|
|
@@ -8827,13 +9117,13 @@ async function cmdUpgrade() {
|
|
|
8827
9117
|
prompt: (message) => prompt.question(message),
|
|
8828
9118
|
print: (message) => console.log(message),
|
|
8829
9119
|
writeConfig: async (filePath, content) => {
|
|
8830
|
-
const dir =
|
|
8831
|
-
if (!
|
|
8832
|
-
|
|
9120
|
+
const dir = path2.dirname(filePath);
|
|
9121
|
+
if (!fs2.existsSync(dir)) fs2.mkdirSync(dir, { recursive: true });
|
|
9122
|
+
fs2.writeFileSync(filePath, content, "utf-8");
|
|
8833
9123
|
},
|
|
8834
9124
|
readConfig: async (filePath) => {
|
|
8835
9125
|
try {
|
|
8836
|
-
return
|
|
9126
|
+
return fs2.readFileSync(filePath, "utf-8");
|
|
8837
9127
|
} catch {
|
|
8838
9128
|
return null;
|
|
8839
9129
|
}
|
|
@@ -8854,13 +9144,13 @@ async function cmdStart() {
|
|
|
8854
9144
|
let gatewayConfig;
|
|
8855
9145
|
const upgraded = await isUpgraded(DEFAULT_CONFIG_DIR, async (p) => {
|
|
8856
9146
|
try {
|
|
8857
|
-
return
|
|
9147
|
+
return fs2.readFileSync(p, "utf-8");
|
|
8858
9148
|
} catch {
|
|
8859
9149
|
return null;
|
|
8860
9150
|
}
|
|
8861
9151
|
});
|
|
8862
9152
|
if (upgraded) {
|
|
8863
|
-
const config = JSON.parse(
|
|
9153
|
+
const config = JSON.parse(fs2.readFileSync(`${DEFAULT_CONFIG_DIR}/config`, "utf-8"));
|
|
8864
9154
|
gatewayConfig = {
|
|
8865
9155
|
mode: config.mode,
|
|
8866
9156
|
apiBaseUrl: config.platformUrl ? `${config.platformUrl}/api/v1` : void 0,
|
|
@@ -8868,7 +9158,7 @@ async function cmdStart() {
|
|
|
8868
9158
|
};
|
|
8869
9159
|
console.log(`[AstraSync] Starting in ${config.mode} mode (agent: ${config.agentId})`);
|
|
8870
9160
|
} else {
|
|
8871
|
-
if (!
|
|
9161
|
+
if (!fs2.existsSync(policyPath)) {
|
|
8872
9162
|
console.error(`No policy file found at ${policyPath}`);
|
|
8873
9163
|
console.error('Run "astrasync guard setup" first.');
|
|
8874
9164
|
process.exit(1);
|
|
@@ -8905,7 +9195,7 @@ async function cmdStatus() {
|
|
|
8905
9195
|
const policyPath = process.argv[4] || DEFAULT_POLICY_PATH;
|
|
8906
9196
|
const upgraded = await isUpgraded(DEFAULT_CONFIG_DIR, async (p) => {
|
|
8907
9197
|
try {
|
|
8908
|
-
return
|
|
9198
|
+
return fs2.readFileSync(p, "utf-8");
|
|
8909
9199
|
} catch {
|
|
8910
9200
|
return null;
|
|
8911
9201
|
}
|
|
@@ -8915,7 +9205,7 @@ async function cmdStatus() {
|
|
|
8915
9205
|
console.log(` ${line}`);
|
|
8916
9206
|
}
|
|
8917
9207
|
if (upgraded) {
|
|
8918
|
-
const config = JSON.parse(
|
|
9208
|
+
const config = JSON.parse(fs2.readFileSync(`${DEFAULT_CONFIG_DIR}/config`, "utf-8"));
|
|
8919
9209
|
console.log(` Mode: ${config.mode}`);
|
|
8920
9210
|
console.log(` Agent: ${config.agentId}`);
|
|
8921
9211
|
console.log(` Platform: ${config.platformUrl}`);
|
|
@@ -8923,7 +9213,7 @@ async function cmdStatus() {
|
|
|
8923
9213
|
} else {
|
|
8924
9214
|
console.log(" Mode: local (free tier)");
|
|
8925
9215
|
}
|
|
8926
|
-
if (
|
|
9216
|
+
if (fs2.existsSync(policyPath)) {
|
|
8927
9217
|
const parsed = parseFile(policyPath);
|
|
8928
9218
|
if (parsed.validation.valid && parsed.policy) {
|
|
8929
9219
|
const p = parsed.policy;
|
|
@@ -8948,7 +9238,7 @@ async function cmdCheck() {
|
|
|
8948
9238
|
(a) => !a.startsWith("--") && a !== "guard" && a !== "check" && a !== process.argv[0] && a !== process.argv[1]
|
|
8949
9239
|
) || DEFAULT_POLICY_PATH;
|
|
8950
9240
|
const trigger = process.argv.find((a) => a.startsWith("--trigger="))?.split("=")[1] || "pre-push";
|
|
8951
|
-
if (!
|
|
9241
|
+
if (!fs2.existsSync(policyPath)) {
|
|
8952
9242
|
console.log("[AstraSync] No policy file \u2014 skipping check");
|
|
8953
9243
|
process.exit(0);
|
|
8954
9244
|
}
|
|
@@ -8960,9 +9250,9 @@ async function cmdCheck() {
|
|
|
8960
9250
|
}
|
|
8961
9251
|
let enforcement = "warn";
|
|
8962
9252
|
const configPath = `${DEFAULT_CONFIG_DIR}/config`;
|
|
8963
|
-
if (
|
|
9253
|
+
if (fs2.existsSync(configPath)) {
|
|
8964
9254
|
try {
|
|
8965
|
-
const config = JSON.parse(
|
|
9255
|
+
const config = JSON.parse(fs2.readFileSync(configPath, "utf-8"));
|
|
8966
9256
|
enforcement = config.gitTriggerEnforcement || "warn";
|
|
8967
9257
|
} catch {
|
|
8968
9258
|
}
|
|
@@ -9025,8 +9315,8 @@ async function cmdUninstallHooks() {
|
|
|
9025
9315
|
}
|
|
9026
9316
|
}
|
|
9027
9317
|
function resolveClaudeHookCommand() {
|
|
9028
|
-
const sibling =
|
|
9029
|
-
if (
|
|
9318
|
+
const sibling = path2.join(__dirname, "astrasync-claude-hook.js");
|
|
9319
|
+
if (fs2.existsSync(sibling)) {
|
|
9030
9320
|
return `"${process.execPath}" "${sibling}"`;
|
|
9031
9321
|
}
|
|
9032
9322
|
return "astrasync-claude-hook";
|
|
@@ -9042,19 +9332,19 @@ function parseClaudeCodeFlags() {
|
|
|
9042
9332
|
};
|
|
9043
9333
|
}
|
|
9044
9334
|
function claudeCodePaths(project) {
|
|
9045
|
-
const root = project ? process.cwd() :
|
|
9335
|
+
const root = project ? process.cwd() : os2.homedir();
|
|
9046
9336
|
return {
|
|
9047
|
-
settingsPath:
|
|
9048
|
-
astrasyncDir:
|
|
9337
|
+
settingsPath: path2.join(root, ".claude", "settings.json"),
|
|
9338
|
+
astrasyncDir: path2.join(root, ".astrasync")
|
|
9049
9339
|
};
|
|
9050
9340
|
}
|
|
9051
9341
|
async function cmdInstallClaudeCode() {
|
|
9052
9342
|
const flags = parseClaudeCodeFlags();
|
|
9053
9343
|
const { settingsPath, astrasyncDir } = claudeCodePaths(flags.project);
|
|
9054
|
-
const policyPath = flags.policyOverride ||
|
|
9055
|
-
const guardJsonPath =
|
|
9344
|
+
const policyPath = flags.policyOverride || path2.join(astrasyncDir, "policy.yaml");
|
|
9345
|
+
const guardJsonPath = path2.join(astrasyncDir, "guard.json");
|
|
9056
9346
|
console.log("\nAstraSync Local Guard for Claude Code \u2014 install\n");
|
|
9057
|
-
if (
|
|
9347
|
+
if (fs2.existsSync(policyPath)) {
|
|
9058
9348
|
console.log(` Policy: using existing ${policyPath}`);
|
|
9059
9349
|
if (ensureGuardSelfProtection(policyPath)) {
|
|
9060
9350
|
console.log(" added guard self-protection patterns to file.write");
|
|
@@ -9062,7 +9352,7 @@ async function cmdInstallClaudeCode() {
|
|
|
9062
9352
|
} else if (flags.wizard) {
|
|
9063
9353
|
const prompt = createPrompt();
|
|
9064
9354
|
try {
|
|
9065
|
-
|
|
9355
|
+
fs2.mkdirSync(path2.dirname(policyPath), { recursive: true });
|
|
9066
9356
|
const wizard = new SetupWizard(prompt);
|
|
9067
9357
|
await wizard.runAndSave(policyPath);
|
|
9068
9358
|
} finally {
|
|
@@ -9071,17 +9361,17 @@ async function cmdInstallClaudeCode() {
|
|
|
9071
9361
|
ensureGuardSelfProtection(policyPath);
|
|
9072
9362
|
console.log(` Policy: created via wizard at ${policyPath}`);
|
|
9073
9363
|
} else {
|
|
9074
|
-
|
|
9075
|
-
|
|
9364
|
+
fs2.mkdirSync(path2.dirname(policyPath), { recursive: true });
|
|
9365
|
+
fs2.writeFileSync(policyPath, toYaml(buildDefaultClaudeCodePolicy()), "utf-8");
|
|
9076
9366
|
console.log(` Policy: default coding-agent policy written to ${policyPath}`);
|
|
9077
9367
|
console.log(" (re-run with --wizard for the interactive setup instead)");
|
|
9078
9368
|
}
|
|
9079
|
-
if (!
|
|
9369
|
+
if (!fs2.existsSync(guardJsonPath)) {
|
|
9080
9370
|
const guardSettings = {
|
|
9081
9371
|
posture: flags.active ? "active" : "passive",
|
|
9082
9372
|
governMcp: false
|
|
9083
9373
|
};
|
|
9084
|
-
|
|
9374
|
+
fs2.writeFileSync(guardJsonPath, `${JSON.stringify(guardSettings, null, 2)}
|
|
9085
9375
|
`, "utf-8");
|
|
9086
9376
|
console.log(
|
|
9087
9377
|
` Guard: ${guardJsonPath} (posture: ${guardSettings.posture}, governMcp: false)`
|
|
@@ -9111,7 +9401,7 @@ async function cmdInstallClaudeCode() {
|
|
|
9111
9401
|
}
|
|
9112
9402
|
console.log("\n Next steps:");
|
|
9113
9403
|
console.log(" 1. Start a NEW Claude Code session (settings load at startup).");
|
|
9114
|
-
console.log(` 2. Watch decisions: tail -f ${
|
|
9404
|
+
console.log(` 2. Watch decisions: tail -f ${path2.join(astrasyncDir, "traces")}/*.jsonl`);
|
|
9115
9405
|
console.log(` 3. When the traces look right, set "posture": "active" in ${guardJsonPath}`);
|
|
9116
9406
|
console.log(" to enforce (denies block, approvals use Claude Code's own prompt).");
|
|
9117
9407
|
console.log(' 4. To govern MCP tools too, set "governMcp": true and add');
|
|
@@ -9141,26 +9431,26 @@ async function cmdUninstallClaudeCode() {
|
|
|
9141
9431
|
);
|
|
9142
9432
|
}
|
|
9143
9433
|
function resolveCodexHookCommand() {
|
|
9144
|
-
const sibling =
|
|
9145
|
-
if (
|
|
9434
|
+
const sibling = path2.join(__dirname, "astrasync-codex-hook.js");
|
|
9435
|
+
if (fs2.existsSync(sibling)) {
|
|
9146
9436
|
return `"${process.execPath}" "${sibling}"`;
|
|
9147
9437
|
}
|
|
9148
9438
|
return "astrasync-codex-hook";
|
|
9149
9439
|
}
|
|
9150
9440
|
function codexPaths(project) {
|
|
9151
|
-
const root = project ? process.cwd() :
|
|
9441
|
+
const root = project ? process.cwd() : os2.homedir();
|
|
9152
9442
|
return {
|
|
9153
|
-
hooksPath:
|
|
9154
|
-
astrasyncDir:
|
|
9443
|
+
hooksPath: path2.join(root, ".codex", "hooks.json"),
|
|
9444
|
+
astrasyncDir: path2.join(root, ".astrasync")
|
|
9155
9445
|
};
|
|
9156
9446
|
}
|
|
9157
9447
|
async function cmdInstallCodex() {
|
|
9158
9448
|
const flags = parseClaudeCodeFlags();
|
|
9159
9449
|
const { hooksPath, astrasyncDir } = codexPaths(flags.project);
|
|
9160
|
-
const policyPath = flags.policyOverride ||
|
|
9161
|
-
const guardJsonPath =
|
|
9450
|
+
const policyPath = flags.policyOverride || path2.join(astrasyncDir, "policy.yaml");
|
|
9451
|
+
const guardJsonPath = path2.join(astrasyncDir, "guard.json");
|
|
9162
9452
|
console.log("\nAstraSync Local Guard for Codex CLI \u2014 install\n");
|
|
9163
|
-
if (
|
|
9453
|
+
if (fs2.existsSync(policyPath)) {
|
|
9164
9454
|
console.log(` Policy: using existing ${policyPath} (shared across adapters)`);
|
|
9165
9455
|
if (ensureGuardSelfProtection(policyPath)) {
|
|
9166
9456
|
console.log(" added guard self-protection patterns to file.write");
|
|
@@ -9168,7 +9458,7 @@ async function cmdInstallCodex() {
|
|
|
9168
9458
|
} else if (flags.wizard) {
|
|
9169
9459
|
const prompt = createPrompt();
|
|
9170
9460
|
try {
|
|
9171
|
-
|
|
9461
|
+
fs2.mkdirSync(path2.dirname(policyPath), { recursive: true });
|
|
9172
9462
|
const wizard = new SetupWizard(prompt);
|
|
9173
9463
|
await wizard.runAndSave(policyPath);
|
|
9174
9464
|
} finally {
|
|
@@ -9177,17 +9467,17 @@ async function cmdInstallCodex() {
|
|
|
9177
9467
|
ensureGuardSelfProtection(policyPath);
|
|
9178
9468
|
console.log(` Policy: created via wizard at ${policyPath}`);
|
|
9179
9469
|
} else {
|
|
9180
|
-
|
|
9181
|
-
|
|
9470
|
+
fs2.mkdirSync(path2.dirname(policyPath), { recursive: true });
|
|
9471
|
+
fs2.writeFileSync(policyPath, toYaml(buildDefaultClaudeCodePolicy()), "utf-8");
|
|
9182
9472
|
console.log(` Policy: default coding-agent policy written to ${policyPath}`);
|
|
9183
9473
|
console.log(" (re-run with --wizard for the interactive setup instead)");
|
|
9184
9474
|
}
|
|
9185
|
-
if (!
|
|
9475
|
+
if (!fs2.existsSync(guardJsonPath)) {
|
|
9186
9476
|
const guardSettings = {
|
|
9187
9477
|
posture: flags.active ? "active" : "passive",
|
|
9188
9478
|
governMcp: false
|
|
9189
9479
|
};
|
|
9190
|
-
|
|
9480
|
+
fs2.writeFileSync(guardJsonPath, `${JSON.stringify(guardSettings, null, 2)}
|
|
9191
9481
|
`, "utf-8");
|
|
9192
9482
|
console.log(
|
|
9193
9483
|
` Guard: ${guardJsonPath} (posture: ${guardSettings.posture}, governMcp: false)`
|
|
@@ -9206,7 +9496,7 @@ async function cmdInstallCodex() {
|
|
|
9206
9496
|
}
|
|
9207
9497
|
console.log("\n Next steps:");
|
|
9208
9498
|
console.log(" 1. Start a NEW Codex session (hooks load at startup; /hooks to inspect).");
|
|
9209
|
-
console.log(` 2. Watch decisions: tail -f ${
|
|
9499
|
+
console.log(` 2. Watch decisions: tail -f ${path2.join(astrasyncDir, "traces")}/*.jsonl`);
|
|
9210
9500
|
console.log(` 3. When the traces look right, set "posture": "active" in ${guardJsonPath}.`);
|
|
9211
9501
|
console.log(" Denies block; approvals fall through to Codex's own prompt \u2014");
|
|
9212
9502
|
console.log(" except in dontAsk/bypassPermissions modes, where they deny.");
|
|
@@ -9231,13 +9521,13 @@ function printCodexStatus() {
|
|
|
9231
9521
|
const { hooksPath, astrasyncDir } = codexPaths(scope === "project");
|
|
9232
9522
|
let hookInstalled = false;
|
|
9233
9523
|
try {
|
|
9234
|
-
const content =
|
|
9524
|
+
const content = fs2.readFileSync(hooksPath, "utf-8");
|
|
9235
9525
|
hookInstalled = content.includes(ASTRASYNC_CODEX_HOOK_MARKER);
|
|
9236
9526
|
} catch {
|
|
9237
9527
|
}
|
|
9238
9528
|
if (hookInstalled) {
|
|
9239
|
-
const policyPath =
|
|
9240
|
-
const policy =
|
|
9529
|
+
const policyPath = path2.join(astrasyncDir, "policy.yaml");
|
|
9530
|
+
const policy = fs2.existsSync(policyPath) ? `policy: ${policyPath}` : "policy: missing";
|
|
9241
9531
|
console.log(` Codex CLI (${scope}): hook installed, ${policy}`);
|
|
9242
9532
|
}
|
|
9243
9533
|
}
|
|
@@ -9247,24 +9537,24 @@ function printClaudeCodeStatus() {
|
|
|
9247
9537
|
const { settingsPath, astrasyncDir } = claudeCodePaths(scope === "project");
|
|
9248
9538
|
let hookInstalled = false;
|
|
9249
9539
|
try {
|
|
9250
|
-
const content =
|
|
9540
|
+
const content = fs2.readFileSync(settingsPath, "utf-8");
|
|
9251
9541
|
hookInstalled = content.includes(ASTRASYNC_HOOK_MARKER);
|
|
9252
9542
|
} catch {
|
|
9253
9543
|
}
|
|
9254
|
-
const policyPath =
|
|
9255
|
-
const guardJsonPath =
|
|
9544
|
+
const policyPath = path2.join(astrasyncDir, "policy.yaml");
|
|
9545
|
+
const guardJsonPath = path2.join(astrasyncDir, "guard.json");
|
|
9256
9546
|
let posture = "";
|
|
9257
|
-
if (
|
|
9547
|
+
if (fs2.existsSync(guardJsonPath)) {
|
|
9258
9548
|
try {
|
|
9259
|
-
const settings = JSON.parse(
|
|
9549
|
+
const settings = JSON.parse(fs2.readFileSync(guardJsonPath, "utf-8"));
|
|
9260
9550
|
posture = settings.posture ? `, posture: ${settings.posture}` : "";
|
|
9261
9551
|
} catch {
|
|
9262
9552
|
posture = ", guard.json unreadable";
|
|
9263
9553
|
}
|
|
9264
9554
|
}
|
|
9265
|
-
if (hookInstalled ||
|
|
9555
|
+
if (hookInstalled || fs2.existsSync(policyPath)) {
|
|
9266
9556
|
const hook = hookInstalled ? "hook installed" : "hook NOT installed";
|
|
9267
|
-
const policy =
|
|
9557
|
+
const policy = fs2.existsSync(policyPath) ? `policy: ${policyPath}` : "policy: missing";
|
|
9268
9558
|
console.log(` Claude Code (${scope}): ${hook}, ${policy}${posture}`);
|
|
9269
9559
|
}
|
|
9270
9560
|
}
|
|
@@ -9310,14 +9600,21 @@ async function cmdFleetStatus() {
|
|
|
9310
9600
|
async function cmdBrowse() {
|
|
9311
9601
|
try {
|
|
9312
9602
|
const port = flagValue("--port");
|
|
9313
|
-
const
|
|
9603
|
+
const open = process.argv.includes("--open");
|
|
9604
|
+
const { proxy, openUrl } = await runBrowse(fleetPaths(), {
|
|
9314
9605
|
checkpoint: flagValue("--checkpoint") ?? "",
|
|
9315
9606
|
slug: flagValue("--slug") ?? "",
|
|
9316
9607
|
upstream: flagValue("--upstream"),
|
|
9317
9608
|
port: port ? Number(port) : void 0,
|
|
9318
|
-
extraHosts: flagValue("--host") ? [flagValue("--host")] : []
|
|
9609
|
+
extraHosts: flagValue("--host") ? [flagValue("--host")] : [],
|
|
9610
|
+
open
|
|
9319
9611
|
});
|
|
9612
|
+
if (open) openThroughProxy({ port: proxy.port, url: openUrl, certSpki: proxy.certSpki });
|
|
9613
|
+
let stopping = false;
|
|
9320
9614
|
const stop = async () => {
|
|
9615
|
+
if (stopping) process.exit(0);
|
|
9616
|
+
stopping = true;
|
|
9617
|
+
setTimeout(() => process.exit(0), 2e3).unref();
|
|
9321
9618
|
await proxy.close();
|
|
9322
9619
|
process.exit(0);
|
|
9323
9620
|
};
|
|
@@ -9352,7 +9649,7 @@ async function cmdGitRoute() {
|
|
|
9352
9649
|
}
|
|
9353
9650
|
async function cmdGitCredential() {
|
|
9354
9651
|
const action = process.argv[process.argv.indexOf("git-credential") + 1] ?? "";
|
|
9355
|
-
const input =
|
|
9652
|
+
const input = fs2.readFileSync(0, "utf-8");
|
|
9356
9653
|
process.stdout.write(runGitCredential(action, input));
|
|
9357
9654
|
}
|
|
9358
9655
|
async function cmdManagedSettings() {
|
|
@@ -9456,8 +9753,9 @@ async function main() {
|
|
|
9456
9753
|
" browse Sign an agent in to your dashboard from this machine and"
|
|
9457
9754
|
);
|
|
9458
9755
|
console.log(
|
|
9459
|
-
" run its device proxy (--checkpoint <url> --slug <agent
|
|
9756
|
+
" run its device proxy (--checkpoint <url> --slug <agent>;"
|
|
9460
9757
|
);
|
|
9758
|
+
console.log(" --open to start a browser through the proxy)");
|
|
9461
9759
|
console.log(" enroll <token> Enrol this machine in your organisation fleet");
|
|
9462
9760
|
console.log(" (--api-base-url <url>, --system for machine scope)");
|
|
9463
9761
|
console.log(" fleet-status Show fleet enrolment, signed policy and heartbeat");
|
|
@@ -9471,13 +9769,13 @@ async function main() {
|
|
|
9471
9769
|
process.exit(command ? 1 : 0);
|
|
9472
9770
|
}
|
|
9473
9771
|
}
|
|
9474
|
-
var
|
|
9772
|
+
var fs2, os2, path2, readline, DEFAULT_POLICY_PATH, DEFAULT_CONFIG_DIR;
|
|
9475
9773
|
var init_guard = __esm({
|
|
9476
9774
|
"src/cli/guard.ts"() {
|
|
9477
9775
|
"use strict";
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
|
|
9776
|
+
fs2 = __toESM(require("fs"));
|
|
9777
|
+
os2 = __toESM(require("os"));
|
|
9778
|
+
path2 = __toESM(require("path"));
|
|
9481
9779
|
readline = __toESM(require("readline"));
|
|
9482
9780
|
init_wizard();
|
|
9483
9781
|
init_upgrade();
|
|
@@ -9491,6 +9789,7 @@ var init_guard = __esm({
|
|
|
9491
9789
|
init_enrolment_store();
|
|
9492
9790
|
init_git_route();
|
|
9493
9791
|
init_browse();
|
|
9792
|
+
init_open_browser();
|
|
9494
9793
|
DEFAULT_POLICY_PATH = "./local-policy.yaml";
|
|
9495
9794
|
DEFAULT_CONFIG_DIR = ".astrasync";
|
|
9496
9795
|
main().catch((err) => {
|
|
@@ -9527,6 +9826,7 @@ COMMANDS:
|
|
|
9527
9826
|
(--api-base-url <url>, --system for machine scope)
|
|
9528
9827
|
guard fleet-status Fleet enrolment, signed policy and heartbeat state
|
|
9529
9828
|
guard browse Sign an agent in to your dashboard via this machine's device proxy
|
|
9829
|
+
(--checkpoint <url> --slug <agent>; --open starts a browser through it)
|
|
9530
9830
|
guard managed-settings MDM templates for Claude Code / Codex (--claude, --codex, --out <dir>)
|
|
9531
9831
|
|
|
9532
9832
|
REGISTER OPTIONS:
|