@hachej/boring-agent 0.1.104 → 0.1.105

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.
@@ -688,11 +688,8 @@ var PiSessionStore = class {
688
688
  }));
689
689
  const existingFiles = fileStats.filter((item) => item !== null);
690
690
  const referencedPiFiles = await this.referencedPiFiles(existingFiles);
691
- const visibleFiles = await Promise.all(existingFiles.filter(({ filepath }) => !referencedPiFiles.has(resolve(filepath))).map(async (file) => ({
692
- ...file,
693
- sortMtimeMs: await this.sessionSortMtimeMs(file)
694
- })));
695
- visibleFiles.sort((a, b) => b.sortMtimeMs - a.sortMtimeMs);
691
+ const visibleFiles = await Promise.all(existingFiles.filter(({ filepath }) => !referencedPiFiles.has(resolve(filepath))).map(async (file) => ({ ...file, ...await this.sessionSortKey(file) })));
692
+ visibleFiles.sort((a, b) => b.sortMtimeMs - a.sortMtimeMs || a.sortId.localeCompare(b.sortId));
696
693
  const { offset, limit } = options;
697
694
  const includeId = options.includeId;
698
695
  const pageSummaries = await this.summarizeVisiblePage(visibleFiles, {
@@ -967,8 +964,8 @@ var PiSessionStore = class {
967
964
  if (readHeaderSessionCtx(header) !== null) return null;
968
965
  const existingWrapper = await this.findWrapperReferencingNativeSession(filepath);
969
966
  if (existingWrapper) {
970
- const wrapperSessionId = await this.readSessionFileId(existingWrapper);
971
- if (wrapperSessionId !== sessionId) return null;
967
+ const wrapperSessionId2 = await this.readSessionFileId(existingWrapper);
968
+ if (wrapperSessionId2 !== sessionId) return null;
972
969
  const wrapperEntries = parseJsonlPrefixEntries2(await readJsonlPrefix2(existingWrapper));
973
970
  const wrapperHeader = wrapperEntries.find((entry) => entry.type === "session");
974
971
  if (!this.headerBelongsToCtx(wrapperHeader, ctx)) return null;
@@ -1069,21 +1066,37 @@ var PiSessionStore = class {
1069
1066
  }));
1070
1067
  return referenced;
1071
1068
  }
1072
- async sessionSortMtimeMs({ filepath, stat }) {
1069
+ async sessionSortKey({ filepath, stat }) {
1073
1070
  let sortMtimeMs = stat.mtime.getTime();
1071
+ let headerId = void 0;
1072
+ const stemFallback = () => ({
1073
+ sortMtimeMs,
1074
+ sortId: wrapperSessionId(filepath)
1075
+ });
1074
1076
  try {
1075
- const linkedPiFile = (await this.readPrefixCache(filepath, stat)).referencedPiFile;
1077
+ const cached = await this.readPrefixCache(filepath, stat);
1078
+ headerId = cached.headerId ?? void 0;
1079
+ const linkedPiFile = cached.referencedPiFile;
1076
1080
  if (linkedPiFile && resolve(linkedPiFile) !== resolve(filepath)) {
1077
1081
  const linkedStat = await fsStat2(linkedPiFile);
1078
1082
  sortMtimeMs = Math.max(sortMtimeMs, linkedStat.mtime.getTime());
1079
1083
  }
1080
- const header = parseJsonlPrefixEntries2(await readJsonlPrefix2(filepath)).find((entry) => entry.type === "session");
1081
- if (header && isTimestampNamedPiSessionFile(filepath, header.id)) {
1082
- sortMtimeMs = await latestNativeMessageTimestamp(filepath, Number(stat.size)) ?? sortMtimeMs;
1084
+ if (!headerId) {
1085
+ return stemFallback();
1086
+ }
1087
+ if (!isTimestampNamedPiSessionFile(filepath, headerId)) {
1088
+ return { sortMtimeMs, sortId: headerId };
1083
1089
  }
1090
+ if (cached.nativeSortMtimeMs !== void 0) {
1091
+ return { sortMtimeMs: cached.nativeSortMtimeMs, sortId: headerId };
1092
+ }
1093
+ const latest = await latestNativeMessageTimestamp(filepath, Number(stat.size));
1094
+ if (latest === void 0) return { sortMtimeMs, sortId: headerId };
1095
+ this.prefixCache.set(filepath, { ...cached, nativeSortMtimeMs: latest });
1096
+ return { sortMtimeMs: latest, sortId: headerId };
1084
1097
  } catch {
1098
+ return headerId ? { sortMtimeMs, sortId: headerId } : stemFallback();
1085
1099
  }
1086
- return sortMtimeMs;
1087
1100
  }
1088
1101
  async summarizeFile(ctx, filepath, existingStat) {
1089
1102
  try {
@@ -1132,6 +1145,10 @@ var PiSessionStore = class {
1132
1145
  mtimeMs: fileStat.mtime.getTime(),
1133
1146
  size: Number(fileStat.size),
1134
1147
  referencedPiFile: linkedPiFile,
1148
+ // Carried so a later `sessionSortMtimeMs` on this same entry still
1149
+ // recognises a native transcript instead of falling back to mtime.
1150
+ headerId: header.id,
1151
+ ...cached?.nativeSortMtimeMs !== void 0 ? { nativeSortMtimeMs: cached.nativeSortMtimeMs } : {},
1135
1152
  sessionCtx,
1136
1153
  ...linked ? { linkedMtimeMs: linked.mtime.getTime(), linkedSize: linked.size } : {},
1137
1154
  ...!nativeSummary ? { summary } : {}
@@ -1162,11 +1179,13 @@ var PiSessionStore = class {
1162
1179
  if (cached) return cached;
1163
1180
  const content = await readJsonlPrefix2(filepath);
1164
1181
  const entries = parseJsonlPrefixEntries2(content);
1182
+ const header = entries.find((item) => item.type === "session");
1165
1183
  const entry = {
1166
1184
  mtimeMs: fileStat.mtime.getTime(),
1167
1185
  size: Number(fileStat.size),
1168
1186
  referencedPiFile: extractPiSessionFilePath(entries),
1169
- sessionCtx: readHeaderSessionCtx(entries.find((item) => item.type === "session"))
1187
+ headerId: header?.id ?? null,
1188
+ sessionCtx: readHeaderSessionCtx(header)
1170
1189
  };
1171
1190
  this.prefixCache.set(filepath, entry);
1172
1191
  return entry;
@@ -1431,6 +1450,10 @@ function extractSessionHeaderId(entries) {
1431
1450
  function nativeSessionFilename(sessionId, isoTimestamp) {
1432
1451
  return `${isoTimestamp.replace(/[:.]/g, "-")}_${sessionId}.jsonl`;
1433
1452
  }
1453
+ function wrapperSessionId(filepath) {
1454
+ const base = basename(filepath);
1455
+ return base.endsWith(".jsonl") ? base.slice(0, -".jsonl".length) : base;
1456
+ }
1434
1457
  function isTimestampNamedPiSessionFile(filepath, sessionId) {
1435
1458
  const filename = basename(filepath);
1436
1459
  return /^\d{4}-\d{2}-\d{2}/.test(filename) && filename.endsWith(`_${sessionId}.jsonl`);