@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/gateway/gateway.mjs
CHANGED
|
@@ -18,7 +18,9 @@ var HIGH_RISK_COMMANDS = [
|
|
|
18
18
|
"git push",
|
|
19
19
|
"npm publish",
|
|
20
20
|
"docker",
|
|
21
|
-
"kubectl"
|
|
21
|
+
"kubectl",
|
|
22
|
+
"gh pr create",
|
|
23
|
+
"gh pr merge"
|
|
22
24
|
];
|
|
23
25
|
var SENSITIVE_PATHS = [
|
|
24
26
|
".ssh",
|
|
@@ -37,6 +39,164 @@ var SENSITIVE_PATHS = [
|
|
|
37
39
|
".pypirc"
|
|
38
40
|
];
|
|
39
41
|
|
|
42
|
+
// src/local-evaluator/command-matcher.ts
|
|
43
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
44
|
+
"sudo",
|
|
45
|
+
"doas",
|
|
46
|
+
"env",
|
|
47
|
+
"nohup",
|
|
48
|
+
"time",
|
|
49
|
+
"timeout",
|
|
50
|
+
"nice",
|
|
51
|
+
"ionice",
|
|
52
|
+
"stdbuf",
|
|
53
|
+
"xargs",
|
|
54
|
+
"command",
|
|
55
|
+
"exec",
|
|
56
|
+
"builtin"
|
|
57
|
+
]);
|
|
58
|
+
var ASSIGN_RE = /^[a-z_][a-z0-9_]*=/;
|
|
59
|
+
var MAX_WRAPPER_HOPS = 4;
|
|
60
|
+
var MAX_RECURSION_DEPTH = 3;
|
|
61
|
+
var MAX_COMMAND_LENGTH = 1e5;
|
|
62
|
+
var LOCAL_HOST_RE = /^(localhost|127\.0\.0\.1|::1|[a-z0-9.-]*\.localhost)$/;
|
|
63
|
+
function buildRiskList(entries) {
|
|
64
|
+
const singleWord = /* @__PURE__ */ new Set();
|
|
65
|
+
const multiWord = [];
|
|
66
|
+
for (const entry of entries) {
|
|
67
|
+
const words = entry.toLowerCase().trim().split(/\s+/);
|
|
68
|
+
if (words.length === 1) singleWord.add(words[0]);
|
|
69
|
+
else multiWord.push(words);
|
|
70
|
+
}
|
|
71
|
+
multiWord.sort((a, b) => b.length - a.length);
|
|
72
|
+
return { singleWord, multiWord };
|
|
73
|
+
}
|
|
74
|
+
function stripHeredocBodies(text) {
|
|
75
|
+
const lines = text.split("\n");
|
|
76
|
+
const kept = [];
|
|
77
|
+
let terminator = null;
|
|
78
|
+
for (const line of lines) {
|
|
79
|
+
if (terminator !== null) {
|
|
80
|
+
if (line.trim() === terminator) terminator = null;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
kept.push(line);
|
|
84
|
+
const heredoc = line.match(/<<-?\s*['"]?(\w+)['"]?/);
|
|
85
|
+
if (heredoc) terminator = heredoc[1];
|
|
86
|
+
}
|
|
87
|
+
return kept.join("\n");
|
|
88
|
+
}
|
|
89
|
+
function extractDollarSubstitutions(text, collect) {
|
|
90
|
+
let result = text;
|
|
91
|
+
let start = result.indexOf("$(");
|
|
92
|
+
let iterations = 0;
|
|
93
|
+
while (start !== -1 && iterations < 50) {
|
|
94
|
+
iterations++;
|
|
95
|
+
let depth = 0;
|
|
96
|
+
let end = result.length;
|
|
97
|
+
for (let i = start + 1; i < result.length; i++) {
|
|
98
|
+
if (result[i] === "(") depth++;
|
|
99
|
+
else if (result[i] === ")") {
|
|
100
|
+
depth--;
|
|
101
|
+
if (depth === 0) {
|
|
102
|
+
end = i;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
collect(result.slice(start + 2, end));
|
|
108
|
+
result = `${result.slice(0, start)} ${result.slice(Math.min(end + 1, result.length))}`;
|
|
109
|
+
start = result.indexOf("$(");
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
function extractBacktickSubstitutions(text, collect) {
|
|
114
|
+
if (!text.includes("`")) return text;
|
|
115
|
+
const chunks = text.split("`");
|
|
116
|
+
const kept = [];
|
|
117
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
118
|
+
if (i % 2 === 1) collect(chunks[i]);
|
|
119
|
+
else kept.push(chunks[i]);
|
|
120
|
+
}
|
|
121
|
+
return kept.join(" ");
|
|
122
|
+
}
|
|
123
|
+
function basename(token) {
|
|
124
|
+
const slash = token.lastIndexOf("/");
|
|
125
|
+
return slash === -1 ? token : token.slice(slash + 1);
|
|
126
|
+
}
|
|
127
|
+
function matchSegment(segment, list) {
|
|
128
|
+
const tokens = segment.split(/\s+/).filter((t) => /[a-z0-9]/.test(t));
|
|
129
|
+
let i = 0;
|
|
130
|
+
let hops = 0;
|
|
131
|
+
while (i < tokens.length) {
|
|
132
|
+
while (i < tokens.length && (tokens[i] === "export" || ASSIGN_RE.test(tokens[i]))) i++;
|
|
133
|
+
if (i >= tokens.length) return null;
|
|
134
|
+
const cmd = basename(tokens[i]);
|
|
135
|
+
const significant = [cmd, ...tokens.slice(i + 1).filter((t) => !t.startsWith("-"))];
|
|
136
|
+
for (const entry of list.multiWord) {
|
|
137
|
+
if (entry.length <= significant.length && entry.every((w, j) => significant[j] === w)) {
|
|
138
|
+
return entry.join(" ");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (list.singleWord.has(cmd)) return cmd;
|
|
142
|
+
if (WRAPPERS.has(cmd) && hops < MAX_WRAPPER_HOPS) {
|
|
143
|
+
hops++;
|
|
144
|
+
i++;
|
|
145
|
+
while (i < tokens.length && (tokens[i].startsWith("-") || ASSIGN_RE.test(tokens[i]))) i++;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
function collectMatches(command, list, matches, depth) {
|
|
153
|
+
if (depth > MAX_RECURSION_DEPTH || command.length > MAX_COMMAND_LENGTH) return;
|
|
154
|
+
let text = command.toLowerCase();
|
|
155
|
+
text = stripHeredocBodies(text);
|
|
156
|
+
const recurse = (inner) => collectMatches(inner, list, matches, depth + 1);
|
|
157
|
+
text = extractDollarSubstitutions(text, recurse);
|
|
158
|
+
text = extractBacktickSubstitutions(text, recurse);
|
|
159
|
+
text = text.replace(/'[^']*'/g, " ").replace(/"[^"]*"/g, " ");
|
|
160
|
+
text = text.replace(/(^|\s)#[^\n]*/g, " ");
|
|
161
|
+
const segments = text.split(/\|\||&&|[;|&\n]|[({]/);
|
|
162
|
+
for (const segment of segments) {
|
|
163
|
+
const matched = matchSegment(segment, list);
|
|
164
|
+
if (matched) matches.add(matched);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function matchHighRiskCommands(command, highRiskCommands = HIGH_RISK_COMMANDS) {
|
|
168
|
+
if (!command) return [];
|
|
169
|
+
const matches = /* @__PURE__ */ new Set();
|
|
170
|
+
collectMatches(command, buildRiskList(highRiskCommands), matches, 0);
|
|
171
|
+
return [...matches];
|
|
172
|
+
}
|
|
173
|
+
function isLocalhostOnlyNetworkCommand(command) {
|
|
174
|
+
const text = command.toLowerCase();
|
|
175
|
+
const tokens = text.split(/\s+/).map((t) => t.replace(/^["'`]+|["'`,;)]+$/g, ""));
|
|
176
|
+
let localCount = 0;
|
|
177
|
+
for (const token of tokens) {
|
|
178
|
+
let host = null;
|
|
179
|
+
if (token.includes("://")) {
|
|
180
|
+
let rest = token.slice(token.indexOf("://") + 3);
|
|
181
|
+
const at = rest.indexOf("@");
|
|
182
|
+
if (at !== -1) rest = rest.slice(at + 1);
|
|
183
|
+
host = rest.split(/[/?#]/)[0];
|
|
184
|
+
} else if (/^[a-z0-9.[\]:-]+:\d+(\/.*)?$/.test(token)) {
|
|
185
|
+
host = token.split("/")[0];
|
|
186
|
+
} else if (/^(localhost|127\.0\.0\.1|\[?::1\]?)(\/.*)?$/.test(token)) {
|
|
187
|
+
host = token.split("/")[0];
|
|
188
|
+
}
|
|
189
|
+
if (host === null) continue;
|
|
190
|
+
const bare = host.replace(/:\d+$/, "").replace(/^\[|\]$/g, "");
|
|
191
|
+
if (LOCAL_HOST_RE.test(bare)) {
|
|
192
|
+
localCount++;
|
|
193
|
+
} else {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return localCount > 0;
|
|
198
|
+
}
|
|
199
|
+
|
|
40
200
|
// src/local-evaluator/evaluator.ts
|
|
41
201
|
var LocalEvaluator = class {
|
|
42
202
|
constructor(policy) {
|
|
@@ -187,12 +347,10 @@ var LocalEvaluator = class {
|
|
|
187
347
|
return score;
|
|
188
348
|
}
|
|
189
349
|
if (context.purpose === "shell.exec" && context.target) {
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
350
|
+
const matched = matchHighRiskCommands(context.target);
|
|
351
|
+
const localProbeOnly = matched.length > 0 && matched.every((cmd) => cmd === "curl" || cmd === "wget") && isLocalhostOnlyNetworkCommand(context.target);
|
|
352
|
+
if (matched.length > 0 && !localProbeOnly) {
|
|
353
|
+
score = Math.max(score, 80);
|
|
196
354
|
}
|
|
197
355
|
}
|
|
198
356
|
if ((context.purpose === "file.read" || context.purpose === "file.write" || context.purpose === "file.delete") && context.target) {
|
|
@@ -3503,7 +3661,7 @@ function getTrustLevel(score) {
|
|
|
3503
3661
|
}
|
|
3504
3662
|
|
|
3505
3663
|
// src/version.ts
|
|
3506
|
-
var SDK_VERSION = "3.
|
|
3664
|
+
var SDK_VERSION = "3.10.1";
|
|
3507
3665
|
|
|
3508
3666
|
// src/well-known.ts
|
|
3509
3667
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -3919,6 +4077,9 @@ async function verify(config, request, options) {
|
|
|
3919
4077
|
// src/adapters/stepup-poll.ts
|
|
3920
4078
|
var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
|
|
3921
4079
|
|
|
4080
|
+
// src/metadata-capture.ts
|
|
4081
|
+
var MAX_TOTAL_BYTES = 16 * 1024;
|
|
4082
|
+
|
|
3922
4083
|
// src/adapters/express.ts
|
|
3923
4084
|
var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
3924
4085
|
|
|
@@ -4061,8 +4222,75 @@ async function verifyOnline(config, context, astraId) {
|
|
|
4061
4222
|
// src/gateway/modes/hybrid.ts
|
|
4062
4223
|
import { existsSync, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
|
|
4063
4224
|
import { dirname } from "path";
|
|
4225
|
+
|
|
4226
|
+
// src/gateway/redact.ts
|
|
4227
|
+
var marker = (type2) => `[REDACTED:${type2}]`;
|
|
4228
|
+
var REDACTION_PATTERNS = [
|
|
4229
|
+
// Multi-line blocks first so later single-line patterns don't shred them.
|
|
4230
|
+
{
|
|
4231
|
+
type: "private-key",
|
|
4232
|
+
re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g
|
|
4233
|
+
},
|
|
4234
|
+
// URL userinfo credentials (https://user:pass@, x-access-token:ghp_…@).
|
|
4235
|
+
{
|
|
4236
|
+
type: "url-credentials",
|
|
4237
|
+
re: /([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+:[^\s/@]+@/gi,
|
|
4238
|
+
replacement: `$1${marker("url-credentials")}@`
|
|
4239
|
+
},
|
|
4240
|
+
// Known token formats.
|
|
4241
|
+
{ type: "github-token", re: /\bgh[pousr]_[A-Za-z0-9]{20,255}\b/g },
|
|
4242
|
+
{ type: "github-token", re: /\bgithub_pat_[A-Za-z0-9_]{20,255}\b/g },
|
|
4243
|
+
{ type: "astrasync-key", re: /\bkya_[A-Fa-f0-9]{32,128}\b/g },
|
|
4244
|
+
{ type: "openai-key", re: /\bsk-[A-Za-z0-9_-]{20,}\b/g },
|
|
4245
|
+
{ type: "aws-access-key-id", re: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
4246
|
+
{ type: "jwt", re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
|
|
4247
|
+
// Bearer/token headers.
|
|
4248
|
+
{
|
|
4249
|
+
type: "bearer-token",
|
|
4250
|
+
re: /\b(bearer\s+)[a-z0-9._~+/=-]{16,}/gi,
|
|
4251
|
+
replacement: `$1${marker("bearer-token")}`
|
|
4252
|
+
},
|
|
4253
|
+
// Generic KEY=value / key: value assignments with secret-ish names.
|
|
4254
|
+
{
|
|
4255
|
+
type: "assigned-secret",
|
|
4256
|
+
re: /\b((?:password|passwd|secret|token|api[_-]?key|apikey|access[_-]?key|client[_-]?secret|private[_-]?key)\s*[=:]\s*)(['"]?)[^\s'"&;]{8,}\2/gi,
|
|
4257
|
+
replacement: `$1$2${marker("assigned-secret")}$2`
|
|
4258
|
+
}
|
|
4259
|
+
];
|
|
4260
|
+
function redactSecrets(text) {
|
|
4261
|
+
let result = text;
|
|
4262
|
+
for (const { type: type2, re, replacement } of REDACTION_PATTERNS) {
|
|
4263
|
+
result = result.replace(re, replacement ?? marker(type2));
|
|
4264
|
+
}
|
|
4265
|
+
return result;
|
|
4266
|
+
}
|
|
4267
|
+
function redactDeep(value) {
|
|
4268
|
+
if (typeof value === "string") {
|
|
4269
|
+
return redactSecrets(value);
|
|
4270
|
+
}
|
|
4271
|
+
if (Array.isArray(value)) {
|
|
4272
|
+
return value.map((item) => redactDeep(item));
|
|
4273
|
+
}
|
|
4274
|
+
if (value !== null && typeof value === "object" && !(value instanceof Date)) {
|
|
4275
|
+
const out = {};
|
|
4276
|
+
for (const [k, v] of Object.entries(value)) {
|
|
4277
|
+
out[k] = redactDeep(v);
|
|
4278
|
+
}
|
|
4279
|
+
return out;
|
|
4280
|
+
}
|
|
4281
|
+
return value;
|
|
4282
|
+
}
|
|
4283
|
+
|
|
4284
|
+
// src/gateway/modes/hybrid.ts
|
|
4064
4285
|
var MAX_QUEUE_SIZE = 1e3;
|
|
4065
4286
|
var MAX_RETRIES = 3;
|
|
4287
|
+
var FLUSH_TIMEOUT = /* @__PURE__ */ Symbol("flush-timeout");
|
|
4288
|
+
function delay(ms) {
|
|
4289
|
+
return new Promise((resolve) => {
|
|
4290
|
+
const timer = setTimeout(() => resolve(FLUSH_TIMEOUT), ms);
|
|
4291
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
4292
|
+
});
|
|
4293
|
+
}
|
|
4066
4294
|
var HybridSyncQueue = class {
|
|
4067
4295
|
constructor(config, persistPath) {
|
|
4068
4296
|
this.queue = [];
|
|
@@ -4083,12 +4311,12 @@ var HybridSyncQueue = class {
|
|
|
4083
4311
|
/**
|
|
4084
4312
|
* Stop periodic sync and flush remaining entries.
|
|
4085
4313
|
*/
|
|
4086
|
-
async stop() {
|
|
4314
|
+
async stop(flushOptions = {}) {
|
|
4087
4315
|
if (this.timer) {
|
|
4088
4316
|
clearInterval(this.timer);
|
|
4089
4317
|
this.timer = null;
|
|
4090
4318
|
}
|
|
4091
|
-
await this.flush();
|
|
4319
|
+
await this.flush(flushOptions);
|
|
4092
4320
|
this.saveToDisk();
|
|
4093
4321
|
}
|
|
4094
4322
|
/**
|
|
@@ -4100,8 +4328,8 @@ var HybridSyncQueue = class {
|
|
|
4100
4328
|
}
|
|
4101
4329
|
this.queue.push({
|
|
4102
4330
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
4103
|
-
context,
|
|
4104
|
-
decision,
|
|
4331
|
+
context: redactDeep(context),
|
|
4332
|
+
decision: redactDeep(decision),
|
|
4105
4333
|
timestamp: /* @__PURE__ */ new Date(),
|
|
4106
4334
|
retryCount: 0,
|
|
4107
4335
|
status: "pending"
|
|
@@ -4111,16 +4339,21 @@ var HybridSyncQueue = class {
|
|
|
4111
4339
|
/**
|
|
4112
4340
|
* Flush pending entries to the API.
|
|
4113
4341
|
*/
|
|
4114
|
-
async flush() {
|
|
4342
|
+
async flush(options = {}) {
|
|
4115
4343
|
if (this.processing) return;
|
|
4116
4344
|
this.processing = true;
|
|
4117
4345
|
try {
|
|
4118
4346
|
const pending = this.queue.filter((e) => e.status === "pending");
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4347
|
+
const batch = typeof options.limit === "number" ? pending.slice(0, options.limit) : pending;
|
|
4348
|
+
for (const entry of batch) {
|
|
4349
|
+
const attempt = verifyOnline(this.config, entry.context, this.config.agentId).then(() => "synced").catch(() => "error");
|
|
4350
|
+
const result = options.perEntryTimeoutMs ? await Promise.race([attempt, delay(options.perEntryTimeoutMs)]) : await attempt;
|
|
4351
|
+
if (result === FLUSH_TIMEOUT) {
|
|
4352
|
+
break;
|
|
4353
|
+
}
|
|
4354
|
+
if (result === "synced") {
|
|
4122
4355
|
entry.status = "synced";
|
|
4123
|
-
}
|
|
4356
|
+
} else {
|
|
4124
4357
|
entry.retryCount++;
|
|
4125
4358
|
if (entry.retryCount >= MAX_RETRIES) {
|
|
4126
4359
|
entry.status = "failed";
|
|
@@ -4197,8 +4430,8 @@ var TraceLogger = class {
|
|
|
4197
4430
|
id: this.generateId(),
|
|
4198
4431
|
timestamp: /* @__PURE__ */ new Date(),
|
|
4199
4432
|
type: "evaluation",
|
|
4200
|
-
context,
|
|
4201
|
-
decision
|
|
4433
|
+
context: redactDeep(context),
|
|
4434
|
+
decision: redactDeep(decision)
|
|
4202
4435
|
});
|
|
4203
4436
|
}
|
|
4204
4437
|
/**
|
|
@@ -4315,10 +4548,12 @@ var AstraSyncGateway = class {
|
|
|
4315
4548
|
}
|
|
4316
4549
|
/**
|
|
4317
4550
|
* Graceful shutdown. Flushes sync queue and cleans up resources.
|
|
4551
|
+
* Stateless callers (hooks) pass bounded flush options so sync never
|
|
4552
|
+
* sits on a tool call's critical path.
|
|
4318
4553
|
*/
|
|
4319
|
-
async shutdown() {
|
|
4554
|
+
async shutdown(options) {
|
|
4320
4555
|
if (this.syncQueue) {
|
|
4321
|
-
await this.syncQueue.stop();
|
|
4556
|
+
await this.syncQueue.stop(options?.syncFlush ?? {});
|
|
4322
4557
|
this.syncQueue = null;
|
|
4323
4558
|
}
|
|
4324
4559
|
this.evaluator = null;
|
|
@@ -4341,7 +4576,7 @@ var AstraSyncGateway = class {
|
|
|
4341
4576
|
let decision;
|
|
4342
4577
|
switch (this.config.mode) {
|
|
4343
4578
|
case "online":
|
|
4344
|
-
decision = await verifyOnline(this.config, context, astraId);
|
|
4579
|
+
decision = await verifyOnline(this.config, context, astraId ?? this.config.agentId);
|
|
4345
4580
|
break;
|
|
4346
4581
|
case "local":
|
|
4347
4582
|
if (!this.evaluator) throw new Error("Local evaluator not initialized");
|