@fml-inc/fml 0.8.13-rc.1 → 0.8.13-rc.2
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/.claude-plugin/plugin.json +1 -1
- package/README.md +42 -0
- package/dist/chunk-3RKICLMI.js +34 -0
- package/dist/{chunk-HVD2GMN3.js → chunk-56ABBKUE.js} +2 -2
- package/dist/chunk-74KOMQZO.js +505 -0
- package/dist/{chunk-4YLCUJ6C.js → chunk-AZSAAPRC.js} +20 -2
- package/dist/{chunk-IUFDFBU7.js → chunk-C4Z6RMQ5.js} +1 -1
- package/dist/chunk-F57IFY3K.js +21 -0
- package/dist/{chunk-5VP4C72Z.js → chunk-K2ANDHRQ.js} +1 -1
- package/dist/{chunk-U7SITLCL.js → chunk-LYKMU7QR.js} +185 -301
- package/dist/{chunk-3VN2SQTP.js → chunk-PVOZYFMP.js} +1 -1
- package/dist/cli.js +10 -9
- package/dist/hook-handler.js +32 -13
- package/dist/mcp/server.js +61 -2
- package/dist/observer-server.js +9 -8
- package/dist/pi/extension.js +788 -343
- package/dist/sync-cycle.js +4 -3
- package/package.json +1 -1
- package/dist/chunk-CSOFP7MT.js +0 -67
- package/dist/chunk-EX5J3MPG.js +0 -142
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
GIT_STATE_CACHE_FILENAME,
|
|
3
|
+
canonicalGitHubRepository,
|
|
4
|
+
createGitStateResolver,
|
|
5
|
+
parseGitState
|
|
6
|
+
} from "./chunk-74KOMQZO.js";
|
|
4
7
|
import {
|
|
5
8
|
FML_INSTALLATION_ID_FILE,
|
|
6
9
|
FML_OBSERVER_DIR,
|
|
@@ -186,10 +189,10 @@ function setSyncEnabled(settingsFile, enabled) {
|
|
|
186
189
|
}
|
|
187
190
|
|
|
188
191
|
// ../../packages/panopticon/src/artifacts.ts
|
|
189
|
-
import { createHash as
|
|
190
|
-
import
|
|
192
|
+
import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
|
|
193
|
+
import fs8 from "fs";
|
|
191
194
|
import os3 from "os";
|
|
192
|
-
import
|
|
195
|
+
import path19 from "path";
|
|
193
196
|
|
|
194
197
|
// ../../packages/agent-targets/src/pi-agent-dir.ts
|
|
195
198
|
import path6 from "path";
|
|
@@ -451,14 +454,29 @@ function repositoryObservation(input) {
|
|
|
451
454
|
...commitHash ? { commitHash } : {}
|
|
452
455
|
};
|
|
453
456
|
}
|
|
457
|
+
function localGitStateMetadata(states, source = "transcript_discovery") {
|
|
458
|
+
const bounded = [];
|
|
459
|
+
for (const state of states) {
|
|
460
|
+
if (!state || Buffer.byteLength(
|
|
461
|
+
JSON.stringify({ version: 1, source, states: [...bounded, state] }),
|
|
462
|
+
"utf8"
|
|
463
|
+
) > 4 * 1024)
|
|
464
|
+
continue;
|
|
465
|
+
bounded.push(state);
|
|
466
|
+
}
|
|
467
|
+
return bounded.length ? { localGitStates: { version: 1, source, states: bounded } } : {};
|
|
468
|
+
}
|
|
454
469
|
|
|
455
470
|
// ../../packages/agent-targets/src/artifacts/targets/claude.ts
|
|
456
471
|
function claudeTranscriptCandidate(sourcePath, context, harnessInstallId) {
|
|
457
472
|
const fallbackObservedAtMs = (context.nowMs ?? Date.now)();
|
|
473
|
+
const states = /* @__PURE__ */ new Map();
|
|
458
474
|
const observations = /* @__PURE__ */ new Map();
|
|
459
475
|
for (const record of readJsonlContextRecords(sourcePath)) {
|
|
460
476
|
if (typeof record.cwd !== "string" || !record.cwd.trim()) continue;
|
|
461
477
|
const origin = context.resolveGitHubOrigin?.(record.cwd);
|
|
478
|
+
const state = origin?.gitState ?? context.resolveGitState?.(record.cwd);
|
|
479
|
+
if (state) states.set(state.worktreeRoot, state);
|
|
462
480
|
if (!origin) continue;
|
|
463
481
|
const observation = repositoryObservation({
|
|
464
482
|
repository: origin.repository,
|
|
@@ -473,7 +491,10 @@ function claudeTranscriptCandidate(sourcePath, context, harnessInstallId) {
|
|
|
473
491
|
return transcriptCandidate({
|
|
474
492
|
targetId: "claude",
|
|
475
493
|
sourcePath,
|
|
476
|
-
metadata:
|
|
494
|
+
metadata: {
|
|
495
|
+
...harnessInstallId ? { harnessInstallId } : {},
|
|
496
|
+
...localGitStateMetadata([...states.values()])
|
|
497
|
+
},
|
|
477
498
|
repositoryObservations: [...observations.values()]
|
|
478
499
|
});
|
|
479
500
|
}
|
|
@@ -513,6 +534,7 @@ function codexTranscriptCandidate(sourcePath, readPath, store, context, harnessI
|
|
|
513
534
|
const git = recordValue(payload.git);
|
|
514
535
|
const nativeRepository = typeof git?.repository_url === "string" ? canonicalGitHubRepository(git.repository_url) : null;
|
|
515
536
|
const origin = cwd ? context.resolveGitHubOrigin?.(cwd) : null;
|
|
537
|
+
const state = origin?.gitState ?? (cwd ? context.resolveGitState?.(cwd) : null);
|
|
516
538
|
const observations = [];
|
|
517
539
|
if (nativeRepository) {
|
|
518
540
|
observations.push(
|
|
@@ -547,7 +569,11 @@ function codexTranscriptCandidate(sourcePath, readPath, store, context, harnessI
|
|
|
547
569
|
identityKey,
|
|
548
570
|
readPath,
|
|
549
571
|
sessionId,
|
|
550
|
-
metadata: {
|
|
572
|
+
metadata: {
|
|
573
|
+
store,
|
|
574
|
+
...identityMetadata,
|
|
575
|
+
...localGitStateMetadata([state])
|
|
576
|
+
},
|
|
551
577
|
repositoryObservations: observations
|
|
552
578
|
});
|
|
553
579
|
}
|
|
@@ -827,6 +853,12 @@ var PI_REPOSITORY_ORIGIN_ENTRY_TYPE = "fml-repository-origin";
|
|
|
827
853
|
var RepositorySlugSchema = z.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/u).transform((slug) => canonicalGitHubRepository(`https://github.com/${slug}`)).pipe(z.string());
|
|
828
854
|
var PiRepositoryOriginDataSchema = z.object({
|
|
829
855
|
version: z.literal(1),
|
|
856
|
+
gitState: z.unknown().transform((value, ctx) => {
|
|
857
|
+
const state = parseGitState(value);
|
|
858
|
+
if (state) return state;
|
|
859
|
+
ctx.addIssue({ code: "custom", message: "Invalid Git state snapshot" });
|
|
860
|
+
return z.NEVER;
|
|
861
|
+
}).nullable().optional(),
|
|
830
862
|
repository: RepositorySlugSchema.nullable(),
|
|
831
863
|
cwd: z.string().min(1).refine(
|
|
832
864
|
(cwd) => cwd.trim().length > 0 && !new RegExp("\\p{Cc}", "u").test(cwd) && Buffer.byteLength(cwd, "utf8") <= 4096
|
|
@@ -868,12 +900,15 @@ function piTranscriptCandidate(sourcePath) {
|
|
|
868
900
|
targetId: "pi",
|
|
869
901
|
sourcePath,
|
|
870
902
|
sessionId,
|
|
903
|
+
metadata: localGitStateMetadata([snapshot?.gitState], "pi_origin"),
|
|
871
904
|
repositoryObservations: snapshot?.repository ? [
|
|
872
905
|
repositoryObservation({
|
|
873
906
|
repository: snapshot.repository,
|
|
874
907
|
source: "git_origin",
|
|
875
908
|
observedAtMs: snapshot.observedAtMs,
|
|
876
|
-
cwd: snapshot.cwd
|
|
909
|
+
cwd: snapshot.cwd,
|
|
910
|
+
branch: snapshot.gitState?.branch,
|
|
911
|
+
commitHash: snapshot.gitState?.commitHash
|
|
877
912
|
})
|
|
878
913
|
] : []
|
|
879
914
|
});
|
|
@@ -1026,78 +1061,18 @@ function pruneMaterializedCache(input) {
|
|
|
1026
1061
|
}
|
|
1027
1062
|
|
|
1028
1063
|
// ../../packages/panopticon/src/repository-context.ts
|
|
1029
|
-
import { execFileSync } from "child_process";
|
|
1030
|
-
import { createHash as createHash4 } from "crypto";
|
|
1031
|
-
import fs8 from "fs";
|
|
1032
|
-
import path19 from "path";
|
|
1033
|
-
var MAX_CWD_BYTES2 = 4096;
|
|
1034
|
-
var GIT_OUTPUT_BYTES = 16 * 1024;
|
|
1035
|
-
var GIT_CONFIG_OUTPUT_BYTES = 4 * 1024 * 1024;
|
|
1036
|
-
var GIT_TIMEOUT_MS = 1e3;
|
|
1037
1064
|
var DEFAULT_GITHUB_ORIGIN_CACHE_MAX_ENTRIES = 512;
|
|
1038
|
-
var
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
}
|
|
1047
|
-
function
|
|
1048
|
-
|
|
1049
|
-
try {
|
|
1050
|
-
return execFileSync("git", ["-C", cwd, ...args], {
|
|
1051
|
-
encoding: "utf8",
|
|
1052
|
-
maxBuffer,
|
|
1053
|
-
timeout: GIT_TIMEOUT_MS,
|
|
1054
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
1055
|
-
windowsHide: true
|
|
1056
|
-
}).trim() || null;
|
|
1057
|
-
} catch (error) {
|
|
1058
|
-
const status = error && typeof error === "object" && "status" in error ? error.status : void 0;
|
|
1059
|
-
if (status === 2 && args.length === 3 && args[0] === "remote" && args[1] === "get-url" && args[2] === "origin") {
|
|
1060
|
-
return null;
|
|
1061
|
-
}
|
|
1062
|
-
throw new ReadOnlyGitCommandError();
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
function resolveGitHubOriginResult(cwd, runGit = runReadOnlyGit) {
|
|
1066
|
-
let remote;
|
|
1067
|
-
try {
|
|
1068
|
-
remote = runGit(cwd, ["remote", "get-url", "origin"]);
|
|
1069
|
-
} catch {
|
|
1070
|
-
return { origin: null, definitive: false };
|
|
1071
|
-
}
|
|
1072
|
-
const repository = remote ? canonicalGitHubRepository(remote) : null;
|
|
1073
|
-
if (!repository) return { origin: null, definitive: true };
|
|
1074
|
-
let branchResult;
|
|
1075
|
-
try {
|
|
1076
|
-
branchResult = runGit(cwd, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
1077
|
-
} catch {
|
|
1078
|
-
return { origin: { repository }, definitive: false };
|
|
1079
|
-
}
|
|
1080
|
-
const branch = branchResult === "HEAD" ? null : branchResult;
|
|
1081
|
-
let commitHash;
|
|
1082
|
-
try {
|
|
1083
|
-
commitHash = runGit(cwd, ["rev-parse", "HEAD"]);
|
|
1084
|
-
} catch {
|
|
1085
|
-
return {
|
|
1086
|
-
origin: { repository, ...branch ? { branch } : {} },
|
|
1087
|
-
definitive: false
|
|
1088
|
-
};
|
|
1089
|
-
}
|
|
1090
|
-
return {
|
|
1091
|
-
origin: {
|
|
1092
|
-
repository,
|
|
1093
|
-
...branch ? { branch } : {},
|
|
1094
|
-
...commitHash ? { commitHash } : {}
|
|
1095
|
-
},
|
|
1096
|
-
definitive: true
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
|
-
function resolveGitHubOrigin(cwd, runGit = runReadOnlyGit) {
|
|
1100
|
-
return resolveGitHubOriginResult(cwd, runGit).origin;
|
|
1065
|
+
var DEFAULT_RESOLVER = createGitStateResolver();
|
|
1066
|
+
function gitStateOrigin(state) {
|
|
1067
|
+
return state?.repository ? {
|
|
1068
|
+
repository: state.repository,
|
|
1069
|
+
...state.branch ? { branch: state.branch } : {},
|
|
1070
|
+
...state.commitHash ? { commitHash: state.commitHash } : {},
|
|
1071
|
+
gitState: state
|
|
1072
|
+
} : null;
|
|
1073
|
+
}
|
|
1074
|
+
function resolveGitHubOrigin(cwd) {
|
|
1075
|
+
return gitStateOrigin(DEFAULT_RESOLVER.resolve(cwd));
|
|
1101
1076
|
}
|
|
1102
1077
|
function createMeasuredGitHubOriginResolver(resolve = (cwd) => resolveGitHubOrigin(cwd), nowMs = () => performance.now(), options = {}) {
|
|
1103
1078
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -1165,173 +1140,29 @@ function createMeasuredGitHubOriginResolver(resolve = (cwd) => resolveGitHubOrig
|
|
|
1165
1140
|
})
|
|
1166
1141
|
};
|
|
1167
1142
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
const
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
function packedRefsIdentity(filePath) {
|
|
1180
|
-
try {
|
|
1181
|
-
const stat = fs8.statSync(filePath, { bigint: true });
|
|
1182
|
-
if (!stat.isFile() || stat.ino === 0n) return null;
|
|
1183
|
-
return [stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(
|
|
1184
|
-
":"
|
|
1185
|
-
);
|
|
1186
|
-
} catch (error) {
|
|
1187
|
-
const code = error && typeof error === "object" && "code" in error ? error.code : void 0;
|
|
1188
|
-
return code === "ENOENT" || code === "ENOTDIR" ? "missing" : null;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
function effectiveConfigIdentity(cwd) {
|
|
1192
|
-
if (["GIT_CONFIG", "GIT_DIR", "GIT_COMMON_DIR", "GIT_WORK_TREE"].some(
|
|
1193
|
-
(name) => process.env[name] !== void 0
|
|
1194
|
-
)) {
|
|
1195
|
-
return null;
|
|
1196
|
-
}
|
|
1197
|
-
try {
|
|
1198
|
-
const config = runReadOnlyGit(
|
|
1199
|
-
cwd,
|
|
1200
|
-
["config", "--includes", "--null", "--list"],
|
|
1201
|
-
GIT_CONFIG_OUTPUT_BYTES
|
|
1202
|
-
);
|
|
1203
|
-
return createHash4("sha256").update(config ?? "").digest("hex");
|
|
1204
|
-
} catch {
|
|
1205
|
-
return null;
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
function readSmallText(filePath) {
|
|
1209
|
-
try {
|
|
1210
|
-
return fs8.readFileSync(filePath, "utf8").trim();
|
|
1211
|
-
} catch {
|
|
1212
|
-
return null;
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
function findGitDirectory(cwd) {
|
|
1216
|
-
let current = path19.resolve(cwd);
|
|
1217
|
-
for (; ; ) {
|
|
1218
|
-
const candidate = path19.join(current, ".git");
|
|
1219
|
-
let stat;
|
|
1220
|
-
try {
|
|
1221
|
-
stat = fs8.statSync(candidate);
|
|
1222
|
-
} catch {
|
|
1223
|
-
stat = void 0;
|
|
1224
|
-
}
|
|
1225
|
-
if (stat?.isDirectory()) {
|
|
1226
|
-
return { gitDir: candidate, commonDir: candidate };
|
|
1227
|
-
}
|
|
1228
|
-
if (stat?.isFile()) {
|
|
1229
|
-
const pointer = readSmallText(candidate);
|
|
1230
|
-
const match = pointer ? /^gitdir:\s*(.+)$/u.exec(pointer) : null;
|
|
1231
|
-
if (!match?.[1]) return null;
|
|
1232
|
-
const gitDir = path19.resolve(current, match[1]);
|
|
1233
|
-
const common = readSmallText(path19.join(gitDir, "commondir"));
|
|
1234
|
-
return {
|
|
1235
|
-
gitDir,
|
|
1236
|
-
commonDir: common ? path19.resolve(gitDir, common) : gitDir
|
|
1237
|
-
};
|
|
1238
|
-
}
|
|
1239
|
-
const parent = path19.dirname(current);
|
|
1240
|
-
if (parent === current) return null;
|
|
1241
|
-
current = parent;
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
function checkoutSignature(layout, cwd) {
|
|
1245
|
-
const headPath = path19.join(layout.gitDir, "HEAD");
|
|
1246
|
-
const head = readSmallText(headPath);
|
|
1247
|
-
const configIdentity = effectiveConfigIdentity(cwd);
|
|
1248
|
-
if (head === null || configIdentity === null) {
|
|
1249
|
-
return null;
|
|
1250
|
-
}
|
|
1251
|
-
const parts = [layout.gitDir, head, configIdentity];
|
|
1252
|
-
const ref = /^ref:\s*(.+)$/u.exec(head)?.[1];
|
|
1253
|
-
if (ref) {
|
|
1254
|
-
const looseRefPath = path19.join(layout.commonDir, ref);
|
|
1255
|
-
if (/^ref:/u.test(readSmallText(looseRefPath) ?? "")) return null;
|
|
1256
|
-
const looseRefIdentity = fileContentIdentity(looseRefPath);
|
|
1257
|
-
const packedIdentity = packedRefsIdentity(
|
|
1258
|
-
path19.join(layout.commonDir, "packed-refs")
|
|
1259
|
-
);
|
|
1260
|
-
const reftableIdentity = fileContentIdentity(
|
|
1261
|
-
path19.join(layout.commonDir, "reftable", "tables.list")
|
|
1262
|
-
);
|
|
1263
|
-
if (!looseRefIdentity || !packedIdentity || !reftableIdentity || looseRefIdentity === "missing" && packedIdentity === "missing" && reftableIdentity === "missing") {
|
|
1264
|
-
return null;
|
|
1265
|
-
}
|
|
1266
|
-
parts.push(looseRefIdentity, packedIdentity, reftableIdentity);
|
|
1267
|
-
}
|
|
1268
|
-
return parts.join("\0");
|
|
1269
|
-
}
|
|
1270
|
-
function readPersistentOriginCache(cacheFile) {
|
|
1271
|
-
try {
|
|
1272
|
-
const parsed = JSON.parse(fs8.readFileSync(cacheFile, "utf8"));
|
|
1273
|
-
if (parsed && typeof parsed === "object" && parsed.schemaVersion === PERSISTENT_ORIGIN_CACHE_SCHEMA_VERSION && parsed.entries && typeof parsed.entries === "object") {
|
|
1274
|
-
return parsed;
|
|
1275
|
-
}
|
|
1276
|
-
} catch {
|
|
1277
|
-
}
|
|
1278
|
-
return { schemaVersion: PERSISTENT_ORIGIN_CACHE_SCHEMA_VERSION, entries: {} };
|
|
1279
|
-
}
|
|
1280
|
-
function writePersistentOriginCache(cacheFile, cache) {
|
|
1281
|
-
const temporary = `${cacheFile}.${process.pid}.tmp`;
|
|
1282
|
-
try {
|
|
1283
|
-
fs8.mkdirSync(path19.dirname(cacheFile), { recursive: true, mode: 448 });
|
|
1284
|
-
fs8.writeFileSync(temporary, `${JSON.stringify(cache)}
|
|
1285
|
-
`, { mode: 384 });
|
|
1286
|
-
fs8.renameSync(temporary, cacheFile);
|
|
1287
|
-
} catch {
|
|
1288
|
-
try {
|
|
1289
|
-
fs8.rmSync(temporary, { force: true });
|
|
1290
|
-
} catch {
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
function createPersistentGitHubOriginResolver(options) {
|
|
1295
|
-
const maxEntries = options.maxEntries ?? DEFAULT_PERSISTENT_ORIGIN_CACHE_MAX_ENTRIES;
|
|
1296
|
-
const cache = readPersistentOriginCache(options.cacheFile);
|
|
1297
|
-
const entries = new Map(Object.entries(cache.entries));
|
|
1298
|
-
const remember = (cwd, entry) => {
|
|
1299
|
-
entries.delete(cwd);
|
|
1300
|
-
entries.set(cwd, entry);
|
|
1301
|
-
while (entries.size > maxEntries) {
|
|
1302
|
-
const oldest = entries.keys().next().value;
|
|
1143
|
+
function createArtifactDiscoveryGitHubOriginResolver(options = {}) {
|
|
1144
|
+
const resolver = createGitStateResolver(options);
|
|
1145
|
+
const states = /* @__PURE__ */ new Map();
|
|
1146
|
+
const measured = createMeasuredGitHubOriginResolver((cwd) => {
|
|
1147
|
+
const state = resolver.resolve(cwd);
|
|
1148
|
+
states.delete(cwd);
|
|
1149
|
+
states.set(cwd, state);
|
|
1150
|
+
while (states.size > DEFAULT_GITHUB_ORIGIN_CACHE_MAX_ENTRIES) {
|
|
1151
|
+
const oldest = states.keys().next().value;
|
|
1303
1152
|
if (oldest === void 0) break;
|
|
1304
|
-
|
|
1305
|
-
}
|
|
1306
|
-
writePersistentOriginCache(options.cacheFile, {
|
|
1307
|
-
schemaVersion: PERSISTENT_ORIGIN_CACHE_SCHEMA_VERSION,
|
|
1308
|
-
entries: Object.fromEntries(entries)
|
|
1309
|
-
});
|
|
1310
|
-
};
|
|
1311
|
-
return (cwd) => {
|
|
1312
|
-
if (!validCwd(cwd)) return null;
|
|
1313
|
-
const layout = findGitDirectory(cwd);
|
|
1314
|
-
if (!layout) return null;
|
|
1315
|
-
const signature = checkoutSignature(layout, cwd);
|
|
1316
|
-
const cached = entries.get(cwd);
|
|
1317
|
-
if (signature !== null && cached && cached.signature === signature) {
|
|
1318
|
-
return cached.origin;
|
|
1153
|
+
states.delete(oldest);
|
|
1319
1154
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
return
|
|
1326
|
-
|
|
1327
|
-
return null;
|
|
1155
|
+
return gitStateOrigin(state);
|
|
1156
|
+
});
|
|
1157
|
+
return {
|
|
1158
|
+
...measured,
|
|
1159
|
+
resolveState: (cwd) => {
|
|
1160
|
+
if (states.has(cwd)) return states.get(cwd) ?? null;
|
|
1161
|
+
const origin = measured.resolve(cwd);
|
|
1162
|
+
return origin?.gitState ?? (states.has(cwd) ? states.get(cwd) ?? null : resolver.resolve(cwd));
|
|
1328
1163
|
}
|
|
1329
1164
|
};
|
|
1330
1165
|
}
|
|
1331
|
-
function createArtifactDiscoveryGitHubOriginResolver(options = {}) {
|
|
1332
|
-
const resolve = options.cacheFile ? createPersistentGitHubOriginResolver({ cacheFile: options.cacheFile }) : (cwd) => resolveGitHubOrigin(cwd);
|
|
1333
|
-
return createMeasuredGitHubOriginResolver(resolve, () => performance.now());
|
|
1334
|
-
}
|
|
1335
1166
|
|
|
1336
1167
|
// ../../packages/panopticon/src/artifacts.ts
|
|
1337
1168
|
var RAW_ARTIFACT_ENDPOINT = "/v1/ingest/raw-artifact";
|
|
@@ -1374,20 +1205,20 @@ function isAbortError(error) {
|
|
|
1374
1205
|
}
|
|
1375
1206
|
function safeStat(filePath) {
|
|
1376
1207
|
try {
|
|
1377
|
-
return
|
|
1208
|
+
return fs8.statSync(filePath);
|
|
1378
1209
|
} catch {
|
|
1379
1210
|
return null;
|
|
1380
1211
|
}
|
|
1381
1212
|
}
|
|
1382
1213
|
function normalizeFilePath2(filePath) {
|
|
1383
|
-
return
|
|
1214
|
+
return path19.resolve(filePath);
|
|
1384
1215
|
}
|
|
1385
1216
|
function artifactReadPath(artifact) {
|
|
1386
1217
|
return normalizeFilePath2(artifact.readPath ?? artifact.sourcePath);
|
|
1387
1218
|
}
|
|
1388
1219
|
function statCandidateSource(sourcePath, transientStatErrors) {
|
|
1389
1220
|
try {
|
|
1390
|
-
return
|
|
1221
|
+
return fs8.statSync(sourcePath);
|
|
1391
1222
|
} catch (error) {
|
|
1392
1223
|
if (error.code === "ENOENT") return null;
|
|
1393
1224
|
if (transientStatErrors === "throw") throw error;
|
|
@@ -1395,7 +1226,7 @@ function statCandidateSource(sourcePath, transientStatErrors) {
|
|
|
1395
1226
|
}
|
|
1396
1227
|
}
|
|
1397
1228
|
function contentTypeForPath(filePath) {
|
|
1398
|
-
const ext =
|
|
1229
|
+
const ext = path19.extname(filePath).toLowerCase();
|
|
1399
1230
|
if (ext === ".json" || ext === ".jsonl") return "application/json";
|
|
1400
1231
|
if (ext === ".md") return "text/markdown";
|
|
1401
1232
|
if (ext === ".toml") return "application/toml";
|
|
@@ -1444,6 +1275,7 @@ function discoverArtifacts(options = {}) {
|
|
|
1444
1275
|
env,
|
|
1445
1276
|
maxFileBytes: maxBytes,
|
|
1446
1277
|
resolveGitHubOrigin: repositoryResolution.resolve,
|
|
1278
|
+
resolveGitState: repositoryResolution.resolveState,
|
|
1447
1279
|
...options.materializeArtifact ? { materializeArtifact: options.materializeArtifact } : {}
|
|
1448
1280
|
});
|
|
1449
1281
|
const byKey = /* @__PURE__ */ new Map();
|
|
@@ -1508,7 +1340,7 @@ function readUploadThrottles(value) {
|
|
|
1508
1340
|
}
|
|
1509
1341
|
function readArtifactQueue(queueFile) {
|
|
1510
1342
|
try {
|
|
1511
|
-
const parsed = JSON.parse(
|
|
1343
|
+
const parsed = JSON.parse(fs8.readFileSync(queueFile, "utf8"));
|
|
1512
1344
|
if (!parsed || typeof parsed !== "object") return emptyQueue();
|
|
1513
1345
|
const record = parsed;
|
|
1514
1346
|
if (record.schemaVersion !== RAW_ARTIFACT_SCHEMA_VERSION) {
|
|
@@ -1524,16 +1356,52 @@ function readArtifactQueue(queueFile) {
|
|
|
1524
1356
|
return emptyQueue();
|
|
1525
1357
|
}
|
|
1526
1358
|
}
|
|
1359
|
+
var QUEUE_WRITE_SLICE_ENTRIES = 256;
|
|
1360
|
+
function writeQueuePiece(fd, piece) {
|
|
1361
|
+
const buffer = Buffer.from(piece, "utf8");
|
|
1362
|
+
let offset = 0;
|
|
1363
|
+
while (offset < buffer.length) {
|
|
1364
|
+
const written = fs8.writeSync(fd, buffer, offset);
|
|
1365
|
+
if (written === 0) {
|
|
1366
|
+
throw new Error("artifact queue write made no progress");
|
|
1367
|
+
}
|
|
1368
|
+
offset += written;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1527
1371
|
function writeArtifactQueue(queueFile, queue) {
|
|
1528
|
-
|
|
1372
|
+
fs8.mkdirSync(path19.dirname(queueFile), { recursive: true, mode: 448 });
|
|
1529
1373
|
const tempFile = `${queueFile}.${process.pid}.${Date.now()}.tmp`;
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1374
|
+
const fd = fs8.openSync(tempFile, "w", 384);
|
|
1375
|
+
try {
|
|
1376
|
+
writeQueuePiece(
|
|
1377
|
+
fd,
|
|
1378
|
+
`{"schemaVersion":${JSON.stringify(queue.schemaVersion)}`
|
|
1379
|
+
);
|
|
1380
|
+
if (queue.uploadThrottles !== void 0) {
|
|
1381
|
+
writeQueuePiece(
|
|
1382
|
+
fd,
|
|
1383
|
+
`,"uploadThrottles":${JSON.stringify(queue.uploadThrottles)}`
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
writeQueuePiece(fd, ',"artifacts":[');
|
|
1387
|
+
const artifacts = queue.artifacts;
|
|
1388
|
+
for (let start = 0; start < artifacts.length; start += QUEUE_WRITE_SLICE_ENTRIES) {
|
|
1389
|
+
const slice = artifacts.slice(start, start + QUEUE_WRITE_SLICE_ENTRIES).map((entry) => JSON.stringify(entry)).join(",");
|
|
1390
|
+
writeQueuePiece(fd, start === 0 ? slice : `,${slice}`);
|
|
1391
|
+
}
|
|
1392
|
+
writeQueuePiece(fd, "]}\n");
|
|
1393
|
+
} catch (error) {
|
|
1394
|
+
fs8.closeSync(fd);
|
|
1395
|
+
try {
|
|
1396
|
+
fs8.rmSync(tempFile, { force: true });
|
|
1397
|
+
} catch {
|
|
1398
|
+
}
|
|
1399
|
+
throw error;
|
|
1400
|
+
}
|
|
1401
|
+
fs8.closeSync(fd);
|
|
1402
|
+
fs8.renameSync(tempFile, queueFile);
|
|
1535
1403
|
try {
|
|
1536
|
-
|
|
1404
|
+
fs8.chmodSync(queueFile, 384);
|
|
1537
1405
|
} catch {
|
|
1538
1406
|
}
|
|
1539
1407
|
}
|
|
@@ -1553,7 +1421,7 @@ function shouldStartNewGeneration(input) {
|
|
|
1553
1421
|
if (input.existing.source === "mini-swe-agent") {
|
|
1554
1422
|
if (input.existing.contentSha256) {
|
|
1555
1423
|
try {
|
|
1556
|
-
return
|
|
1424
|
+
return createHash4("sha256").update(fs8.readFileSync(input.nextReadPath)).digest("hex") !== input.existing.contentSha256;
|
|
1557
1425
|
} catch {
|
|
1558
1426
|
}
|
|
1559
1427
|
}
|
|
@@ -1563,7 +1431,7 @@ function shouldStartNewGeneration(input) {
|
|
|
1563
1431
|
if (input.nextSizeBytes < input.existing.sizeBytes) return true;
|
|
1564
1432
|
if ((input.nextReadPath !== artifactReadPath(input.existing) || input.existing.readPath !== void 0) && input.nextSizeBytes === input.existing.sizeBytes && input.existing.uploadedSizeBytes >= input.nextSizeBytes && input.existing.contentSha256) {
|
|
1565
1433
|
try {
|
|
1566
|
-
const contentSha256 =
|
|
1434
|
+
const contentSha256 = createHash4("sha256").update(fs8.readFileSync(input.nextReadPath)).digest("hex");
|
|
1567
1435
|
if (contentSha256 === input.existing.contentSha256) return false;
|
|
1568
1436
|
} catch {
|
|
1569
1437
|
}
|
|
@@ -1674,13 +1542,24 @@ function metadataForGeneration(input) {
|
|
|
1674
1542
|
observations: input.candidateObservations,
|
|
1675
1543
|
metadataWithoutContext
|
|
1676
1544
|
});
|
|
1677
|
-
|
|
1545
|
+
const metadata = {
|
|
1678
1546
|
...metadataWithoutContext,
|
|
1679
1547
|
...hasInstallIdentity ? {
|
|
1680
1548
|
installIdentitySchemaVersion: RAW_ARTIFACT_IDENTITY_SCHEMA_VERSION
|
|
1681
1549
|
} : {},
|
|
1682
1550
|
...repositoryContext ? { repositoryContext } : {}
|
|
1683
1551
|
};
|
|
1552
|
+
const rawGitStates = metadata.localGitStates;
|
|
1553
|
+
const statesValue = Array.isArray(rawGitStates) ? rawGitStates : rawGitStates !== null && typeof rawGitStates === "object" && "version" in rawGitStates && rawGitStates.version === 1 && "states" in rawGitStates ? rawGitStates.states : void 0;
|
|
1554
|
+
if (Array.isArray(statesValue) && rawGitStates && typeof rawGitStates === "object") {
|
|
1555
|
+
const states = [...statesValue];
|
|
1556
|
+
metadata.localGitStates = Array.isArray(rawGitStates) ? states : { ...rawGitStates, states };
|
|
1557
|
+
while (states.length && Buffer.byteLength(JSON.stringify(metadata), "utf8") > MAX_RAW_ARTIFACT_NESTED_METADATA_BYTES)
|
|
1558
|
+
states.pop();
|
|
1559
|
+
if (!states.length && Buffer.byteLength(JSON.stringify(metadata), "utf8") > MAX_RAW_ARTIFACT_NESTED_METADATA_BYTES)
|
|
1560
|
+
delete metadata.localGitStates;
|
|
1561
|
+
}
|
|
1562
|
+
return metadata;
|
|
1684
1563
|
}
|
|
1685
1564
|
function snapshotCandidate2(candidate, existing, nowMs, maxFileBytes, transientStatErrors = "ignore", observerIdentity) {
|
|
1686
1565
|
const sourcePath = normalizeFilePath2(candidate.sourcePath);
|
|
@@ -1897,7 +1776,7 @@ function sameSourceRevision(left, right) {
|
|
|
1897
1776
|
}
|
|
1898
1777
|
function safeSourceRevision(filePath) {
|
|
1899
1778
|
try {
|
|
1900
|
-
const stat =
|
|
1779
|
+
const stat = fs8.statSync(filePath, { bigint: true });
|
|
1901
1780
|
return stat.isFile() ? sourceRevisionFromStat(stat) : null;
|
|
1902
1781
|
} catch {
|
|
1903
1782
|
return null;
|
|
@@ -1909,7 +1788,7 @@ function readExactRange(fd, startByte, endByte) {
|
|
|
1909
1788
|
const buffer = Buffer.alloc(sizeBytes);
|
|
1910
1789
|
let offset = 0;
|
|
1911
1790
|
while (offset < sizeBytes) {
|
|
1912
|
-
const bytesRead =
|
|
1791
|
+
const bytesRead = fs8.readSync(
|
|
1913
1792
|
fd,
|
|
1914
1793
|
buffer,
|
|
1915
1794
|
offset,
|
|
@@ -1928,19 +1807,19 @@ function readFileRangeAtRevision(filePath, startByte, endByte, expectedRevision)
|
|
|
1928
1807
|
}
|
|
1929
1808
|
let fd;
|
|
1930
1809
|
try {
|
|
1931
|
-
fd =
|
|
1810
|
+
fd = fs8.openSync(filePath, "r");
|
|
1932
1811
|
} catch {
|
|
1933
1812
|
return null;
|
|
1934
1813
|
}
|
|
1935
1814
|
try {
|
|
1936
1815
|
const openedRevision = sourceRevisionFromStat(
|
|
1937
|
-
|
|
1816
|
+
fs8.fstatSync(fd, { bigint: true })
|
|
1938
1817
|
);
|
|
1939
1818
|
if (!sameSourceRevision(pathRevisionBefore, openedRevision)) return null;
|
|
1940
1819
|
const bytes = readExactRange(fd, startByte, endByte);
|
|
1941
1820
|
if (!bytes) return null;
|
|
1942
1821
|
const revisionAfterRead = sourceRevisionFromStat(
|
|
1943
|
-
|
|
1822
|
+
fs8.fstatSync(fd, { bigint: true })
|
|
1944
1823
|
);
|
|
1945
1824
|
const pathRevisionAfter = safeSourceRevision(filePath);
|
|
1946
1825
|
if (!sameSourceRevision(openedRevision, revisionAfterRead) || !pathRevisionAfter || !sameSourceRevision(openedRevision, pathRevisionAfter)) {
|
|
@@ -1950,7 +1829,7 @@ function readFileRangeAtRevision(filePath, startByte, endByte, expectedRevision)
|
|
|
1950
1829
|
} catch {
|
|
1951
1830
|
return null;
|
|
1952
1831
|
} finally {
|
|
1953
|
-
|
|
1832
|
+
fs8.closeSync(fd);
|
|
1954
1833
|
}
|
|
1955
1834
|
}
|
|
1956
1835
|
function uploadMetadata(input) {
|
|
@@ -2082,18 +1961,18 @@ function validateCheckpointPrefix(input) {
|
|
|
2082
1961
|
}
|
|
2083
1962
|
let fd;
|
|
2084
1963
|
try {
|
|
2085
|
-
fd =
|
|
1964
|
+
fd = fs8.openSync(input.sourcePath, "r");
|
|
2086
1965
|
} catch {
|
|
2087
1966
|
return { status: "changed" };
|
|
2088
1967
|
}
|
|
2089
1968
|
try {
|
|
2090
1969
|
const openedRevision = sourceRevisionFromStat(
|
|
2091
|
-
|
|
1970
|
+
fs8.fstatSync(fd, { bigint: true })
|
|
2092
1971
|
);
|
|
2093
1972
|
if (!sameSourceRevision(pathRevisionBefore, openedRevision)) {
|
|
2094
1973
|
return { status: "changed" };
|
|
2095
1974
|
}
|
|
2096
|
-
const contentHash =
|
|
1975
|
+
const contentHash = createHash4("sha256");
|
|
2097
1976
|
let checkpointMismatch = false;
|
|
2098
1977
|
for (const checkpoint of checkpoints) {
|
|
2099
1978
|
const chunk = readExactRange(
|
|
@@ -2108,7 +1987,7 @@ function validateCheckpointPrefix(input) {
|
|
|
2108
1987
|
contentHash.update(chunk);
|
|
2109
1988
|
}
|
|
2110
1989
|
const revisionAfterRead = sourceRevisionFromStat(
|
|
2111
|
-
|
|
1990
|
+
fs8.fstatSync(fd, { bigint: true })
|
|
2112
1991
|
);
|
|
2113
1992
|
const pathRevisionAfter = safeSourceRevision(input.sourcePath);
|
|
2114
1993
|
if (!sameSourceRevision(openedRevision, revisionAfterRead) || !pathRevisionAfter || !sameSourceRevision(openedRevision, pathRevisionAfter)) {
|
|
@@ -2123,7 +2002,7 @@ function validateCheckpointPrefix(input) {
|
|
|
2123
2002
|
} catch {
|
|
2124
2003
|
return { status: "changed" };
|
|
2125
2004
|
} finally {
|
|
2126
|
-
|
|
2005
|
+
fs8.closeSync(fd);
|
|
2127
2006
|
}
|
|
2128
2007
|
}
|
|
2129
2008
|
function validatedPrefixStillApplies(prefix, entry, uploadDestinationId, revision) {
|
|
@@ -2257,14 +2136,14 @@ function defaultIsPidAlive(pid) {
|
|
|
2257
2136
|
}
|
|
2258
2137
|
function readQueueLockHolder(lockFile) {
|
|
2259
2138
|
try {
|
|
2260
|
-
const parsed = JSON.parse(
|
|
2139
|
+
const parsed = JSON.parse(fs8.readFileSync(lockFile, "utf8"));
|
|
2261
2140
|
if (!parsed || typeof parsed !== "object") return null;
|
|
2262
2141
|
const record = parsed;
|
|
2263
2142
|
if (typeof record.pid !== "number" || typeof record.timestampMs !== "number") {
|
|
2264
2143
|
return null;
|
|
2265
2144
|
}
|
|
2266
2145
|
const ownerToken = typeof record.ownerToken === "string" ? record.ownerToken : void 0;
|
|
2267
|
-
const timestampMs = ownerToken ? Math.max(record.timestampMs,
|
|
2146
|
+
const timestampMs = ownerToken ? Math.max(record.timestampMs, fs8.statSync(lockFile).mtimeMs) : record.timestampMs;
|
|
2268
2147
|
return { pid: record.pid, timestampMs, ownerToken };
|
|
2269
2148
|
} catch {
|
|
2270
2149
|
return null;
|
|
@@ -2272,8 +2151,8 @@ function readQueueLockHolder(lockFile) {
|
|
|
2272
2151
|
}
|
|
2273
2152
|
function queueLockFileMatchesOwner(lockFile, fd, ownerToken) {
|
|
2274
2153
|
try {
|
|
2275
|
-
const openStat =
|
|
2276
|
-
const pathStat =
|
|
2154
|
+
const openStat = fs8.fstatSync(fd);
|
|
2155
|
+
const pathStat = fs8.statSync(lockFile);
|
|
2277
2156
|
if (openStat.dev !== pathStat.dev || openStat.ino !== pathStat.ino) {
|
|
2278
2157
|
return false;
|
|
2279
2158
|
}
|
|
@@ -2284,14 +2163,14 @@ function queueLockFileMatchesOwner(lockFile, fd, ownerToken) {
|
|
|
2284
2163
|
}
|
|
2285
2164
|
function acquireQueueLock(queueFile, deps) {
|
|
2286
2165
|
const lockFile = queueLockFile(queueFile);
|
|
2287
|
-
|
|
2166
|
+
fs8.mkdirSync(path19.dirname(lockFile), { recursive: true, mode: 448 });
|
|
2288
2167
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
2289
2168
|
try {
|
|
2290
|
-
const fd =
|
|
2169
|
+
const fd = fs8.openSync(lockFile, "wx+", 384);
|
|
2291
2170
|
const ownerToken = randomUUID3();
|
|
2292
2171
|
let released = false;
|
|
2293
2172
|
try {
|
|
2294
|
-
|
|
2173
|
+
fs8.writeSync(
|
|
2295
2174
|
fd,
|
|
2296
2175
|
`${JSON.stringify({
|
|
2297
2176
|
pid: process.pid,
|
|
@@ -2301,11 +2180,11 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2301
2180
|
`
|
|
2302
2181
|
);
|
|
2303
2182
|
const heartbeatAt = new Date(deps.nowMs());
|
|
2304
|
-
|
|
2183
|
+
fs8.futimesSync(fd, heartbeatAt, heartbeatAt);
|
|
2305
2184
|
} catch (error) {
|
|
2306
|
-
|
|
2185
|
+
fs8.closeSync(fd);
|
|
2307
2186
|
try {
|
|
2308
|
-
|
|
2187
|
+
fs8.unlinkSync(lockFile);
|
|
2309
2188
|
} catch {
|
|
2310
2189
|
}
|
|
2311
2190
|
throw error;
|
|
@@ -2313,7 +2192,7 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2313
2192
|
const close = () => {
|
|
2314
2193
|
if (released) return;
|
|
2315
2194
|
released = true;
|
|
2316
|
-
|
|
2195
|
+
fs8.closeSync(fd);
|
|
2317
2196
|
};
|
|
2318
2197
|
return {
|
|
2319
2198
|
heartbeat() {
|
|
@@ -2322,7 +2201,7 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2322
2201
|
return false;
|
|
2323
2202
|
try {
|
|
2324
2203
|
const heartbeatAt = new Date(deps.nowMs());
|
|
2325
|
-
|
|
2204
|
+
fs8.futimesSync(fd, heartbeatAt, heartbeatAt);
|
|
2326
2205
|
return true;
|
|
2327
2206
|
} catch {
|
|
2328
2207
|
return false;
|
|
@@ -2332,7 +2211,7 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2332
2211
|
if (released) return;
|
|
2333
2212
|
if (queueLockFileMatchesOwner(lockFile, fd, ownerToken)) {
|
|
2334
2213
|
try {
|
|
2335
|
-
|
|
2214
|
+
fs8.unlinkSync(lockFile);
|
|
2336
2215
|
} catch {
|
|
2337
2216
|
}
|
|
2338
2217
|
}
|
|
@@ -2345,7 +2224,7 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2345
2224
|
const stale = !holder || !deps.isPidAlive(holder.pid) || deps.nowMs() - holder.timestampMs > QUEUE_LOCK_STALE_MS;
|
|
2346
2225
|
if (!stale) return null;
|
|
2347
2226
|
try {
|
|
2348
|
-
|
|
2227
|
+
fs8.unlinkSync(lockFile);
|
|
2349
2228
|
} catch {
|
|
2350
2229
|
}
|
|
2351
2230
|
}
|
|
@@ -2403,7 +2282,7 @@ async function postRawArtifact(url, metadata, content, headers, fetchImpl = fetc
|
|
|
2403
2282
|
form.append(
|
|
2404
2283
|
"file",
|
|
2405
2284
|
new Blob([new Uint8Array(content)], { type: metadata.contentType }),
|
|
2406
|
-
|
|
2285
|
+
path19.basename(metadata.sourcePath) || "raw-artifact"
|
|
2407
2286
|
);
|
|
2408
2287
|
const abort = new AbortController();
|
|
2409
2288
|
const timeout = setTimeout(() => abort.abort(), timeoutMs);
|
|
@@ -2684,14 +2563,15 @@ async function syncArtifacts(options) {
|
|
|
2684
2563
|
}
|
|
2685
2564
|
const upload = await uploadPendingArtifactsLocked(
|
|
2686
2565
|
options,
|
|
2687
|
-
resolveUploadRun(options, lock)
|
|
2566
|
+
resolveUploadRun(options, lock),
|
|
2567
|
+
snapshot.queue
|
|
2688
2568
|
);
|
|
2689
2569
|
return { snapshot, upload };
|
|
2690
2570
|
} finally {
|
|
2691
2571
|
lock.release();
|
|
2692
2572
|
}
|
|
2693
2573
|
}
|
|
2694
|
-
async function uploadPendingArtifactsLocked(options, run) {
|
|
2574
|
+
async function uploadPendingArtifactsLocked(options, run, currentQueue) {
|
|
2695
2575
|
const {
|
|
2696
2576
|
nowMs,
|
|
2697
2577
|
limit,
|
|
@@ -2703,7 +2583,7 @@ async function uploadPendingArtifactsLocked(options, run) {
|
|
|
2703
2583
|
retryExhausted,
|
|
2704
2584
|
lock
|
|
2705
2585
|
} = run;
|
|
2706
|
-
const queue = readArtifactQueue(options.queueFile);
|
|
2586
|
+
const queue = currentQueue ?? readArtifactQueue(options.queueFile);
|
|
2707
2587
|
const entries = queue.artifacts.filter((entry) => artifactSourceEnabled(entry.source)).map(
|
|
2708
2588
|
(entry) => activateUploadDestination(entry, uploadDestinationId, targetName)
|
|
2709
2589
|
);
|
|
@@ -3255,7 +3135,11 @@ async function uploadPendingArtifactsLocked(options, run) {
|
|
|
3255
3135
|
persist();
|
|
3256
3136
|
}
|
|
3257
3137
|
}
|
|
3258
|
-
const nextQueue =
|
|
3138
|
+
const nextQueue = {
|
|
3139
|
+
schemaVersion: RAW_ARTIFACT_SCHEMA_VERSION,
|
|
3140
|
+
artifacts: entries,
|
|
3141
|
+
uploadThrottles: Object.keys(uploadThrottles).length > 0 ? uploadThrottles : void 0
|
|
3142
|
+
};
|
|
3259
3143
|
const completedAtMs = nowMs();
|
|
3260
3144
|
const exhausted = nextQueue.artifacts.filter(
|
|
3261
3145
|
(entry) => isExhaustedForDestination(entry, uploadDestinationId, retryExhausted)
|
|
@@ -3292,12 +3176,12 @@ async function uploadPendingArtifactsLocked(options, run) {
|
|
|
3292
3176
|
}
|
|
3293
3177
|
|
|
3294
3178
|
// ../../packages/panopticon/src/raw-sync.ts
|
|
3295
|
-
import
|
|
3296
|
-
import
|
|
3179
|
+
import fs10 from "fs";
|
|
3180
|
+
import path20 from "path";
|
|
3297
3181
|
import os4 from "os";
|
|
3298
3182
|
|
|
3299
3183
|
// ../../packages/panopticon/src/artifact-materializer.ts
|
|
3300
|
-
import
|
|
3184
|
+
import fs9 from "fs";
|
|
3301
3185
|
function entryNeedsBytes(entry, amendmentPending) {
|
|
3302
3186
|
if (entry.uploadedSizeBytes < entry.sizeBytes) return true;
|
|
3303
3187
|
return amendmentPending(entry);
|
|
@@ -3312,7 +3196,7 @@ function createArtifactMaterializer(input) {
|
|
|
3312
3196
|
const unsupportedReason = (input.supportsCompression ?? supportsCompressedArtifacts)() ? void 0 : `compressed artifacts need Node 22.15 or newer (running ${process.version})`;
|
|
3313
3197
|
const chargeExisting = (cachePath) => {
|
|
3314
3198
|
try {
|
|
3315
|
-
const stat =
|
|
3199
|
+
const stat = fs9.statSync(cachePath);
|
|
3316
3200
|
if (!stat.isFile()) return false;
|
|
3317
3201
|
if (!retained.has(cachePath)) {
|
|
3318
3202
|
retained.add(cachePath);
|
|
@@ -3360,20 +3244,20 @@ function getRawArtifactSyncPaths(stateDir) {
|
|
|
3360
3244
|
if (stateDir.length === 0) {
|
|
3361
3245
|
throw new Error("raw artifact sync state directory must not be empty");
|
|
3362
3246
|
}
|
|
3363
|
-
const root =
|
|
3247
|
+
const root = path20.resolve(stateDir);
|
|
3364
3248
|
const managed = getManagedClientPaths({ PANOPTICON_HOME: root });
|
|
3365
3249
|
return {
|
|
3366
3250
|
root,
|
|
3367
3251
|
settingsFile: managed.syncSettingsFile,
|
|
3368
3252
|
queueFile: managed.artifactQueue,
|
|
3369
3253
|
artifactCacheDir: managed.artifactCache,
|
|
3370
|
-
discoveryCacheFile:
|
|
3371
|
-
githubOriginCacheFile:
|
|
3254
|
+
discoveryCacheFile: path20.join(root, "discovery.cache.json"),
|
|
3255
|
+
githubOriginCacheFile: path20.join(root, GIT_STATE_CACHE_FILENAME)
|
|
3372
3256
|
};
|
|
3373
3257
|
}
|
|
3374
3258
|
function invalidateRawArtifactDiscoveryCache(stateDir) {
|
|
3375
3259
|
try {
|
|
3376
|
-
|
|
3260
|
+
fs10.rmSync(getRawArtifactSyncPaths(stateDir).discoveryCacheFile, {
|
|
3377
3261
|
force: true
|
|
3378
3262
|
});
|
|
3379
3263
|
} catch {
|
|
@@ -3476,9 +3360,9 @@ function createRawArtifactSync(options) {
|
|
|
3476
3360
|
options.homeDir ?? null,
|
|
3477
3361
|
options.projectRoots ?? null,
|
|
3478
3362
|
options.maxFileBytes ?? null,
|
|
3479
|
-
|
|
3363
|
+
path20.resolve(
|
|
3480
3364
|
resolvePiAgentDir({
|
|
3481
|
-
homeDir:
|
|
3365
|
+
homeDir: path20.resolve(
|
|
3482
3366
|
options.homeDir ?? process.env.HOME ?? os4.homedir()
|
|
3483
3367
|
),
|
|
3484
3368
|
env: process.env
|
|
@@ -3491,7 +3375,7 @@ function createRawArtifactSync(options) {
|
|
|
3491
3375
|
if (reuseMs <= 0) return null;
|
|
3492
3376
|
try {
|
|
3493
3377
|
const parsed = JSON.parse(
|
|
3494
|
-
|
|
3378
|
+
fs10.readFileSync(paths.discoveryCacheFile, "utf8")
|
|
3495
3379
|
);
|
|
3496
3380
|
if (parsed.schemaVersion !== DISCOVERY_CACHE_SCHEMA_VERSION || typeof parsed.createdAtMs !== "number" || parsed.inputs !== discoveryInputs() || !parsed.discovery || typeof parsed.discovery !== "object") {
|
|
3497
3381
|
return null;
|
|
@@ -3507,11 +3391,11 @@ function createRawArtifactSync(options) {
|
|
|
3507
3391
|
if ((options.discoveryReuseMs ?? 0) <= 0) return;
|
|
3508
3392
|
const temporary = `${paths.discoveryCacheFile}.${process.pid}.tmp`;
|
|
3509
3393
|
try {
|
|
3510
|
-
|
|
3394
|
+
fs10.mkdirSync(path20.dirname(paths.discoveryCacheFile), {
|
|
3511
3395
|
recursive: true,
|
|
3512
3396
|
mode: 448
|
|
3513
3397
|
});
|
|
3514
|
-
|
|
3398
|
+
fs10.writeFileSync(
|
|
3515
3399
|
temporary,
|
|
3516
3400
|
`${JSON.stringify({
|
|
3517
3401
|
schemaVersion: DISCOVERY_CACHE_SCHEMA_VERSION,
|
|
@@ -3522,10 +3406,10 @@ function createRawArtifactSync(options) {
|
|
|
3522
3406
|
`,
|
|
3523
3407
|
{ mode: 384 }
|
|
3524
3408
|
);
|
|
3525
|
-
|
|
3409
|
+
fs10.renameSync(temporary, paths.discoveryCacheFile);
|
|
3526
3410
|
} catch {
|
|
3527
3411
|
try {
|
|
3528
|
-
|
|
3412
|
+
fs10.rmSync(temporary, { force: true });
|
|
3529
3413
|
} catch {
|
|
3530
3414
|
}
|
|
3531
3415
|
}
|