@astrasyncai/verification-gateway 3.9.0 → 3.10.1
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/dist/adapter-interface/interface.d.mts +3 -2
- package/dist/adapter-interface/interface.d.ts +3 -2
- package/dist/adapters/express.d.mts +3 -2
- package/dist/adapters/express.d.ts +3 -2
- package/dist/adapters/express.js +151 -2
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +151 -2
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +2 -1
- package/dist/adapters/mcp.d.ts +2 -1
- package/dist/adapters/mcp.js +1 -1
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +1 -1
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +3 -2
- package/dist/adapters/nextjs.d.ts +3 -2
- package/dist/adapters/nextjs.js +151 -2
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +151 -2
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +3 -2
- package/dist/adapters/sdk.d.ts +3 -2
- package/dist/adapters/sdk.js +1 -1
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +1 -1
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +3 -2
- package/dist/agent/index.d.ts +3 -2
- package/dist/bin/astrasync-claude-hook.js +276 -25
- package/dist/bin/astrasync-guard.js +258 -23
- package/dist/bin/astrasync.js +282 -24
- package/dist/browser/background.js +257 -22
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +257 -22
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +3 -2
- package/dist/browser/browser-adapter.d.ts +3 -2
- package/dist/claude-code/claude-code-adapter.d.mts +3 -2
- package/dist/claude-code/claude-code-adapter.d.ts +3 -2
- package/dist/cli/index.d.mts +3 -2
- package/dist/cli/index.d.ts +3 -2
- package/dist/cursor/cursor-adapter.d.mts +3 -2
- package/dist/cursor/cursor-adapter.d.ts +3 -2
- package/dist/cursor/extension.d.mts +3 -2
- package/dist/cursor/extension.d.ts +3 -2
- package/dist/cursor/extension.js +257 -22
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +257 -22
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +2 -1
- package/dist/edge-config.d.ts +2 -1
- package/dist/{express-sGXhDdd0.d.ts → express-ClNtDhhc.d.ts} +1 -1
- package/dist/{express-DXUyvv7t.d.mts → express-DCXa1oqj.d.mts} +1 -1
- package/dist/gateway/gateway.d.mts +29 -3
- package/dist/gateway/gateway.d.ts +29 -3
- package/dist/gateway/gateway.js +257 -22
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +257 -22
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +3 -2
- package/dist/git-trigger/git-hooks.d.ts +3 -2
- package/dist/{index-Dalih3EB.d.mts → index-BrNKDmiR.d.mts} +1 -1
- package/dist/{index-C61VL_OW.d.ts → index-CfHurO1P.d.ts} +1 -1
- package/dist/{index-CMg-vjEK.d.ts → index-D2ztkumS.d.ts} +1 -1
- package/dist/{index-DmmdehNu.d.mts → index-Dr_XiN65.d.mts} +1 -1
- package/dist/index.d.mts +10 -9
- package/dist/index.d.ts +10 -9
- package/dist/index.js +218 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +211 -11
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +3 -2
- package/dist/local-evaluator/evaluator.d.ts +3 -2
- package/dist/local-evaluator/evaluator.js +165 -7
- package/dist/local-evaluator/evaluator.js.map +1 -1
- package/dist/local-evaluator/evaluator.mjs +165 -7
- package/dist/local-evaluator/evaluator.mjs.map +1 -1
- package/dist/metadata-capture.d.mts +87 -0
- package/dist/metadata-capture.d.ts +87 -0
- package/dist/metadata-capture.js +184 -0
- package/dist/metadata-capture.js.map +1 -0
- package/dist/metadata-capture.mjs +154 -0
- package/dist/metadata-capture.mjs.map +1 -0
- package/dist/{nextjs-DwUW-Nm1.d.ts → nextjs-CEBVBsdi.d.ts} +1 -1
- package/dist/{nextjs-F_2pbPIA.d.mts → nextjs-DcQIk6Zj.d.mts} +1 -1
- package/dist/platform-signatures.d.mts +60 -10
- package/dist/platform-signatures.d.ts +60 -10
- package/dist/platform-signatures.js +37 -10
- package/dist/platform-signatures.js.map +1 -1
- package/dist/platform-signatures.mjs +35 -9
- package/dist/platform-signatures.mjs.map +1 -1
- package/dist/{sdk-Clob2-0A.d.mts → sdk-CZkbSOeO.d.mts} +1 -1
- package/dist/{sdk-CfHANs4A.d.ts → sdk-H0JCLW2y.d.ts} +1 -1
- package/dist/transport/index.d.mts +3 -2
- package/dist/transport/index.d.ts +3 -2
- package/dist/{types-ACMsV07B.d.mts → types-9tns4wyl.d.ts} +12 -0
- package/dist/{types-DmSDgPpG.d.ts → types-BV6abBnF.d.mts} +7 -1
- package/dist/{types-BtqUvK8v.d.mts → types-C23_uaY8.d.ts} +7 -1
- package/dist/{types-ACMsV07B.d.ts → types-sy3tq8lp.d.mts} +12 -0
- package/dist/ui/index.d.mts +2 -1
- package/dist/ui/index.d.ts +2 -1
- package/dist/verify.d.mts +8 -1
- package/dist/verify.d.ts +8 -1
- package/dist/verify.js +1 -1
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +1 -1
- package/dist/verify.mjs.map +1 -1
- package/package.json +6 -1
package/dist/bin/astrasync.js
CHANGED
|
@@ -4543,7 +4543,9 @@ var init_types = __esm({
|
|
|
4543
4543
|
"git push",
|
|
4544
4544
|
"npm publish",
|
|
4545
4545
|
"docker",
|
|
4546
|
-
"kubectl"
|
|
4546
|
+
"kubectl",
|
|
4547
|
+
"gh pr create",
|
|
4548
|
+
"gh pr merge"
|
|
4547
4549
|
];
|
|
4548
4550
|
SENSITIVE_PATHS = [
|
|
4549
4551
|
".ssh",
|
|
@@ -4564,12 +4566,178 @@ var init_types = __esm({
|
|
|
4564
4566
|
}
|
|
4565
4567
|
});
|
|
4566
4568
|
|
|
4569
|
+
// src/local-evaluator/command-matcher.ts
|
|
4570
|
+
function buildRiskList(entries) {
|
|
4571
|
+
const singleWord = /* @__PURE__ */ new Set();
|
|
4572
|
+
const multiWord = [];
|
|
4573
|
+
for (const entry of entries) {
|
|
4574
|
+
const words = entry.toLowerCase().trim().split(/\s+/);
|
|
4575
|
+
if (words.length === 1) singleWord.add(words[0]);
|
|
4576
|
+
else multiWord.push(words);
|
|
4577
|
+
}
|
|
4578
|
+
multiWord.sort((a, b) => b.length - a.length);
|
|
4579
|
+
return { singleWord, multiWord };
|
|
4580
|
+
}
|
|
4581
|
+
function stripHeredocBodies(text) {
|
|
4582
|
+
const lines = text.split("\n");
|
|
4583
|
+
const kept = [];
|
|
4584
|
+
let terminator = null;
|
|
4585
|
+
for (const line of lines) {
|
|
4586
|
+
if (terminator !== null) {
|
|
4587
|
+
if (line.trim() === terminator) terminator = null;
|
|
4588
|
+
continue;
|
|
4589
|
+
}
|
|
4590
|
+
kept.push(line);
|
|
4591
|
+
const heredoc = line.match(/<<-?\s*['"]?(\w+)['"]?/);
|
|
4592
|
+
if (heredoc) terminator = heredoc[1];
|
|
4593
|
+
}
|
|
4594
|
+
return kept.join("\n");
|
|
4595
|
+
}
|
|
4596
|
+
function extractDollarSubstitutions(text, collect) {
|
|
4597
|
+
let result = text;
|
|
4598
|
+
let start = result.indexOf("$(");
|
|
4599
|
+
let iterations = 0;
|
|
4600
|
+
while (start !== -1 && iterations < 50) {
|
|
4601
|
+
iterations++;
|
|
4602
|
+
let depth = 0;
|
|
4603
|
+
let end = result.length;
|
|
4604
|
+
for (let i = start + 1; i < result.length; i++) {
|
|
4605
|
+
if (result[i] === "(") depth++;
|
|
4606
|
+
else if (result[i] === ")") {
|
|
4607
|
+
depth--;
|
|
4608
|
+
if (depth === 0) {
|
|
4609
|
+
end = i;
|
|
4610
|
+
break;
|
|
4611
|
+
}
|
|
4612
|
+
}
|
|
4613
|
+
}
|
|
4614
|
+
collect(result.slice(start + 2, end));
|
|
4615
|
+
result = `${result.slice(0, start)} ${result.slice(Math.min(end + 1, result.length))}`;
|
|
4616
|
+
start = result.indexOf("$(");
|
|
4617
|
+
}
|
|
4618
|
+
return result;
|
|
4619
|
+
}
|
|
4620
|
+
function extractBacktickSubstitutions(text, collect) {
|
|
4621
|
+
if (!text.includes("`")) return text;
|
|
4622
|
+
const chunks = text.split("`");
|
|
4623
|
+
const kept = [];
|
|
4624
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
4625
|
+
if (i % 2 === 1) collect(chunks[i]);
|
|
4626
|
+
else kept.push(chunks[i]);
|
|
4627
|
+
}
|
|
4628
|
+
return kept.join(" ");
|
|
4629
|
+
}
|
|
4630
|
+
function basename(token) {
|
|
4631
|
+
const slash = token.lastIndexOf("/");
|
|
4632
|
+
return slash === -1 ? token : token.slice(slash + 1);
|
|
4633
|
+
}
|
|
4634
|
+
function matchSegment(segment, list) {
|
|
4635
|
+
const tokens = segment.split(/\s+/).filter((t) => /[a-z0-9]/.test(t));
|
|
4636
|
+
let i = 0;
|
|
4637
|
+
let hops = 0;
|
|
4638
|
+
while (i < tokens.length) {
|
|
4639
|
+
while (i < tokens.length && (tokens[i] === "export" || ASSIGN_RE.test(tokens[i]))) i++;
|
|
4640
|
+
if (i >= tokens.length) return null;
|
|
4641
|
+
const cmd = basename(tokens[i]);
|
|
4642
|
+
const significant = [cmd, ...tokens.slice(i + 1).filter((t) => !t.startsWith("-"))];
|
|
4643
|
+
for (const entry of list.multiWord) {
|
|
4644
|
+
if (entry.length <= significant.length && entry.every((w, j) => significant[j] === w)) {
|
|
4645
|
+
return entry.join(" ");
|
|
4646
|
+
}
|
|
4647
|
+
}
|
|
4648
|
+
if (list.singleWord.has(cmd)) return cmd;
|
|
4649
|
+
if (WRAPPERS.has(cmd) && hops < MAX_WRAPPER_HOPS) {
|
|
4650
|
+
hops++;
|
|
4651
|
+
i++;
|
|
4652
|
+
while (i < tokens.length && (tokens[i].startsWith("-") || ASSIGN_RE.test(tokens[i]))) i++;
|
|
4653
|
+
continue;
|
|
4654
|
+
}
|
|
4655
|
+
return null;
|
|
4656
|
+
}
|
|
4657
|
+
return null;
|
|
4658
|
+
}
|
|
4659
|
+
function collectMatches(command, list, matches, depth) {
|
|
4660
|
+
if (depth > MAX_RECURSION_DEPTH || command.length > MAX_COMMAND_LENGTH) return;
|
|
4661
|
+
let text = command.toLowerCase();
|
|
4662
|
+
text = stripHeredocBodies(text);
|
|
4663
|
+
const recurse = (inner) => collectMatches(inner, list, matches, depth + 1);
|
|
4664
|
+
text = extractDollarSubstitutions(text, recurse);
|
|
4665
|
+
text = extractBacktickSubstitutions(text, recurse);
|
|
4666
|
+
text = text.replace(/'[^']*'/g, " ").replace(/"[^"]*"/g, " ");
|
|
4667
|
+
text = text.replace(/(^|\s)#[^\n]*/g, " ");
|
|
4668
|
+
const segments = text.split(/\|\||&&|[;|&\n]|[({]/);
|
|
4669
|
+
for (const segment of segments) {
|
|
4670
|
+
const matched = matchSegment(segment, list);
|
|
4671
|
+
if (matched) matches.add(matched);
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4674
|
+
function matchHighRiskCommands(command, highRiskCommands = HIGH_RISK_COMMANDS) {
|
|
4675
|
+
if (!command) return [];
|
|
4676
|
+
const matches = /* @__PURE__ */ new Set();
|
|
4677
|
+
collectMatches(command, buildRiskList(highRiskCommands), matches, 0);
|
|
4678
|
+
return [...matches];
|
|
4679
|
+
}
|
|
4680
|
+
function isLocalhostOnlyNetworkCommand(command) {
|
|
4681
|
+
const text = command.toLowerCase();
|
|
4682
|
+
const tokens = text.split(/\s+/).map((t) => t.replace(/^["'`]+|["'`,;)]+$/g, ""));
|
|
4683
|
+
let localCount = 0;
|
|
4684
|
+
for (const token of tokens) {
|
|
4685
|
+
let host = null;
|
|
4686
|
+
if (token.includes("://")) {
|
|
4687
|
+
let rest = token.slice(token.indexOf("://") + 3);
|
|
4688
|
+
const at = rest.indexOf("@");
|
|
4689
|
+
if (at !== -1) rest = rest.slice(at + 1);
|
|
4690
|
+
host = rest.split(/[/?#]/)[0];
|
|
4691
|
+
} else if (/^[a-z0-9.[\]:-]+:\d+(\/.*)?$/.test(token)) {
|
|
4692
|
+
host = token.split("/")[0];
|
|
4693
|
+
} else if (/^(localhost|127\.0\.0\.1|\[?::1\]?)(\/.*)?$/.test(token)) {
|
|
4694
|
+
host = token.split("/")[0];
|
|
4695
|
+
}
|
|
4696
|
+
if (host === null) continue;
|
|
4697
|
+
const bare = host.replace(/:\d+$/, "").replace(/^\[|\]$/g, "");
|
|
4698
|
+
if (LOCAL_HOST_RE.test(bare)) {
|
|
4699
|
+
localCount++;
|
|
4700
|
+
} else {
|
|
4701
|
+
return false;
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
return localCount > 0;
|
|
4705
|
+
}
|
|
4706
|
+
var WRAPPERS, ASSIGN_RE, MAX_WRAPPER_HOPS, MAX_RECURSION_DEPTH, MAX_COMMAND_LENGTH, LOCAL_HOST_RE;
|
|
4707
|
+
var init_command_matcher = __esm({
|
|
4708
|
+
"src/local-evaluator/command-matcher.ts"() {
|
|
4709
|
+
"use strict";
|
|
4710
|
+
init_types();
|
|
4711
|
+
WRAPPERS = /* @__PURE__ */ new Set([
|
|
4712
|
+
"sudo",
|
|
4713
|
+
"doas",
|
|
4714
|
+
"env",
|
|
4715
|
+
"nohup",
|
|
4716
|
+
"time",
|
|
4717
|
+
"timeout",
|
|
4718
|
+
"nice",
|
|
4719
|
+
"ionice",
|
|
4720
|
+
"stdbuf",
|
|
4721
|
+
"xargs",
|
|
4722
|
+
"command",
|
|
4723
|
+
"exec",
|
|
4724
|
+
"builtin"
|
|
4725
|
+
]);
|
|
4726
|
+
ASSIGN_RE = /^[a-z_][a-z0-9_]*=/;
|
|
4727
|
+
MAX_WRAPPER_HOPS = 4;
|
|
4728
|
+
MAX_RECURSION_DEPTH = 3;
|
|
4729
|
+
MAX_COMMAND_LENGTH = 1e5;
|
|
4730
|
+
LOCAL_HOST_RE = /^(localhost|127\.0\.0\.1|::1|[a-z0-9.-]*\.localhost)$/;
|
|
4731
|
+
}
|
|
4732
|
+
});
|
|
4733
|
+
|
|
4567
4734
|
// src/local-evaluator/evaluator.ts
|
|
4568
4735
|
var LocalEvaluator;
|
|
4569
4736
|
var init_evaluator = __esm({
|
|
4570
4737
|
"src/local-evaluator/evaluator.ts"() {
|
|
4571
4738
|
"use strict";
|
|
4572
4739
|
init_types();
|
|
4740
|
+
init_command_matcher();
|
|
4573
4741
|
LocalEvaluator = class {
|
|
4574
4742
|
constructor(policy) {
|
|
4575
4743
|
this.requestCounts = /* @__PURE__ */ new Map();
|
|
@@ -4719,12 +4887,10 @@ var init_evaluator = __esm({
|
|
|
4719
4887
|
return score;
|
|
4720
4888
|
}
|
|
4721
4889
|
if (context.purpose === "shell.exec" && context.target) {
|
|
4722
|
-
const
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
break;
|
|
4727
|
-
}
|
|
4890
|
+
const matched = matchHighRiskCommands(context.target);
|
|
4891
|
+
const localProbeOnly = matched.length > 0 && matched.every((cmd) => cmd === "curl" || cmd === "wget") && isLocalhostOnlyNetworkCommand(context.target);
|
|
4892
|
+
if (matched.length > 0 && !localProbeOnly) {
|
|
4893
|
+
score = Math.max(score, 80);
|
|
4728
4894
|
}
|
|
4729
4895
|
}
|
|
4730
4896
|
if ((context.purpose === "file.read" || context.purpose === "file.write" || context.purpose === "file.delete") && context.target) {
|
|
@@ -4823,7 +4989,7 @@ var SDK_VERSION;
|
|
|
4823
4989
|
var init_version = __esm({
|
|
4824
4990
|
"src/version.ts"() {
|
|
4825
4991
|
"use strict";
|
|
4826
|
-
SDK_VERSION = "3.
|
|
4992
|
+
SDK_VERSION = "3.10.1";
|
|
4827
4993
|
}
|
|
4828
4994
|
});
|
|
4829
4995
|
|
|
@@ -5299,6 +5465,15 @@ var init_pdlss_pre_check = __esm({
|
|
|
5299
5465
|
}
|
|
5300
5466
|
});
|
|
5301
5467
|
|
|
5468
|
+
// src/metadata-capture.ts
|
|
5469
|
+
var MAX_TOTAL_BYTES;
|
|
5470
|
+
var init_metadata_capture = __esm({
|
|
5471
|
+
"src/metadata-capture.ts"() {
|
|
5472
|
+
"use strict";
|
|
5473
|
+
MAX_TOTAL_BYTES = 16 * 1024;
|
|
5474
|
+
}
|
|
5475
|
+
});
|
|
5476
|
+
|
|
5302
5477
|
// src/adapters/express.ts
|
|
5303
5478
|
var DEFAULT_ROUTES_REFRESH_MS;
|
|
5304
5479
|
var init_express = __esm({
|
|
@@ -5311,6 +5486,7 @@ var init_express = __esm({
|
|
|
5311
5486
|
init_approval_gate();
|
|
5312
5487
|
init_pdlss_pre_check();
|
|
5313
5488
|
init_well_known();
|
|
5489
|
+
init_metadata_capture();
|
|
5314
5490
|
DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
5315
5491
|
}
|
|
5316
5492
|
});
|
|
@@ -5324,6 +5500,7 @@ var init_nextjs = __esm({
|
|
|
5324
5500
|
init_verify();
|
|
5325
5501
|
init_http();
|
|
5326
5502
|
init_pdlss_pre_check();
|
|
5503
|
+
init_metadata_capture();
|
|
5327
5504
|
init_http_pdlss();
|
|
5328
5505
|
init_approval_gate();
|
|
5329
5506
|
DEFAULT_ROUTES_REFRESH_MS2 = 5 * 60 * 1e3;
|
|
@@ -5761,6 +5938,7 @@ var init_src = __esm({
|
|
|
5761
5938
|
init_edge_config();
|
|
5762
5939
|
init_platform_signatures();
|
|
5763
5940
|
init_verify();
|
|
5941
|
+
init_metadata_capture();
|
|
5764
5942
|
init_version();
|
|
5765
5943
|
}
|
|
5766
5944
|
});
|
|
@@ -5827,21 +6005,93 @@ var init_online = __esm({
|
|
|
5827
6005
|
}
|
|
5828
6006
|
});
|
|
5829
6007
|
|
|
6008
|
+
// src/gateway/redact.ts
|
|
6009
|
+
function redactSecrets(text) {
|
|
6010
|
+
let result = text;
|
|
6011
|
+
for (const { type: type2, re, replacement } of REDACTION_PATTERNS) {
|
|
6012
|
+
result = result.replace(re, replacement ?? marker(type2));
|
|
6013
|
+
}
|
|
6014
|
+
return result;
|
|
6015
|
+
}
|
|
6016
|
+
function redactDeep(value) {
|
|
6017
|
+
if (typeof value === "string") {
|
|
6018
|
+
return redactSecrets(value);
|
|
6019
|
+
}
|
|
6020
|
+
if (Array.isArray(value)) {
|
|
6021
|
+
return value.map((item) => redactDeep(item));
|
|
6022
|
+
}
|
|
6023
|
+
if (value !== null && typeof value === "object" && !(value instanceof Date)) {
|
|
6024
|
+
const out = {};
|
|
6025
|
+
for (const [k, v] of Object.entries(value)) {
|
|
6026
|
+
out[k] = redactDeep(v);
|
|
6027
|
+
}
|
|
6028
|
+
return out;
|
|
6029
|
+
}
|
|
6030
|
+
return value;
|
|
6031
|
+
}
|
|
6032
|
+
var marker, REDACTION_PATTERNS;
|
|
6033
|
+
var init_redact = __esm({
|
|
6034
|
+
"src/gateway/redact.ts"() {
|
|
6035
|
+
"use strict";
|
|
6036
|
+
marker = (type2) => `[REDACTED:${type2}]`;
|
|
6037
|
+
REDACTION_PATTERNS = [
|
|
6038
|
+
// Multi-line blocks first so later single-line patterns don't shred them.
|
|
6039
|
+
{
|
|
6040
|
+
type: "private-key",
|
|
6041
|
+
re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g
|
|
6042
|
+
},
|
|
6043
|
+
// URL userinfo credentials (https://user:pass@, x-access-token:ghp_…@).
|
|
6044
|
+
{
|
|
6045
|
+
type: "url-credentials",
|
|
6046
|
+
re: /([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+:[^\s/@]+@/gi,
|
|
6047
|
+
replacement: `$1${marker("url-credentials")}@`
|
|
6048
|
+
},
|
|
6049
|
+
// Known token formats.
|
|
6050
|
+
{ type: "github-token", re: /\bgh[pousr]_[A-Za-z0-9]{20,255}\b/g },
|
|
6051
|
+
{ type: "github-token", re: /\bgithub_pat_[A-Za-z0-9_]{20,255}\b/g },
|
|
6052
|
+
{ type: "astrasync-key", re: /\bkya_[A-Fa-f0-9]{32,128}\b/g },
|
|
6053
|
+
{ type: "openai-key", re: /\bsk-[A-Za-z0-9_-]{20,}\b/g },
|
|
6054
|
+
{ type: "aws-access-key-id", re: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
6055
|
+
{ type: "jwt", re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
|
|
6056
|
+
// Bearer/token headers.
|
|
6057
|
+
{
|
|
6058
|
+
type: "bearer-token",
|
|
6059
|
+
re: /\b(bearer\s+)[a-z0-9._~+/=-]{16,}/gi,
|
|
6060
|
+
replacement: `$1${marker("bearer-token")}`
|
|
6061
|
+
},
|
|
6062
|
+
// Generic KEY=value / key: value assignments with secret-ish names.
|
|
6063
|
+
{
|
|
6064
|
+
type: "assigned-secret",
|
|
6065
|
+
re: /\b((?:password|passwd|secret|token|api[_-]?key|apikey|access[_-]?key|client[_-]?secret|private[_-]?key)\s*[=:]\s*)(['"]?)[^\s'"&;]{8,}\2/gi,
|
|
6066
|
+
replacement: `$1$2${marker("assigned-secret")}$2`
|
|
6067
|
+
}
|
|
6068
|
+
];
|
|
6069
|
+
}
|
|
6070
|
+
});
|
|
6071
|
+
|
|
5830
6072
|
// src/gateway/modes/hybrid.ts
|
|
6073
|
+
function delay(ms) {
|
|
6074
|
+
return new Promise((resolve) => {
|
|
6075
|
+
const timer = setTimeout(() => resolve(FLUSH_TIMEOUT), ms);
|
|
6076
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
6077
|
+
});
|
|
6078
|
+
}
|
|
5831
6079
|
function verifyHybrid(evaluator, syncQueue, context) {
|
|
5832
6080
|
const decision = evaluator.evaluate(context);
|
|
5833
6081
|
syncQueue.enqueue(context, decision);
|
|
5834
6082
|
return decision;
|
|
5835
6083
|
}
|
|
5836
|
-
var import_fs2, import_path, MAX_QUEUE_SIZE, MAX_RETRIES, HybridSyncQueue;
|
|
6084
|
+
var import_fs2, import_path, MAX_QUEUE_SIZE, MAX_RETRIES, FLUSH_TIMEOUT, HybridSyncQueue;
|
|
5837
6085
|
var init_hybrid = __esm({
|
|
5838
6086
|
"src/gateway/modes/hybrid.ts"() {
|
|
5839
6087
|
"use strict";
|
|
5840
6088
|
import_fs2 = require("fs");
|
|
5841
6089
|
import_path = require("path");
|
|
5842
6090
|
init_online();
|
|
6091
|
+
init_redact();
|
|
5843
6092
|
MAX_QUEUE_SIZE = 1e3;
|
|
5844
6093
|
MAX_RETRIES = 3;
|
|
6094
|
+
FLUSH_TIMEOUT = /* @__PURE__ */ Symbol("flush-timeout");
|
|
5845
6095
|
HybridSyncQueue = class {
|
|
5846
6096
|
constructor(config, persistPath) {
|
|
5847
6097
|
this.queue = [];
|
|
@@ -5862,12 +6112,12 @@ var init_hybrid = __esm({
|
|
|
5862
6112
|
/**
|
|
5863
6113
|
* Stop periodic sync and flush remaining entries.
|
|
5864
6114
|
*/
|
|
5865
|
-
async stop() {
|
|
6115
|
+
async stop(flushOptions = {}) {
|
|
5866
6116
|
if (this.timer) {
|
|
5867
6117
|
clearInterval(this.timer);
|
|
5868
6118
|
this.timer = null;
|
|
5869
6119
|
}
|
|
5870
|
-
await this.flush();
|
|
6120
|
+
await this.flush(flushOptions);
|
|
5871
6121
|
this.saveToDisk();
|
|
5872
6122
|
}
|
|
5873
6123
|
/**
|
|
@@ -5879,8 +6129,8 @@ var init_hybrid = __esm({
|
|
|
5879
6129
|
}
|
|
5880
6130
|
this.queue.push({
|
|
5881
6131
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
5882
|
-
context,
|
|
5883
|
-
decision,
|
|
6132
|
+
context: redactDeep(context),
|
|
6133
|
+
decision: redactDeep(decision),
|
|
5884
6134
|
timestamp: /* @__PURE__ */ new Date(),
|
|
5885
6135
|
retryCount: 0,
|
|
5886
6136
|
status: "pending"
|
|
@@ -5890,16 +6140,21 @@ var init_hybrid = __esm({
|
|
|
5890
6140
|
/**
|
|
5891
6141
|
* Flush pending entries to the API.
|
|
5892
6142
|
*/
|
|
5893
|
-
async flush() {
|
|
6143
|
+
async flush(options = {}) {
|
|
5894
6144
|
if (this.processing) return;
|
|
5895
6145
|
this.processing = true;
|
|
5896
6146
|
try {
|
|
5897
6147
|
const pending = this.queue.filter((e) => e.status === "pending");
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
6148
|
+
const batch = typeof options.limit === "number" ? pending.slice(0, options.limit) : pending;
|
|
6149
|
+
for (const entry of batch) {
|
|
6150
|
+
const attempt = verifyOnline(this.config, entry.context, this.config.agentId).then(() => "synced").catch(() => "error");
|
|
6151
|
+
const result = options.perEntryTimeoutMs ? await Promise.race([attempt, delay(options.perEntryTimeoutMs)]) : await attempt;
|
|
6152
|
+
if (result === FLUSH_TIMEOUT) {
|
|
6153
|
+
break;
|
|
6154
|
+
}
|
|
6155
|
+
if (result === "synced") {
|
|
5901
6156
|
entry.status = "synced";
|
|
5902
|
-
}
|
|
6157
|
+
} else {
|
|
5903
6158
|
entry.retryCount++;
|
|
5904
6159
|
if (entry.retryCount >= MAX_RETRIES) {
|
|
5905
6160
|
entry.status = "failed";
|
|
@@ -5958,6 +6213,7 @@ var init_trace_logger = __esm({
|
|
|
5958
6213
|
"use strict";
|
|
5959
6214
|
import_fs3 = require("fs");
|
|
5960
6215
|
import_path2 = require("path");
|
|
6216
|
+
init_redact();
|
|
5961
6217
|
MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
5962
6218
|
MAX_FILES = 10;
|
|
5963
6219
|
TraceLogger = class {
|
|
@@ -5977,8 +6233,8 @@ var init_trace_logger = __esm({
|
|
|
5977
6233
|
id: this.generateId(),
|
|
5978
6234
|
timestamp: /* @__PURE__ */ new Date(),
|
|
5979
6235
|
type: "evaluation",
|
|
5980
|
-
context,
|
|
5981
|
-
decision
|
|
6236
|
+
context: redactDeep(context),
|
|
6237
|
+
decision: redactDeep(decision)
|
|
5982
6238
|
});
|
|
5983
6239
|
}
|
|
5984
6240
|
/**
|
|
@@ -6106,10 +6362,12 @@ var init_gateway = __esm({
|
|
|
6106
6362
|
}
|
|
6107
6363
|
/**
|
|
6108
6364
|
* Graceful shutdown. Flushes sync queue and cleans up resources.
|
|
6365
|
+
* Stateless callers (hooks) pass bounded flush options so sync never
|
|
6366
|
+
* sits on a tool call's critical path.
|
|
6109
6367
|
*/
|
|
6110
|
-
async shutdown() {
|
|
6368
|
+
async shutdown(options) {
|
|
6111
6369
|
if (this.syncQueue) {
|
|
6112
|
-
await this.syncQueue.stop();
|
|
6370
|
+
await this.syncQueue.stop(options?.syncFlush ?? {});
|
|
6113
6371
|
this.syncQueue = null;
|
|
6114
6372
|
}
|
|
6115
6373
|
this.evaluator = null;
|
|
@@ -6132,7 +6390,7 @@ var init_gateway = __esm({
|
|
|
6132
6390
|
let decision;
|
|
6133
6391
|
switch (this.config.mode) {
|
|
6134
6392
|
case "online":
|
|
6135
|
-
decision = await verifyOnline(this.config, context, astraId);
|
|
6393
|
+
decision = await verifyOnline(this.config, context, astraId ?? this.config.agentId);
|
|
6136
6394
|
break;
|
|
6137
6395
|
case "local":
|
|
6138
6396
|
if (!this.evaluator) throw new Error("Local evaluator not initialized");
|
|
@@ -6700,7 +6958,7 @@ async function cmdUninstallHooks() {
|
|
|
6700
6958
|
function resolveClaudeHookCommand() {
|
|
6701
6959
|
const sibling = path.join(__dirname, "astrasync-claude-hook.js");
|
|
6702
6960
|
if (fs.existsSync(sibling)) {
|
|
6703
|
-
return `
|
|
6961
|
+
return `"${process.execPath}" "${sibling}"`;
|
|
6704
6962
|
}
|
|
6705
6963
|
return "astrasync-claude-hook";
|
|
6706
6964
|
}
|