@fml-inc/fml 0.8.12 → 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 +58 -0
- package/dist/chunk-3RKICLMI.js +34 -0
- package/dist/{chunk-JK5JGPUN.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-VFZWTVPD.js → chunk-LYKMU7QR.js} +252 -343
- package/dist/{chunk-Z7MXNJ6X.js → chunk-PVOZYFMP.js} +1 -1
- package/dist/cli.js +12 -21
- 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 +802 -354
- 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,29 +189,44 @@ 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
195
|
import path19 from "path";
|
|
193
196
|
|
|
197
|
+
// ../../packages/agent-targets/src/pi-agent-dir.ts
|
|
198
|
+
import path6 from "path";
|
|
199
|
+
function resolvePiAgentDir(context) {
|
|
200
|
+
const pathApi = (context.platform ?? process.platform) === "win32" ? path6.win32 : path6.posix;
|
|
201
|
+
const configured = context.env.PI_CODING_AGENT_DIR?.trim();
|
|
202
|
+
if (!configured) {
|
|
203
|
+
return pathApi.join(context.homeDir, ".pi", "agent");
|
|
204
|
+
}
|
|
205
|
+
if (configured === "~") return context.homeDir;
|
|
206
|
+
if (configured.startsWith("~/") || configured.startsWith("~\\")) {
|
|
207
|
+
return pathApi.join(context.homeDir, configured.slice(2));
|
|
208
|
+
}
|
|
209
|
+
return pathApi.normalize(configured);
|
|
210
|
+
}
|
|
211
|
+
|
|
194
212
|
// ../../packages/agent-targets/src/artifacts/targets/claude.ts
|
|
195
|
-
import
|
|
213
|
+
import path9 from "path";
|
|
196
214
|
|
|
197
215
|
// ../../packages/agent-targets/src/config-paths.ts
|
|
198
|
-
import
|
|
216
|
+
import path7 from "path";
|
|
199
217
|
function claudeConfigDirectory(context) {
|
|
200
218
|
const configuredDir = context.claudeConfigDir ?? context.env?.CLAUDE_CONFIG_DIR;
|
|
201
|
-
return typeof configuredDir === "string" && configuredDir.trim().length > 0 ?
|
|
219
|
+
return typeof configuredDir === "string" && configuredDir.trim().length > 0 ? path7.resolve(configuredDir) : path7.join(context.homeDir, ".claude");
|
|
202
220
|
}
|
|
203
221
|
function geminiConfigDirectory(context) {
|
|
204
222
|
const configuredHome = context.env.GEMINI_CLI_HOME;
|
|
205
|
-
const homeRoot = typeof configuredHome === "string" && configuredHome.trim().length > 0 ?
|
|
206
|
-
return
|
|
223
|
+
const homeRoot = typeof configuredHome === "string" && configuredHome.trim().length > 0 ? path7.resolve(configuredHome) : context.homeDir;
|
|
224
|
+
return path7.join(homeRoot, ".gemini");
|
|
207
225
|
}
|
|
208
226
|
|
|
209
227
|
// ../../packages/agent-targets/src/artifacts/filesystem.ts
|
|
210
228
|
import fs3 from "fs";
|
|
211
|
-
import
|
|
229
|
+
import path8 from "path";
|
|
212
230
|
var DEFAULT_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
213
231
|
"node_modules",
|
|
214
232
|
"dist",
|
|
@@ -225,7 +243,7 @@ var DEFAULT_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
225
243
|
"designqc-captures"
|
|
226
244
|
]);
|
|
227
245
|
function normalizeFilePath(filePath) {
|
|
228
|
-
return
|
|
246
|
+
return path8.resolve(filePath);
|
|
229
247
|
}
|
|
230
248
|
function safeReaddir(dir) {
|
|
231
249
|
try {
|
|
@@ -242,7 +260,7 @@ function walkFiles(input) {
|
|
|
242
260
|
function walk(dir, depth) {
|
|
243
261
|
if (depth > input.maxDepth) return;
|
|
244
262
|
for (const entry of safeReaddir(dir)) {
|
|
245
|
-
const entryPath =
|
|
263
|
+
const entryPath = path8.join(dir, entry.name);
|
|
246
264
|
if (entry.isDirectory()) {
|
|
247
265
|
if (!skipDirs.has(entry.name)) walk(entryPath, depth + 1);
|
|
248
266
|
continue;
|
|
@@ -436,14 +454,29 @@ function repositoryObservation(input) {
|
|
|
436
454
|
...commitHash ? { commitHash } : {}
|
|
437
455
|
};
|
|
438
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
|
+
}
|
|
439
469
|
|
|
440
470
|
// ../../packages/agent-targets/src/artifacts/targets/claude.ts
|
|
441
471
|
function claudeTranscriptCandidate(sourcePath, context, harnessInstallId) {
|
|
442
472
|
const fallbackObservedAtMs = (context.nowMs ?? Date.now)();
|
|
473
|
+
const states = /* @__PURE__ */ new Map();
|
|
443
474
|
const observations = /* @__PURE__ */ new Map();
|
|
444
475
|
for (const record of readJsonlContextRecords(sourcePath)) {
|
|
445
476
|
if (typeof record.cwd !== "string" || !record.cwd.trim()) continue;
|
|
446
477
|
const origin = context.resolveGitHubOrigin?.(record.cwd);
|
|
478
|
+
const state = origin?.gitState ?? context.resolveGitState?.(record.cwd);
|
|
479
|
+
if (state) states.set(state.worktreeRoot, state);
|
|
447
480
|
if (!origin) continue;
|
|
448
481
|
const observation = repositoryObservation({
|
|
449
482
|
repository: origin.repository,
|
|
@@ -458,7 +491,10 @@ function claudeTranscriptCandidate(sourcePath, context, harnessInstallId) {
|
|
|
458
491
|
return transcriptCandidate({
|
|
459
492
|
targetId: "claude",
|
|
460
493
|
sourcePath,
|
|
461
|
-
metadata:
|
|
494
|
+
metadata: {
|
|
495
|
+
...harnessInstallId ? { harnessInstallId } : {},
|
|
496
|
+
...localGitStateMetadata([...states.values()])
|
|
497
|
+
},
|
|
462
498
|
repositoryObservations: [...observations.values()]
|
|
463
499
|
});
|
|
464
500
|
}
|
|
@@ -467,9 +503,9 @@ var claudeArtifactDiscovery = Object.freeze({
|
|
|
467
503
|
discover: (context) => {
|
|
468
504
|
const { homeDir, env } = context;
|
|
469
505
|
const configDir = claudeConfigDirectory({ homeDir, env });
|
|
470
|
-
const harnessInstallId = readClaudeMachineId(
|
|
506
|
+
const harnessInstallId = readClaudeMachineId(path9.join(configDir, ".claude.json")) ?? readClaudeMachineId(path9.join(homeDir, ".claude.json"));
|
|
471
507
|
return walkFiles({
|
|
472
|
-
root:
|
|
508
|
+
root: path9.join(configDir, "projects"),
|
|
473
509
|
maxDepth: 6,
|
|
474
510
|
includeFile: (filePath) => filePath.endsWith(".jsonl")
|
|
475
511
|
}).map(
|
|
@@ -479,10 +515,10 @@ var claudeArtifactDiscovery = Object.freeze({
|
|
|
479
515
|
});
|
|
480
516
|
|
|
481
517
|
// ../../packages/agent-targets/src/artifacts/targets/codex.ts
|
|
482
|
-
import
|
|
518
|
+
import path10 from "path";
|
|
483
519
|
var CODEX_ROLLOUT_ID = /-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl(?:\.zst)?$/i;
|
|
484
520
|
function codexRolloutId(sourcePath) {
|
|
485
|
-
return CODEX_ROLLOUT_ID.exec(
|
|
521
|
+
return CODEX_ROLLOUT_ID.exec(path10.basename(sourcePath))?.[1]?.toLowerCase() ?? null;
|
|
486
522
|
}
|
|
487
523
|
function codexTranscriptCandidate(sourcePath, readPath, store, context, harnessInstallId) {
|
|
488
524
|
const rolloutId = codexRolloutId(sourcePath);
|
|
@@ -498,6 +534,7 @@ function codexTranscriptCandidate(sourcePath, readPath, store, context, harnessI
|
|
|
498
534
|
const git = recordValue(payload.git);
|
|
499
535
|
const nativeRepository = typeof git?.repository_url === "string" ? canonicalGitHubRepository(git.repository_url) : null;
|
|
500
536
|
const origin = cwd ? context.resolveGitHubOrigin?.(cwd) : null;
|
|
537
|
+
const state = origin?.gitState ?? (cwd ? context.resolveGitState?.(cwd) : null);
|
|
501
538
|
const observations = [];
|
|
502
539
|
if (nativeRepository) {
|
|
503
540
|
observations.push(
|
|
@@ -532,7 +569,11 @@ function codexTranscriptCandidate(sourcePath, readPath, store, context, harnessI
|
|
|
532
569
|
identityKey,
|
|
533
570
|
readPath,
|
|
534
571
|
sessionId,
|
|
535
|
-
metadata: {
|
|
572
|
+
metadata: {
|
|
573
|
+
store,
|
|
574
|
+
...identityMetadata,
|
|
575
|
+
...localGitStateMetadata([state])
|
|
576
|
+
},
|
|
536
577
|
repositoryObservations: observations
|
|
537
578
|
});
|
|
538
579
|
}
|
|
@@ -552,15 +593,15 @@ var codexArtifactDiscovery = Object.freeze({
|
|
|
552
593
|
discover: (context) => {
|
|
553
594
|
const { homeDir, env } = context;
|
|
554
595
|
const configuredHome = env.CODEX_HOME?.trim();
|
|
555
|
-
const codexHome = configuredHome ?
|
|
596
|
+
const codexHome = configuredHome ? path10.resolve(configuredHome) : path10.join(homeDir, ".codex");
|
|
556
597
|
const harnessInstallId = readHarnessInstallIdFile(
|
|
557
|
-
|
|
598
|
+
path10.join(codexHome, "installation_id")
|
|
558
599
|
);
|
|
559
600
|
const roots = [
|
|
560
|
-
{ store: "sessions", root:
|
|
601
|
+
{ store: "sessions", root: path10.join(codexHome, "sessions") },
|
|
561
602
|
{
|
|
562
603
|
store: "archived_sessions",
|
|
563
|
-
root:
|
|
604
|
+
root: path10.join(codexHome, "archived_sessions")
|
|
564
605
|
}
|
|
565
606
|
];
|
|
566
607
|
const files = roots.flatMap(
|
|
@@ -598,27 +639,27 @@ var codexArtifactDiscovery = Object.freeze({
|
|
|
598
639
|
});
|
|
599
640
|
|
|
600
641
|
// ../../packages/agent-targets/src/artifacts/targets/copilot-cli.ts
|
|
601
|
-
import
|
|
642
|
+
import path11 from "path";
|
|
602
643
|
var copilotCliArtifactDiscovery = Object.freeze({
|
|
603
644
|
targetId: "copilot-cli",
|
|
604
645
|
discover: ({ homeDir }) => walkFiles({
|
|
605
|
-
root:
|
|
646
|
+
root: path11.join(homeDir, ".copilot", "session-state"),
|
|
606
647
|
maxDepth: 3,
|
|
607
|
-
includeFile: (filePath) =>
|
|
648
|
+
includeFile: (filePath) => path11.basename(filePath) === "events.jsonl"
|
|
608
649
|
}).map(
|
|
609
650
|
(sourcePath) => transcriptCandidate({ targetId: "copilot-cli", sourcePath })
|
|
610
651
|
)
|
|
611
652
|
});
|
|
612
653
|
|
|
613
654
|
// ../../packages/agent-targets/src/artifacts/targets/cursor.ts
|
|
614
|
-
import
|
|
655
|
+
import path12 from "path";
|
|
615
656
|
function hasPathSegment(filePath, segment) {
|
|
616
|
-
return normalizeFilePath(filePath).split(
|
|
657
|
+
return normalizeFilePath(filePath).split(path12.sep).includes(segment);
|
|
617
658
|
}
|
|
618
659
|
var cursorArtifactDiscovery = Object.freeze({
|
|
619
660
|
targetId: "cursor",
|
|
620
661
|
discover: ({ homeDir }) => walkFiles({
|
|
621
|
-
root:
|
|
662
|
+
root: path12.join(homeDir, ".cursor", "projects"),
|
|
622
663
|
maxDepth: 5,
|
|
623
664
|
includeFile: (filePath) => filePath.endsWith(".jsonl") && hasPathSegment(filePath, "agent-transcripts")
|
|
624
665
|
}).map(
|
|
@@ -627,11 +668,11 @@ var cursorArtifactDiscovery = Object.freeze({
|
|
|
627
668
|
});
|
|
628
669
|
|
|
629
670
|
// ../../packages/agent-targets/src/artifacts/targets/factory-droid.ts
|
|
630
|
-
import
|
|
671
|
+
import path13 from "path";
|
|
631
672
|
var factoryDroidArtifactDiscovery = Object.freeze({
|
|
632
673
|
targetId: "factory-droid",
|
|
633
674
|
discover: ({ homeDir }) => walkFiles({
|
|
634
|
-
root:
|
|
675
|
+
root: path13.join(homeDir, ".factory", "sessions"),
|
|
635
676
|
maxDepth: 4,
|
|
636
677
|
includeFile: (filePath) => filePath.endsWith(".jsonl")
|
|
637
678
|
}).map(
|
|
@@ -640,7 +681,7 @@ var factoryDroidArtifactDiscovery = Object.freeze({
|
|
|
640
681
|
});
|
|
641
682
|
|
|
642
683
|
// ../../packages/agent-targets/src/artifacts/targets/gemini.ts
|
|
643
|
-
import
|
|
684
|
+
import path14 from "path";
|
|
644
685
|
var GEMINI_DISCOVER_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
645
686
|
"bin",
|
|
646
687
|
"checkpoints",
|
|
@@ -655,15 +696,15 @@ var geminiArtifactDiscovery = Object.freeze({
|
|
|
655
696
|
discover: ({ homeDir, env }) => {
|
|
656
697
|
const geminiDir = geminiConfigDirectory({ homeDir, env });
|
|
657
698
|
const harnessInstallId = readHarnessInstallIdFile(
|
|
658
|
-
|
|
699
|
+
path14.join(geminiDir, "installation_id")
|
|
659
700
|
);
|
|
660
|
-
const root =
|
|
701
|
+
const root = path14.join(geminiDir, "tmp");
|
|
661
702
|
const files = [];
|
|
662
703
|
const seen = /* @__PURE__ */ new Set();
|
|
663
704
|
function walk(dir, depth) {
|
|
664
705
|
if (depth > 4) return;
|
|
665
706
|
for (const entry of safeReaddir(dir)) {
|
|
666
|
-
const entryPath =
|
|
707
|
+
const entryPath = path14.join(dir, entry.name);
|
|
667
708
|
if (!entry.isDirectory()) continue;
|
|
668
709
|
if (GEMINI_DISCOVER_SKIP_DIRS.has(entry.name)) continue;
|
|
669
710
|
if (entry.name === "chats") {
|
|
@@ -672,7 +713,7 @@ var geminiArtifactDiscovery = Object.freeze({
|
|
|
672
713
|
continue;
|
|
673
714
|
}
|
|
674
715
|
const sourcePath = normalizeFilePath(
|
|
675
|
-
|
|
716
|
+
path14.join(entryPath, chatEntry.name)
|
|
676
717
|
);
|
|
677
718
|
if (seen.has(sourcePath)) continue;
|
|
678
719
|
seen.add(sourcePath);
|
|
@@ -695,17 +736,17 @@ var geminiArtifactDiscovery = Object.freeze({
|
|
|
695
736
|
});
|
|
696
737
|
|
|
697
738
|
// ../../packages/agent-targets/src/artifacts/targets/grok.ts
|
|
698
|
-
import
|
|
739
|
+
import path15 from "path";
|
|
699
740
|
function grokHome(homeDir, env) {
|
|
700
741
|
const configuredHome = env.GROK_HOME?.trim();
|
|
701
|
-
return configuredHome ?
|
|
742
|
+
return configuredHome ? path15.resolve(configuredHome) : path15.join(homeDir, ".grok");
|
|
702
743
|
}
|
|
703
744
|
var grokArtifactDiscovery = Object.freeze({
|
|
704
745
|
targetId: "grok",
|
|
705
746
|
discover: ({ homeDir, env }) => walkFiles({
|
|
706
|
-
root:
|
|
747
|
+
root: path15.join(grokHome(homeDir, env), "sessions"),
|
|
707
748
|
maxDepth: 5,
|
|
708
|
-
includeFile: (filePath) =>
|
|
749
|
+
includeFile: (filePath) => path15.basename(filePath) === "updates.jsonl"
|
|
709
750
|
}).map(
|
|
710
751
|
(sourcePath) => transcriptCandidate({ targetId: "grok", sourcePath })
|
|
711
752
|
)
|
|
@@ -713,24 +754,24 @@ var grokArtifactDiscovery = Object.freeze({
|
|
|
713
754
|
|
|
714
755
|
// ../../packages/agent-targets/src/artifacts/targets/mini-swe-agent.ts
|
|
715
756
|
import fs6 from "fs";
|
|
716
|
-
import
|
|
757
|
+
import path16 from "path";
|
|
717
758
|
var SESSION_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
718
759
|
function dataDirectory({ homeDir, env }) {
|
|
719
760
|
if (env.FML_DATA_DIR?.trim()) {
|
|
720
|
-
if (!
|
|
761
|
+
if (!path16.isAbsolute(env.FML_DATA_DIR)) {
|
|
721
762
|
throw new Error("FML_DATA_DIR must be an absolute path");
|
|
722
763
|
}
|
|
723
|
-
return
|
|
764
|
+
return path16.normalize(env.FML_DATA_DIR);
|
|
724
765
|
}
|
|
725
766
|
if (process.platform === "darwin") {
|
|
726
|
-
return
|
|
767
|
+
return path16.join(homeDir, "Library", "Application Support", "fml");
|
|
727
768
|
}
|
|
728
769
|
if (process.platform === "win32") {
|
|
729
|
-
const roaming = env.APPDATA &&
|
|
730
|
-
return
|
|
770
|
+
const roaming = env.APPDATA && path16.isAbsolute(env.APPDATA) ? env.APPDATA : path16.join(homeDir, "AppData", "Roaming");
|
|
771
|
+
return path16.join(roaming, "fml");
|
|
731
772
|
}
|
|
732
|
-
const xdgDataHome = env.XDG_DATA_HOME &&
|
|
733
|
-
return
|
|
773
|
+
const xdgDataHome = env.XDG_DATA_HOME && path16.isAbsolute(env.XDG_DATA_HOME) ? env.XDG_DATA_HOME : path16.join(homeDir, ".local", "share");
|
|
774
|
+
return path16.join(xdgDataHome, "fml");
|
|
734
775
|
}
|
|
735
776
|
function snapshotCandidate(sourcePath, context) {
|
|
736
777
|
let file;
|
|
@@ -794,7 +835,7 @@ function snapshotCandidate(sourcePath, context) {
|
|
|
794
835
|
var miniSweAgentArtifactDiscovery = Object.freeze({
|
|
795
836
|
targetId: "mini-swe-agent",
|
|
796
837
|
discover: (context) => walkFiles({
|
|
797
|
-
root:
|
|
838
|
+
root: path16.join(dataDirectory(context), "mini-swe-agent", "trajectories"),
|
|
798
839
|
maxDepth: 0,
|
|
799
840
|
includeFile: (filePath) => filePath.endsWith(".traj.json")
|
|
800
841
|
}).flatMap((sourcePath) => {
|
|
@@ -804,7 +845,7 @@ var miniSweAgentArtifactDiscovery = Object.freeze({
|
|
|
804
845
|
});
|
|
805
846
|
|
|
806
847
|
// ../../packages/agent-targets/src/artifacts/targets/pi.ts
|
|
807
|
-
import
|
|
848
|
+
import path17 from "path";
|
|
808
849
|
|
|
809
850
|
// ../../packages/agent-targets/src/artifacts/pi-repository-origin.ts
|
|
810
851
|
import { z } from "zod";
|
|
@@ -812,6 +853,12 @@ var PI_REPOSITORY_ORIGIN_ENTRY_TYPE = "fml-repository-origin";
|
|
|
812
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());
|
|
813
854
|
var PiRepositoryOriginDataSchema = z.object({
|
|
814
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(),
|
|
815
862
|
repository: RepositorySlugSchema.nullable(),
|
|
816
863
|
cwd: z.string().min(1).refine(
|
|
817
864
|
(cwd) => cwd.trim().length > 0 && !new RegExp("\\p{Cc}", "u").test(cwd) && Buffer.byteLength(cwd, "utf8") <= 4096
|
|
@@ -853,12 +900,15 @@ function piTranscriptCandidate(sourcePath) {
|
|
|
853
900
|
targetId: "pi",
|
|
854
901
|
sourcePath,
|
|
855
902
|
sessionId,
|
|
903
|
+
metadata: localGitStateMetadata([snapshot?.gitState], "pi_origin"),
|
|
856
904
|
repositoryObservations: snapshot?.repository ? [
|
|
857
905
|
repositoryObservation({
|
|
858
906
|
repository: snapshot.repository,
|
|
859
907
|
source: "git_origin",
|
|
860
908
|
observedAtMs: snapshot.observedAtMs,
|
|
861
|
-
cwd: snapshot.cwd
|
|
909
|
+
cwd: snapshot.cwd,
|
|
910
|
+
branch: snapshot.gitState?.branch,
|
|
911
|
+
commitHash: snapshot.gitState?.commitHash
|
|
862
912
|
})
|
|
863
913
|
] : []
|
|
864
914
|
});
|
|
@@ -866,9 +916,8 @@ function piTranscriptCandidate(sourcePath) {
|
|
|
866
916
|
var piArtifactDiscovery = Object.freeze({
|
|
867
917
|
targetId: "pi",
|
|
868
918
|
discover: (context) => {
|
|
869
|
-
const { homeDir } = context;
|
|
870
919
|
return walkFiles({
|
|
871
|
-
root:
|
|
920
|
+
root: path17.join(resolvePiAgentDir(context), "sessions"),
|
|
872
921
|
maxDepth: 8,
|
|
873
922
|
includeFile: (filePath) => filePath.endsWith(".jsonl"),
|
|
874
923
|
skipDirs: PI_SKIP_DIRS
|
|
@@ -902,12 +951,12 @@ function discoverTargetArtifactCandidates(context) {
|
|
|
902
951
|
// ../../packages/agent-targets/src/artifacts/materialize.ts
|
|
903
952
|
import { createHash as createHash3 } from "crypto";
|
|
904
953
|
import fs7 from "fs";
|
|
905
|
-
import
|
|
954
|
+
import path18 from "path";
|
|
906
955
|
import zlib from "zlib";
|
|
907
956
|
var MAX_MATERIALIZED_ARTIFACT_BYTES = 100 * 1024 * 1024;
|
|
908
957
|
var DEFAULT_MATERIALIZED_CACHE_BYTES = 2 * 1024 * 1024 * 1024;
|
|
909
958
|
function cacheEntryName(sourcePath, stat) {
|
|
910
|
-
const identity = `${
|
|
959
|
+
const identity = `${path18.resolve(sourcePath)}\0${stat.size}\0${Math.floor(
|
|
911
960
|
stat.mtimeMs
|
|
912
961
|
)}`;
|
|
913
962
|
const digest = createHash3("sha256").update(identity).digest("hex");
|
|
@@ -931,7 +980,7 @@ function materializedArtifactPath(input) {
|
|
|
931
980
|
try {
|
|
932
981
|
const stat = fs7.statSync(input.sourcePath);
|
|
933
982
|
if (!stat.isFile() || stat.size === 0) return null;
|
|
934
|
-
return
|
|
983
|
+
return path18.join(input.cacheDir, cacheEntryName(input.sourcePath, stat));
|
|
935
984
|
} catch {
|
|
936
985
|
return null;
|
|
937
986
|
}
|
|
@@ -944,7 +993,7 @@ function materializeCompressedArtifact(input) {
|
|
|
944
993
|
return null;
|
|
945
994
|
}
|
|
946
995
|
if (!stat.isFile() || stat.size === 0) return null;
|
|
947
|
-
const cachePath =
|
|
996
|
+
const cachePath = path18.join(
|
|
948
997
|
input.cacheDir,
|
|
949
998
|
cacheEntryName(input.sourcePath, stat)
|
|
950
999
|
);
|
|
@@ -985,7 +1034,7 @@ function pruneMaterializedCache(input) {
|
|
|
985
1034
|
const files = [];
|
|
986
1035
|
for (const entry of entries) {
|
|
987
1036
|
if (!entry.isFile()) continue;
|
|
988
|
-
const filePath =
|
|
1037
|
+
const filePath = path18.join(input.cacheDir, entry.name);
|
|
989
1038
|
try {
|
|
990
1039
|
const stat = fs7.statSync(filePath);
|
|
991
1040
|
files.push({ path: filePath, size: stat.size, atimeMs: stat.atimeMs });
|
|
@@ -1012,78 +1061,18 @@ function pruneMaterializedCache(input) {
|
|
|
1012
1061
|
}
|
|
1013
1062
|
|
|
1014
1063
|
// ../../packages/panopticon/src/repository-context.ts
|
|
1015
|
-
import { execFileSync } from "child_process";
|
|
1016
|
-
import { createHash as createHash4 } from "crypto";
|
|
1017
|
-
import fs8 from "fs";
|
|
1018
|
-
import path18 from "path";
|
|
1019
|
-
var MAX_CWD_BYTES2 = 4096;
|
|
1020
|
-
var GIT_OUTPUT_BYTES = 16 * 1024;
|
|
1021
|
-
var GIT_CONFIG_OUTPUT_BYTES = 4 * 1024 * 1024;
|
|
1022
|
-
var GIT_TIMEOUT_MS = 1e3;
|
|
1023
1064
|
var DEFAULT_GITHUB_ORIGIN_CACHE_MAX_ENTRIES = 512;
|
|
1024
|
-
var
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
}
|
|
1033
|
-
function
|
|
1034
|
-
|
|
1035
|
-
try {
|
|
1036
|
-
return execFileSync("git", ["-C", cwd, ...args], {
|
|
1037
|
-
encoding: "utf8",
|
|
1038
|
-
maxBuffer,
|
|
1039
|
-
timeout: GIT_TIMEOUT_MS,
|
|
1040
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
1041
|
-
windowsHide: true
|
|
1042
|
-
}).trim() || null;
|
|
1043
|
-
} catch (error) {
|
|
1044
|
-
const status = error && typeof error === "object" && "status" in error ? error.status : void 0;
|
|
1045
|
-
if (status === 2 && args.length === 3 && args[0] === "remote" && args[1] === "get-url" && args[2] === "origin") {
|
|
1046
|
-
return null;
|
|
1047
|
-
}
|
|
1048
|
-
throw new ReadOnlyGitCommandError();
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
function resolveGitHubOriginResult(cwd, runGit = runReadOnlyGit) {
|
|
1052
|
-
let remote;
|
|
1053
|
-
try {
|
|
1054
|
-
remote = runGit(cwd, ["remote", "get-url", "origin"]);
|
|
1055
|
-
} catch {
|
|
1056
|
-
return { origin: null, definitive: false };
|
|
1057
|
-
}
|
|
1058
|
-
const repository = remote ? canonicalGitHubRepository(remote) : null;
|
|
1059
|
-
if (!repository) return { origin: null, definitive: true };
|
|
1060
|
-
let branchResult;
|
|
1061
|
-
try {
|
|
1062
|
-
branchResult = runGit(cwd, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
1063
|
-
} catch {
|
|
1064
|
-
return { origin: { repository }, definitive: false };
|
|
1065
|
-
}
|
|
1066
|
-
const branch = branchResult === "HEAD" ? null : branchResult;
|
|
1067
|
-
let commitHash;
|
|
1068
|
-
try {
|
|
1069
|
-
commitHash = runGit(cwd, ["rev-parse", "HEAD"]);
|
|
1070
|
-
} catch {
|
|
1071
|
-
return {
|
|
1072
|
-
origin: { repository, ...branch ? { branch } : {} },
|
|
1073
|
-
definitive: false
|
|
1074
|
-
};
|
|
1075
|
-
}
|
|
1076
|
-
return {
|
|
1077
|
-
origin: {
|
|
1078
|
-
repository,
|
|
1079
|
-
...branch ? { branch } : {},
|
|
1080
|
-
...commitHash ? { commitHash } : {}
|
|
1081
|
-
},
|
|
1082
|
-
definitive: true
|
|
1083
|
-
};
|
|
1084
|
-
}
|
|
1085
|
-
function resolveGitHubOrigin(cwd, runGit = runReadOnlyGit) {
|
|
1086
|
-
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));
|
|
1087
1076
|
}
|
|
1088
1077
|
function createMeasuredGitHubOriginResolver(resolve = (cwd) => resolveGitHubOrigin(cwd), nowMs = () => performance.now(), options = {}) {
|
|
1089
1078
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -1151,173 +1140,29 @@ function createMeasuredGitHubOriginResolver(resolve = (cwd) => resolveGitHubOrig
|
|
|
1151
1140
|
})
|
|
1152
1141
|
};
|
|
1153
1142
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
const
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
function packedRefsIdentity(filePath) {
|
|
1166
|
-
try {
|
|
1167
|
-
const stat = fs8.statSync(filePath, { bigint: true });
|
|
1168
|
-
if (!stat.isFile() || stat.ino === 0n) return null;
|
|
1169
|
-
return [stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(
|
|
1170
|
-
":"
|
|
1171
|
-
);
|
|
1172
|
-
} catch (error) {
|
|
1173
|
-
const code = error && typeof error === "object" && "code" in error ? error.code : void 0;
|
|
1174
|
-
return code === "ENOENT" || code === "ENOTDIR" ? "missing" : null;
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
function effectiveConfigIdentity(cwd) {
|
|
1178
|
-
if (["GIT_CONFIG", "GIT_DIR", "GIT_COMMON_DIR", "GIT_WORK_TREE"].some(
|
|
1179
|
-
(name) => process.env[name] !== void 0
|
|
1180
|
-
)) {
|
|
1181
|
-
return null;
|
|
1182
|
-
}
|
|
1183
|
-
try {
|
|
1184
|
-
const config = runReadOnlyGit(
|
|
1185
|
-
cwd,
|
|
1186
|
-
["config", "--includes", "--null", "--list"],
|
|
1187
|
-
GIT_CONFIG_OUTPUT_BYTES
|
|
1188
|
-
);
|
|
1189
|
-
return createHash4("sha256").update(config ?? "").digest("hex");
|
|
1190
|
-
} catch {
|
|
1191
|
-
return null;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
function readSmallText(filePath) {
|
|
1195
|
-
try {
|
|
1196
|
-
return fs8.readFileSync(filePath, "utf8").trim();
|
|
1197
|
-
} catch {
|
|
1198
|
-
return null;
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
function findGitDirectory(cwd) {
|
|
1202
|
-
let current = path18.resolve(cwd);
|
|
1203
|
-
for (; ; ) {
|
|
1204
|
-
const candidate = path18.join(current, ".git");
|
|
1205
|
-
let stat;
|
|
1206
|
-
try {
|
|
1207
|
-
stat = fs8.statSync(candidate);
|
|
1208
|
-
} catch {
|
|
1209
|
-
stat = void 0;
|
|
1210
|
-
}
|
|
1211
|
-
if (stat?.isDirectory()) {
|
|
1212
|
-
return { gitDir: candidate, commonDir: candidate };
|
|
1213
|
-
}
|
|
1214
|
-
if (stat?.isFile()) {
|
|
1215
|
-
const pointer = readSmallText(candidate);
|
|
1216
|
-
const match = pointer ? /^gitdir:\s*(.+)$/u.exec(pointer) : null;
|
|
1217
|
-
if (!match?.[1]) return null;
|
|
1218
|
-
const gitDir = path18.resolve(current, match[1]);
|
|
1219
|
-
const common = readSmallText(path18.join(gitDir, "commondir"));
|
|
1220
|
-
return {
|
|
1221
|
-
gitDir,
|
|
1222
|
-
commonDir: common ? path18.resolve(gitDir, common) : gitDir
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
1225
|
-
const parent = path18.dirname(current);
|
|
1226
|
-
if (parent === current) return null;
|
|
1227
|
-
current = parent;
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
function checkoutSignature(layout, cwd) {
|
|
1231
|
-
const headPath = path18.join(layout.gitDir, "HEAD");
|
|
1232
|
-
const head = readSmallText(headPath);
|
|
1233
|
-
const configIdentity = effectiveConfigIdentity(cwd);
|
|
1234
|
-
if (head === null || configIdentity === null) {
|
|
1235
|
-
return null;
|
|
1236
|
-
}
|
|
1237
|
-
const parts = [layout.gitDir, head, configIdentity];
|
|
1238
|
-
const ref = /^ref:\s*(.+)$/u.exec(head)?.[1];
|
|
1239
|
-
if (ref) {
|
|
1240
|
-
const looseRefPath = path18.join(layout.commonDir, ref);
|
|
1241
|
-
if (/^ref:/u.test(readSmallText(looseRefPath) ?? "")) return null;
|
|
1242
|
-
const looseRefIdentity = fileContentIdentity(looseRefPath);
|
|
1243
|
-
const packedIdentity = packedRefsIdentity(
|
|
1244
|
-
path18.join(layout.commonDir, "packed-refs")
|
|
1245
|
-
);
|
|
1246
|
-
const reftableIdentity = fileContentIdentity(
|
|
1247
|
-
path18.join(layout.commonDir, "reftable", "tables.list")
|
|
1248
|
-
);
|
|
1249
|
-
if (!looseRefIdentity || !packedIdentity || !reftableIdentity || looseRefIdentity === "missing" && packedIdentity === "missing" && reftableIdentity === "missing") {
|
|
1250
|
-
return null;
|
|
1251
|
-
}
|
|
1252
|
-
parts.push(looseRefIdentity, packedIdentity, reftableIdentity);
|
|
1253
|
-
}
|
|
1254
|
-
return parts.join("\0");
|
|
1255
|
-
}
|
|
1256
|
-
function readPersistentOriginCache(cacheFile) {
|
|
1257
|
-
try {
|
|
1258
|
-
const parsed = JSON.parse(fs8.readFileSync(cacheFile, "utf8"));
|
|
1259
|
-
if (parsed && typeof parsed === "object" && parsed.schemaVersion === PERSISTENT_ORIGIN_CACHE_SCHEMA_VERSION && parsed.entries && typeof parsed.entries === "object") {
|
|
1260
|
-
return parsed;
|
|
1261
|
-
}
|
|
1262
|
-
} catch {
|
|
1263
|
-
}
|
|
1264
|
-
return { schemaVersion: PERSISTENT_ORIGIN_CACHE_SCHEMA_VERSION, entries: {} };
|
|
1265
|
-
}
|
|
1266
|
-
function writePersistentOriginCache(cacheFile, cache) {
|
|
1267
|
-
const temporary = `${cacheFile}.${process.pid}.tmp`;
|
|
1268
|
-
try {
|
|
1269
|
-
fs8.mkdirSync(path18.dirname(cacheFile), { recursive: true, mode: 448 });
|
|
1270
|
-
fs8.writeFileSync(temporary, `${JSON.stringify(cache)}
|
|
1271
|
-
`, { mode: 384 });
|
|
1272
|
-
fs8.renameSync(temporary, cacheFile);
|
|
1273
|
-
} catch {
|
|
1274
|
-
try {
|
|
1275
|
-
fs8.rmSync(temporary, { force: true });
|
|
1276
|
-
} catch {
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
function createPersistentGitHubOriginResolver(options) {
|
|
1281
|
-
const maxEntries = options.maxEntries ?? DEFAULT_PERSISTENT_ORIGIN_CACHE_MAX_ENTRIES;
|
|
1282
|
-
const cache = readPersistentOriginCache(options.cacheFile);
|
|
1283
|
-
const entries = new Map(Object.entries(cache.entries));
|
|
1284
|
-
const remember = (cwd, entry) => {
|
|
1285
|
-
entries.delete(cwd);
|
|
1286
|
-
entries.set(cwd, entry);
|
|
1287
|
-
while (entries.size > maxEntries) {
|
|
1288
|
-
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;
|
|
1289
1152
|
if (oldest === void 0) break;
|
|
1290
|
-
|
|
1153
|
+
states.delete(oldest);
|
|
1291
1154
|
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
if (!layout) return null;
|
|
1301
|
-
const signature = checkoutSignature(layout, cwd);
|
|
1302
|
-
const cached = entries.get(cwd);
|
|
1303
|
-
if (signature !== null && cached && cached.signature === signature) {
|
|
1304
|
-
return cached.origin;
|
|
1305
|
-
}
|
|
1306
|
-
try {
|
|
1307
|
-
const result = options.resolve ? { origin: options.resolve(cwd), definitive: true } : resolveGitHubOriginResult(cwd);
|
|
1308
|
-
if (signature !== null && result.definitive) {
|
|
1309
|
-
remember(cwd, { signature, origin: result.origin });
|
|
1310
|
-
}
|
|
1311
|
-
return result.origin;
|
|
1312
|
-
} catch {
|
|
1313
|
-
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));
|
|
1314
1163
|
}
|
|
1315
1164
|
};
|
|
1316
1165
|
}
|
|
1317
|
-
function createArtifactDiscoveryGitHubOriginResolver(options = {}) {
|
|
1318
|
-
const resolve = options.cacheFile ? createPersistentGitHubOriginResolver({ cacheFile: options.cacheFile }) : (cwd) => resolveGitHubOrigin(cwd);
|
|
1319
|
-
return createMeasuredGitHubOriginResolver(resolve, () => performance.now());
|
|
1320
|
-
}
|
|
1321
1166
|
|
|
1322
1167
|
// ../../packages/panopticon/src/artifacts.ts
|
|
1323
1168
|
var RAW_ARTIFACT_ENDPOINT = "/v1/ingest/raw-artifact";
|
|
@@ -1360,7 +1205,7 @@ function isAbortError(error) {
|
|
|
1360
1205
|
}
|
|
1361
1206
|
function safeStat(filePath) {
|
|
1362
1207
|
try {
|
|
1363
|
-
return
|
|
1208
|
+
return fs8.statSync(filePath);
|
|
1364
1209
|
} catch {
|
|
1365
1210
|
return null;
|
|
1366
1211
|
}
|
|
@@ -1373,7 +1218,7 @@ function artifactReadPath(artifact) {
|
|
|
1373
1218
|
}
|
|
1374
1219
|
function statCandidateSource(sourcePath, transientStatErrors) {
|
|
1375
1220
|
try {
|
|
1376
|
-
return
|
|
1221
|
+
return fs8.statSync(sourcePath);
|
|
1377
1222
|
} catch (error) {
|
|
1378
1223
|
if (error.code === "ENOENT") return null;
|
|
1379
1224
|
if (transientStatErrors === "throw") throw error;
|
|
@@ -1430,6 +1275,7 @@ function discoverArtifacts(options = {}) {
|
|
|
1430
1275
|
env,
|
|
1431
1276
|
maxFileBytes: maxBytes,
|
|
1432
1277
|
resolveGitHubOrigin: repositoryResolution.resolve,
|
|
1278
|
+
resolveGitState: repositoryResolution.resolveState,
|
|
1433
1279
|
...options.materializeArtifact ? { materializeArtifact: options.materializeArtifact } : {}
|
|
1434
1280
|
});
|
|
1435
1281
|
const byKey = /* @__PURE__ */ new Map();
|
|
@@ -1494,7 +1340,7 @@ function readUploadThrottles(value) {
|
|
|
1494
1340
|
}
|
|
1495
1341
|
function readArtifactQueue(queueFile) {
|
|
1496
1342
|
try {
|
|
1497
|
-
const parsed = JSON.parse(
|
|
1343
|
+
const parsed = JSON.parse(fs8.readFileSync(queueFile, "utf8"));
|
|
1498
1344
|
if (!parsed || typeof parsed !== "object") return emptyQueue();
|
|
1499
1345
|
const record = parsed;
|
|
1500
1346
|
if (record.schemaVersion !== RAW_ARTIFACT_SCHEMA_VERSION) {
|
|
@@ -1510,16 +1356,52 @@ function readArtifactQueue(queueFile) {
|
|
|
1510
1356
|
return emptyQueue();
|
|
1511
1357
|
}
|
|
1512
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
|
+
}
|
|
1513
1371
|
function writeArtifactQueue(queueFile, queue) {
|
|
1514
|
-
|
|
1372
|
+
fs8.mkdirSync(path19.dirname(queueFile), { recursive: true, mode: 448 });
|
|
1515
1373
|
const tempFile = `${queueFile}.${process.pid}.${Date.now()}.tmp`;
|
|
1516
|
-
|
|
1517
|
-
`, {
|
|
1518
|
-
mode: 384
|
|
1519
|
-
});
|
|
1520
|
-
fs9.renameSync(tempFile, queueFile);
|
|
1374
|
+
const fd = fs8.openSync(tempFile, "w", 384);
|
|
1521
1375
|
try {
|
|
1522
|
-
|
|
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);
|
|
1403
|
+
try {
|
|
1404
|
+
fs8.chmodSync(queueFile, 384);
|
|
1523
1405
|
} catch {
|
|
1524
1406
|
}
|
|
1525
1407
|
}
|
|
@@ -1539,7 +1421,7 @@ function shouldStartNewGeneration(input) {
|
|
|
1539
1421
|
if (input.existing.source === "mini-swe-agent") {
|
|
1540
1422
|
if (input.existing.contentSha256) {
|
|
1541
1423
|
try {
|
|
1542
|
-
return
|
|
1424
|
+
return createHash4("sha256").update(fs8.readFileSync(input.nextReadPath)).digest("hex") !== input.existing.contentSha256;
|
|
1543
1425
|
} catch {
|
|
1544
1426
|
}
|
|
1545
1427
|
}
|
|
@@ -1549,7 +1431,7 @@ function shouldStartNewGeneration(input) {
|
|
|
1549
1431
|
if (input.nextSizeBytes < input.existing.sizeBytes) return true;
|
|
1550
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) {
|
|
1551
1433
|
try {
|
|
1552
|
-
const contentSha256 =
|
|
1434
|
+
const contentSha256 = createHash4("sha256").update(fs8.readFileSync(input.nextReadPath)).digest("hex");
|
|
1553
1435
|
if (contentSha256 === input.existing.contentSha256) return false;
|
|
1554
1436
|
} catch {
|
|
1555
1437
|
}
|
|
@@ -1660,13 +1542,24 @@ function metadataForGeneration(input) {
|
|
|
1660
1542
|
observations: input.candidateObservations,
|
|
1661
1543
|
metadataWithoutContext
|
|
1662
1544
|
});
|
|
1663
|
-
|
|
1545
|
+
const metadata = {
|
|
1664
1546
|
...metadataWithoutContext,
|
|
1665
1547
|
...hasInstallIdentity ? {
|
|
1666
1548
|
installIdentitySchemaVersion: RAW_ARTIFACT_IDENTITY_SCHEMA_VERSION
|
|
1667
1549
|
} : {},
|
|
1668
1550
|
...repositoryContext ? { repositoryContext } : {}
|
|
1669
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;
|
|
1670
1563
|
}
|
|
1671
1564
|
function snapshotCandidate2(candidate, existing, nowMs, maxFileBytes, transientStatErrors = "ignore", observerIdentity) {
|
|
1672
1565
|
const sourcePath = normalizeFilePath2(candidate.sourcePath);
|
|
@@ -1883,7 +1776,7 @@ function sameSourceRevision(left, right) {
|
|
|
1883
1776
|
}
|
|
1884
1777
|
function safeSourceRevision(filePath) {
|
|
1885
1778
|
try {
|
|
1886
|
-
const stat =
|
|
1779
|
+
const stat = fs8.statSync(filePath, { bigint: true });
|
|
1887
1780
|
return stat.isFile() ? sourceRevisionFromStat(stat) : null;
|
|
1888
1781
|
} catch {
|
|
1889
1782
|
return null;
|
|
@@ -1895,7 +1788,7 @@ function readExactRange(fd, startByte, endByte) {
|
|
|
1895
1788
|
const buffer = Buffer.alloc(sizeBytes);
|
|
1896
1789
|
let offset = 0;
|
|
1897
1790
|
while (offset < sizeBytes) {
|
|
1898
|
-
const bytesRead =
|
|
1791
|
+
const bytesRead = fs8.readSync(
|
|
1899
1792
|
fd,
|
|
1900
1793
|
buffer,
|
|
1901
1794
|
offset,
|
|
@@ -1914,19 +1807,19 @@ function readFileRangeAtRevision(filePath, startByte, endByte, expectedRevision)
|
|
|
1914
1807
|
}
|
|
1915
1808
|
let fd;
|
|
1916
1809
|
try {
|
|
1917
|
-
fd =
|
|
1810
|
+
fd = fs8.openSync(filePath, "r");
|
|
1918
1811
|
} catch {
|
|
1919
1812
|
return null;
|
|
1920
1813
|
}
|
|
1921
1814
|
try {
|
|
1922
1815
|
const openedRevision = sourceRevisionFromStat(
|
|
1923
|
-
|
|
1816
|
+
fs8.fstatSync(fd, { bigint: true })
|
|
1924
1817
|
);
|
|
1925
1818
|
if (!sameSourceRevision(pathRevisionBefore, openedRevision)) return null;
|
|
1926
1819
|
const bytes = readExactRange(fd, startByte, endByte);
|
|
1927
1820
|
if (!bytes) return null;
|
|
1928
1821
|
const revisionAfterRead = sourceRevisionFromStat(
|
|
1929
|
-
|
|
1822
|
+
fs8.fstatSync(fd, { bigint: true })
|
|
1930
1823
|
);
|
|
1931
1824
|
const pathRevisionAfter = safeSourceRevision(filePath);
|
|
1932
1825
|
if (!sameSourceRevision(openedRevision, revisionAfterRead) || !pathRevisionAfter || !sameSourceRevision(openedRevision, pathRevisionAfter)) {
|
|
@@ -1936,7 +1829,7 @@ function readFileRangeAtRevision(filePath, startByte, endByte, expectedRevision)
|
|
|
1936
1829
|
} catch {
|
|
1937
1830
|
return null;
|
|
1938
1831
|
} finally {
|
|
1939
|
-
|
|
1832
|
+
fs8.closeSync(fd);
|
|
1940
1833
|
}
|
|
1941
1834
|
}
|
|
1942
1835
|
function uploadMetadata(input) {
|
|
@@ -2068,18 +1961,18 @@ function validateCheckpointPrefix(input) {
|
|
|
2068
1961
|
}
|
|
2069
1962
|
let fd;
|
|
2070
1963
|
try {
|
|
2071
|
-
fd =
|
|
1964
|
+
fd = fs8.openSync(input.sourcePath, "r");
|
|
2072
1965
|
} catch {
|
|
2073
1966
|
return { status: "changed" };
|
|
2074
1967
|
}
|
|
2075
1968
|
try {
|
|
2076
1969
|
const openedRevision = sourceRevisionFromStat(
|
|
2077
|
-
|
|
1970
|
+
fs8.fstatSync(fd, { bigint: true })
|
|
2078
1971
|
);
|
|
2079
1972
|
if (!sameSourceRevision(pathRevisionBefore, openedRevision)) {
|
|
2080
1973
|
return { status: "changed" };
|
|
2081
1974
|
}
|
|
2082
|
-
const contentHash =
|
|
1975
|
+
const contentHash = createHash4("sha256");
|
|
2083
1976
|
let checkpointMismatch = false;
|
|
2084
1977
|
for (const checkpoint of checkpoints) {
|
|
2085
1978
|
const chunk = readExactRange(
|
|
@@ -2094,7 +1987,7 @@ function validateCheckpointPrefix(input) {
|
|
|
2094
1987
|
contentHash.update(chunk);
|
|
2095
1988
|
}
|
|
2096
1989
|
const revisionAfterRead = sourceRevisionFromStat(
|
|
2097
|
-
|
|
1990
|
+
fs8.fstatSync(fd, { bigint: true })
|
|
2098
1991
|
);
|
|
2099
1992
|
const pathRevisionAfter = safeSourceRevision(input.sourcePath);
|
|
2100
1993
|
if (!sameSourceRevision(openedRevision, revisionAfterRead) || !pathRevisionAfter || !sameSourceRevision(openedRevision, pathRevisionAfter)) {
|
|
@@ -2109,7 +2002,7 @@ function validateCheckpointPrefix(input) {
|
|
|
2109
2002
|
} catch {
|
|
2110
2003
|
return { status: "changed" };
|
|
2111
2004
|
} finally {
|
|
2112
|
-
|
|
2005
|
+
fs8.closeSync(fd);
|
|
2113
2006
|
}
|
|
2114
2007
|
}
|
|
2115
2008
|
function validatedPrefixStillApplies(prefix, entry, uploadDestinationId, revision) {
|
|
@@ -2243,14 +2136,14 @@ function defaultIsPidAlive(pid) {
|
|
|
2243
2136
|
}
|
|
2244
2137
|
function readQueueLockHolder(lockFile) {
|
|
2245
2138
|
try {
|
|
2246
|
-
const parsed = JSON.parse(
|
|
2139
|
+
const parsed = JSON.parse(fs8.readFileSync(lockFile, "utf8"));
|
|
2247
2140
|
if (!parsed || typeof parsed !== "object") return null;
|
|
2248
2141
|
const record = parsed;
|
|
2249
2142
|
if (typeof record.pid !== "number" || typeof record.timestampMs !== "number") {
|
|
2250
2143
|
return null;
|
|
2251
2144
|
}
|
|
2252
2145
|
const ownerToken = typeof record.ownerToken === "string" ? record.ownerToken : void 0;
|
|
2253
|
-
const timestampMs = ownerToken ? Math.max(record.timestampMs,
|
|
2146
|
+
const timestampMs = ownerToken ? Math.max(record.timestampMs, fs8.statSync(lockFile).mtimeMs) : record.timestampMs;
|
|
2254
2147
|
return { pid: record.pid, timestampMs, ownerToken };
|
|
2255
2148
|
} catch {
|
|
2256
2149
|
return null;
|
|
@@ -2258,8 +2151,8 @@ function readQueueLockHolder(lockFile) {
|
|
|
2258
2151
|
}
|
|
2259
2152
|
function queueLockFileMatchesOwner(lockFile, fd, ownerToken) {
|
|
2260
2153
|
try {
|
|
2261
|
-
const openStat =
|
|
2262
|
-
const pathStat =
|
|
2154
|
+
const openStat = fs8.fstatSync(fd);
|
|
2155
|
+
const pathStat = fs8.statSync(lockFile);
|
|
2263
2156
|
if (openStat.dev !== pathStat.dev || openStat.ino !== pathStat.ino) {
|
|
2264
2157
|
return false;
|
|
2265
2158
|
}
|
|
@@ -2270,14 +2163,14 @@ function queueLockFileMatchesOwner(lockFile, fd, ownerToken) {
|
|
|
2270
2163
|
}
|
|
2271
2164
|
function acquireQueueLock(queueFile, deps) {
|
|
2272
2165
|
const lockFile = queueLockFile(queueFile);
|
|
2273
|
-
|
|
2166
|
+
fs8.mkdirSync(path19.dirname(lockFile), { recursive: true, mode: 448 });
|
|
2274
2167
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
2275
2168
|
try {
|
|
2276
|
-
const fd =
|
|
2169
|
+
const fd = fs8.openSync(lockFile, "wx+", 384);
|
|
2277
2170
|
const ownerToken = randomUUID3();
|
|
2278
2171
|
let released = false;
|
|
2279
2172
|
try {
|
|
2280
|
-
|
|
2173
|
+
fs8.writeSync(
|
|
2281
2174
|
fd,
|
|
2282
2175
|
`${JSON.stringify({
|
|
2283
2176
|
pid: process.pid,
|
|
@@ -2287,11 +2180,11 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2287
2180
|
`
|
|
2288
2181
|
);
|
|
2289
2182
|
const heartbeatAt = new Date(deps.nowMs());
|
|
2290
|
-
|
|
2183
|
+
fs8.futimesSync(fd, heartbeatAt, heartbeatAt);
|
|
2291
2184
|
} catch (error) {
|
|
2292
|
-
|
|
2185
|
+
fs8.closeSync(fd);
|
|
2293
2186
|
try {
|
|
2294
|
-
|
|
2187
|
+
fs8.unlinkSync(lockFile);
|
|
2295
2188
|
} catch {
|
|
2296
2189
|
}
|
|
2297
2190
|
throw error;
|
|
@@ -2299,7 +2192,7 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2299
2192
|
const close = () => {
|
|
2300
2193
|
if (released) return;
|
|
2301
2194
|
released = true;
|
|
2302
|
-
|
|
2195
|
+
fs8.closeSync(fd);
|
|
2303
2196
|
};
|
|
2304
2197
|
return {
|
|
2305
2198
|
heartbeat() {
|
|
@@ -2308,7 +2201,7 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2308
2201
|
return false;
|
|
2309
2202
|
try {
|
|
2310
2203
|
const heartbeatAt = new Date(deps.nowMs());
|
|
2311
|
-
|
|
2204
|
+
fs8.futimesSync(fd, heartbeatAt, heartbeatAt);
|
|
2312
2205
|
return true;
|
|
2313
2206
|
} catch {
|
|
2314
2207
|
return false;
|
|
@@ -2318,7 +2211,7 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2318
2211
|
if (released) return;
|
|
2319
2212
|
if (queueLockFileMatchesOwner(lockFile, fd, ownerToken)) {
|
|
2320
2213
|
try {
|
|
2321
|
-
|
|
2214
|
+
fs8.unlinkSync(lockFile);
|
|
2322
2215
|
} catch {
|
|
2323
2216
|
}
|
|
2324
2217
|
}
|
|
@@ -2331,7 +2224,7 @@ function acquireQueueLock(queueFile, deps) {
|
|
|
2331
2224
|
const stale = !holder || !deps.isPidAlive(holder.pid) || deps.nowMs() - holder.timestampMs > QUEUE_LOCK_STALE_MS;
|
|
2332
2225
|
if (!stale) return null;
|
|
2333
2226
|
try {
|
|
2334
|
-
|
|
2227
|
+
fs8.unlinkSync(lockFile);
|
|
2335
2228
|
} catch {
|
|
2336
2229
|
}
|
|
2337
2230
|
}
|
|
@@ -2670,14 +2563,15 @@ async function syncArtifacts(options) {
|
|
|
2670
2563
|
}
|
|
2671
2564
|
const upload = await uploadPendingArtifactsLocked(
|
|
2672
2565
|
options,
|
|
2673
|
-
resolveUploadRun(options, lock)
|
|
2566
|
+
resolveUploadRun(options, lock),
|
|
2567
|
+
snapshot.queue
|
|
2674
2568
|
);
|
|
2675
2569
|
return { snapshot, upload };
|
|
2676
2570
|
} finally {
|
|
2677
2571
|
lock.release();
|
|
2678
2572
|
}
|
|
2679
2573
|
}
|
|
2680
|
-
async function uploadPendingArtifactsLocked(options, run) {
|
|
2574
|
+
async function uploadPendingArtifactsLocked(options, run, currentQueue) {
|
|
2681
2575
|
const {
|
|
2682
2576
|
nowMs,
|
|
2683
2577
|
limit,
|
|
@@ -2689,7 +2583,7 @@ async function uploadPendingArtifactsLocked(options, run) {
|
|
|
2689
2583
|
retryExhausted,
|
|
2690
2584
|
lock
|
|
2691
2585
|
} = run;
|
|
2692
|
-
const queue = readArtifactQueue(options.queueFile);
|
|
2586
|
+
const queue = currentQueue ?? readArtifactQueue(options.queueFile);
|
|
2693
2587
|
const entries = queue.artifacts.filter((entry) => artifactSourceEnabled(entry.source)).map(
|
|
2694
2588
|
(entry) => activateUploadDestination(entry, uploadDestinationId, targetName)
|
|
2695
2589
|
);
|
|
@@ -3241,7 +3135,11 @@ async function uploadPendingArtifactsLocked(options, run) {
|
|
|
3241
3135
|
persist();
|
|
3242
3136
|
}
|
|
3243
3137
|
}
|
|
3244
|
-
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
|
+
};
|
|
3245
3143
|
const completedAtMs = nowMs();
|
|
3246
3144
|
const exhausted = nextQueue.artifacts.filter(
|
|
3247
3145
|
(entry) => isExhaustedForDestination(entry, uploadDestinationId, retryExhausted)
|
|
@@ -3278,11 +3176,12 @@ async function uploadPendingArtifactsLocked(options, run) {
|
|
|
3278
3176
|
}
|
|
3279
3177
|
|
|
3280
3178
|
// ../../packages/panopticon/src/raw-sync.ts
|
|
3281
|
-
import
|
|
3179
|
+
import fs10 from "fs";
|
|
3282
3180
|
import path20 from "path";
|
|
3181
|
+
import os4 from "os";
|
|
3283
3182
|
|
|
3284
3183
|
// ../../packages/panopticon/src/artifact-materializer.ts
|
|
3285
|
-
import
|
|
3184
|
+
import fs9 from "fs";
|
|
3286
3185
|
function entryNeedsBytes(entry, amendmentPending) {
|
|
3287
3186
|
if (entry.uploadedSizeBytes < entry.sizeBytes) return true;
|
|
3288
3187
|
return amendmentPending(entry);
|
|
@@ -3297,7 +3196,7 @@ function createArtifactMaterializer(input) {
|
|
|
3297
3196
|
const unsupportedReason = (input.supportsCompression ?? supportsCompressedArtifacts)() ? void 0 : `compressed artifacts need Node 22.15 or newer (running ${process.version})`;
|
|
3298
3197
|
const chargeExisting = (cachePath) => {
|
|
3299
3198
|
try {
|
|
3300
|
-
const stat =
|
|
3199
|
+
const stat = fs9.statSync(cachePath);
|
|
3301
3200
|
if (!stat.isFile()) return false;
|
|
3302
3201
|
if (!retained.has(cachePath)) {
|
|
3303
3202
|
retained.add(cachePath);
|
|
@@ -3353,12 +3252,12 @@ function getRawArtifactSyncPaths(stateDir) {
|
|
|
3353
3252
|
queueFile: managed.artifactQueue,
|
|
3354
3253
|
artifactCacheDir: managed.artifactCache,
|
|
3355
3254
|
discoveryCacheFile: path20.join(root, "discovery.cache.json"),
|
|
3356
|
-
githubOriginCacheFile: path20.join(root,
|
|
3255
|
+
githubOriginCacheFile: path20.join(root, GIT_STATE_CACHE_FILENAME)
|
|
3357
3256
|
};
|
|
3358
3257
|
}
|
|
3359
3258
|
function invalidateRawArtifactDiscoveryCache(stateDir) {
|
|
3360
3259
|
try {
|
|
3361
|
-
|
|
3260
|
+
fs10.rmSync(getRawArtifactSyncPaths(stateDir).discoveryCacheFile, {
|
|
3362
3261
|
force: true
|
|
3363
3262
|
});
|
|
3364
3263
|
} catch {
|
|
@@ -3460,14 +3359,23 @@ function createRawArtifactSync(options) {
|
|
|
3460
3359
|
const discoveryInputs = () => JSON.stringify([
|
|
3461
3360
|
options.homeDir ?? null,
|
|
3462
3361
|
options.projectRoots ?? null,
|
|
3463
|
-
options.maxFileBytes ?? null
|
|
3362
|
+
options.maxFileBytes ?? null,
|
|
3363
|
+
path20.resolve(
|
|
3364
|
+
resolvePiAgentDir({
|
|
3365
|
+
homeDir: path20.resolve(
|
|
3366
|
+
options.homeDir ?? process.env.HOME ?? os4.homedir()
|
|
3367
|
+
),
|
|
3368
|
+
env: process.env
|
|
3369
|
+
}),
|
|
3370
|
+
"sessions"
|
|
3371
|
+
)
|
|
3464
3372
|
]);
|
|
3465
3373
|
const readReusableDiscovery = (nowMs) => {
|
|
3466
3374
|
const reuseMs = options.discoveryReuseMs ?? 0;
|
|
3467
3375
|
if (reuseMs <= 0) return null;
|
|
3468
3376
|
try {
|
|
3469
3377
|
const parsed = JSON.parse(
|
|
3470
|
-
|
|
3378
|
+
fs10.readFileSync(paths.discoveryCacheFile, "utf8")
|
|
3471
3379
|
);
|
|
3472
3380
|
if (parsed.schemaVersion !== DISCOVERY_CACHE_SCHEMA_VERSION || typeof parsed.createdAtMs !== "number" || parsed.inputs !== discoveryInputs() || !parsed.discovery || typeof parsed.discovery !== "object") {
|
|
3473
3381
|
return null;
|
|
@@ -3483,11 +3391,11 @@ function createRawArtifactSync(options) {
|
|
|
3483
3391
|
if ((options.discoveryReuseMs ?? 0) <= 0) return;
|
|
3484
3392
|
const temporary = `${paths.discoveryCacheFile}.${process.pid}.tmp`;
|
|
3485
3393
|
try {
|
|
3486
|
-
|
|
3394
|
+
fs10.mkdirSync(path20.dirname(paths.discoveryCacheFile), {
|
|
3487
3395
|
recursive: true,
|
|
3488
3396
|
mode: 448
|
|
3489
3397
|
});
|
|
3490
|
-
|
|
3398
|
+
fs10.writeFileSync(
|
|
3491
3399
|
temporary,
|
|
3492
3400
|
`${JSON.stringify({
|
|
3493
3401
|
schemaVersion: DISCOVERY_CACHE_SCHEMA_VERSION,
|
|
@@ -3498,10 +3406,10 @@ function createRawArtifactSync(options) {
|
|
|
3498
3406
|
`,
|
|
3499
3407
|
{ mode: 384 }
|
|
3500
3408
|
);
|
|
3501
|
-
|
|
3409
|
+
fs10.renameSync(temporary, paths.discoveryCacheFile);
|
|
3502
3410
|
} catch {
|
|
3503
3411
|
try {
|
|
3504
|
-
|
|
3412
|
+
fs10.rmSync(temporary, { force: true });
|
|
3505
3413
|
} catch {
|
|
3506
3414
|
}
|
|
3507
3415
|
}
|
|
@@ -3694,6 +3602,7 @@ async function runRawSyncOnce(opts = {}) {
|
|
|
3694
3602
|
}
|
|
3695
3603
|
|
|
3696
3604
|
export {
|
|
3605
|
+
resolvePiAgentDir,
|
|
3697
3606
|
claudeConfigDirectory,
|
|
3698
3607
|
geminiConfigDirectory,
|
|
3699
3608
|
initializeSyncSettings,
|