@astrasyncai/verification-gateway 3.10.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 +1 -1
- package/dist/adapter-interface/interface.d.ts +1 -1
- package/dist/adapters/express.js +1 -1
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +1 -1
- package/dist/adapters/express.mjs.map +1 -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.js +1 -1
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +1 -1
- package/dist/adapters/nextjs.mjs.map +1 -1
- 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/bin/astrasync-claude-hook.js +273 -25
- package/dist/bin/astrasync-guard.js +255 -23
- package/dist/bin/astrasync.js +270 -24
- package/dist/browser/background.js +254 -22
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +254 -22
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +1 -1
- package/dist/browser/browser-adapter.d.ts +1 -1
- package/dist/claude-code/claude-code-adapter.d.mts +1 -1
- package/dist/claude-code/claude-code-adapter.d.ts +1 -1
- package/dist/cli/index.d.mts +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cursor/cursor-adapter.d.mts +1 -1
- package/dist/cursor/cursor-adapter.d.ts +1 -1
- package/dist/cursor/extension.d.mts +1 -1
- package/dist/cursor/extension.d.ts +1 -1
- package/dist/cursor/extension.js +254 -22
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +254 -22
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/gateway/gateway.d.mts +27 -2
- package/dist/gateway/gateway.d.ts +27 -2
- package/dist/gateway/gateway.js +254 -22
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +254 -22
- 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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +1 -1
- package/dist/local-evaluator/evaluator.d.ts +1 -1
- 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/{types-D0lCtFQ7.d.mts → types-BV6abBnF.d.mts} +6 -0
- package/dist/{types-YbiXYKx1.d.ts → types-C23_uaY8.d.ts} +6 -0
- 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 +1 -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.10.
|
|
4992
|
+
SDK_VERSION = "3.10.1";
|
|
4827
4993
|
}
|
|
4828
4994
|
});
|
|
4829
4995
|
|
|
@@ -5839,21 +6005,93 @@ var init_online = __esm({
|
|
|
5839
6005
|
}
|
|
5840
6006
|
});
|
|
5841
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
|
+
|
|
5842
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
|
+
}
|
|
5843
6079
|
function verifyHybrid(evaluator, syncQueue, context) {
|
|
5844
6080
|
const decision = evaluator.evaluate(context);
|
|
5845
6081
|
syncQueue.enqueue(context, decision);
|
|
5846
6082
|
return decision;
|
|
5847
6083
|
}
|
|
5848
|
-
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;
|
|
5849
6085
|
var init_hybrid = __esm({
|
|
5850
6086
|
"src/gateway/modes/hybrid.ts"() {
|
|
5851
6087
|
"use strict";
|
|
5852
6088
|
import_fs2 = require("fs");
|
|
5853
6089
|
import_path = require("path");
|
|
5854
6090
|
init_online();
|
|
6091
|
+
init_redact();
|
|
5855
6092
|
MAX_QUEUE_SIZE = 1e3;
|
|
5856
6093
|
MAX_RETRIES = 3;
|
|
6094
|
+
FLUSH_TIMEOUT = /* @__PURE__ */ Symbol("flush-timeout");
|
|
5857
6095
|
HybridSyncQueue = class {
|
|
5858
6096
|
constructor(config, persistPath) {
|
|
5859
6097
|
this.queue = [];
|
|
@@ -5874,12 +6112,12 @@ var init_hybrid = __esm({
|
|
|
5874
6112
|
/**
|
|
5875
6113
|
* Stop periodic sync and flush remaining entries.
|
|
5876
6114
|
*/
|
|
5877
|
-
async stop() {
|
|
6115
|
+
async stop(flushOptions = {}) {
|
|
5878
6116
|
if (this.timer) {
|
|
5879
6117
|
clearInterval(this.timer);
|
|
5880
6118
|
this.timer = null;
|
|
5881
6119
|
}
|
|
5882
|
-
await this.flush();
|
|
6120
|
+
await this.flush(flushOptions);
|
|
5883
6121
|
this.saveToDisk();
|
|
5884
6122
|
}
|
|
5885
6123
|
/**
|
|
@@ -5891,8 +6129,8 @@ var init_hybrid = __esm({
|
|
|
5891
6129
|
}
|
|
5892
6130
|
this.queue.push({
|
|
5893
6131
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
5894
|
-
context,
|
|
5895
|
-
decision,
|
|
6132
|
+
context: redactDeep(context),
|
|
6133
|
+
decision: redactDeep(decision),
|
|
5896
6134
|
timestamp: /* @__PURE__ */ new Date(),
|
|
5897
6135
|
retryCount: 0,
|
|
5898
6136
|
status: "pending"
|
|
@@ -5902,16 +6140,21 @@ var init_hybrid = __esm({
|
|
|
5902
6140
|
/**
|
|
5903
6141
|
* Flush pending entries to the API.
|
|
5904
6142
|
*/
|
|
5905
|
-
async flush() {
|
|
6143
|
+
async flush(options = {}) {
|
|
5906
6144
|
if (this.processing) return;
|
|
5907
6145
|
this.processing = true;
|
|
5908
6146
|
try {
|
|
5909
6147
|
const pending = this.queue.filter((e) => e.status === "pending");
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
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") {
|
|
5913
6156
|
entry.status = "synced";
|
|
5914
|
-
}
|
|
6157
|
+
} else {
|
|
5915
6158
|
entry.retryCount++;
|
|
5916
6159
|
if (entry.retryCount >= MAX_RETRIES) {
|
|
5917
6160
|
entry.status = "failed";
|
|
@@ -5970,6 +6213,7 @@ var init_trace_logger = __esm({
|
|
|
5970
6213
|
"use strict";
|
|
5971
6214
|
import_fs3 = require("fs");
|
|
5972
6215
|
import_path2 = require("path");
|
|
6216
|
+
init_redact();
|
|
5973
6217
|
MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
5974
6218
|
MAX_FILES = 10;
|
|
5975
6219
|
TraceLogger = class {
|
|
@@ -5989,8 +6233,8 @@ var init_trace_logger = __esm({
|
|
|
5989
6233
|
id: this.generateId(),
|
|
5990
6234
|
timestamp: /* @__PURE__ */ new Date(),
|
|
5991
6235
|
type: "evaluation",
|
|
5992
|
-
context,
|
|
5993
|
-
decision
|
|
6236
|
+
context: redactDeep(context),
|
|
6237
|
+
decision: redactDeep(decision)
|
|
5994
6238
|
});
|
|
5995
6239
|
}
|
|
5996
6240
|
/**
|
|
@@ -6118,10 +6362,12 @@ var init_gateway = __esm({
|
|
|
6118
6362
|
}
|
|
6119
6363
|
/**
|
|
6120
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.
|
|
6121
6367
|
*/
|
|
6122
|
-
async shutdown() {
|
|
6368
|
+
async shutdown(options) {
|
|
6123
6369
|
if (this.syncQueue) {
|
|
6124
|
-
await this.syncQueue.stop();
|
|
6370
|
+
await this.syncQueue.stop(options?.syncFlush ?? {});
|
|
6125
6371
|
this.syncQueue = null;
|
|
6126
6372
|
}
|
|
6127
6373
|
this.evaluator = null;
|
|
@@ -6144,7 +6390,7 @@ var init_gateway = __esm({
|
|
|
6144
6390
|
let decision;
|
|
6145
6391
|
switch (this.config.mode) {
|
|
6146
6392
|
case "online":
|
|
6147
|
-
decision = await verifyOnline(this.config, context, astraId);
|
|
6393
|
+
decision = await verifyOnline(this.config, context, astraId ?? this.config.agentId);
|
|
6148
6394
|
break;
|
|
6149
6395
|
case "local":
|
|
6150
6396
|
if (!this.evaluator) throw new Error("Local evaluator not initialized");
|
|
@@ -6712,7 +6958,7 @@ async function cmdUninstallHooks() {
|
|
|
6712
6958
|
function resolveClaudeHookCommand() {
|
|
6713
6959
|
const sibling = path.join(__dirname, "astrasync-claude-hook.js");
|
|
6714
6960
|
if (fs.existsSync(sibling)) {
|
|
6715
|
-
return `
|
|
6961
|
+
return `"${process.execPath}" "${sibling}"`;
|
|
6716
6962
|
}
|
|
6717
6963
|
return "astrasync-claude-hook";
|
|
6718
6964
|
}
|