@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.
@@ -1,6 +1,9 @@
1
1
  import {
2
- canonicalGitHubRepository
3
- } from "./chunk-CSOFP7MT.js";
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 createHash5, randomUUID as randomUUID3 } from "crypto";
190
- import fs9 from "fs";
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 path8 from "path";
213
+ import path9 from "path";
196
214
 
197
215
  // ../../packages/agent-targets/src/config-paths.ts
198
- import path6 from "path";
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 ? path6.resolve(configuredDir) : path6.join(context.homeDir, ".claude");
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 ? path6.resolve(configuredHome) : context.homeDir;
206
- return path6.join(homeRoot, ".gemini");
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 path7 from "path";
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 path7.resolve(filePath);
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 = path7.join(dir, entry.name);
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: harnessInstallId ? { harnessInstallId } : void 0,
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(path8.join(configDir, ".claude.json")) ?? readClaudeMachineId(path8.join(homeDir, ".claude.json"));
506
+ const harnessInstallId = readClaudeMachineId(path9.join(configDir, ".claude.json")) ?? readClaudeMachineId(path9.join(homeDir, ".claude.json"));
471
507
  return walkFiles({
472
- root: path8.join(configDir, "projects"),
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 path9 from "path";
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(path9.basename(sourcePath))?.[1]?.toLowerCase() ?? null;
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: { store, ...identityMetadata },
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 ? path9.resolve(configuredHome) : path9.join(homeDir, ".codex");
596
+ const codexHome = configuredHome ? path10.resolve(configuredHome) : path10.join(homeDir, ".codex");
556
597
  const harnessInstallId = readHarnessInstallIdFile(
557
- path9.join(codexHome, "installation_id")
598
+ path10.join(codexHome, "installation_id")
558
599
  );
559
600
  const roots = [
560
- { store: "sessions", root: path9.join(codexHome, "sessions") },
601
+ { store: "sessions", root: path10.join(codexHome, "sessions") },
561
602
  {
562
603
  store: "archived_sessions",
563
- root: path9.join(codexHome, "archived_sessions")
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 path10 from "path";
642
+ import path11 from "path";
602
643
  var copilotCliArtifactDiscovery = Object.freeze({
603
644
  targetId: "copilot-cli",
604
645
  discover: ({ homeDir }) => walkFiles({
605
- root: path10.join(homeDir, ".copilot", "session-state"),
646
+ root: path11.join(homeDir, ".copilot", "session-state"),
606
647
  maxDepth: 3,
607
- includeFile: (filePath) => path10.basename(filePath) === "events.jsonl"
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 path11 from "path";
655
+ import path12 from "path";
615
656
  function hasPathSegment(filePath, segment) {
616
- return normalizeFilePath(filePath).split(path11.sep).includes(segment);
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: path11.join(homeDir, ".cursor", "projects"),
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 path12 from "path";
671
+ import path13 from "path";
631
672
  var factoryDroidArtifactDiscovery = Object.freeze({
632
673
  targetId: "factory-droid",
633
674
  discover: ({ homeDir }) => walkFiles({
634
- root: path12.join(homeDir, ".factory", "sessions"),
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 path13 from "path";
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
- path13.join(geminiDir, "installation_id")
699
+ path14.join(geminiDir, "installation_id")
659
700
  );
660
- const root = path13.join(geminiDir, "tmp");
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 = path13.join(dir, entry.name);
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
- path13.join(entryPath, chatEntry.name)
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 path14 from "path";
739
+ import path15 from "path";
699
740
  function grokHome(homeDir, env) {
700
741
  const configuredHome = env.GROK_HOME?.trim();
701
- return configuredHome ? path14.resolve(configuredHome) : path14.join(homeDir, ".grok");
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: path14.join(grokHome(homeDir, env), "sessions"),
747
+ root: path15.join(grokHome(homeDir, env), "sessions"),
707
748
  maxDepth: 5,
708
- includeFile: (filePath) => path14.basename(filePath) === "updates.jsonl"
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 path15 from "path";
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 (!path15.isAbsolute(env.FML_DATA_DIR)) {
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 path15.normalize(env.FML_DATA_DIR);
764
+ return path16.normalize(env.FML_DATA_DIR);
724
765
  }
725
766
  if (process.platform === "darwin") {
726
- return path15.join(homeDir, "Library", "Application Support", "fml");
767
+ return path16.join(homeDir, "Library", "Application Support", "fml");
727
768
  }
728
769
  if (process.platform === "win32") {
729
- const roaming = env.APPDATA && path15.isAbsolute(env.APPDATA) ? env.APPDATA : path15.join(homeDir, "AppData", "Roaming");
730
- return path15.join(roaming, "fml");
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 && path15.isAbsolute(env.XDG_DATA_HOME) ? env.XDG_DATA_HOME : path15.join(homeDir, ".local", "share");
733
- return path15.join(xdgDataHome, "fml");
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: path15.join(dataDirectory(context), "mini-swe-agent", "trajectories"),
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 path16 from "path";
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: path16.join(homeDir, ".pi", "agent", "sessions"),
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 path17 from "path";
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 = `${path17.resolve(sourcePath)}\0${stat.size}\0${Math.floor(
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 path17.join(input.cacheDir, cacheEntryName(input.sourcePath, stat));
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 = path17.join(
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 = path17.join(input.cacheDir, entry.name);
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 ReadOnlyGitCommandError = class extends Error {
1025
- constructor() {
1026
- super("read-only git command failed");
1027
- }
1028
- };
1029
- function validCwd(cwd) {
1030
- const trimmed = cwd.trim();
1031
- return trimmed === cwd && trimmed.length > 0 && !new RegExp("\\p{Cc}", "u").test(trimmed) && Buffer.byteLength(trimmed, "utf8") <= MAX_CWD_BYTES2;
1032
- }
1033
- function runReadOnlyGit(cwd, args, maxBuffer = GIT_OUTPUT_BYTES) {
1034
- if (!validCwd(cwd)) return null;
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
- var PERSISTENT_ORIGIN_CACHE_SCHEMA_VERSION = 2;
1155
- var DEFAULT_PERSISTENT_ORIGIN_CACHE_MAX_ENTRIES = 512;
1156
- function fileContentIdentity(filePath) {
1157
- try {
1158
- const contents = fs8.readFileSync(filePath);
1159
- return `sha256:${createHash4("sha256").update(contents).digest("hex")}`;
1160
- } catch (error) {
1161
- const code = error && typeof error === "object" && "code" in error ? error.code : void 0;
1162
- return code === "ENOENT" || code === "ENOTDIR" ? "missing" : null;
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
- entries.delete(oldest);
1153
+ states.delete(oldest);
1291
1154
  }
1292
- writePersistentOriginCache(options.cacheFile, {
1293
- schemaVersion: PERSISTENT_ORIGIN_CACHE_SCHEMA_VERSION,
1294
- entries: Object.fromEntries(entries)
1295
- });
1296
- };
1297
- return (cwd) => {
1298
- if (!validCwd(cwd)) return null;
1299
- const layout = findGitDirectory(cwd);
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 fs9.statSync(filePath);
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 fs9.statSync(sourcePath);
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(fs9.readFileSync(queueFile, "utf8"));
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
- fs9.mkdirSync(path19.dirname(queueFile), { recursive: true, mode: 448 });
1372
+ fs8.mkdirSync(path19.dirname(queueFile), { recursive: true, mode: 448 });
1515
1373
  const tempFile = `${queueFile}.${process.pid}.${Date.now()}.tmp`;
1516
- fs9.writeFileSync(tempFile, `${JSON.stringify(queue, null, 2)}
1517
- `, {
1518
- mode: 384
1519
- });
1520
- fs9.renameSync(tempFile, queueFile);
1374
+ const fd = fs8.openSync(tempFile, "w", 384);
1521
1375
  try {
1522
- fs9.chmodSync(queueFile, 384);
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 createHash5("sha256").update(fs9.readFileSync(input.nextReadPath)).digest("hex") !== input.existing.contentSha256;
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 = createHash5("sha256").update(fs9.readFileSync(input.nextReadPath)).digest("hex");
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
- return {
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 = fs9.statSync(filePath, { bigint: true });
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 = fs9.readSync(
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 = fs9.openSync(filePath, "r");
1810
+ fd = fs8.openSync(filePath, "r");
1918
1811
  } catch {
1919
1812
  return null;
1920
1813
  }
1921
1814
  try {
1922
1815
  const openedRevision = sourceRevisionFromStat(
1923
- fs9.fstatSync(fd, { bigint: true })
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
- fs9.fstatSync(fd, { bigint: true })
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
- fs9.closeSync(fd);
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 = fs9.openSync(input.sourcePath, "r");
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
- fs9.fstatSync(fd, { bigint: true })
1970
+ fs8.fstatSync(fd, { bigint: true })
2078
1971
  );
2079
1972
  if (!sameSourceRevision(pathRevisionBefore, openedRevision)) {
2080
1973
  return { status: "changed" };
2081
1974
  }
2082
- const contentHash = createHash5("sha256");
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
- fs9.fstatSync(fd, { bigint: true })
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
- fs9.closeSync(fd);
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(fs9.readFileSync(lockFile, "utf8"));
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, fs9.statSync(lockFile).mtimeMs) : 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 = fs9.fstatSync(fd);
2262
- const pathStat = fs9.statSync(lockFile);
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
- fs9.mkdirSync(path19.dirname(lockFile), { recursive: true, mode: 448 });
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 = fs9.openSync(lockFile, "wx+", 384);
2169
+ const fd = fs8.openSync(lockFile, "wx+", 384);
2277
2170
  const ownerToken = randomUUID3();
2278
2171
  let released = false;
2279
2172
  try {
2280
- fs9.writeSync(
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
- fs9.futimesSync(fd, heartbeatAt, heartbeatAt);
2183
+ fs8.futimesSync(fd, heartbeatAt, heartbeatAt);
2291
2184
  } catch (error) {
2292
- fs9.closeSync(fd);
2185
+ fs8.closeSync(fd);
2293
2186
  try {
2294
- fs9.unlinkSync(lockFile);
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
- fs9.closeSync(fd);
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
- fs9.futimesSync(fd, heartbeatAt, heartbeatAt);
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
- fs9.unlinkSync(lockFile);
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
- fs9.unlinkSync(lockFile);
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 = readArtifactQueue(options.queueFile);
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 fs11 from "fs";
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 fs10 from "fs";
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 = fs10.statSync(cachePath);
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, "github-origins.cache.json")
3255
+ githubOriginCacheFile: path20.join(root, GIT_STATE_CACHE_FILENAME)
3357
3256
  };
3358
3257
  }
3359
3258
  function invalidateRawArtifactDiscoveryCache(stateDir) {
3360
3259
  try {
3361
- fs11.rmSync(getRawArtifactSyncPaths(stateDir).discoveryCacheFile, {
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
- fs11.readFileSync(paths.discoveryCacheFile, "utf8")
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
- fs11.mkdirSync(path20.dirname(paths.discoveryCacheFile), {
3394
+ fs10.mkdirSync(path20.dirname(paths.discoveryCacheFile), {
3487
3395
  recursive: true,
3488
3396
  mode: 448
3489
3397
  });
3490
- fs11.writeFileSync(
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
- fs11.renameSync(temporary, paths.discoveryCacheFile);
3409
+ fs10.renameSync(temporary, paths.discoveryCacheFile);
3502
3410
  } catch {
3503
3411
  try {
3504
- fs11.rmSync(temporary, { force: true });
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,