@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
|
@@ -284,7 +284,9 @@ var HIGH_RISK_COMMANDS = [
|
|
|
284
284
|
"git push",
|
|
285
285
|
"npm publish",
|
|
286
286
|
"docker",
|
|
287
|
-
"kubectl"
|
|
287
|
+
"kubectl",
|
|
288
|
+
"gh pr create",
|
|
289
|
+
"gh pr merge"
|
|
288
290
|
];
|
|
289
291
|
var SENSITIVE_PATHS = [
|
|
290
292
|
".ssh",
|
|
@@ -303,6 +305,164 @@ var SENSITIVE_PATHS = [
|
|
|
303
305
|
".pypirc"
|
|
304
306
|
];
|
|
305
307
|
|
|
308
|
+
// src/local-evaluator/command-matcher.ts
|
|
309
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
310
|
+
"sudo",
|
|
311
|
+
"doas",
|
|
312
|
+
"env",
|
|
313
|
+
"nohup",
|
|
314
|
+
"time",
|
|
315
|
+
"timeout",
|
|
316
|
+
"nice",
|
|
317
|
+
"ionice",
|
|
318
|
+
"stdbuf",
|
|
319
|
+
"xargs",
|
|
320
|
+
"command",
|
|
321
|
+
"exec",
|
|
322
|
+
"builtin"
|
|
323
|
+
]);
|
|
324
|
+
var ASSIGN_RE = /^[a-z_][a-z0-9_]*=/;
|
|
325
|
+
var MAX_WRAPPER_HOPS = 4;
|
|
326
|
+
var MAX_RECURSION_DEPTH = 3;
|
|
327
|
+
var MAX_COMMAND_LENGTH = 1e5;
|
|
328
|
+
var LOCAL_HOST_RE = /^(localhost|127\.0\.0\.1|::1|[a-z0-9.-]*\.localhost)$/;
|
|
329
|
+
function buildRiskList(entries) {
|
|
330
|
+
const singleWord = /* @__PURE__ */ new Set();
|
|
331
|
+
const multiWord = [];
|
|
332
|
+
for (const entry of entries) {
|
|
333
|
+
const words = entry.toLowerCase().trim().split(/\s+/);
|
|
334
|
+
if (words.length === 1) singleWord.add(words[0]);
|
|
335
|
+
else multiWord.push(words);
|
|
336
|
+
}
|
|
337
|
+
multiWord.sort((a, b) => b.length - a.length);
|
|
338
|
+
return { singleWord, multiWord };
|
|
339
|
+
}
|
|
340
|
+
function stripHeredocBodies(text) {
|
|
341
|
+
const lines = text.split("\n");
|
|
342
|
+
const kept = [];
|
|
343
|
+
let terminator = null;
|
|
344
|
+
for (const line of lines) {
|
|
345
|
+
if (terminator !== null) {
|
|
346
|
+
if (line.trim() === terminator) terminator = null;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
kept.push(line);
|
|
350
|
+
const heredoc = line.match(/<<-?\s*['"]?(\w+)['"]?/);
|
|
351
|
+
if (heredoc) terminator = heredoc[1];
|
|
352
|
+
}
|
|
353
|
+
return kept.join("\n");
|
|
354
|
+
}
|
|
355
|
+
function extractDollarSubstitutions(text, collect) {
|
|
356
|
+
let result = text;
|
|
357
|
+
let start = result.indexOf("$(");
|
|
358
|
+
let iterations = 0;
|
|
359
|
+
while (start !== -1 && iterations < 50) {
|
|
360
|
+
iterations++;
|
|
361
|
+
let depth = 0;
|
|
362
|
+
let end = result.length;
|
|
363
|
+
for (let i = start + 1; i < result.length; i++) {
|
|
364
|
+
if (result[i] === "(") depth++;
|
|
365
|
+
else if (result[i] === ")") {
|
|
366
|
+
depth--;
|
|
367
|
+
if (depth === 0) {
|
|
368
|
+
end = i;
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
collect(result.slice(start + 2, end));
|
|
374
|
+
result = `${result.slice(0, start)} ${result.slice(Math.min(end + 1, result.length))}`;
|
|
375
|
+
start = result.indexOf("$(");
|
|
376
|
+
}
|
|
377
|
+
return result;
|
|
378
|
+
}
|
|
379
|
+
function extractBacktickSubstitutions(text, collect) {
|
|
380
|
+
if (!text.includes("`")) return text;
|
|
381
|
+
const chunks = text.split("`");
|
|
382
|
+
const kept = [];
|
|
383
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
384
|
+
if (i % 2 === 1) collect(chunks[i]);
|
|
385
|
+
else kept.push(chunks[i]);
|
|
386
|
+
}
|
|
387
|
+
return kept.join(" ");
|
|
388
|
+
}
|
|
389
|
+
function basename(token) {
|
|
390
|
+
const slash = token.lastIndexOf("/");
|
|
391
|
+
return slash === -1 ? token : token.slice(slash + 1);
|
|
392
|
+
}
|
|
393
|
+
function matchSegment(segment, list) {
|
|
394
|
+
const tokens = segment.split(/\s+/).filter((t) => /[a-z0-9]/.test(t));
|
|
395
|
+
let i = 0;
|
|
396
|
+
let hops = 0;
|
|
397
|
+
while (i < tokens.length) {
|
|
398
|
+
while (i < tokens.length && (tokens[i] === "export" || ASSIGN_RE.test(tokens[i]))) i++;
|
|
399
|
+
if (i >= tokens.length) return null;
|
|
400
|
+
const cmd = basename(tokens[i]);
|
|
401
|
+
const significant = [cmd, ...tokens.slice(i + 1).filter((t) => !t.startsWith("-"))];
|
|
402
|
+
for (const entry of list.multiWord) {
|
|
403
|
+
if (entry.length <= significant.length && entry.every((w, j) => significant[j] === w)) {
|
|
404
|
+
return entry.join(" ");
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (list.singleWord.has(cmd)) return cmd;
|
|
408
|
+
if (WRAPPERS.has(cmd) && hops < MAX_WRAPPER_HOPS) {
|
|
409
|
+
hops++;
|
|
410
|
+
i++;
|
|
411
|
+
while (i < tokens.length && (tokens[i].startsWith("-") || ASSIGN_RE.test(tokens[i]))) i++;
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
function collectMatches(command, list, matches, depth) {
|
|
419
|
+
if (depth > MAX_RECURSION_DEPTH || command.length > MAX_COMMAND_LENGTH) return;
|
|
420
|
+
let text = command.toLowerCase();
|
|
421
|
+
text = stripHeredocBodies(text);
|
|
422
|
+
const recurse = (inner) => collectMatches(inner, list, matches, depth + 1);
|
|
423
|
+
text = extractDollarSubstitutions(text, recurse);
|
|
424
|
+
text = extractBacktickSubstitutions(text, recurse);
|
|
425
|
+
text = text.replace(/'[^']*'/g, " ").replace(/"[^"]*"/g, " ");
|
|
426
|
+
text = text.replace(/(^|\s)#[^\n]*/g, " ");
|
|
427
|
+
const segments = text.split(/\|\||&&|[;|&\n]|[({]/);
|
|
428
|
+
for (const segment of segments) {
|
|
429
|
+
const matched = matchSegment(segment, list);
|
|
430
|
+
if (matched) matches.add(matched);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
function matchHighRiskCommands(command, highRiskCommands = HIGH_RISK_COMMANDS) {
|
|
434
|
+
if (!command) return [];
|
|
435
|
+
const matches = /* @__PURE__ */ new Set();
|
|
436
|
+
collectMatches(command, buildRiskList(highRiskCommands), matches, 0);
|
|
437
|
+
return [...matches];
|
|
438
|
+
}
|
|
439
|
+
function isLocalhostOnlyNetworkCommand(command) {
|
|
440
|
+
const text = command.toLowerCase();
|
|
441
|
+
const tokens = text.split(/\s+/).map((t) => t.replace(/^["'`]+|["'`,;)]+$/g, ""));
|
|
442
|
+
let localCount = 0;
|
|
443
|
+
for (const token of tokens) {
|
|
444
|
+
let host = null;
|
|
445
|
+
if (token.includes("://")) {
|
|
446
|
+
let rest = token.slice(token.indexOf("://") + 3);
|
|
447
|
+
const at = rest.indexOf("@");
|
|
448
|
+
if (at !== -1) rest = rest.slice(at + 1);
|
|
449
|
+
host = rest.split(/[/?#]/)[0];
|
|
450
|
+
} else if (/^[a-z0-9.[\]:-]+:\d+(\/.*)?$/.test(token)) {
|
|
451
|
+
host = token.split("/")[0];
|
|
452
|
+
} else if (/^(localhost|127\.0\.0\.1|\[?::1\]?)(\/.*)?$/.test(token)) {
|
|
453
|
+
host = token.split("/")[0];
|
|
454
|
+
}
|
|
455
|
+
if (host === null) continue;
|
|
456
|
+
const bare = host.replace(/:\d+$/, "").replace(/^\[|\]$/g, "");
|
|
457
|
+
if (LOCAL_HOST_RE.test(bare)) {
|
|
458
|
+
localCount++;
|
|
459
|
+
} else {
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return localCount > 0;
|
|
464
|
+
}
|
|
465
|
+
|
|
306
466
|
// src/local-evaluator/evaluator.ts
|
|
307
467
|
var LocalEvaluator = class {
|
|
308
468
|
constructor(policy) {
|
|
@@ -453,12 +613,10 @@ var LocalEvaluator = class {
|
|
|
453
613
|
return score;
|
|
454
614
|
}
|
|
455
615
|
if (context.purpose === "shell.exec" && context.target) {
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
break;
|
|
461
|
-
}
|
|
616
|
+
const matched = matchHighRiskCommands(context.target);
|
|
617
|
+
const localProbeOnly = matched.length > 0 && matched.every((cmd) => cmd === "curl" || cmd === "wget") && isLocalhostOnlyNetworkCommand(context.target);
|
|
618
|
+
if (matched.length > 0 && !localProbeOnly) {
|
|
619
|
+
score = Math.max(score, 80);
|
|
462
620
|
}
|
|
463
621
|
}
|
|
464
622
|
if ((context.purpose === "file.read" || context.purpose === "file.write" || context.purpose === "file.delete") && context.target) {
|
|
@@ -3769,7 +3927,7 @@ function getTrustLevel(score) {
|
|
|
3769
3927
|
}
|
|
3770
3928
|
|
|
3771
3929
|
// src/version.ts
|
|
3772
|
-
var SDK_VERSION = "3.
|
|
3930
|
+
var SDK_VERSION = "3.10.1";
|
|
3773
3931
|
|
|
3774
3932
|
// src/well-known.ts
|
|
3775
3933
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -4185,6 +4343,9 @@ async function verify(config, request, options) {
|
|
|
4185
4343
|
// src/adapters/stepup-poll.ts
|
|
4186
4344
|
var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
|
|
4187
4345
|
|
|
4346
|
+
// src/metadata-capture.ts
|
|
4347
|
+
var MAX_TOTAL_BYTES = 16 * 1024;
|
|
4348
|
+
|
|
4188
4349
|
// src/adapters/express.ts
|
|
4189
4350
|
var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
4190
4351
|
|
|
@@ -4324,8 +4485,75 @@ async function verifyOnline(config, context, astraId) {
|
|
|
4324
4485
|
// src/gateway/modes/hybrid.ts
|
|
4325
4486
|
var import_fs2 = require("fs");
|
|
4326
4487
|
var import_path = require("path");
|
|
4488
|
+
|
|
4489
|
+
// src/gateway/redact.ts
|
|
4490
|
+
var marker = (type2) => `[REDACTED:${type2}]`;
|
|
4491
|
+
var REDACTION_PATTERNS = [
|
|
4492
|
+
// Multi-line blocks first so later single-line patterns don't shred them.
|
|
4493
|
+
{
|
|
4494
|
+
type: "private-key",
|
|
4495
|
+
re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g
|
|
4496
|
+
},
|
|
4497
|
+
// URL userinfo credentials (https://user:pass@, x-access-token:ghp_…@).
|
|
4498
|
+
{
|
|
4499
|
+
type: "url-credentials",
|
|
4500
|
+
re: /([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+:[^\s/@]+@/gi,
|
|
4501
|
+
replacement: `$1${marker("url-credentials")}@`
|
|
4502
|
+
},
|
|
4503
|
+
// Known token formats.
|
|
4504
|
+
{ type: "github-token", re: /\bgh[pousr]_[A-Za-z0-9]{20,255}\b/g },
|
|
4505
|
+
{ type: "github-token", re: /\bgithub_pat_[A-Za-z0-9_]{20,255}\b/g },
|
|
4506
|
+
{ type: "astrasync-key", re: /\bkya_[A-Fa-f0-9]{32,128}\b/g },
|
|
4507
|
+
{ type: "openai-key", re: /\bsk-[A-Za-z0-9_-]{20,}\b/g },
|
|
4508
|
+
{ type: "aws-access-key-id", re: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
4509
|
+
{ type: "jwt", re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
|
|
4510
|
+
// Bearer/token headers.
|
|
4511
|
+
{
|
|
4512
|
+
type: "bearer-token",
|
|
4513
|
+
re: /\b(bearer\s+)[a-z0-9._~+/=-]{16,}/gi,
|
|
4514
|
+
replacement: `$1${marker("bearer-token")}`
|
|
4515
|
+
},
|
|
4516
|
+
// Generic KEY=value / key: value assignments with secret-ish names.
|
|
4517
|
+
{
|
|
4518
|
+
type: "assigned-secret",
|
|
4519
|
+
re: /\b((?:password|passwd|secret|token|api[_-]?key|apikey|access[_-]?key|client[_-]?secret|private[_-]?key)\s*[=:]\s*)(['"]?)[^\s'"&;]{8,}\2/gi,
|
|
4520
|
+
replacement: `$1$2${marker("assigned-secret")}$2`
|
|
4521
|
+
}
|
|
4522
|
+
];
|
|
4523
|
+
function redactSecrets(text) {
|
|
4524
|
+
let result = text;
|
|
4525
|
+
for (const { type: type2, re, replacement } of REDACTION_PATTERNS) {
|
|
4526
|
+
result = result.replace(re, replacement ?? marker(type2));
|
|
4527
|
+
}
|
|
4528
|
+
return result;
|
|
4529
|
+
}
|
|
4530
|
+
function redactDeep(value) {
|
|
4531
|
+
if (typeof value === "string") {
|
|
4532
|
+
return redactSecrets(value);
|
|
4533
|
+
}
|
|
4534
|
+
if (Array.isArray(value)) {
|
|
4535
|
+
return value.map((item) => redactDeep(item));
|
|
4536
|
+
}
|
|
4537
|
+
if (value !== null && typeof value === "object" && !(value instanceof Date)) {
|
|
4538
|
+
const out = {};
|
|
4539
|
+
for (const [k, v] of Object.entries(value)) {
|
|
4540
|
+
out[k] = redactDeep(v);
|
|
4541
|
+
}
|
|
4542
|
+
return out;
|
|
4543
|
+
}
|
|
4544
|
+
return value;
|
|
4545
|
+
}
|
|
4546
|
+
|
|
4547
|
+
// src/gateway/modes/hybrid.ts
|
|
4327
4548
|
var MAX_QUEUE_SIZE = 1e3;
|
|
4328
4549
|
var MAX_RETRIES = 3;
|
|
4550
|
+
var FLUSH_TIMEOUT = /* @__PURE__ */ Symbol("flush-timeout");
|
|
4551
|
+
function delay(ms) {
|
|
4552
|
+
return new Promise((resolve) => {
|
|
4553
|
+
const timer = setTimeout(() => resolve(FLUSH_TIMEOUT), ms);
|
|
4554
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
4555
|
+
});
|
|
4556
|
+
}
|
|
4329
4557
|
var HybridSyncQueue = class {
|
|
4330
4558
|
constructor(config, persistPath) {
|
|
4331
4559
|
this.queue = [];
|
|
@@ -4346,12 +4574,12 @@ var HybridSyncQueue = class {
|
|
|
4346
4574
|
/**
|
|
4347
4575
|
* Stop periodic sync and flush remaining entries.
|
|
4348
4576
|
*/
|
|
4349
|
-
async stop() {
|
|
4577
|
+
async stop(flushOptions = {}) {
|
|
4350
4578
|
if (this.timer) {
|
|
4351
4579
|
clearInterval(this.timer);
|
|
4352
4580
|
this.timer = null;
|
|
4353
4581
|
}
|
|
4354
|
-
await this.flush();
|
|
4582
|
+
await this.flush(flushOptions);
|
|
4355
4583
|
this.saveToDisk();
|
|
4356
4584
|
}
|
|
4357
4585
|
/**
|
|
@@ -4363,8 +4591,8 @@ var HybridSyncQueue = class {
|
|
|
4363
4591
|
}
|
|
4364
4592
|
this.queue.push({
|
|
4365
4593
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
4366
|
-
context,
|
|
4367
|
-
decision,
|
|
4594
|
+
context: redactDeep(context),
|
|
4595
|
+
decision: redactDeep(decision),
|
|
4368
4596
|
timestamp: /* @__PURE__ */ new Date(),
|
|
4369
4597
|
retryCount: 0,
|
|
4370
4598
|
status: "pending"
|
|
@@ -4374,16 +4602,21 @@ var HybridSyncQueue = class {
|
|
|
4374
4602
|
/**
|
|
4375
4603
|
* Flush pending entries to the API.
|
|
4376
4604
|
*/
|
|
4377
|
-
async flush() {
|
|
4605
|
+
async flush(options = {}) {
|
|
4378
4606
|
if (this.processing) return;
|
|
4379
4607
|
this.processing = true;
|
|
4380
4608
|
try {
|
|
4381
4609
|
const pending = this.queue.filter((e) => e.status === "pending");
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4610
|
+
const batch = typeof options.limit === "number" ? pending.slice(0, options.limit) : pending;
|
|
4611
|
+
for (const entry of batch) {
|
|
4612
|
+
const attempt = verifyOnline(this.config, entry.context, this.config.agentId).then(() => "synced").catch(() => "error");
|
|
4613
|
+
const result = options.perEntryTimeoutMs ? await Promise.race([attempt, delay(options.perEntryTimeoutMs)]) : await attempt;
|
|
4614
|
+
if (result === FLUSH_TIMEOUT) {
|
|
4615
|
+
break;
|
|
4616
|
+
}
|
|
4617
|
+
if (result === "synced") {
|
|
4385
4618
|
entry.status = "synced";
|
|
4386
|
-
}
|
|
4619
|
+
} else {
|
|
4387
4620
|
entry.retryCount++;
|
|
4388
4621
|
if (entry.retryCount >= MAX_RETRIES) {
|
|
4389
4622
|
entry.status = "failed";
|
|
@@ -4460,8 +4693,8 @@ var TraceLogger = class {
|
|
|
4460
4693
|
id: this.generateId(),
|
|
4461
4694
|
timestamp: /* @__PURE__ */ new Date(),
|
|
4462
4695
|
type: "evaluation",
|
|
4463
|
-
context,
|
|
4464
|
-
decision
|
|
4696
|
+
context: redactDeep(context),
|
|
4697
|
+
decision: redactDeep(decision)
|
|
4465
4698
|
});
|
|
4466
4699
|
}
|
|
4467
4700
|
/**
|
|
@@ -4578,10 +4811,12 @@ var AstraSyncGateway = class {
|
|
|
4578
4811
|
}
|
|
4579
4812
|
/**
|
|
4580
4813
|
* Graceful shutdown. Flushes sync queue and cleans up resources.
|
|
4814
|
+
* Stateless callers (hooks) pass bounded flush options so sync never
|
|
4815
|
+
* sits on a tool call's critical path.
|
|
4581
4816
|
*/
|
|
4582
|
-
async shutdown() {
|
|
4817
|
+
async shutdown(options) {
|
|
4583
4818
|
if (this.syncQueue) {
|
|
4584
|
-
await this.syncQueue.stop();
|
|
4819
|
+
await this.syncQueue.stop(options?.syncFlush ?? {});
|
|
4585
4820
|
this.syncQueue = null;
|
|
4586
4821
|
}
|
|
4587
4822
|
this.evaluator = null;
|
|
@@ -4604,7 +4839,7 @@ var AstraSyncGateway = class {
|
|
|
4604
4839
|
let decision;
|
|
4605
4840
|
switch (this.config.mode) {
|
|
4606
4841
|
case "online":
|
|
4607
|
-
decision = await verifyOnline(this.config, context, astraId);
|
|
4842
|
+
decision = await verifyOnline(this.config, context, astraId ?? this.config.agentId);
|
|
4608
4843
|
break;
|
|
4609
4844
|
case "local":
|
|
4610
4845
|
if (!this.evaluator) throw new Error("Local evaluator not initialized");
|