@astrasyncai/verification-gateway 3.10.0 → 3.11.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/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 +317 -35
- package/dist/bin/astrasync-codex-hook.js +5107 -0
- package/dist/bin/astrasync-guard.js +430 -40
- package/dist/bin/astrasync.js +453 -41
- package/dist/browser/background.js +279 -24
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +279 -24
- 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/claude-code/claude-code-adapter.js +9 -1
- package/dist/claude-code/claude-code-adapter.js.map +1 -1
- package/dist/claude-code/claude-code-adapter.mjs +9 -1
- package/dist/claude-code/claude-code-adapter.mjs.map +1 -1
- package/dist/cli/index.d.mts +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/codex/index.d.mts +230 -0
- package/dist/codex/index.d.ts +230 -0
- package/dist/codex/index.js +5225 -0
- package/dist/codex/index.js.map +1 -0
- package/dist/codex/index.mjs +5197 -0
- package/dist/codex/index.mjs.map +1 -0
- 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 +279 -24
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +279 -24
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/gateway/gateway.d.mts +32 -2
- package/dist/gateway/gateway.d.ts +32 -2
- package/dist/gateway/gateway.js +279 -24
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +279 -24
- 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 +8 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlatformAdapter, AdapterConfig } from '../adapter-interface/interface.mjs';
|
|
2
|
-
import { P as PDLSSContext, V as VerificationDecision, A as AgentAction, I as InterceptResult } from '../types-
|
|
2
|
+
import { P as PDLSSContext, V as VerificationDecision, A as AgentAction, I as InterceptResult } from '../types-BV6abBnF.mjs';
|
|
3
3
|
import '../gateway/gateway.mjs';
|
|
4
4
|
import '../types-sy3tq8lp.mjs';
|
|
5
5
|
import '../metadata-capture.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlatformAdapter, AdapterConfig } from '../adapter-interface/interface.js';
|
|
2
|
-
import { P as PDLSSContext, V as VerificationDecision, A as AgentAction, I as InterceptResult } from '../types-
|
|
2
|
+
import { P as PDLSSContext, V as VerificationDecision, A as AgentAction, I as InterceptResult } from '../types-C23_uaY8.js';
|
|
3
3
|
import '../gateway/gateway.js';
|
|
4
4
|
import '../types-9tns4wyl.js';
|
|
5
5
|
import '../metadata-capture.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VSCodeAPI } from './cursor-adapter.mjs';
|
|
2
2
|
import '../adapter-interface/interface.mjs';
|
|
3
3
|
import '../gateway/gateway.mjs';
|
|
4
|
-
import '../types-
|
|
4
|
+
import '../types-BV6abBnF.mjs';
|
|
5
5
|
import '../types-sy3tq8lp.mjs';
|
|
6
6
|
import '../metadata-capture.mjs';
|
|
7
7
|
|
package/dist/cursor/extension.js
CHANGED
|
@@ -288,7 +288,9 @@ var HIGH_RISK_COMMANDS = [
|
|
|
288
288
|
"git push",
|
|
289
289
|
"npm publish",
|
|
290
290
|
"docker",
|
|
291
|
-
"kubectl"
|
|
291
|
+
"kubectl",
|
|
292
|
+
"gh pr create",
|
|
293
|
+
"gh pr merge"
|
|
292
294
|
];
|
|
293
295
|
var SENSITIVE_PATHS = [
|
|
294
296
|
".ssh",
|
|
@@ -307,6 +309,164 @@ var SENSITIVE_PATHS = [
|
|
|
307
309
|
".pypirc"
|
|
308
310
|
];
|
|
309
311
|
|
|
312
|
+
// src/local-evaluator/command-matcher.ts
|
|
313
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
314
|
+
"sudo",
|
|
315
|
+
"doas",
|
|
316
|
+
"env",
|
|
317
|
+
"nohup",
|
|
318
|
+
"time",
|
|
319
|
+
"timeout",
|
|
320
|
+
"nice",
|
|
321
|
+
"ionice",
|
|
322
|
+
"stdbuf",
|
|
323
|
+
"xargs",
|
|
324
|
+
"command",
|
|
325
|
+
"exec",
|
|
326
|
+
"builtin"
|
|
327
|
+
]);
|
|
328
|
+
var ASSIGN_RE = /^[a-z_][a-z0-9_]*=/;
|
|
329
|
+
var MAX_WRAPPER_HOPS = 4;
|
|
330
|
+
var MAX_RECURSION_DEPTH = 3;
|
|
331
|
+
var MAX_COMMAND_LENGTH = 1e5;
|
|
332
|
+
var LOCAL_HOST_RE = /^(localhost|127\.0\.0\.1|::1|[a-z0-9.-]*\.localhost)$/;
|
|
333
|
+
function buildRiskList(entries) {
|
|
334
|
+
const singleWord = /* @__PURE__ */ new Set();
|
|
335
|
+
const multiWord = [];
|
|
336
|
+
for (const entry of entries) {
|
|
337
|
+
const words = entry.toLowerCase().trim().split(/\s+/);
|
|
338
|
+
if (words.length === 1) singleWord.add(words[0]);
|
|
339
|
+
else multiWord.push(words);
|
|
340
|
+
}
|
|
341
|
+
multiWord.sort((a, b) => b.length - a.length);
|
|
342
|
+
return { singleWord, multiWord };
|
|
343
|
+
}
|
|
344
|
+
function stripHeredocBodies(text) {
|
|
345
|
+
const lines = text.split("\n");
|
|
346
|
+
const kept = [];
|
|
347
|
+
let terminator = null;
|
|
348
|
+
for (const line of lines) {
|
|
349
|
+
if (terminator !== null) {
|
|
350
|
+
if (line.trim() === terminator) terminator = null;
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
kept.push(line);
|
|
354
|
+
const heredoc = line.match(/<<-?\s*['"]?(\w+)['"]?/);
|
|
355
|
+
if (heredoc) terminator = heredoc[1];
|
|
356
|
+
}
|
|
357
|
+
return kept.join("\n");
|
|
358
|
+
}
|
|
359
|
+
function extractDollarSubstitutions(text, collect) {
|
|
360
|
+
let result = text;
|
|
361
|
+
let start = result.indexOf("$(");
|
|
362
|
+
let iterations = 0;
|
|
363
|
+
while (start !== -1 && iterations < 50) {
|
|
364
|
+
iterations++;
|
|
365
|
+
let depth = 0;
|
|
366
|
+
let end = result.length;
|
|
367
|
+
for (let i = start + 1; i < result.length; i++) {
|
|
368
|
+
if (result[i] === "(") depth++;
|
|
369
|
+
else if (result[i] === ")") {
|
|
370
|
+
depth--;
|
|
371
|
+
if (depth === 0) {
|
|
372
|
+
end = i;
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
collect(result.slice(start + 2, end));
|
|
378
|
+
result = `${result.slice(0, start)} ${result.slice(Math.min(end + 1, result.length))}`;
|
|
379
|
+
start = result.indexOf("$(");
|
|
380
|
+
}
|
|
381
|
+
return result;
|
|
382
|
+
}
|
|
383
|
+
function extractBacktickSubstitutions(text, collect) {
|
|
384
|
+
if (!text.includes("`")) return text;
|
|
385
|
+
const chunks = text.split("`");
|
|
386
|
+
const kept = [];
|
|
387
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
388
|
+
if (i % 2 === 1) collect(chunks[i]);
|
|
389
|
+
else kept.push(chunks[i]);
|
|
390
|
+
}
|
|
391
|
+
return kept.join(" ");
|
|
392
|
+
}
|
|
393
|
+
function basename(token) {
|
|
394
|
+
const slash = token.lastIndexOf("/");
|
|
395
|
+
return slash === -1 ? token : token.slice(slash + 1);
|
|
396
|
+
}
|
|
397
|
+
function matchSegment(segment, list) {
|
|
398
|
+
const tokens = segment.split(/\s+/).filter((t) => /[a-z0-9]/.test(t));
|
|
399
|
+
let i = 0;
|
|
400
|
+
let hops = 0;
|
|
401
|
+
while (i < tokens.length) {
|
|
402
|
+
while (i < tokens.length && (tokens[i] === "export" || ASSIGN_RE.test(tokens[i]))) i++;
|
|
403
|
+
if (i >= tokens.length) return null;
|
|
404
|
+
const cmd = basename(tokens[i]);
|
|
405
|
+
const significant = [cmd, ...tokens.slice(i + 1).filter((t) => !t.startsWith("-"))];
|
|
406
|
+
for (const entry of list.multiWord) {
|
|
407
|
+
if (entry.length <= significant.length && entry.every((w, j) => significant[j] === w)) {
|
|
408
|
+
return entry.join(" ");
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (list.singleWord.has(cmd)) return cmd;
|
|
412
|
+
if (WRAPPERS.has(cmd) && hops < MAX_WRAPPER_HOPS) {
|
|
413
|
+
hops++;
|
|
414
|
+
i++;
|
|
415
|
+
while (i < tokens.length && (tokens[i].startsWith("-") || ASSIGN_RE.test(tokens[i]))) i++;
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
function collectMatches(command, list, matches, depth) {
|
|
423
|
+
if (depth > MAX_RECURSION_DEPTH || command.length > MAX_COMMAND_LENGTH) return;
|
|
424
|
+
let text = command.toLowerCase();
|
|
425
|
+
text = stripHeredocBodies(text);
|
|
426
|
+
const recurse = (inner) => collectMatches(inner, list, matches, depth + 1);
|
|
427
|
+
text = extractDollarSubstitutions(text, recurse);
|
|
428
|
+
text = extractBacktickSubstitutions(text, recurse);
|
|
429
|
+
text = text.replace(/'[^']*'/g, " ").replace(/"[^"]*"/g, " ");
|
|
430
|
+
text = text.replace(/(^|\s)#[^\n]*/g, " ");
|
|
431
|
+
const segments = text.split(/\|\||&&|[;|&\n]|[({]/);
|
|
432
|
+
for (const segment of segments) {
|
|
433
|
+
const matched = matchSegment(segment, list);
|
|
434
|
+
if (matched) matches.add(matched);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function matchHighRiskCommands(command, highRiskCommands = HIGH_RISK_COMMANDS) {
|
|
438
|
+
if (!command) return [];
|
|
439
|
+
const matches = /* @__PURE__ */ new Set();
|
|
440
|
+
collectMatches(command, buildRiskList(highRiskCommands), matches, 0);
|
|
441
|
+
return [...matches];
|
|
442
|
+
}
|
|
443
|
+
function isLocalhostOnlyNetworkCommand(command) {
|
|
444
|
+
const text = command.toLowerCase();
|
|
445
|
+
const tokens = text.split(/\s+/).map((t) => t.replace(/^["'`]+|["'`,;)]+$/g, ""));
|
|
446
|
+
let localCount = 0;
|
|
447
|
+
for (const token of tokens) {
|
|
448
|
+
let host = null;
|
|
449
|
+
if (token.includes("://")) {
|
|
450
|
+
let rest = token.slice(token.indexOf("://") + 3);
|
|
451
|
+
const at = rest.indexOf("@");
|
|
452
|
+
if (at !== -1) rest = rest.slice(at + 1);
|
|
453
|
+
host = rest.split(/[/?#]/)[0];
|
|
454
|
+
} else if (/^[a-z0-9.[\]:-]+:\d+(\/.*)?$/.test(token)) {
|
|
455
|
+
host = token.split("/")[0];
|
|
456
|
+
} else if (/^(localhost|127\.0\.0\.1|\[?::1\]?)(\/.*)?$/.test(token)) {
|
|
457
|
+
host = token.split("/")[0];
|
|
458
|
+
}
|
|
459
|
+
if (host === null) continue;
|
|
460
|
+
const bare = host.replace(/:\d+$/, "").replace(/^\[|\]$/g, "");
|
|
461
|
+
if (LOCAL_HOST_RE.test(bare)) {
|
|
462
|
+
localCount++;
|
|
463
|
+
} else {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
return localCount > 0;
|
|
468
|
+
}
|
|
469
|
+
|
|
310
470
|
// src/local-evaluator/evaluator.ts
|
|
311
471
|
var LocalEvaluator = class {
|
|
312
472
|
constructor(policy) {
|
|
@@ -457,12 +617,10 @@ var LocalEvaluator = class {
|
|
|
457
617
|
return score;
|
|
458
618
|
}
|
|
459
619
|
if (context.purpose === "shell.exec" && context.target) {
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
break;
|
|
465
|
-
}
|
|
620
|
+
const matched = matchHighRiskCommands(context.target);
|
|
621
|
+
const localProbeOnly = matched.length > 0 && matched.every((cmd) => cmd === "curl" || cmd === "wget") && isLocalhostOnlyNetworkCommand(context.target);
|
|
622
|
+
if (matched.length > 0 && !localProbeOnly) {
|
|
623
|
+
score = Math.max(score, 80);
|
|
466
624
|
}
|
|
467
625
|
}
|
|
468
626
|
if ((context.purpose === "file.read" || context.purpose === "file.write" || context.purpose === "file.delete") && context.target) {
|
|
@@ -3773,7 +3931,7 @@ function getTrustLevel(score) {
|
|
|
3773
3931
|
}
|
|
3774
3932
|
|
|
3775
3933
|
// src/version.ts
|
|
3776
|
-
var SDK_VERSION = "3.
|
|
3934
|
+
var SDK_VERSION = "3.11.0";
|
|
3777
3935
|
|
|
3778
3936
|
// src/well-known.ts
|
|
3779
3937
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -4288,10 +4446,12 @@ function toGatewayConfig(config) {
|
|
|
4288
4446
|
};
|
|
4289
4447
|
}
|
|
4290
4448
|
function toVerificationRequest(context, astraId) {
|
|
4449
|
+
const dotIndex = context.purpose.indexOf(".");
|
|
4450
|
+
const dotted = dotIndex > 0;
|
|
4291
4451
|
return {
|
|
4292
4452
|
credentials: { astraId },
|
|
4293
|
-
purpose: context.purpose,
|
|
4294
|
-
action: context.action,
|
|
4453
|
+
purpose: dotted ? context.purpose.slice(0, dotIndex) : context.purpose,
|
|
4454
|
+
action: dotted ? context.purpose : context.action,
|
|
4295
4455
|
resourceType: context.resourceType,
|
|
4296
4456
|
resource: context.target,
|
|
4297
4457
|
transactionValue: context.transactionValue,
|
|
@@ -4331,8 +4491,75 @@ async function verifyOnline(config, context, astraId) {
|
|
|
4331
4491
|
// src/gateway/modes/hybrid.ts
|
|
4332
4492
|
var import_fs2 = require("fs");
|
|
4333
4493
|
var import_path = require("path");
|
|
4494
|
+
|
|
4495
|
+
// src/gateway/redact.ts
|
|
4496
|
+
var marker = (type2) => `[REDACTED:${type2}]`;
|
|
4497
|
+
var REDACTION_PATTERNS = [
|
|
4498
|
+
// Multi-line blocks first so later single-line patterns don't shred them.
|
|
4499
|
+
{
|
|
4500
|
+
type: "private-key",
|
|
4501
|
+
re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g
|
|
4502
|
+
},
|
|
4503
|
+
// URL userinfo credentials (https://user:pass@, x-access-token:ghp_…@).
|
|
4504
|
+
{
|
|
4505
|
+
type: "url-credentials",
|
|
4506
|
+
re: /([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+:[^\s/@]+@/gi,
|
|
4507
|
+
replacement: `$1${marker("url-credentials")}@`
|
|
4508
|
+
},
|
|
4509
|
+
// Known token formats.
|
|
4510
|
+
{ type: "github-token", re: /\bgh[pousr]_[A-Za-z0-9]{20,255}\b/g },
|
|
4511
|
+
{ type: "github-token", re: /\bgithub_pat_[A-Za-z0-9_]{20,255}\b/g },
|
|
4512
|
+
{ type: "astrasync-key", re: /\bkya_[A-Fa-f0-9]{32,128}\b/g },
|
|
4513
|
+
{ type: "openai-key", re: /\bsk-[A-Za-z0-9_-]{20,}\b/g },
|
|
4514
|
+
{ type: "aws-access-key-id", re: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
4515
|
+
{ type: "jwt", re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
|
|
4516
|
+
// Bearer/token headers.
|
|
4517
|
+
{
|
|
4518
|
+
type: "bearer-token",
|
|
4519
|
+
re: /\b(bearer\s+)[a-z0-9._~+/=-]{16,}/gi,
|
|
4520
|
+
replacement: `$1${marker("bearer-token")}`
|
|
4521
|
+
},
|
|
4522
|
+
// Generic KEY=value / key: value assignments with secret-ish names.
|
|
4523
|
+
{
|
|
4524
|
+
type: "assigned-secret",
|
|
4525
|
+
re: /\b((?:password|passwd|secret|token|api[_-]?key|apikey|access[_-]?key|client[_-]?secret|private[_-]?key)\s*[=:]\s*)(['"]?)[^\s'"&;]{8,}\2/gi,
|
|
4526
|
+
replacement: `$1$2${marker("assigned-secret")}$2`
|
|
4527
|
+
}
|
|
4528
|
+
];
|
|
4529
|
+
function redactSecrets(text) {
|
|
4530
|
+
let result = text;
|
|
4531
|
+
for (const { type: type2, re, replacement } of REDACTION_PATTERNS) {
|
|
4532
|
+
result = result.replace(re, replacement ?? marker(type2));
|
|
4533
|
+
}
|
|
4534
|
+
return result;
|
|
4535
|
+
}
|
|
4536
|
+
function redactDeep(value) {
|
|
4537
|
+
if (typeof value === "string") {
|
|
4538
|
+
return redactSecrets(value);
|
|
4539
|
+
}
|
|
4540
|
+
if (Array.isArray(value)) {
|
|
4541
|
+
return value.map((item) => redactDeep(item));
|
|
4542
|
+
}
|
|
4543
|
+
if (value !== null && typeof value === "object" && !(value instanceof Date)) {
|
|
4544
|
+
const out = {};
|
|
4545
|
+
for (const [k, v] of Object.entries(value)) {
|
|
4546
|
+
out[k] = redactDeep(v);
|
|
4547
|
+
}
|
|
4548
|
+
return out;
|
|
4549
|
+
}
|
|
4550
|
+
return value;
|
|
4551
|
+
}
|
|
4552
|
+
|
|
4553
|
+
// src/gateway/modes/hybrid.ts
|
|
4334
4554
|
var MAX_QUEUE_SIZE = 1e3;
|
|
4335
4555
|
var MAX_RETRIES = 3;
|
|
4556
|
+
var FLUSH_TIMEOUT = /* @__PURE__ */ Symbol("flush-timeout");
|
|
4557
|
+
function delay(ms) {
|
|
4558
|
+
return new Promise((resolve) => {
|
|
4559
|
+
const timer = setTimeout(() => resolve(FLUSH_TIMEOUT), ms);
|
|
4560
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
4561
|
+
});
|
|
4562
|
+
}
|
|
4336
4563
|
var HybridSyncQueue = class {
|
|
4337
4564
|
constructor(config, persistPath) {
|
|
4338
4565
|
this.queue = [];
|
|
@@ -4353,12 +4580,12 @@ var HybridSyncQueue = class {
|
|
|
4353
4580
|
/**
|
|
4354
4581
|
* Stop periodic sync and flush remaining entries.
|
|
4355
4582
|
*/
|
|
4356
|
-
async stop() {
|
|
4583
|
+
async stop(flushOptions = {}) {
|
|
4357
4584
|
if (this.timer) {
|
|
4358
4585
|
clearInterval(this.timer);
|
|
4359
4586
|
this.timer = null;
|
|
4360
4587
|
}
|
|
4361
|
-
await this.flush();
|
|
4588
|
+
await this.flush(flushOptions);
|
|
4362
4589
|
this.saveToDisk();
|
|
4363
4590
|
}
|
|
4364
4591
|
/**
|
|
@@ -4370,8 +4597,8 @@ var HybridSyncQueue = class {
|
|
|
4370
4597
|
}
|
|
4371
4598
|
this.queue.push({
|
|
4372
4599
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
4373
|
-
context,
|
|
4374
|
-
decision,
|
|
4600
|
+
context: redactDeep(context),
|
|
4601
|
+
decision: redactDeep(decision),
|
|
4375
4602
|
timestamp: /* @__PURE__ */ new Date(),
|
|
4376
4603
|
retryCount: 0,
|
|
4377
4604
|
status: "pending"
|
|
@@ -4381,16 +4608,21 @@ var HybridSyncQueue = class {
|
|
|
4381
4608
|
/**
|
|
4382
4609
|
* Flush pending entries to the API.
|
|
4383
4610
|
*/
|
|
4384
|
-
async flush() {
|
|
4611
|
+
async flush(options = {}) {
|
|
4385
4612
|
if (this.processing) return;
|
|
4386
4613
|
this.processing = true;
|
|
4387
4614
|
try {
|
|
4388
4615
|
const pending = this.queue.filter((e) => e.status === "pending");
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4616
|
+
const batch = typeof options.limit === "number" ? pending.slice(0, options.limit) : pending;
|
|
4617
|
+
for (const entry of batch) {
|
|
4618
|
+
const attempt = verifyOnline(this.config, entry.context, this.config.agentId).then(() => "synced").catch(() => "error");
|
|
4619
|
+
const result = options.perEntryTimeoutMs ? await Promise.race([attempt, delay(options.perEntryTimeoutMs)]) : await attempt;
|
|
4620
|
+
if (result === FLUSH_TIMEOUT) {
|
|
4621
|
+
break;
|
|
4622
|
+
}
|
|
4623
|
+
if (result === "synced") {
|
|
4392
4624
|
entry.status = "synced";
|
|
4393
|
-
}
|
|
4625
|
+
} else {
|
|
4394
4626
|
entry.retryCount++;
|
|
4395
4627
|
if (entry.retryCount >= MAX_RETRIES) {
|
|
4396
4628
|
entry.status = "failed";
|
|
@@ -4467,8 +4699,22 @@ var TraceLogger = class {
|
|
|
4467
4699
|
id: this.generateId(),
|
|
4468
4700
|
timestamp: /* @__PURE__ */ new Date(),
|
|
4469
4701
|
type: "evaluation",
|
|
4470
|
-
context,
|
|
4471
|
-
decision
|
|
4702
|
+
context: redactDeep(context),
|
|
4703
|
+
decision: redactDeep(decision)
|
|
4704
|
+
});
|
|
4705
|
+
}
|
|
4706
|
+
/**
|
|
4707
|
+
* Log a tool call the guard saw but did not govern. One line per skip
|
|
4708
|
+
* keeps coverage holes (unmapped platform tools) visible in the traces
|
|
4709
|
+
* instead of silently indistinguishable from ALLOW.
|
|
4710
|
+
*/
|
|
4711
|
+
logSkipped(toolName, reason) {
|
|
4712
|
+
if (!this.enabled) return;
|
|
4713
|
+
this.write({
|
|
4714
|
+
id: this.generateId(),
|
|
4715
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
4716
|
+
type: "skipped",
|
|
4717
|
+
metadata: { toolName, reason }
|
|
4472
4718
|
});
|
|
4473
4719
|
}
|
|
4474
4720
|
/**
|
|
@@ -4585,10 +4831,12 @@ var AstraSyncGateway = class {
|
|
|
4585
4831
|
}
|
|
4586
4832
|
/**
|
|
4587
4833
|
* Graceful shutdown. Flushes sync queue and cleans up resources.
|
|
4834
|
+
* Stateless callers (hooks) pass bounded flush options so sync never
|
|
4835
|
+
* sits on a tool call's critical path.
|
|
4588
4836
|
*/
|
|
4589
|
-
async shutdown() {
|
|
4837
|
+
async shutdown(options) {
|
|
4590
4838
|
if (this.syncQueue) {
|
|
4591
|
-
await this.syncQueue.stop();
|
|
4839
|
+
await this.syncQueue.stop(options?.syncFlush ?? {});
|
|
4592
4840
|
this.syncQueue = null;
|
|
4593
4841
|
}
|
|
4594
4842
|
this.evaluator = null;
|
|
@@ -4611,7 +4859,7 @@ var AstraSyncGateway = class {
|
|
|
4611
4859
|
let decision;
|
|
4612
4860
|
switch (this.config.mode) {
|
|
4613
4861
|
case "online":
|
|
4614
|
-
decision = await verifyOnline(this.config, context, astraId);
|
|
4862
|
+
decision = await verifyOnline(this.config, context, astraId ?? this.config.agentId);
|
|
4615
4863
|
break;
|
|
4616
4864
|
case "local":
|
|
4617
4865
|
if (!this.evaluator) throw new Error("Local evaluator not initialized");
|
|
@@ -4666,6 +4914,13 @@ var AstraSyncGateway = class {
|
|
|
4666
4914
|
getSyncStatus() {
|
|
4667
4915
|
return this.syncQueue?.getStatus() || null;
|
|
4668
4916
|
}
|
|
4917
|
+
/**
|
|
4918
|
+
* Record a tool call the calling adapter saw but did not govern
|
|
4919
|
+
* (unmapped tool, skipTools, MCP with governMcp off). Trace-only.
|
|
4920
|
+
*/
|
|
4921
|
+
logSkippedTool(toolName, reason) {
|
|
4922
|
+
this.traceLogger?.logSkipped(toolName, reason);
|
|
4923
|
+
}
|
|
4669
4924
|
};
|
|
4670
4925
|
|
|
4671
4926
|
// src/cursor/extension.ts
|