grix-connector 4.0.2 → 4.2.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/acp/acp-adapter.js +3 -3
- package/dist/adapter/acp/session-activity.js +1 -1
- package/dist/adapter/claude/claude-bridge-server.js +1 -0
- package/dist/adapter/claude/claude-tools.js +1 -0
- package/dist/adapter/claude/claude-worker-client.js +1 -0
- package/dist/adapter/claude/mcp-http-launcher.js +2 -0
- package/dist/adapter/claude/result-timeout.js +1 -0
- package/dist/adapter/deepseek/deepseek-adapter.js +6 -0
- package/dist/adapter/deepseek/index.js +1 -0
- package/dist/adapter/qwen/index.js +1 -0
- package/dist/adapter/qwen/qwen-adapter.js +4 -0
- package/dist/aibot/client.js +1 -0
- package/dist/aibot/index.js +1 -0
- package/dist/aibot/types.js +0 -0
- package/dist/assets/dsh-bridge/grix-dsh-bridge-4.2.0.tgz +0 -0
- package/dist/assets/dsh-bridge/manifest.json +5 -5
- package/dist/audit/adapters/agy/agy-audit-adapter.js +1 -1
- package/dist/audit/adapters/agy/agy-gen-metadata.js +1 -0
- package/dist/bridge/bridge.js +7 -7
- package/dist/bridge/lifecycle-barrier.js +1 -1
- package/dist/core/access/allowlist-gate.js +1 -0
- package/dist/core/access/allowlist-store.js +1 -0
- package/dist/core/access/index.js +1 -0
- package/dist/core/aibot/connection-manager.js +1 -1
- package/dist/core/config/agent-config-repository.js +2 -0
- package/dist/core/file-ops/handler.js +1 -0
- package/dist/core/file-ops/list-files.js +1 -0
- package/dist/core/file-ops/types.js +0 -0
- package/dist/core/installer/npm-registry.js +4 -4
- package/dist/core/runtime/health.js +1 -1
- package/dist/core/skill-sync/skill-syncer.js +1 -1
- package/dist/core/upgrade/npm-upgrader.js +2 -2
- package/dist/core/upgrade/upgrade-checker.js +1 -1
- package/dist/default-skills/grix-agent-dispatch/SKILL.md +9 -9
- package/dist/grix.js +7 -7
- package/dist/log.js +3 -0
- package/dist/main.js +31 -0
- package/dist/manager.js +1 -2
- package/dist/mcp/stream-http/config.js +1 -0
- package/dist/mcp/stream-http/connection-binding.js +1 -0
- package/dist/mcp/stream-http/event-tool-executor.js +1 -0
- package/dist/mcp/stream-http/gateway.js +1 -0
- package/dist/mcp/stream-http/index.js +1 -0
- package/dist/mcp/stream-http/security.js +1 -0
- package/dist/mcp/stream-http/session-manager.js +1 -0
- package/dist/mcp/stream-http/tool-executor.js +1 -0
- package/dist/mcp/stream-http/tool-registry.js +1 -0
- package/dist/mcp/stream-http/tool-schemas.js +1 -0
- package/dist/service/platform-adapter.js +25 -24
- package/dist/service/process-control.js +1 -1
- package/dist/service/service-manager.js +3 -3
- package/dist/service/service-paths.js +2 -2
- package/dist/service/windows-wrapper-migration.js +1 -0
- package/dist/session/index.js +1 -0
- package/dist/session/manager.js +1 -0
- package/dist/transport/index.js +1 -0
- package/dist/transport/json-rpc.js +3 -0
- package/openclaw-plugin/audit-recorder-worker.js +496 -54
- package/package.json +2 -1
- package/scripts/install-guardian.mjs +35 -19
- package/scripts/upgrade-guardian.mjs +1345 -0
- package/scripts/upgrade-guardian.sh +100 -75
- package/dist/assets/dsh-bridge/grix-dsh-bridge-4.0.2.tgz +0 -0
|
@@ -773,9 +773,9 @@ async function collectClaudeTranscript(boundary, includeSubagents) {
|
|
|
773
773
|
}
|
|
774
774
|
const subagentRoot = typeof boundary.subagentRoot === "string" ? boundary.subagentRoot : void 0;
|
|
775
775
|
if (!includeSubagents || !subagentRoot) return evidence;
|
|
776
|
-
let
|
|
776
|
+
let paths2;
|
|
777
777
|
try {
|
|
778
|
-
|
|
778
|
+
paths2 = await findSubagentFiles(subagentRoot);
|
|
779
779
|
} catch (error) {
|
|
780
780
|
evidence.anomalies.push({
|
|
781
781
|
code: "claude_subagent_root_unreadable",
|
|
@@ -789,7 +789,7 @@ async function collectClaudeTranscript(boundary, includeSubagents) {
|
|
|
789
789
|
return evidence;
|
|
790
790
|
}
|
|
791
791
|
const offsets = isRecord(boundary.subagentOffsets) ? boundary.subagentOffsets : {};
|
|
792
|
-
for (const path of
|
|
792
|
+
for (const path of paths2) {
|
|
793
793
|
const fileBoundary = subagentBoundary(offsets[path] ?? offsets[basename(path)]);
|
|
794
794
|
const result = await readJsonlRange(
|
|
795
795
|
path,
|
|
@@ -1291,7 +1291,7 @@ function groupMessages(job, evidence, anomalies) {
|
|
|
1291
1291
|
});
|
|
1292
1292
|
continue;
|
|
1293
1293
|
}
|
|
1294
|
-
const
|
|
1294
|
+
const timestamp6 = asTimestamp(line.record.timestamp, job.startedAt);
|
|
1295
1295
|
let group = groups.get(messageId);
|
|
1296
1296
|
if (!group) {
|
|
1297
1297
|
group = {
|
|
@@ -1301,14 +1301,14 @@ function groupMessages(job, evidence, anomalies) {
|
|
|
1301
1301
|
sourcePath: line.sourcePath,
|
|
1302
1302
|
isSubagent: line.isSubagent,
|
|
1303
1303
|
promptId: targetPromptId,
|
|
1304
|
-
startedAt:
|
|
1305
|
-
endedAt:
|
|
1304
|
+
startedAt: timestamp6,
|
|
1305
|
+
endedAt: timestamp6,
|
|
1306
1306
|
samples: [],
|
|
1307
1307
|
blocks: []
|
|
1308
1308
|
};
|
|
1309
1309
|
groups.set(messageId, group);
|
|
1310
1310
|
} else {
|
|
1311
|
-
group.endedAt =
|
|
1311
|
+
group.endedAt = timestamp6;
|
|
1312
1312
|
if (typeof line.record.requestId === "string") {
|
|
1313
1313
|
group.requestId = line.record.requestId;
|
|
1314
1314
|
}
|
|
@@ -2299,9 +2299,9 @@ function stableHash(value) {
|
|
|
2299
2299
|
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
2300
2300
|
}
|
|
2301
2301
|
function observedAt(value) {
|
|
2302
|
-
const
|
|
2303
|
-
if (!
|
|
2304
|
-
return
|
|
2302
|
+
const timestamp6 = stringValue2(value);
|
|
2303
|
+
if (!timestamp6 || Number.isNaN(Date.parse(timestamp6))) return void 0;
|
|
2304
|
+
return timestamp6;
|
|
2305
2305
|
}
|
|
2306
2306
|
function captureOptions2(job) {
|
|
2307
2307
|
return job.options?.enabled === true ? job.options.capture : DEFAULT_CAPTURE2;
|
|
@@ -2816,7 +2816,7 @@ function toSpan(job, candidate, modelId) {
|
|
|
2816
2816
|
if (candidate.snapshotKey) {
|
|
2817
2817
|
nativeIds2.usageSnapshotId = stableHash(candidate.snapshotKey);
|
|
2818
2818
|
}
|
|
2819
|
-
const
|
|
2819
|
+
const timestamp6 = candidate.observedAt ?? job.startedAt;
|
|
2820
2820
|
return {
|
|
2821
2821
|
spanId: `codex-llm-${stableHash(`${job.traceId}|${nativeRequestId}`)}`,
|
|
2822
2822
|
traceId: job.traceId,
|
|
@@ -2827,8 +2827,8 @@ function toSpan(job, candidate, modelId) {
|
|
|
2827
2827
|
name: "codex response",
|
|
2828
2828
|
sequence: candidate.sequence,
|
|
2829
2829
|
status: "completed",
|
|
2830
|
-
startedAt:
|
|
2831
|
-
endedAt:
|
|
2830
|
+
startedAt: timestamp6,
|
|
2831
|
+
endedAt: timestamp6,
|
|
2832
2832
|
...modelId ? { modelId } : {},
|
|
2833
2833
|
inputRefs: [],
|
|
2834
2834
|
outputRefs: [],
|
|
@@ -4378,9 +4378,9 @@ function eventTime(value) {
|
|
|
4378
4378
|
}
|
|
4379
4379
|
return void 0;
|
|
4380
4380
|
}
|
|
4381
|
-
function withinTurn(
|
|
4382
|
-
if (!
|
|
4383
|
-
const at = Date.parse(
|
|
4381
|
+
function withinTurn(timestamp6, job) {
|
|
4382
|
+
if (!timestamp6) return false;
|
|
4383
|
+
const at = Date.parse(timestamp6);
|
|
4384
4384
|
return at >= Date.parse(job.startedAt) - 5e3 && at <= Date.parse(job.endedAt) + 3e4;
|
|
4385
4385
|
}
|
|
4386
4386
|
function contentText2(value) {
|
|
@@ -5023,8 +5023,8 @@ function lineEvent(line) {
|
|
|
5023
5023
|
return line.record.type === "context.append_loop_event" && isRecord7(line.record.event) ? line.record.event : void 0;
|
|
5024
5024
|
}
|
|
5025
5025
|
function withinTurn2(value, job) {
|
|
5026
|
-
const
|
|
5027
|
-
return Number.isFinite(
|
|
5026
|
+
const timestamp6 = Date.parse(isoTime(value, ""));
|
|
5027
|
+
return Number.isFinite(timestamp6) && timestamp6 >= Date.parse(job.startedAt) - 5e3 && timestamp6 <= Date.parse(job.endedAt) + 3e4;
|
|
5028
5028
|
}
|
|
5029
5029
|
async function readJsonl2(sourcePath) {
|
|
5030
5030
|
const raw = await readFile4(sourcePath, "utf8");
|
|
@@ -8059,7 +8059,7 @@ var DeepSeekHarnessAuditAdapter = class {
|
|
|
8059
8059
|
const mapped = mapDshSessionEvent(event);
|
|
8060
8060
|
const eventSessionId = String(event.sessionId ?? "");
|
|
8061
8061
|
const isChild = !!eventSessionId && !!rootSessionId && eventSessionId !== rootSessionId;
|
|
8062
|
-
const
|
|
8062
|
+
const timestamp6 = iso(record4.at, job.startedAt);
|
|
8063
8063
|
if (mapped.kind === "thinking") {
|
|
8064
8064
|
if (capture.thinking && mapped.text) {
|
|
8065
8065
|
addContent10(contents, { role: "thinking", format: "text", value: mapped.text, captureLevel: "runtime_exact" });
|
|
@@ -8134,9 +8134,9 @@ var DeepSeekHarnessAuditAdapter = class {
|
|
|
8134
8134
|
continue;
|
|
8135
8135
|
}
|
|
8136
8136
|
tool.span.status = mapped.isError ? "failed" : "completed";
|
|
8137
|
-
tool.span.endedAt =
|
|
8137
|
+
tool.span.endedAt = timestamp6;
|
|
8138
8138
|
const startMs = Date.parse(tool.span.startedAt);
|
|
8139
|
-
const endMs = Date.parse(
|
|
8139
|
+
const endMs = Date.parse(timestamp6);
|
|
8140
8140
|
if (Number.isFinite(startMs) && Number.isFinite(endMs)) {
|
|
8141
8141
|
tool.span.durationMs = Math.max(0, endMs - startMs);
|
|
8142
8142
|
}
|
|
@@ -8234,7 +8234,7 @@ function turnSpan(job, spanId) {
|
|
|
8234
8234
|
};
|
|
8235
8235
|
}
|
|
8236
8236
|
function simpleSpan(job, parentSpanId, sequence, kind, name, at, nativeIds2) {
|
|
8237
|
-
const
|
|
8237
|
+
const timestamp6 = iso(at, job.startedAt);
|
|
8238
8238
|
return {
|
|
8239
8239
|
spanId: `deepseek-harness:${job.turnId}:${sequence}`,
|
|
8240
8240
|
traceId: job.traceId,
|
|
@@ -8245,8 +8245,8 @@ function simpleSpan(job, parentSpanId, sequence, kind, name, at, nativeIds2) {
|
|
|
8245
8245
|
name,
|
|
8246
8246
|
sequence,
|
|
8247
8247
|
status: "completed",
|
|
8248
|
-
startedAt:
|
|
8249
|
-
endedAt:
|
|
8248
|
+
startedAt: timestamp6,
|
|
8249
|
+
endedAt: timestamp6,
|
|
8250
8250
|
inputRefs: [],
|
|
8251
8251
|
outputRefs: [],
|
|
8252
8252
|
provider: { provider: "deepseek-harness", nativeEventType: name, nativeIds: nativeIds2 },
|
|
@@ -8306,6 +8306,387 @@ function usageSpan(job, parentSpanId, sequence, at, raw, requestId2, modelId, pr
|
|
|
8306
8306
|
|
|
8307
8307
|
// src/audit/adapters/agy/agy-audit-adapter.ts
|
|
8308
8308
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
8309
|
+
|
|
8310
|
+
// src/audit/adapters/agy/agy-gen-metadata.ts
|
|
8311
|
+
import { homedir as homedir4 } from "node:os";
|
|
8312
|
+
import { join as join6 } from "node:path";
|
|
8313
|
+
|
|
8314
|
+
// src/core/util/sqlite-reader.ts
|
|
8315
|
+
import { createRequire } from "node:module";
|
|
8316
|
+
|
|
8317
|
+
// src/core/log/logger.ts
|
|
8318
|
+
import { createWriteStream, mkdirSync, existsSync, readdirSync, statSync, unlinkSync } from "node:fs";
|
|
8319
|
+
import { join as join5 } from "node:path";
|
|
8320
|
+
|
|
8321
|
+
// src/core/config/paths.ts
|
|
8322
|
+
import { join as join4 } from "node:path";
|
|
8323
|
+
import { homedir as homedir3 } from "node:os";
|
|
8324
|
+
var GRIX_HOME_ENV = "GRIX_CONNECTOR_HOME";
|
|
8325
|
+
var DEFAULT_GRIX_HOME = join4(homedir3(), ".grix");
|
|
8326
|
+
function resolveRuntimePaths(runtimeDir) {
|
|
8327
|
+
const rootDir = runtimeDir ? runtimeDir : process.env[GRIX_HOME_ENV] ? process.env[GRIX_HOME_ENV] : DEFAULT_GRIX_HOME;
|
|
8328
|
+
return {
|
|
8329
|
+
rootDir,
|
|
8330
|
+
configDir: join4(rootDir, "config"),
|
|
8331
|
+
logDir: join4(rootDir, "log"),
|
|
8332
|
+
dataDir: join4(rootDir, "data"),
|
|
8333
|
+
serviceDir: join4(rootDir, "service"),
|
|
8334
|
+
skillsDir: join4(rootDir, "skills"),
|
|
8335
|
+
stateFile: join4(rootDir, "service.json"),
|
|
8336
|
+
pidFile: join4(rootDir, "grix-connector.pid"),
|
|
8337
|
+
daemonLockFile: join4(rootDir, "daemon.lock.json"),
|
|
8338
|
+
daemonStatusFile: join4(rootDir, "daemon-status.json"),
|
|
8339
|
+
stdoutLogFile: join4(rootDir, "service", "daemon.out.log"),
|
|
8340
|
+
stderrLogFile: join4(rootDir, "service", "daemon.err.log"),
|
|
8341
|
+
contextsDir: join4(rootDir, "data", "session-contexts"),
|
|
8342
|
+
hookSignalsPath: join4(rootDir, "data", "hook-signals.json"),
|
|
8343
|
+
hookSignalsLogPath: join4(rootDir, "log", "hook-signals.log"),
|
|
8344
|
+
elicitationRequestsDir: join4(rootDir, "data", "elicitation-requests"),
|
|
8345
|
+
eventStatesDir: join4(rootDir, "data", "event-states"),
|
|
8346
|
+
questionRequestsDir: join4(rootDir, "data", "question-requests"),
|
|
8347
|
+
permissionRequestsDir: join4(rootDir, "data", "permission-requests"),
|
|
8348
|
+
agentGlobalConfigsFile: join4(rootDir, "data", "agent-global-configs.json")
|
|
8349
|
+
};
|
|
8350
|
+
}
|
|
8351
|
+
|
|
8352
|
+
// src/core/log/logger.ts
|
|
8353
|
+
var paths = resolveRuntimePaths();
|
|
8354
|
+
var GRIX_PATHS = {
|
|
8355
|
+
base: paths.rootDir,
|
|
8356
|
+
config: paths.configDir,
|
|
8357
|
+
log: paths.logDir,
|
|
8358
|
+
data: paths.dataDir,
|
|
8359
|
+
skills: paths.skillsDir
|
|
8360
|
+
};
|
|
8361
|
+
var LEVEL_PRIORITY = {
|
|
8362
|
+
trace: 0,
|
|
8363
|
+
debug: 1,
|
|
8364
|
+
info: 2,
|
|
8365
|
+
warn: 3,
|
|
8366
|
+
error: 4
|
|
8367
|
+
};
|
|
8368
|
+
function parseLevel(raw, fallback) {
|
|
8369
|
+
if (!raw) return fallback;
|
|
8370
|
+
const lower = raw.trim().toLowerCase();
|
|
8371
|
+
return lower in LEVEL_PRIORITY ? lower : fallback;
|
|
8372
|
+
}
|
|
8373
|
+
function parseTagOverrides(env) {
|
|
8374
|
+
const map = /* @__PURE__ */ new Map();
|
|
8375
|
+
if (!env) return map;
|
|
8376
|
+
for (const pair of env.split(",")) {
|
|
8377
|
+
const eq = pair.indexOf("=");
|
|
8378
|
+
if (eq < 0) continue;
|
|
8379
|
+
const tag = pair.slice(0, eq).trim();
|
|
8380
|
+
const level = parseLevel(pair.slice(eq + 1), "info");
|
|
8381
|
+
if (tag) map.set(tag, level);
|
|
8382
|
+
}
|
|
8383
|
+
return map;
|
|
8384
|
+
}
|
|
8385
|
+
var globalLevel = parseLevel(process.env.GRIX_CONNECTOR_LOG_LEVEL, "info");
|
|
8386
|
+
var tagOverrides = parseTagOverrides(process.env.GRIX_CONNECTOR_LOG_TAG_LEVELS);
|
|
8387
|
+
function effectiveLevel(tag) {
|
|
8388
|
+
return tagOverrides.get(tag) ?? globalLevel;
|
|
8389
|
+
}
|
|
8390
|
+
function shouldLog(tag, level) {
|
|
8391
|
+
return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[effectiveLevel(tag)];
|
|
8392
|
+
}
|
|
8393
|
+
var logStream = null;
|
|
8394
|
+
var currentLogDate = "";
|
|
8395
|
+
var LOG_RETENTION_DAYS_ENV = "GRIX_CONNECTOR_LOG_RETENTION_DAYS";
|
|
8396
|
+
var DEFAULT_LOG_RETENTION_DAYS = 14;
|
|
8397
|
+
function resolveRetentionDays() {
|
|
8398
|
+
const raw = process.env[LOG_RETENTION_DAYS_ENV];
|
|
8399
|
+
const n2 = raw ? Number.parseInt(raw, 10) : Number.NaN;
|
|
8400
|
+
return Number.isFinite(n2) && n2 > 0 ? n2 : DEFAULT_LOG_RETENTION_DAYS;
|
|
8401
|
+
}
|
|
8402
|
+
function currentDate() {
|
|
8403
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8404
|
+
}
|
|
8405
|
+
function cleanupOldLogs() {
|
|
8406
|
+
const cutoff = Date.now() - resolveRetentionDays() * 24 * 60 * 60 * 1e3;
|
|
8407
|
+
let entries;
|
|
8408
|
+
try {
|
|
8409
|
+
entries = readdirSync(GRIX_PATHS.log);
|
|
8410
|
+
} catch {
|
|
8411
|
+
return;
|
|
8412
|
+
}
|
|
8413
|
+
for (const name of entries) {
|
|
8414
|
+
if (!name.startsWith("grix-connector-") || !name.includes(".log")) continue;
|
|
8415
|
+
const full = join5(GRIX_PATHS.log, name);
|
|
8416
|
+
try {
|
|
8417
|
+
if (statSync(full).mtimeMs < cutoff) unlinkSync(full);
|
|
8418
|
+
} catch {
|
|
8419
|
+
}
|
|
8420
|
+
}
|
|
8421
|
+
}
|
|
8422
|
+
function openLogStream(date) {
|
|
8423
|
+
try {
|
|
8424
|
+
logStream?.end();
|
|
8425
|
+
} catch {
|
|
8426
|
+
}
|
|
8427
|
+
const logFile = join5(GRIX_PATHS.log, `grix-connector-${date}.log`);
|
|
8428
|
+
logStream = createWriteStream(logFile, { flags: "a" });
|
|
8429
|
+
currentLogDate = date;
|
|
8430
|
+
cleanupOldLogs();
|
|
8431
|
+
}
|
|
8432
|
+
function timestamp4() {
|
|
8433
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
|
|
8434
|
+
}
|
|
8435
|
+
var consoleEnabled = true;
|
|
8436
|
+
function emitConsole(level, line) {
|
|
8437
|
+
if (!consoleEnabled) return;
|
|
8438
|
+
if (level === "warn") console.warn(line);
|
|
8439
|
+
else if (level === "error") console.error(line);
|
|
8440
|
+
else console.log(line);
|
|
8441
|
+
}
|
|
8442
|
+
function safeWrite(line) {
|
|
8443
|
+
try {
|
|
8444
|
+
const date = currentDate();
|
|
8445
|
+
if (date !== currentLogDate) openLogStream(date);
|
|
8446
|
+
logStream?.write(line);
|
|
8447
|
+
} catch {
|
|
8448
|
+
}
|
|
8449
|
+
}
|
|
8450
|
+
function formatLine(level, tag, msg, args) {
|
|
8451
|
+
const levelStr = level === "info" ? "" : `${level.toUpperCase()} `;
|
|
8452
|
+
return `${timestamp4()} [${tag}] ${levelStr}${msg}${args.length ? " " + args.map(String).join(" ") : ""}`;
|
|
8453
|
+
}
|
|
8454
|
+
var log = {
|
|
8455
|
+
trace(tag, msg, ...args) {
|
|
8456
|
+
if (!shouldLog(tag, "trace")) return;
|
|
8457
|
+
const line = formatLine("trace", tag, msg, args);
|
|
8458
|
+
emitConsole("trace", line);
|
|
8459
|
+
safeWrite(line + "\n");
|
|
8460
|
+
},
|
|
8461
|
+
debug(tag, msg, ...args) {
|
|
8462
|
+
if (!shouldLog(tag, "debug")) return;
|
|
8463
|
+
const line = formatLine("debug", tag, msg, args);
|
|
8464
|
+
emitConsole("debug", line);
|
|
8465
|
+
safeWrite(line + "\n");
|
|
8466
|
+
},
|
|
8467
|
+
info(tag, msg, ...args) {
|
|
8468
|
+
if (!shouldLog(tag, "info")) return;
|
|
8469
|
+
const line = formatLine("info", tag, msg, args);
|
|
8470
|
+
emitConsole("info", line);
|
|
8471
|
+
safeWrite(line + "\n");
|
|
8472
|
+
},
|
|
8473
|
+
warn(tag, msg, ...args) {
|
|
8474
|
+
if (!shouldLog(tag, "warn")) return;
|
|
8475
|
+
const line = formatLine("warn", tag, msg, args);
|
|
8476
|
+
emitConsole("warn", line);
|
|
8477
|
+
safeWrite(line + "\n");
|
|
8478
|
+
},
|
|
8479
|
+
error(tag, msg, ...args) {
|
|
8480
|
+
if (!shouldLog(tag, "error")) return;
|
|
8481
|
+
const line = formatLine("error", tag, msg, args);
|
|
8482
|
+
emitConsole("error", line);
|
|
8483
|
+
safeWrite(line + "\n");
|
|
8484
|
+
}
|
|
8485
|
+
};
|
|
8486
|
+
|
|
8487
|
+
// src/core/log/rotation.ts
|
|
8488
|
+
var DEFAULT_LOG_MAX_BYTES = 10 * 1024 * 1024;
|
|
8489
|
+
|
|
8490
|
+
// src/core/log/packet-log.ts
|
|
8491
|
+
var DEFAULT_MAX_BYTES = 128 * 1024 * 1024;
|
|
8492
|
+
|
|
8493
|
+
// src/core/util/sqlite-reader.ts
|
|
8494
|
+
var cachedCtor;
|
|
8495
|
+
function loadDatabaseSync() {
|
|
8496
|
+
if (cachedCtor !== void 0) return cachedCtor;
|
|
8497
|
+
try {
|
|
8498
|
+
const require2 = createRequire(import.meta.url);
|
|
8499
|
+
cachedCtor = require2("node:sqlite").DatabaseSync;
|
|
8500
|
+
} catch {
|
|
8501
|
+
cachedCtor = null;
|
|
8502
|
+
log.warn(
|
|
8503
|
+
"sqlite-reader",
|
|
8504
|
+
`node:sqlite unavailable on Node ${process.version}; sessions stored in sqlite (cursor/opencode) will not be listed`
|
|
8505
|
+
);
|
|
8506
|
+
}
|
|
8507
|
+
return cachedCtor;
|
|
8508
|
+
}
|
|
8509
|
+
function openReadOnlyDatabase(dbPath) {
|
|
8510
|
+
const DatabaseSync = loadDatabaseSync();
|
|
8511
|
+
if (!DatabaseSync) return null;
|
|
8512
|
+
try {
|
|
8513
|
+
const db = new DatabaseSync(dbPath, { readOnly: true });
|
|
8514
|
+
return {
|
|
8515
|
+
all(sql, ...params) {
|
|
8516
|
+
return db.prepare(sql).all(...params);
|
|
8517
|
+
},
|
|
8518
|
+
close() {
|
|
8519
|
+
try {
|
|
8520
|
+
db.close();
|
|
8521
|
+
} catch {
|
|
8522
|
+
}
|
|
8523
|
+
}
|
|
8524
|
+
};
|
|
8525
|
+
} catch {
|
|
8526
|
+
return null;
|
|
8527
|
+
}
|
|
8528
|
+
}
|
|
8529
|
+
|
|
8530
|
+
// src/audit/adapters/agy/agy-gen-metadata.ts
|
|
8531
|
+
function resolveAgyAntigravityHome() {
|
|
8532
|
+
return process.env.GRIX_AGY_ANTIGRAVITY_HOME ?? join6(homedir4(), ".gemini", "antigravity-cli");
|
|
8533
|
+
}
|
|
8534
|
+
function extractAgyResponseIds(logExcerpt) {
|
|
8535
|
+
const ids = [];
|
|
8536
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8537
|
+
for (const line of logExcerpt.split(/\r?\n/)) {
|
|
8538
|
+
if (!line.includes("streamGenerateContent")) continue;
|
|
8539
|
+
const match = /ResponseID: (\S+)/.exec(line);
|
|
8540
|
+
if (!match) continue;
|
|
8541
|
+
const id = match[1];
|
|
8542
|
+
if (!seen.has(id)) {
|
|
8543
|
+
seen.add(id);
|
|
8544
|
+
ids.push(id);
|
|
8545
|
+
}
|
|
8546
|
+
}
|
|
8547
|
+
return ids;
|
|
8548
|
+
}
|
|
8549
|
+
function readVarint(buf, pos) {
|
|
8550
|
+
let value = 0n;
|
|
8551
|
+
let shift = 0n;
|
|
8552
|
+
let cursor = pos;
|
|
8553
|
+
for (; ; ) {
|
|
8554
|
+
if (cursor >= buf.length || shift > 63n) throw new Error("bad varint");
|
|
8555
|
+
const byte = buf[cursor];
|
|
8556
|
+
value |= BigInt(byte & 127) << shift;
|
|
8557
|
+
cursor += 1;
|
|
8558
|
+
if ((byte & 128) === 0) return { value, next: cursor };
|
|
8559
|
+
shift += 7n;
|
|
8560
|
+
}
|
|
8561
|
+
}
|
|
8562
|
+
function parseProtoFields(buf) {
|
|
8563
|
+
const fields = [];
|
|
8564
|
+
let pos = 0;
|
|
8565
|
+
while (pos < buf.length) {
|
|
8566
|
+
const tag = readVarint(buf, pos);
|
|
8567
|
+
pos = tag.next;
|
|
8568
|
+
const field2 = Number(tag.value >> 3n);
|
|
8569
|
+
const wire = Number(tag.value & 0x7n);
|
|
8570
|
+
if (field2 <= 0) throw new Error("bad field number");
|
|
8571
|
+
if (wire === 0) {
|
|
8572
|
+
const v = readVarint(buf, pos);
|
|
8573
|
+
pos = v.next;
|
|
8574
|
+
fields.push({ field: field2, wire, varint: v.value });
|
|
8575
|
+
} else if (wire === 2) {
|
|
8576
|
+
const len = readVarint(buf, pos);
|
|
8577
|
+
pos = len.next;
|
|
8578
|
+
const end = pos + Number(len.value);
|
|
8579
|
+
if (end > buf.length) throw new Error("bad length");
|
|
8580
|
+
fields.push({ field: field2, wire, bytes: buf.subarray(pos, end) });
|
|
8581
|
+
pos = end;
|
|
8582
|
+
} else if (wire === 5) {
|
|
8583
|
+
pos += 4;
|
|
8584
|
+
if (pos > buf.length) throw new Error("bad fixed32");
|
|
8585
|
+
} else if (wire === 1) {
|
|
8586
|
+
pos += 8;
|
|
8587
|
+
if (pos > buf.length) throw new Error("bad fixed64");
|
|
8588
|
+
} else {
|
|
8589
|
+
throw new Error(`unsupported wire type ${wire}`);
|
|
8590
|
+
}
|
|
8591
|
+
}
|
|
8592
|
+
return fields;
|
|
8593
|
+
}
|
|
8594
|
+
function firstMessage(fields, fieldNumber) {
|
|
8595
|
+
const field2 = fields.find((item) => item.field === fieldNumber && item.wire === 2);
|
|
8596
|
+
if (!field2?.bytes) return void 0;
|
|
8597
|
+
try {
|
|
8598
|
+
return parseProtoFields(field2.bytes);
|
|
8599
|
+
} catch {
|
|
8600
|
+
return void 0;
|
|
8601
|
+
}
|
|
8602
|
+
}
|
|
8603
|
+
function firstVarint(fields, fieldNumber) {
|
|
8604
|
+
const field2 = fields.find((item) => item.field === fieldNumber && item.wire === 0);
|
|
8605
|
+
if (field2?.varint === void 0) return void 0;
|
|
8606
|
+
if (field2.varint < 0n || field2.varint > 0xffffffffn) return void 0;
|
|
8607
|
+
return Number(field2.varint);
|
|
8608
|
+
}
|
|
8609
|
+
var RESPONSE_ID_PATTERN = /^[\x21-\x7e]{8,64}$/;
|
|
8610
|
+
function tryDecodeUtf8(bytes) {
|
|
8611
|
+
try {
|
|
8612
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
8613
|
+
} catch {
|
|
8614
|
+
return void 0;
|
|
8615
|
+
}
|
|
8616
|
+
}
|
|
8617
|
+
function firstString(fields, fieldNumber, pattern) {
|
|
8618
|
+
const field2 = fields.find((item) => item.field === fieldNumber && item.wire === 2);
|
|
8619
|
+
if (!field2?.bytes) return void 0;
|
|
8620
|
+
const value = tryDecodeUtf8(field2.bytes);
|
|
8621
|
+
if (value === void 0) return void 0;
|
|
8622
|
+
if (pattern && !pattern.test(value)) return void 0;
|
|
8623
|
+
return value;
|
|
8624
|
+
}
|
|
8625
|
+
function decodeAgyGenMetadata(data) {
|
|
8626
|
+
try {
|
|
8627
|
+
const top = parseProtoFields(data);
|
|
8628
|
+
const record4 = firstMessage(top, 1);
|
|
8629
|
+
if (!record4) return void 0;
|
|
8630
|
+
const usage = firstMessage(record4, 4);
|
|
8631
|
+
if (!usage) return void 0;
|
|
8632
|
+
const responseId = firstString(usage, 11, RESPONSE_ID_PATTERN);
|
|
8633
|
+
if (!responseId) return void 0;
|
|
8634
|
+
return {
|
|
8635
|
+
responseId,
|
|
8636
|
+
inputTokens: firstVarint(usage, 2),
|
|
8637
|
+
outputTokens: firstVarint(usage, 3),
|
|
8638
|
+
model: firstString(record4, 19)
|
|
8639
|
+
};
|
|
8640
|
+
} catch {
|
|
8641
|
+
return void 0;
|
|
8642
|
+
}
|
|
8643
|
+
}
|
|
8644
|
+
var SAFE_CONVERSATION_ID = /^[a-zA-Z0-9._-]+$/;
|
|
8645
|
+
function readAgyTurnUsage(conversationId, responseIds) {
|
|
8646
|
+
if (!SAFE_CONVERSATION_ID.test(conversationId) || responseIds.length === 0) {
|
|
8647
|
+
return null;
|
|
8648
|
+
}
|
|
8649
|
+
const dbPath = join6(
|
|
8650
|
+
resolveAgyAntigravityHome(),
|
|
8651
|
+
"conversations",
|
|
8652
|
+
`${conversationId}.db`
|
|
8653
|
+
);
|
|
8654
|
+
const db = openReadOnlyDatabase(dbPath);
|
|
8655
|
+
if (!db) return null;
|
|
8656
|
+
try {
|
|
8657
|
+
const wanted = new Set(responseIds);
|
|
8658
|
+
const rows = db.all(
|
|
8659
|
+
"SELECT idx, data FROM gen_metadata"
|
|
8660
|
+
);
|
|
8661
|
+
const byResponseId = /* @__PURE__ */ new Map();
|
|
8662
|
+
let model;
|
|
8663
|
+
for (const row of rows) {
|
|
8664
|
+
if (!(row.data instanceof Uint8Array)) continue;
|
|
8665
|
+
const decoded = decodeAgyGenMetadata(row.data);
|
|
8666
|
+
if (!decoded || !wanted.has(decoded.responseId)) continue;
|
|
8667
|
+
const existing = byResponseId.get(decoded.responseId);
|
|
8668
|
+
if (existing && existing.idx >= row.idx) continue;
|
|
8669
|
+
byResponseId.set(decoded.responseId, {
|
|
8670
|
+
idx: row.idx,
|
|
8671
|
+
responseId: decoded.responseId,
|
|
8672
|
+
inputTokens: decoded.inputTokens ?? null,
|
|
8673
|
+
outputTokens: decoded.outputTokens ?? null
|
|
8674
|
+
});
|
|
8675
|
+
model ??= decoded.model;
|
|
8676
|
+
}
|
|
8677
|
+
if (byResponseId.size === 0) return null;
|
|
8678
|
+
const records = Array.from(byResponseId.values()).sort(
|
|
8679
|
+
(left, right) => left.idx - right.idx
|
|
8680
|
+
);
|
|
8681
|
+
return { records, ...model ? { model } : {} };
|
|
8682
|
+
} catch {
|
|
8683
|
+
return null;
|
|
8684
|
+
} finally {
|
|
8685
|
+
db.close();
|
|
8686
|
+
}
|
|
8687
|
+
}
|
|
8688
|
+
|
|
8689
|
+
// src/audit/adapters/agy/agy-audit-adapter.ts
|
|
8309
8690
|
var DEFAULT_CAPTURE11 = Object.freeze({
|
|
8310
8691
|
inputOutput: true,
|
|
8311
8692
|
tools: true,
|
|
@@ -8339,7 +8720,7 @@ function append5(target, reference) {
|
|
|
8339
8720
|
target.push(reference);
|
|
8340
8721
|
}
|
|
8341
8722
|
}
|
|
8342
|
-
function
|
|
8723
|
+
function timestamp5(value, fallback) {
|
|
8343
8724
|
return typeof value === "string" && Number.isFinite(Date.parse(value)) ? value : fallback;
|
|
8344
8725
|
}
|
|
8345
8726
|
function makeSpan8(input) {
|
|
@@ -8392,6 +8773,51 @@ function parseToolInvocation(value) {
|
|
|
8392
8773
|
...typeof value.completedAt === "string" ? { completedAt: value.completedAt } : {}
|
|
8393
8774
|
};
|
|
8394
8775
|
}
|
|
8776
|
+
function agyUsage(evidence) {
|
|
8777
|
+
const records = evidence.usageRecords;
|
|
8778
|
+
if (!records || records.length === 0) return void 0;
|
|
8779
|
+
let input = 0;
|
|
8780
|
+
let output = 0;
|
|
8781
|
+
for (const record4 of records) {
|
|
8782
|
+
input += record4.inputTokens ?? 0;
|
|
8783
|
+
output += record4.outputTokens ?? 0;
|
|
8784
|
+
}
|
|
8785
|
+
const hasNullTokenRecord = records.some(
|
|
8786
|
+
(record4) => record4.inputTokens === null && record4.outputTokens === null
|
|
8787
|
+
);
|
|
8788
|
+
const complete = evidence.usageExpectedCount !== void 0 && records.length === evidence.usageExpectedCount && !hasNullTokenRecord;
|
|
8789
|
+
return {
|
|
8790
|
+
input: {
|
|
8791
|
+
total: input,
|
|
8792
|
+
uncached: null,
|
|
8793
|
+
cacheRead: null,
|
|
8794
|
+
cacheWrite: null,
|
|
8795
|
+
other: null
|
|
8796
|
+
},
|
|
8797
|
+
output: {
|
|
8798
|
+
total: output,
|
|
8799
|
+
reasoning: null,
|
|
8800
|
+
visible: null
|
|
8801
|
+
},
|
|
8802
|
+
totalProcessed: input + output,
|
|
8803
|
+
requestCount: records.length,
|
|
8804
|
+
accuracy: "provider_reported",
|
|
8805
|
+
completeness: complete ? "complete" : "partial",
|
|
8806
|
+
provider: "agy",
|
|
8807
|
+
providerUsageRaw: records,
|
|
8808
|
+
normalization: {
|
|
8809
|
+
adapter: "agy-gen-metadata",
|
|
8810
|
+
version: 1,
|
|
8811
|
+
formula: "sum of per-generation input_tokens/output_tokens from the agy conversation sqlite gen_metadata table, matched to this turn by streamGenerateContent ResponseID"
|
|
8812
|
+
}
|
|
8813
|
+
};
|
|
8814
|
+
}
|
|
8815
|
+
function agyUsageGapDetail(evidence) {
|
|
8816
|
+
if (evidence.usageExpectedCount === void 0) {
|
|
8817
|
+
return "agy gen_metadata extraction skipped: conversation id or streamGenerateContent log excerpt unavailable";
|
|
8818
|
+
}
|
|
8819
|
+
return `agy gen_metadata extraction found no matching rows for ${evidence.usageExpectedCount} ResponseID(s)`;
|
|
8820
|
+
}
|
|
8395
8821
|
var AgyAuditAdapter = class {
|
|
8396
8822
|
provider = "agy";
|
|
8397
8823
|
async collect(job) {
|
|
@@ -8465,6 +8891,16 @@ var AgyAuditAdapter = class {
|
|
|
8465
8891
|
});
|
|
8466
8892
|
}
|
|
8467
8893
|
}
|
|
8894
|
+
const conversationId = stringValue10(job.boundary.providerSessionId);
|
|
8895
|
+
const responseIds = evidence.logExcerpt ? extractAgyResponseIds(evidence.logExcerpt) : [];
|
|
8896
|
+
if (conversationId && responseIds.length > 0) {
|
|
8897
|
+
evidence.usageExpectedCount = responseIds.length;
|
|
8898
|
+
const usage = readAgyTurnUsage(conversationId, responseIds);
|
|
8899
|
+
if (usage) {
|
|
8900
|
+
evidence.usageRecords = usage.records;
|
|
8901
|
+
if (usage.model) evidence.usageModel = usage.model;
|
|
8902
|
+
}
|
|
8903
|
+
}
|
|
8468
8904
|
return evidence;
|
|
8469
8905
|
}
|
|
8470
8906
|
async normalize(job, rawEvidence) {
|
|
@@ -8558,8 +8994,8 @@ var AgyAuditAdapter = class {
|
|
|
8558
8994
|
name: invocation.action,
|
|
8559
8995
|
sequence: sequence++,
|
|
8560
8996
|
status: invocation.error ? "failed" : invocation.completedAt ? "completed" : "running",
|
|
8561
|
-
startedAt:
|
|
8562
|
-
endedAt:
|
|
8997
|
+
startedAt: timestamp5(invocation.observedAt, job.startedAt),
|
|
8998
|
+
endedAt: timestamp5(invocation.completedAt, job.endedAt),
|
|
8563
8999
|
nativeEventType: "grix_tool_invoke",
|
|
8564
9000
|
nativeIds: { toolSequence: String(invocation.sequence) },
|
|
8565
9001
|
rawAttributes: { toolInvocation: invocation }
|
|
@@ -8584,11 +9020,17 @@ var AgyAuditAdapter = class {
|
|
|
8584
9020
|
spans.push(tool);
|
|
8585
9021
|
}
|
|
8586
9022
|
}
|
|
8587
|
-
collection
|
|
8588
|
-
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
}
|
|
9023
|
+
const usage = agyUsage(collection);
|
|
9024
|
+
if (usage) {
|
|
9025
|
+
request.usage = usage;
|
|
9026
|
+
if (collection.usageModel) request.modelId = collection.usageModel;
|
|
9027
|
+
} else {
|
|
9028
|
+
collection.gaps.push({
|
|
9029
|
+
category: "provider_usage",
|
|
9030
|
+
reason: "provider_usage_missing",
|
|
9031
|
+
detail: agyUsageGapDetail(collection)
|
|
9032
|
+
});
|
|
9033
|
+
}
|
|
8592
9034
|
return {
|
|
8593
9035
|
spans,
|
|
8594
9036
|
contents,
|
|
@@ -8609,7 +9051,7 @@ var AgyAuditAdapter = class {
|
|
|
8609
9051
|
const inputComplete = !evidence.capture.inputOutput || job.input !== void 0 || evidence.collection.prompt !== void 0;
|
|
8610
9052
|
const outputComplete = !evidence.capture.inputOutput || job.finalOutput !== void 0 || requests.some((request) => request.outputRefs.length > 0);
|
|
8611
9053
|
const toolCallsComplete = !evidence.capture.tools || tools.every((tool) => tool.status !== "running");
|
|
8612
|
-
const usageComplete =
|
|
9054
|
+
const usageComplete = requests.length > 0 && requests.every((request) => request.usage?.completeness === "complete");
|
|
8613
9055
|
const gaps = [...evidence.collection.gaps];
|
|
8614
9056
|
if (evidence.capture.rawProviderBody) {
|
|
8615
9057
|
gaps.push({
|
|
@@ -8634,7 +9076,7 @@ var AgyAuditAdapter = class {
|
|
|
8634
9076
|
|
|
8635
9077
|
// src/audit/adapters/openclaw/openclaw-audit-adapter.ts
|
|
8636
9078
|
import { readFile as readFile6, readdir as readdir4, stat as stat7 } from "node:fs/promises";
|
|
8637
|
-
import { basename as basename6, dirname as dirname2, join as
|
|
9079
|
+
import { basename as basename6, dirname as dirname2, join as join7 } from "node:path";
|
|
8638
9080
|
function isRecord15(value) {
|
|
8639
9081
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8640
9082
|
}
|
|
@@ -8661,7 +9103,7 @@ async function resolveResetTranscriptPath(transcriptPath, expectedIdentity) {
|
|
|
8661
9103
|
const prefix = `${basename6(transcriptPath)}.reset`;
|
|
8662
9104
|
const candidates = (await readdir4(directory)).filter((entry) => entry.startsWith(prefix)).sort().reverse();
|
|
8663
9105
|
for (const entry of candidates) {
|
|
8664
|
-
const candidate =
|
|
9106
|
+
const candidate = join7(directory, entry);
|
|
8665
9107
|
if (await fileIdentity(candidate) === expectedIdentity) return candidate;
|
|
8666
9108
|
}
|
|
8667
9109
|
} catch {
|
|
@@ -8676,7 +9118,7 @@ async function resolveCurrentTranscriptPath(boundary) {
|
|
|
8676
9118
|
const parsed = JSON.parse(await readFile6(storePath, "utf8"));
|
|
8677
9119
|
if (!isRecord15(parsed) || !isRecord15(parsed[sessionKey])) return void 0;
|
|
8678
9120
|
const session = parsed[sessionKey];
|
|
8679
|
-
return typeof session.sessionFile === "string" ? session.sessionFile : typeof session.sessionId === "string" ?
|
|
9121
|
+
return typeof session.sessionFile === "string" ? session.sessionFile : typeof session.sessionId === "string" ? join7(dirname2(storePath), `${session.sessionId}.jsonl`) : void 0;
|
|
8680
9122
|
} catch {
|
|
8681
9123
|
return void 0;
|
|
8682
9124
|
}
|
|
@@ -8784,7 +9226,7 @@ import {
|
|
|
8784
9226
|
rm,
|
|
8785
9227
|
writeFile
|
|
8786
9228
|
} from "node:fs/promises";
|
|
8787
|
-
import { basename as basename7, dirname as dirname3, join as
|
|
9229
|
+
import { basename as basename7, dirname as dirname3, join as join8, relative, resolve as resolve3, sep as sep3 } from "node:path";
|
|
8788
9230
|
var SHA256_PATTERN = /^[a-f0-9]{64}$/;
|
|
8789
9231
|
var NO_CAPTURE = Object.freeze({
|
|
8790
9232
|
inputOutput: false,
|
|
@@ -8877,7 +9319,7 @@ var FileAuditReplayStore = class {
|
|
|
8877
9319
|
const replaySha256 = sha256(replayBytes);
|
|
8878
9320
|
const auditKey = idKey(replay.auditId);
|
|
8879
9321
|
const turnKey = idKey(replay.turnId);
|
|
8880
|
-
const replayPath =
|
|
9322
|
+
const replayPath = join8(
|
|
8881
9323
|
this.rootDir,
|
|
8882
9324
|
"replays",
|
|
8883
9325
|
auditKey,
|
|
@@ -8943,7 +9385,7 @@ var FileAuditReplayStore = class {
|
|
|
8943
9385
|
return this.readReplay(manifest);
|
|
8944
9386
|
}
|
|
8945
9387
|
async findByAuditId(auditId) {
|
|
8946
|
-
const directory =
|
|
9388
|
+
const directory = join8(
|
|
8947
9389
|
this.rootDir,
|
|
8948
9390
|
"manifests",
|
|
8949
9391
|
"by-audit",
|
|
@@ -8952,7 +9394,7 @@ var FileAuditReplayStore = class {
|
|
|
8952
9394
|
const names = await readDirectory(directory);
|
|
8953
9395
|
const replays = [];
|
|
8954
9396
|
for (const name of names.filter((item) => item.endsWith(".json")).sort()) {
|
|
8955
|
-
const manifest = await this.readManifest(
|
|
9397
|
+
const manifest = await this.readManifest(join8(directory, name));
|
|
8956
9398
|
if (!manifest || manifest.auditId !== auditId || manifestExpired(manifest)) {
|
|
8957
9399
|
continue;
|
|
8958
9400
|
}
|
|
@@ -8961,7 +9403,7 @@ var FileAuditReplayStore = class {
|
|
|
8961
9403
|
return sortReplays(replays);
|
|
8962
9404
|
}
|
|
8963
9405
|
async findByTurnId(turnId) {
|
|
8964
|
-
const directory =
|
|
9406
|
+
const directory = join8(
|
|
8965
9407
|
this.rootDir,
|
|
8966
9408
|
"indexes",
|
|
8967
9409
|
"by-turn",
|
|
@@ -8970,7 +9412,7 @@ var FileAuditReplayStore = class {
|
|
|
8970
9412
|
const names = await readDirectory(directory);
|
|
8971
9413
|
const replays = [];
|
|
8972
9414
|
for (const name of names.filter((item) => item.endsWith(".json")).sort()) {
|
|
8973
|
-
const entry = await this.readIndex(
|
|
9415
|
+
const entry = await this.readIndex(join8(directory, name));
|
|
8974
9416
|
if (!entry || entry.turnId !== turnId) continue;
|
|
8975
9417
|
const manifestPath = this.resolveStoredPath(entry.manifestPath);
|
|
8976
9418
|
const manifest = await this.readManifest(manifestPath);
|
|
@@ -9083,13 +9525,13 @@ var FileAuditReplayStore = class {
|
|
|
9083
9525
|
await mkdir(this.rootDir, { recursive: true, mode: 448 });
|
|
9084
9526
|
}
|
|
9085
9527
|
async currentManifests() {
|
|
9086
|
-
const root =
|
|
9528
|
+
const root = join8(this.rootDir, "manifests", "by-audit");
|
|
9087
9529
|
const manifests = [];
|
|
9088
9530
|
for (const auditKey of await readDirectory(root)) {
|
|
9089
|
-
const directory =
|
|
9531
|
+
const directory = join8(root, auditKey);
|
|
9090
9532
|
for (const name of await readDirectory(directory)) {
|
|
9091
9533
|
if (!name.endsWith(".json")) continue;
|
|
9092
|
-
const path =
|
|
9534
|
+
const path = join8(directory, name);
|
|
9093
9535
|
const manifest = await this.readManifest(path);
|
|
9094
9536
|
if (manifest) manifests.push({ path, manifest });
|
|
9095
9537
|
}
|
|
@@ -9097,7 +9539,7 @@ var FileAuditReplayStore = class {
|
|
|
9097
9539
|
return manifests;
|
|
9098
9540
|
}
|
|
9099
9541
|
async revisionManifests(manifest) {
|
|
9100
|
-
const directory =
|
|
9542
|
+
const directory = join8(
|
|
9101
9543
|
this.rootDir,
|
|
9102
9544
|
"manifests",
|
|
9103
9545
|
"revisions",
|
|
@@ -9107,7 +9549,7 @@ var FileAuditReplayStore = class {
|
|
|
9107
9549
|
const revisions = [];
|
|
9108
9550
|
for (const name of await readDirectory(directory)) {
|
|
9109
9551
|
if (!name.endsWith(".json")) continue;
|
|
9110
|
-
const revision = await this.readManifest(
|
|
9552
|
+
const revision = await this.readManifest(join8(directory, name));
|
|
9111
9553
|
if (revision) revisions.push(revision);
|
|
9112
9554
|
}
|
|
9113
9555
|
return revisions;
|
|
@@ -9119,14 +9561,14 @@ var FileAuditReplayStore = class {
|
|
|
9119
9561
|
rm(this.manifestPath(manifest.auditId, manifest.turnId), {
|
|
9120
9562
|
force: true
|
|
9121
9563
|
}),
|
|
9122
|
-
rm(
|
|
9564
|
+
rm(join8(
|
|
9123
9565
|
this.rootDir,
|
|
9124
9566
|
"manifests",
|
|
9125
9567
|
"revisions",
|
|
9126
9568
|
auditKey,
|
|
9127
9569
|
turnKey
|
|
9128
9570
|
), { recursive: true, force: true }),
|
|
9129
|
-
rm(
|
|
9571
|
+
rm(join8(this.rootDir, "replays", auditKey, turnKey), {
|
|
9130
9572
|
recursive: true,
|
|
9131
9573
|
force: true
|
|
9132
9574
|
}),
|
|
@@ -9180,7 +9622,7 @@ var FileAuditReplayStore = class {
|
|
|
9180
9622
|
async atomicWrite(path, body) {
|
|
9181
9623
|
const directory = dirname3(path);
|
|
9182
9624
|
await mkdir(directory, { recursive: true, mode: 448 });
|
|
9183
|
-
const temporary =
|
|
9625
|
+
const temporary = join8(
|
|
9184
9626
|
directory,
|
|
9185
9627
|
`.${basename7(path)}.${process.pid}.${randomUUID()}.tmp`
|
|
9186
9628
|
);
|
|
@@ -9192,7 +9634,7 @@ var FileAuditReplayStore = class {
|
|
|
9192
9634
|
}
|
|
9193
9635
|
}
|
|
9194
9636
|
manifestPath(auditId, turnId) {
|
|
9195
|
-
return
|
|
9637
|
+
return join8(
|
|
9196
9638
|
this.rootDir,
|
|
9197
9639
|
"manifests",
|
|
9198
9640
|
"by-audit",
|
|
@@ -9201,7 +9643,7 @@ var FileAuditReplayStore = class {
|
|
|
9201
9643
|
);
|
|
9202
9644
|
}
|
|
9203
9645
|
revisionManifestPath(auditId, turnId, revision) {
|
|
9204
|
-
return
|
|
9646
|
+
return join8(
|
|
9205
9647
|
this.rootDir,
|
|
9206
9648
|
"manifests",
|
|
9207
9649
|
"revisions",
|
|
@@ -9211,7 +9653,7 @@ var FileAuditReplayStore = class {
|
|
|
9211
9653
|
);
|
|
9212
9654
|
}
|
|
9213
9655
|
turnIndexPath(turnId, auditId) {
|
|
9214
|
-
return
|
|
9656
|
+
return join8(
|
|
9215
9657
|
this.rootDir,
|
|
9216
9658
|
"indexes",
|
|
9217
9659
|
"by-turn",
|
|
@@ -9220,7 +9662,7 @@ var FileAuditReplayStore = class {
|
|
|
9220
9662
|
);
|
|
9221
9663
|
}
|
|
9222
9664
|
blobPath(contentId) {
|
|
9223
|
-
return
|
|
9665
|
+
return join8(
|
|
9224
9666
|
this.rootDir,
|
|
9225
9667
|
"blobs",
|
|
9226
9668
|
"sha256",
|