@cortexkit/pi-magic-context 0.49.26 → 0.49.28

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.
Files changed (39) hide show
  1. package/dist/auto-search-worker.js +4 -4
  2. package/dist/chunk-embedding-write-worker.js +8 -9
  3. package/dist/{compartment-chunk-embedding-vt6afvdm.js → compartment-chunk-embedding-pkk5beqp.js} +3 -3
  4. package/dist/{embedding-backfill-jc5fqt5s.js → embedding-backfill-25fp3b8w.js} +7 -7
  5. package/dist/{index-0dr64gsy.js → index-0s14xaca.js} +2 -2
  6. package/dist/{index-n8e5e9fp.js → index-0x1c054v.js} +1 -1
  7. package/dist/{index-hxp6q5f8.js → index-48twbev2.js} +50 -36
  8. package/dist/{index-j3pz3a1b.js → index-4zemngt7.js} +1 -1
  9. package/dist/{index-r1hvaza0.js → index-5d506f7y.js} +719 -23
  10. package/dist/{index-z24d75tz.js → index-6981g1xv.js} +0 -2
  11. package/dist/{index-zpmz6x24.js → index-bkcwcghx.js} +1308 -104
  12. package/dist/{index-g0d51qzc.js → index-bvpar0bg.js} +2 -5
  13. package/dist/{index-w1avzkdt.js → index-g026ztby.js} +1 -1
  14. package/dist/{index-rjnc6kkf.js → index-kagezf2h.js} +3 -3
  15. package/dist/{index-dnadppqx.js → index-kmk3xpf9.js} +1 -1
  16. package/dist/{index-zz7dnyh6.js → index-sdsnb5b6.js} +8 -8
  17. package/dist/index-v0ht940m.js +488 -0
  18. package/dist/{index-kbswhkc8.js → index-vea2d9ka.js} +1 -1
  19. package/dist/{index-w5v0ntbw.js → index-wjbqw6r1.js} +1 -1
  20. package/dist/{index-z6k6jsmh.js → index-xa90f88m.js} +3 -3
  21. package/dist/{index-wpy2rzb2.js → index-xw070axm.js} +3 -3
  22. package/dist/index.js +499 -440
  23. package/dist/{message-fts-rowid-map-xe3ss2g3.js → message-fts-rowid-map-3mbvdgn9.js} +2 -4
  24. package/dist/{message-index-bounded-2zffszp9.js → message-index-bounded-avbaa7wa.js} +19 -22
  25. package/dist/migration-worker.js +7 -8
  26. package/dist/{project-embedding-registry-bn9ts1h0.js → project-embedding-registry-hc4ahjdt.js} +6 -6
  27. package/dist/raw-ordinal-warmup-worker.js +7 -30
  28. package/dist/{read-session-chunk-p0cexvvs.js → read-session-chunk-1rfprgc1.js} +4 -4
  29. package/dist/{read-session-raw-mq03ws9v.js → read-session-raw-g9b1zdn5.js} +1 -1
  30. package/dist/{search-archive-jw2wm4tw.js → search-archive-mpjeecwj.js} +5 -5
  31. package/dist/{search-vmcbbwm5.js → search-vkkfg27q.js} +13 -14
  32. package/dist/{storage-tags-r48vxthe.js → storage-tags-9qaasrky.js} +2 -2
  33. package/dist/subagent-entry.js +17 -18
  34. package/dist/tag-snapshot-worker-pi.js +9 -10
  35. package/package.json +1 -1
  36. package/dist/index-87xm7z44.js +0 -2100
  37. package/dist/index-n4wyxcgr.js +0 -712
  38. package/dist/index-wrr9rp9a.js +0 -16
  39. package/dist/message-index-jv1m3g8d.js +0 -58
@@ -67,7 +67,7 @@ import {
67
67
  visitRawSessionMessages2,
68
68
  readRawSessionMessageById2,
69
69
  readSessionChunk2
70
- } from "./index-rjnc6kkf.js";
70
+ } from "./index-kagezf2h.js";
71
71
  import {
72
72
  isRecord,
73
73
  providerVisibleMessage,
@@ -81,34 +81,33 @@ import {
81
81
  getTagNumberByMessageId2,
82
82
  getTagsBySession2,
83
83
  getTagById2
84
- } from "./index-n8e5e9fp.js";
84
+ } from "./index-0x1c054v.js";
85
85
  import {
86
86
  estimateTokens
87
87
  } from "./index-my0dn413.js";
88
88
  import {
89
89
  inRootAsyncContext2,
90
90
  Database2,
91
+ prepareCachedStatement2,
91
92
  withSqliteBackgroundWriter2,
92
93
  withoutSqliteTransformPass2
93
94
  } from "./index-2qtx0q6h.js";
94
95
  import {
95
96
  stableStringify,
96
97
  closeQuietly,
97
- getTableColumnNames
98
- } from "./index-w1avzkdt.js";
98
+ getTableColumnNames,
99
+ tagTombstoneOwnerRange,
100
+ tagTombstoneOwnerKey,
101
+ tagRevisionKey,
102
+ tagIdentityRevisionKey,
103
+ deleteTagIdentityRevisions
104
+ } from "./index-g026ztby.js";
99
105
  import {
100
106
  piHarnessKindFromExecutable,
101
- isPidAlive
102
- } from "./index-n4wyxcgr.js";
103
- import {
104
- clearLkgFenceProcessState,
105
- commitLkgWithRecoveryFence,
106
- clearLkgRecoveryFence,
107
- gaDatabasePath,
108
- V2StoreReader,
109
- deleteSessionScopedRows,
110
- getLastIndexedOrdinal2
111
- } from "./index-87xm7z44.js";
107
+ isPidAlive,
108
+ readProcessStartTime,
109
+ getErrorMessage
110
+ } from "./index-5d506f7y.js";
112
111
  import {
113
112
  BoundedSessionMap,
114
113
  resolveOpenCodeDbPath,
@@ -116,7 +115,7 @@ import {
116
115
  } from "./index-23t8ryqw.js";
117
116
  import {
118
117
  noteRawSessionSummaryRowWritten2
119
- } from "./index-z24d75tz.js";
118
+ } from "./index-6981g1xv.js";
120
119
  import {
121
120
  SubcClient,
122
121
  connectionFileExists,
@@ -124,6 +123,12 @@ import {
124
123
  toSynapseLaneDescriptor,
125
124
  SynapseEmbeddingProvider
126
125
  } from "./index-gwxaz0z5.js";
126
+ import {
127
+ deleteUnmappedMessageFtsRows2
128
+ } from "./index-bvpar0bg.js";
129
+ import {
130
+ deleteChunkEmbedBackoffForSession2
131
+ } from "./index-kmk3xpf9.js";
127
132
  import {
128
133
  invalidateAutoEmbedSession,
129
134
  drainBackgroundBatches,
@@ -136,10 +141,10 @@ import {
136
141
  unregisterProjectEmbedding2,
137
142
  getProjectEmbeddingSnapshot2,
138
143
  embedTextForProject2
139
- } from "./index-z6k6jsmh.js";
144
+ } from "./index-xa90f88m.js";
140
145
  import {
141
- getErrorMessage
142
- } from "./index-r1hvaza0.js";
146
+ getLastIndexedOrdinal
147
+ } from "./index-v0ht940m.js";
143
148
  import {
144
149
  V2_MEMORY_CATEGORIES,
145
150
  CATEGORY_PRIORITY,
@@ -153,13 +158,14 @@ import {
153
158
  expandWorkspaceIdentitySetWithAliases,
154
159
  resolveStoredPathWorkspaceIdentity,
155
160
  storedPathBelongsToWorkspace
156
- } from "./index-0dr64gsy.js";
161
+ } from "./index-0s14xaca.js";
157
162
  import {
163
+ sameProjectDirectory,
158
164
  directoryHasGitMetadata,
159
165
  resolveProjectIdentityForSession,
160
166
  normalizeStoredProjectPath,
161
167
  storedPathBelongsToIdentity
162
- } from "./index-hxp6q5f8.js";
168
+ } from "./index-48twbev2.js";
163
169
  import {
164
170
  getNoteByIdInScope,
165
171
  getNotes,
@@ -175,7 +181,7 @@ import {
175
181
  resolveMemoriesByIdsForSearch2,
176
182
  unifiedSearch2,
177
183
  formatSearchResults2
178
- } from "./index-zz7dnyh6.js";
184
+ } from "./index-sdsnb5b6.js";
179
185
  import {
180
186
  computeCueContentHash,
181
187
  getMuralCueState,
@@ -206,7 +212,7 @@ import {
206
212
  } from "./index-6wdwv3a6.js";
207
213
  import {
208
214
  renderSearchArchive2
209
- } from "./index-kbswhkc8.js";
215
+ } from "./index-vea2d9ka.js";
210
216
  import {
211
217
  computeNormalizedHash
212
218
  } from "./index-9x1f96r8.js";
@@ -215,7 +221,11 @@ import {
215
221
  } from "./index-hqw0rt9k.js";
216
222
  import {
217
223
  ensureStorageDirectorySync,
218
- writeStorageFileAtomicSync
224
+ ensurePrivateStorageDirectorySync,
225
+ writeStorageFileSync,
226
+ writeStorageFileAtomicSync,
227
+ syncStorageDirectorySync,
228
+ writeStorageFileDurableAtomicSync
219
229
  } from "./index-81nthk8j.js";
220
230
 
221
231
  // ../plugin/src/config/agent-disable.ts
@@ -2778,6 +2788,389 @@ function substituteConfigVariables(input) {
2778
2788
  // ../plugin/src/features/magic-context/storage-meta-session.ts
2779
2789
  import { Buffer as Buffer2 } from "node:buffer";
2780
2790
 
2791
+ // ../plugin/src/hooks/magic-context/lkg-recovery-fence.ts
2792
+ import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
2793
+ import { lstatSync, readdirSync as readdirSync2, readFileSync as readFileSync7, rmdirSync, rmSync as rmSync3 } from "node:fs";
2794
+ import { basename as basename3, dirname as dirname4, join as join5 } from "node:path";
2795
+
2796
+ // ../plugin/src/shared/storage-file-mutex.ts
2797
+ import { execFileSync } from "node:child_process";
2798
+ import { createHash, randomUUID } from "node:crypto";
2799
+ import { readdirSync, readFileSync as readFileSync6, rmSync as rmSync2 } from "node:fs";
2800
+ import { join as join4 } from "node:path";
2801
+ var ticketChecksum = (name, ticket) => createHash("sha256").update(JSON.stringify([name, ticket.choosing, ticket.number, ticket.birth])).digest("hex");
2802
+ function processBirth(pid) {
2803
+ if (process.platform === "linux") {
2804
+ try {
2805
+ const stat = readFileSync6(`/proc/${pid}/stat`, "utf8");
2806
+ const ticks = stat.slice(stat.lastIndexOf(")") + 2).trim().split(/\s+/)[19];
2807
+ if (!ticks || !/^\d+$/.test(ticks))
2808
+ return null;
2809
+ return `${readFileSync6("/proc/sys/kernel/random/boot_id", "utf8").trim()}:${ticks}`;
2810
+ } catch {
2811
+ return null;
2812
+ }
2813
+ }
2814
+ if (process.platform === "darwin") {
2815
+ try {
2816
+ return execFileSync("ps", ["-p", String(pid), "-o", "lstart="], {
2817
+ encoding: "utf8",
2818
+ timeout: 1000,
2819
+ windowsHide: true,
2820
+ env: { ...process.env, TZ: "UTC", LC_ALL: "C" },
2821
+ stdio: ["ignore", "pipe", "pipe"]
2822
+ }).trim() || null;
2823
+ } catch {
2824
+ return null;
2825
+ }
2826
+ }
2827
+ const start = readProcessStartTime(pid);
2828
+ return start === null ? null : String(start);
2829
+ }
2830
+ var pause = new Int32Array(new SharedArrayBuffer(4));
2831
+ function withStorageFileMutex(directory, work, timeoutMs = 1000) {
2832
+ ensurePrivateStorageDirectorySync(directory);
2833
+ const name = `${process.pid}-${randomUUID()}.lock`;
2834
+ const ownPath = join4(directory, name);
2835
+ const birth = processBirth(process.pid);
2836
+ const ticket = { choosing: true, number: 0, birth, checksum: "" };
2837
+ const encodedTicket = () => JSON.stringify({ ...ticket, checksum: ticketChecksum(name, ticket) });
2838
+ for (let attempt = 0;; attempt++) {
2839
+ try {
2840
+ writeStorageFileSync(ownPath, encodedTicket(), { flag: "wx", forcePrivate: true });
2841
+ break;
2842
+ } catch (error) {
2843
+ if (error.code !== "ENOENT" || attempt >= 2)
2844
+ throw error;
2845
+ ensurePrivateStorageDirectorySync(directory);
2846
+ }
2847
+ }
2848
+ const deadline = performance.now() + timeoutMs;
2849
+ const peers = () => {
2850
+ const found = [];
2851
+ for (const other of readdirSync(directory)) {
2852
+ if (other === name || !/^\d+-[\da-f-]+\.lock$/.test(other))
2853
+ continue;
2854
+ const pid = Number(other.split("-")[0]);
2855
+ const otherPath = join4(directory, other);
2856
+ let value = null;
2857
+ try {
2858
+ const parsed = JSON.parse(readFileSync6(otherPath, "utf8"));
2859
+ if (typeof parsed.choosing === "boolean" && Number.isSafeInteger(parsed.number) && parsed.number >= 0 && (parsed.birth === null || typeof parsed.birth === "string") && parsed.checksum === ticketChecksum(other, parsed))
2860
+ value = parsed;
2861
+ } catch (error) {
2862
+ if (error.code === "ENOENT")
2863
+ continue;
2864
+ }
2865
+ const alive = isPidAlive(pid);
2866
+ const actualBirth = alive === "alive" && value?.birth ? processBirth(pid) : null;
2867
+ if (alive === "dead" || actualBirth !== null && value?.birth && actualBirth !== value.birth) {
2868
+ rmSync2(otherPath, { force: true });
2869
+ continue;
2870
+ }
2871
+ found.push([other, value]);
2872
+ }
2873
+ return found;
2874
+ };
2875
+ try {
2876
+ ticket.number = 1 + Math.max(0, ...peers().map(([, value]) => value?.number ?? 0));
2877
+ ticket.choosing = false;
2878
+ writeStorageFileAtomicSync(ownPath, encodedTicket(), true);
2879
+ while (peers().some(([other, value]) => !value || value.choosing || value.number < ticket.number || value.number === ticket.number && other < name)) {
2880
+ if (performance.now() >= deadline)
2881
+ throw new Error("Storage safety publication lock is unavailable");
2882
+ Atomics.wait(pause, 0, 0, 10);
2883
+ }
2884
+ const result = work();
2885
+ if (result && typeof result.then === "function")
2886
+ throw new TypeError("Storage publication mutex requires synchronous work");
2887
+ return result;
2888
+ } finally {
2889
+ rmSync2(ownPath, { force: true });
2890
+ }
2891
+ }
2892
+
2893
+ // ../plugin/src/hooks/magic-context/lkg-recovery-fence.ts
2894
+ class LkgRecoveryFenceError extends Error {
2895
+ constructor(message) {
2896
+ super(message);
2897
+ this.name = "LkgRecoveryFenceError";
2898
+ }
2899
+ }
2900
+ var platform = process.platform;
2901
+ var observer;
2902
+ var knownFences = new BoundedSessionMap(1000);
2903
+ var ioObserver;
2904
+ var cacheKey = (sessionId) => `${getMagicContextStorageDir()}\x00${getHarness2()}\x00${sessionId}`;
2905
+ function remember(sessionId, value) {
2906
+ knownFences.set(cacheKey(sessionId), value);
2907
+ return value;
2908
+ }
2909
+ function known(sessionId) {
2910
+ const prior = knownFences.get(cacheKey(sessionId));
2911
+ if (prior)
2912
+ return prior;
2913
+ const record = read(sessionId);
2914
+ if (record)
2915
+ return remember(sessionId, { state: record.state, record });
2916
+ try {
2917
+ lstatSync(lkgRecoveryFencePath(sessionId));
2918
+ } catch (error) {
2919
+ if (error.code === "ENOENT")
2920
+ return remember(sessionId, { state: "clean", record: null });
2921
+ }
2922
+ return remember(sessionId, { state: "invalid", record: null });
2923
+ }
2924
+ function clearLkgFenceProcessState(sessionId) {
2925
+ if (sessionId)
2926
+ knownFences.delete(cacheKey(sessionId));
2927
+ else
2928
+ knownFences.clear();
2929
+ }
2930
+ var durableFencesSupported = () => platform !== "win32";
2931
+ var hash = (value) => createHash2("sha256").update(value).digest("hex");
2932
+ function lkgRecoveryFencePath(sessionId) {
2933
+ return join5(getMagicContextStorageDir(), "lkg-recovery-fences", `${hash(sessionId)}.json`);
2934
+ }
2935
+ function metadata(slot) {
2936
+ return [
2937
+ slot.inputIdSeq,
2938
+ slot.inputContentDigests,
2939
+ slot.inputContentSignatures ?? null,
2940
+ slot.piOutputEntryIds ?? null,
2941
+ slot.lastInputMessageId,
2942
+ slot.modelKey,
2943
+ slot.providerKey
2944
+ ];
2945
+ }
2946
+ function representationKey(slot) {
2947
+ return createHash2("sha256").update(slot.jsonPrefix).update(JSON.stringify(metadata(slot))).digest("hex");
2948
+ }
2949
+ function lkgRecoverySlotKey(slot) {
2950
+ return hash(JSON.stringify([
2951
+ representationKey(slot),
2952
+ slot.capturedAt,
2953
+ slot.rowVersion ?? null,
2954
+ slot.captureSequence ?? null
2955
+ ]));
2956
+ }
2957
+ function payload(record) {
2958
+ return [
2959
+ record.version,
2960
+ record.sessionId,
2961
+ record.host,
2962
+ record.modelKey,
2963
+ record.providerKey,
2964
+ record.slotKey,
2965
+ record.servedDigest,
2966
+ record.revision,
2967
+ record.state
2968
+ ];
2969
+ }
2970
+ function publishRecord(record) {
2971
+ ioObserver?.("write");
2972
+ try {
2973
+ if (record.state === "clean")
2974
+ observer?.("clean");
2975
+ writeStorageFileDurableAtomicSync(lkgRecoveryFencePath(record.sessionId), JSON.stringify({ ...record, checksum: hash(JSON.stringify(payload(record))) }), () => observer?.("temp-synced"));
2976
+ if (record.state === "dirty")
2977
+ observer?.("dirty");
2978
+ remember(record.sessionId, {
2979
+ state: record.state,
2980
+ record: { ...record, checksum: hash(JSON.stringify(payload(record))) }
2981
+ });
2982
+ } catch (error) {
2983
+ const visible = read(record.sessionId);
2984
+ if (record.state === "clean" && visible?.state === "clean" && visible.revision === record.revision && visible.slotKey === record.slotKey) {
2985
+ const dirty = { ...record, state: "dirty" };
2986
+ writeStorageFileDurableAtomicSync(lkgRecoveryFencePath(record.sessionId), JSON.stringify({ ...dirty, checksum: hash(JSON.stringify(payload(dirty))) }));
2987
+ }
2988
+ remember(record.sessionId, { state: "invalid", record: null });
2989
+ throw error;
2990
+ }
2991
+ }
2992
+ function read(sessionId) {
2993
+ ioObserver?.("read");
2994
+ try {
2995
+ const path = lkgRecoveryFencePath(sessionId);
2996
+ const stat = lstatSync(path);
2997
+ const directory = lstatSync(dirname4(path));
2998
+ if (!stat.isFile() || stat.size > 4096 || !directory.isDirectory() || directory.isSymbolicLink() || process.platform !== "win32" && ((stat.mode & 63) !== 0 || (directory.mode & 63) !== 0 || process.getuid && stat.uid !== process.getuid()))
2999
+ return null;
3000
+ const value = JSON.parse(readFileSync7(path, "utf8"));
3001
+ if (value.version !== 1 || value.sessionId !== sessionId || value.host !== getHarness2() || value.modelKey !== null && typeof value.modelKey !== "string" || value.providerKey !== null && typeof value.providerKey !== "string" || !/^[a-f0-9]{64}$/.test(value.slotKey) || !/^[a-f0-9]{64}$/.test(value.servedDigest) || typeof value.revision !== "string" || !["clean", "dirty"].includes(value.state) || value.checksum !== hash(JSON.stringify(payload(value))))
3002
+ return null;
3003
+ return value;
3004
+ } catch {
3005
+ return null;
3006
+ }
3007
+ }
3008
+ function publish(sessionId, slot, state, revision) {
3009
+ const record = {
3010
+ version: 1,
3011
+ sessionId,
3012
+ host: getHarness2(),
3013
+ modelKey: slot.modelKey,
3014
+ providerKey: slot.providerKey,
3015
+ slotKey: lkgRecoverySlotKey(slot),
3016
+ servedDigest: hash(slot.jsonPrefix),
3017
+ revision,
3018
+ state
3019
+ };
3020
+ publishRecord(record);
3021
+ }
3022
+ function locked(sessionId, work) {
3023
+ ioObserver?.("mutex");
3024
+ return withStorageFileMutex(`${lkgRecoveryFencePath(sessionId)}.locks`, () => {
3025
+ const path = lkgRecoveryFencePath(sessionId);
3026
+ for (const name of readdirSync2(dirname4(path))) {
3027
+ if (name.startsWith(`${basename3(path)}.`) && name.endsWith(".tmp"))
3028
+ rmSync3(join5(dirname4(path), name), { force: true });
3029
+ }
3030
+ return work();
3031
+ });
3032
+ }
3033
+ function hasCleanLkgRecoveryFence(sessionId, _slot) {
3034
+ if (!durableFencesSupported())
3035
+ return false;
3036
+ const state = known(sessionId);
3037
+ return state.state === "clean";
3038
+ }
3039
+ function lkgFenceRequiresRebuild(sessionId, slot, processLocalProof) {
3040
+ return !processLocalProof && (durableFencesSupported() ? !hasCleanLkgRecoveryFence(sessionId, slot) : true);
3041
+ }
3042
+ function lkgRecoveryFenceUnclean(sessionId) {
3043
+ return durableFencesSupported() && known(sessionId).state !== "clean";
3044
+ }
3045
+ function ownsLkgDirtyFence(sessionId, revision) {
3046
+ if (!durableFencesSupported())
3047
+ return revision === "process-local";
3048
+ const record = known(sessionId).record;
3049
+ return revision !== undefined && record?.state === "dirty" && record.revision === revision;
3050
+ }
3051
+ function invalidateCleanLkgRecoveryFence(sessionId, load, ownRevision) {
3052
+ if (!durableFencesSupported())
3053
+ return "process-local";
3054
+ const prior = known(sessionId);
3055
+ if (prior.state === "dirty")
3056
+ return prior.record?.revision === ownRevision ? ownRevision : undefined;
3057
+ return locked(sessionId, () => {
3058
+ const slot = load() ?? {
3059
+ jsonPrefix: "",
3060
+ inputIdSeq: [],
3061
+ inputContentDigests: [],
3062
+ lastInputMessageId: "",
3063
+ modelKey: null,
3064
+ providerKey: null,
3065
+ capturedAt: 0
3066
+ };
3067
+ const record = read(sessionId);
3068
+ if (record?.state !== "dirty") {
3069
+ const revision = randomUUID2();
3070
+ publish(sessionId, slot, "dirty", revision);
3071
+ return revision;
3072
+ }
3073
+ return record?.state === "dirty" && record.revision === ownRevision ? ownRevision : undefined;
3074
+ });
3075
+ }
3076
+ function markLkgRecoveryDirty(args) {
3077
+ if (!durableFencesSupported()) {
3078
+ if (!args.processLocalProof)
3079
+ throw new LkgRecoveryFenceError("Restart replay requires a healthy rebuild on Windows");
3080
+ return "process-local";
3081
+ }
3082
+ const state = known(args.sessionId);
3083
+ if (state.state === "dirty" && args.processLocalProof && state.record && state.record.revision === args.ownDirtyRevision)
3084
+ return state.record.revision;
3085
+ if (state.state === "invalid")
3086
+ throw new LkgRecoveryFenceError("No clean durable recovery certificate");
3087
+ return locked(args.sessionId, () => {
3088
+ const slot = args.slot;
3089
+ const before = read(args.sessionId);
3090
+ if (before?.state === "dirty") {
3091
+ if (!args.processLocalProof || before.revision !== args.ownDirtyRevision)
3092
+ throw new LkgRecoveryFenceError(`Recovery superseded this process's last-good request (local=${args.processLocalProof}, owned=${before.revision === args.ownDirtyRevision})`);
3093
+ return before.revision;
3094
+ }
3095
+ if (before && before.state !== "clean")
3096
+ throw new LkgRecoveryFenceError("No clean durable recovery certificate");
3097
+ const revision = randomUUID2();
3098
+ publish(args.sessionId, slot, "dirty", revision);
3099
+ return revision;
3100
+ });
3101
+ }
3102
+ function commitLkgWithRecoveryFence(args) {
3103
+ if (!durableFencesSupported())
3104
+ return args.commit();
3105
+ const state = known(args.sessionId);
3106
+ if (state.state === "clean" && !args.requiredRevision && !args.retainDirtyRevision) {
3107
+ const committed = args.commit();
3108
+ if (committed) {
3109
+ observer?.("committed");
3110
+ remember(args.sessionId, { state: "clean", record: null });
3111
+ }
3112
+ return committed;
3113
+ }
3114
+ if (state.state === "invalid" && !args.rebuild)
3115
+ throw new LkgRecoveryFenceError("Unproven prior request requires a prefix rebuild");
3116
+ return locked(args.sessionId, () => {
3117
+ const before = read(args.sessionId);
3118
+ if (args.requiredRevision && before?.revision !== args.requiredRevision)
3119
+ throw new LkgRecoveryFenceError("A later publisher superseded the rollback snapshot");
3120
+ const ownsDirty = before?.state === "dirty" && (before.revision === args.retainDirtyRevision || before.revision === args.ownDirtyRevision);
3121
+ if (before?.state === "dirty" && !ownsDirty && !args.rebuild)
3122
+ throw new LkgRecoveryFenceError("A concurrent recovery requires a declared prefix rebuild");
3123
+ if (before?.state !== "dirty" && state.state === "invalid")
3124
+ publish(args.sessionId, args.load() ?? args.slot, "dirty", randomUUID2());
3125
+ if (!args.commit())
3126
+ return false;
3127
+ observer?.("committed");
3128
+ const saved = args.load();
3129
+ if (!saved || representationKey(saved) !== representationKey(args.slot))
3130
+ throw new LkgRecoveryFenceError("Last-good commit did not match its certificate");
3131
+ if (args.retainDirtyRevision || args.cleanDigest !== undefined && hash(saved.jsonPrefix) !== args.cleanDigest)
3132
+ return true;
3133
+ const dirty = read(args.sessionId);
3134
+ if (dirty?.state === "dirty")
3135
+ publish(args.sessionId, saved, "clean", dirty.revision);
3136
+ else
3137
+ remember(args.sessionId, { state: "clean", record: null });
3138
+ return true;
3139
+ });
3140
+ }
3141
+ function clearLkgRecoveryFence(sessionId, remove, shouldClear) {
3142
+ if (!durableFencesSupported())
3143
+ return remove?.();
3144
+ const path = lkgRecoveryFencePath(sessionId);
3145
+ const missing = (file) => {
3146
+ try {
3147
+ lstatSync(file);
3148
+ return false;
3149
+ } catch (error) {
3150
+ return error.code === "ENOENT";
3151
+ }
3152
+ };
3153
+ if (!remove && !shouldClear && missing(path) && missing(`${path}.locks`)) {
3154
+ clearLkgFenceProcessState(sessionId);
3155
+ return;
3156
+ }
3157
+ try {
3158
+ return locked(sessionId, () => {
3159
+ const result = remove?.();
3160
+ if (shouldClear && !shouldClear(result))
3161
+ return result;
3162
+ rmSync3(lkgRecoveryFencePath(sessionId), { force: true });
3163
+ syncStorageDirectorySync(dirname4(lkgRecoveryFencePath(sessionId)));
3164
+ clearLkgFenceProcessState(sessionId);
3165
+ return result;
3166
+ });
3167
+ } finally {
3168
+ try {
3169
+ rmdirSync(`${path}.locks`);
3170
+ } catch {}
3171
+ }
3172
+ }
3173
+
2781
3174
  // ../plugin/src/shared/auto-search-lifecycle.ts
2782
3175
  var pending = new Map;
2783
3176
  var unpublishedNoHints = new Map;
@@ -2829,6 +3222,598 @@ function cancelAutoSearchWork(sessionId) {
2829
3222
  }
2830
3223
  }
2831
3224
 
3225
+ // ../plugin/src/v2/store-reader.ts
3226
+ import { createHash as createHash3 } from "node:crypto";
3227
+ import { statSync as statSync3 } from "node:fs";
3228
+ import { hostname } from "node:os";
3229
+ import { resolve as resolve2 } from "node:path";
3230
+ function gaDatabasePath(dataHome, channel = "latest", env = process.env) {
3231
+ return resolveOpenCodeDbPath("v2", { dataHome, channel, env }).path;
3232
+ }
3233
+ var RAW_MESSAGE_TYPES = [
3234
+ "user",
3235
+ "synthetic",
3236
+ "assistant",
3237
+ "skill",
3238
+ "shell",
3239
+ "system"
3240
+ ];
3241
+ var RAW_MESSAGE_TYPE_PARAMETERS = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
3242
+ var V2_MESSAGE_PAGE_SQL = `WITH bounds AS (
3243
+ SELECT
3244
+ CASE WHEN ? = 0 THEN -1 ELSE COALESCE((
3245
+ SELECT seq FROM session_message
3246
+ WHERE session_id = ? AND type IN (${RAW_MESSAGE_TYPE_PARAMETERS})
3247
+ ORDER BY seq ASC LIMIT 1 OFFSET ?
3248
+ ), (SELECT MAX(seq) FROM session_message WHERE session_id = ?), -1) END AS after_seq,
3249
+ COALESCE((
3250
+ SELECT seq FROM session_message
3251
+ WHERE session_id = ? AND type IN (${RAW_MESSAGE_TYPE_PARAMETERS})
3252
+ ORDER BY seq ASC LIMIT 1 OFFSET ?
3253
+ ), ?) AS watermark_seq
3254
+ )
3255
+ SELECT id, session_id, type, seq, time_created, data FROM session_message, bounds
3256
+ WHERE session_id = ?
3257
+ AND type IN (${RAW_MESSAGE_TYPE_PARAMETERS})
3258
+ AND seq > bounds.after_seq
3259
+ AND seq <= bounds.watermark_seq
3260
+ ORDER BY seq ASC LIMIT ?`;
3261
+ var V2_STORE_READER_DEBUG_COUNTER_KEY = "magic-context.v2.store-reader-debug";
3262
+ var debugSymbol = Symbol.for(V2_STORE_READER_DEBUG_COUNTER_KEY);
3263
+ var debugGlobal = globalThis;
3264
+ var QUERY_STATEMENTS = {
3265
+ messagePage: V2_MESSAGE_PAGE_SQL,
3266
+ messageCount: "SELECT COUNT(*) AS count FROM session_message WHERE session_id = ? AND type IN (?)",
3267
+ storedMessageCount: "SELECT COUNT(*) AS count FROM session_message WHERE session_id = ?",
3268
+ messageById: "SELECT id, session_id, type, seq, time_created, data FROM session_message WHERE session_id = ? AND id = ? AND type IN (?) LIMIT 1",
3269
+ messageExistsById: "SELECT 1 FROM session_message WHERE id = ? AND session_id = ? AND type IN (?) LIMIT 1",
3270
+ messageOrdinalById: `WITH target AS (
3271
+ SELECT seq FROM session_message WHERE session_id = ? AND id = ? AND type IN (?) LIMIT 1
3272
+ )
3273
+ SELECT (SELECT COUNT(*) FROM session_message WHERE session_id = ? AND type IN (?) AND seq <= target.seq) AS ordinal FROM target`,
3274
+ messageIdOrdinals: "SELECT id FROM session_message WHERE session_id = ? AND type IN (?) ORDER BY seq ASC LIMIT ? OFFSET ?",
3275
+ messageOrdinalPage: "SELECT id, type, seq, json_valid(data) AS valid FROM session_message WHERE session_id = ? AND seq > ? ORDER BY seq ASC, id ASC LIMIT ?",
3276
+ rawRowsThrough: "SELECT id, session_id, type, seq, time_created, data FROM session_message WHERE session_id = ? AND type IN (?) AND seq <= ? ORDER BY seq DESC LIMIT ?"
3277
+ };
3278
+ function debugCounters() {
3279
+ const counters = debugGlobal[debugSymbol] ??= {
3280
+ decodedRows: 0,
3281
+ operations: {},
3282
+ openReaders: 0,
3283
+ maxOpenReaders: 0,
3284
+ readersOpened: 0,
3285
+ readersClosed: 0
3286
+ };
3287
+ counters.openReaders ??= 0;
3288
+ counters.maxOpenReaders ??= 0;
3289
+ counters.readersOpened ??= 0;
3290
+ counters.readersClosed ??= 0;
3291
+ return counters;
3292
+ }
3293
+ function returnedRowCount(value) {
3294
+ if (Array.isArray(value))
3295
+ return value.length;
3296
+ if (value === null || value === undefined || value === false)
3297
+ return 0;
3298
+ return 1;
3299
+ }
3300
+ function trackDecodeOperation(name, operation) {
3301
+ const counters = debugCounters();
3302
+ const before = counters.decodedRows;
3303
+ const started = performance.now();
3304
+ let value;
3305
+ try {
3306
+ value = operation();
3307
+ return value;
3308
+ } finally {
3309
+ const decodedRows = counters.decodedRows - before;
3310
+ const current = counters.operations[name] ?? {
3311
+ calls: 0,
3312
+ decodedRows: 0,
3313
+ maxDecodedRows: 0
3314
+ };
3315
+ current.calls += 1;
3316
+ current.decodedRows += decodedRows;
3317
+ current.maxDecodedRows = Math.max(current.maxDecodedRows, decodedRows);
3318
+ counters.operations[name] = current;
3319
+ const statement = QUERY_STATEMENTS[name];
3320
+ if (counters.captureQueries && statement) {
3321
+ (counters.queries ??= []).push({
3322
+ operation: name,
3323
+ statement,
3324
+ rows: returnedRowCount(value),
3325
+ elapsedMs: performance.now() - started
3326
+ });
3327
+ }
3328
+ }
3329
+ }
3330
+ function decode(row) {
3331
+ debugCounters().decodedRows += 1;
3332
+ const data = JSON.parse(row.data);
3333
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
3334
+ throw new Error(`Invalid session_message data at seq ${row.seq}`);
3335
+ }
3336
+ if (row.type === "idle" && !["succeeded", "failed", "interrupted"].includes(String(data.outcome))) {
3337
+ throw new Error(`Invalid idle outcome at seq ${row.seq}`);
3338
+ }
3339
+ return { ...row, data };
3340
+ }
3341
+ function connect(path, identity = "") {
3342
+ const stat = statSync3(path);
3343
+ const acquiredIdentity = identity || `${stat.dev}:${stat.ino}:${stat.birthtimeMs}`;
3344
+ const db = new Database2(path, { readonly: true, fileMustExist: true });
3345
+ try {
3346
+ assertOpenCodeStoreGeneration(db, "v2", path);
3347
+ } catch (error) {
3348
+ db.close();
3349
+ throw error;
3350
+ }
3351
+ const counters = debugCounters();
3352
+ counters.openReaders += 1;
3353
+ counters.readersOpened += 1;
3354
+ counters.maxOpenReaders = Math.max(counters.maxOpenReaders, counters.openReaders);
3355
+ return { db, statements: new Map, identity: acquiredIdentity, leases: 0, retired: false };
3356
+ }
3357
+ function closeConnection(connection) {
3358
+ connection.statements.clear();
3359
+ try {
3360
+ connection.db.close();
3361
+ } finally {
3362
+ const counters = debugCounters();
3363
+ counters.openReaders = Math.max(0, counters.openReaders - 1);
3364
+ counters.readersClosed += 1;
3365
+ }
3366
+ }
3367
+ function messageTimesQuery(count) {
3368
+ return `SELECT id, COALESCE(time_created, json_extract(data, '$.time.created')) AS created,
3369
+ json_extract(data, '$.time.completed') AS completed
3370
+ FROM session_message WHERE +session_id = ? AND id IN (${Array.from({ length: count }, () => "?").join(",")})`;
3371
+ }
3372
+
3373
+ class V2StoreReader {
3374
+ path;
3375
+ pool;
3376
+ db;
3377
+ connection;
3378
+ closed = false;
3379
+ constructor(path, pool) {
3380
+ this.path = path;
3381
+ this.pool = pool;
3382
+ this.connection = pool ? pool.acquire(path) : connect(path);
3383
+ this.db = this.connection.db;
3384
+ }
3385
+ hostIdentity() {
3386
+ return createHash3("sha256").update(JSON.stringify([hostname(), resolve2(this.path), this.connection.identity])).digest("hex");
3387
+ }
3388
+ prepare(sql) {
3389
+ if (this.closed)
3390
+ throw new Error("Store reader is closed");
3391
+ const statements = this.connection.statements;
3392
+ let statement = statements.get(sql);
3393
+ if (!statement) {
3394
+ statement = this.db.prepare(sql);
3395
+ if (statements.size >= 128)
3396
+ statements.clear();
3397
+ statements.set(sql, statement);
3398
+ }
3399
+ return statement;
3400
+ }
3401
+ close() {
3402
+ if (this.closed)
3403
+ return;
3404
+ this.closed = true;
3405
+ if (this.pool)
3406
+ this.pool.release(this.connection);
3407
+ else
3408
+ closeConnection(this.connection);
3409
+ }
3410
+ page(sessionID, options = {}) {
3411
+ return trackDecodeOperation("page", () => {
3412
+ const limit = options.limit ?? 100;
3413
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e4)
3414
+ throw new Error("Invalid page limit");
3415
+ const after = options.after ?? -1;
3416
+ if (!Number.isSafeInteger(after))
3417
+ throw new Error("Invalid seq cursor");
3418
+ if (options.through !== undefined && !Number.isSafeInteger(options.through))
3419
+ throw new Error("Invalid seq upper bound");
3420
+ const predicates = ["session_id = ?", "seq > ?"];
3421
+ const parameters = [sessionID, after];
3422
+ if (options.through !== undefined) {
3423
+ predicates.push("seq <= ?");
3424
+ parameters.push(options.through);
3425
+ }
3426
+ if (options.type) {
3427
+ predicates.push("type = ?");
3428
+ parameters.push(options.type);
3429
+ }
3430
+ const rows = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
3431
+ WHERE ${predicates.join(" AND ")}
3432
+ ORDER BY seq ASC LIMIT ?`).all(...parameters, limit).map(decode);
3433
+ return { rows, cursor: rows.at(-1)?.seq };
3434
+ });
3435
+ }
3436
+ messagePage(sessionID, afterOrdinal, limit, finalWatermark, after) {
3437
+ return trackDecodeOperation("messagePage", () => {
3438
+ if (!Number.isSafeInteger(afterOrdinal) || afterOrdinal < 0)
3439
+ throw new Error("Invalid raw-message ordinal cursor");
3440
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e4)
3441
+ throw new Error("Invalid page limit");
3442
+ if (!Number.isSafeInteger(finalWatermark) || finalWatermark < 0)
3443
+ throw new Error("Invalid raw-message watermark");
3444
+ const pageSize = Math.min(limit, finalWatermark - afterOrdinal);
3445
+ if (pageSize <= 0)
3446
+ return [];
3447
+ if (after) {
3448
+ const anchor = this.prepare("SELECT seq FROM session_message WHERE session_id = ? AND id = ?").get(sessionID, after.id);
3449
+ if (anchor) {
3450
+ return this.prepare(`SELECT id, session_id, type, seq, time_created, data
3451
+ FROM session_message WHERE session_id = ? AND seq > ?
3452
+ AND type IN (${RAW_MESSAGE_TYPE_PARAMETERS}) ORDER BY seq ASC LIMIT ?`).all(sessionID, anchor.seq, ...RAW_MESSAGE_TYPES, pageSize).map(decode);
3453
+ }
3454
+ }
3455
+ const maximumSeq = Number.MAX_SAFE_INTEGER;
3456
+ const rows = this.prepare(V2_MESSAGE_PAGE_SQL).all(afterOrdinal, sessionID, ...RAW_MESSAGE_TYPES, Math.max(0, afterOrdinal - 1), sessionID, sessionID, ...RAW_MESSAGE_TYPES, finalWatermark - 1, maximumSeq, sessionID, ...RAW_MESSAGE_TYPES, pageSize);
3457
+ return rows.map(decode);
3458
+ });
3459
+ }
3460
+ messageCount(sessionID) {
3461
+ return trackDecodeOperation("messageCount", () => {
3462
+ const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
3463
+ const row = this.prepare(`SELECT COUNT(*) AS count FROM session_message
3464
+ WHERE session_id = ? AND type IN (${rawTypes})`).get(sessionID, ...RAW_MESSAGE_TYPES);
3465
+ return typeof row?.count === "number" ? row.count : 0;
3466
+ });
3467
+ }
3468
+ messageCountAfterSequence(sessionID, after, through) {
3469
+ const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
3470
+ const row = this.prepare(`SELECT COUNT(*) AS count FROM session_message
3471
+ WHERE session_id = ? AND seq > ? AND seq <= ? AND type IN (${rawTypes})`).get(sessionID, after, through, ...RAW_MESSAGE_TYPES);
3472
+ return typeof row?.count === "number" ? row.count : 0;
3473
+ }
3474
+ sessionDirectoryPage(afterSessionID, limit) {
3475
+ const rows = this.prepare(`SELECT id, COALESCE(directory, '') AS directory FROM session_v2
3476
+ WHERE id > ? ORDER BY id ASC LIMIT ?`).all(afterSessionID ?? "", limit);
3477
+ return rows.map((row) => ({ sessionId: row.id, directory: row.directory }));
3478
+ }
3479
+ latestMessageTime(sessionID) {
3480
+ const row = this.prepare("SELECT MAX(time_created) AS time FROM session_message WHERE session_id = ?").get(sessionID);
3481
+ return row?.time ?? undefined;
3482
+ }
3483
+ isSubagent(sessionID) {
3484
+ const row = this.prepare("SELECT parent_id FROM session_v2 WHERE id = ?").get(sessionID);
3485
+ if (!row)
3486
+ return null;
3487
+ return typeof row.parent_id === "string" && row.parent_id.length > 0;
3488
+ }
3489
+ latestRootSessionInDirectory(directory) {
3490
+ const columns = new Set(this.prepare("PRAGMA table_info(session_v2)").all().map((column) => column.name));
3491
+ const archived = columns.has("time_archived") ? " AND time_archived IS NULL" : "";
3492
+ const order = columns.has("time_updated") ? "time_updated DESC, id DESC" : "id DESC";
3493
+ const page = this.prepare(`SELECT id, COALESCE(directory, '') AS directory FROM session_v2
3494
+ WHERE parent_id IS NULL${archived}
3495
+ AND COALESCE(json_extract(metadata, '$.magic_context'), '') <> 'hidden-run'
3496
+ ORDER BY ${order} LIMIT ? OFFSET ?`);
3497
+ const pageSize = 500;
3498
+ for (let offset = 0;; offset += pageSize) {
3499
+ const rows = page.all(pageSize, offset);
3500
+ const match = rows.find((row) => sameProjectDirectory(row.directory, directory));
3501
+ if (match)
3502
+ return match.id;
3503
+ if (rows.length < pageSize)
3504
+ return;
3505
+ }
3506
+ }
3507
+ rootSessionActivity(sessionIDs) {
3508
+ const roots = new Map;
3509
+ for (let offset = 0;offset < sessionIDs.length; offset += 500) {
3510
+ const chunk = sessionIDs.slice(offset, offset + 500);
3511
+ const rows = this.prepare(`SELECT id, (
3512
+ SELECT MAX(time_created) FROM session_message
3513
+ WHERE session_id = session_v2.id AND type = 'user'
3514
+ ) AS time FROM session_v2
3515
+ WHERE parent_id IS NULL
3516
+ AND COALESCE(json_extract(metadata, '$.magic_context'), '') <> 'hidden-run'
3517
+ AND id IN (${chunk.map(() => "?").join(",")})`).all(...chunk);
3518
+ for (const row of rows)
3519
+ if (row.time !== null)
3520
+ roots.set(row.id, row.time);
3521
+ }
3522
+ return roots;
3523
+ }
3524
+ oldestUserMessageTimesSince(sessionIDs, sinceMs) {
3525
+ const result = new Map;
3526
+ for (let offset = 0;offset < sessionIDs.length; offset += 500) {
3527
+ const chunk = sessionIDs.slice(offset, offset + 500);
3528
+ const rows = this.prepare(`SELECT session_id, MIN(time_created) AS time FROM session_message
3529
+ WHERE type = 'user' AND time_created > ? AND session_id IN (${chunk.map(() => "?").join(",")})
3530
+ GROUP BY session_id`).all(sinceMs, ...chunk);
3531
+ for (const row of rows)
3532
+ result.set(row.session_id, row.time);
3533
+ }
3534
+ return result;
3535
+ }
3536
+ retrospectiveUserPage(sessionID, options) {
3537
+ const { boundaryMs, before, limit, maxChars, truncationMarker } = options;
3538
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e4)
3539
+ throw new Error("Invalid page limit");
3540
+ if (!Number.isSafeInteger(maxChars) || maxChars <= truncationMarker.length)
3541
+ throw new Error("Invalid text limit");
3542
+ const direction = before ? "DESC" : "ASC";
3543
+ const head = Math.floor((maxChars - truncationMarker.length) / 2);
3544
+ const tail = maxChars - truncationMarker.length - head;
3545
+ return this.prepare(`WITH users AS (
3546
+ SELECT session_id, seq, time_created, data FROM session_message
3547
+ WHERE session_id = ? AND type = 'user' AND time_created ${before ? "<=" : ">"}
3548
+ ?
3549
+ ORDER BY time_created ${direction}, seq ${direction} LIMIT ?
3550
+ ), texts AS (
3551
+ SELECT session_id, seq, time_created, CASE
3552
+ WHEN json_extract(data, '$.synthetic') = 1 OR json_extract(data, '$.ignored') = 1 THEN ''
3553
+ WHEN json_type(data, '$.text') = 'text' THEN json_extract(data, '$.text')
3554
+ ELSE COALESCE((SELECT group_concat(json_extract(value, '$.text'), char(10))
3555
+ FROM json_each(users.data, '$.content')
3556
+ WHERE json_extract(value, '$.type') IN ('text', 'input_text')
3557
+ AND COALESCE(json_extract(value, '$.synthetic'), 0) <> 1
3558
+ AND COALESCE(json_extract(value, '$.ignored'), 0) <> 1), '') END AS text
3559
+ FROM users WHERE json_valid(data)
3560
+ ) SELECT seq, time_created, CASE WHEN length(text) > ?
3561
+ THEN substr(text, 1, ?) || ? || substr(text, -?) ELSE text END AS text,
3562
+ EXISTS (
3563
+ SELECT 1 FROM session_message assistant_reply
3564
+ WHERE assistant_reply.session_id = texts.session_id
3565
+ AND assistant_reply.type = 'assistant'
3566
+ AND assistant_reply.seq < texts.seq
3567
+ AND EXISTS (
3568
+ SELECT 1 FROM session_message prior_user
3569
+ WHERE prior_user.session_id = texts.session_id
3570
+ AND prior_user.type = 'user'
3571
+ AND prior_user.seq < assistant_reply.seq
3572
+ )
3573
+ ) AS follows_assistant_reply
3574
+ FROM texts ORDER BY time_created ${direction}, seq ${direction}`).all(sessionID, boundaryMs, limit, maxChars, head, truncationMarker, tail);
3575
+ }
3576
+ storedRowsAfter(sessionID, after) {
3577
+ const row = this.prepare("SELECT COUNT(*) AS count FROM session_message WHERE session_id = ? AND seq > ?").get(sessionID, after);
3578
+ return row.count;
3579
+ }
3580
+ storedMessageCount(sessionID) {
3581
+ return trackDecodeOperation("storedMessageCount", () => {
3582
+ const row = this.prepare("SELECT COUNT(*) AS count FROM session_message WHERE session_id = ?").get(sessionID);
3583
+ return typeof row?.count === "number" ? row.count : 0;
3584
+ });
3585
+ }
3586
+ messageById(sessionID, id) {
3587
+ return trackDecodeOperation("messageById", () => {
3588
+ const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
3589
+ const row = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
3590
+ WHERE session_id = ? AND id = ? AND type IN (${rawTypes}) LIMIT 1`).get(sessionID, id, ...RAW_MESSAGE_TYPES);
3591
+ return row ? decode(row) : null;
3592
+ });
3593
+ }
3594
+ messageTimes(sessionID, ids) {
3595
+ const times = new Map;
3596
+ for (let offset = 0;offset < ids.length; offset += 500) {
3597
+ const batch = ids.slice(offset, offset + 500);
3598
+ const rows = this.prepare(messageTimesQuery(batch.length)).all(sessionID, ...batch);
3599
+ for (const row of rows)
3600
+ times.set(row.id, {
3601
+ created: typeof row.created === "number" ? row.created : undefined,
3602
+ completed: typeof row.completed === "number" ? row.completed : undefined
3603
+ });
3604
+ }
3605
+ return times;
3606
+ }
3607
+ messageExistsById(sessionID, id) {
3608
+ return trackDecodeOperation("messageExistsById", () => {
3609
+ const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
3610
+ const row = this.prepare(`SELECT 1 FROM session_message
3611
+ WHERE id = ? AND session_id = ? AND type IN (${rawTypes}) LIMIT 1`).get(id, sessionID, ...RAW_MESSAGE_TYPES);
3612
+ return row != null;
3613
+ });
3614
+ }
3615
+ messageOrdinalById(sessionID, id) {
3616
+ return trackDecodeOperation("messageOrdinalById", () => {
3617
+ const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
3618
+ const row = this.prepare(`WITH target AS (
3619
+ SELECT seq FROM session_message
3620
+ WHERE session_id = ? AND id = ? AND type IN (${rawTypes})
3621
+ LIMIT 1
3622
+ )
3623
+ SELECT (
3624
+ SELECT COUNT(*) FROM session_message
3625
+ WHERE session_id = ?
3626
+ AND type IN (${rawTypes})
3627
+ AND seq <= target.seq
3628
+ ) AS ordinal
3629
+ FROM target`).get(sessionID, id, ...RAW_MESSAGE_TYPES, sessionID, ...RAW_MESSAGE_TYPES);
3630
+ return typeof row?.ordinal === "number" ? row.ordinal : null;
3631
+ });
3632
+ }
3633
+ messageIdOrdinals(sessionID, fromOrdinal, toOrdinal) {
3634
+ return trackDecodeOperation("messageIdOrdinals", () => {
3635
+ if (!Number.isSafeInteger(fromOrdinal) || fromOrdinal < 1)
3636
+ throw new Error("Invalid raw-message range start");
3637
+ if (!Number.isSafeInteger(toOrdinal) || toOrdinal < fromOrdinal)
3638
+ throw new Error("Invalid raw-message range end");
3639
+ const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
3640
+ const rows = this.prepare(`SELECT id FROM session_message
3641
+ WHERE session_id = ? AND type IN (${rawTypes})
3642
+ ORDER BY seq ASC LIMIT ? OFFSET ?`).all(sessionID, ...RAW_MESSAGE_TYPES, toOrdinal - fromOrdinal + 1, fromOrdinal - 1);
3643
+ return new Map(rows.map((row, index) => [row.id, fromOrdinal + index]));
3644
+ });
3645
+ }
3646
+ messageOrdinalPage(sessionID, after, limit) {
3647
+ return trackDecodeOperation("messageOrdinalPage", () => {
3648
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e4)
3649
+ throw new Error("Invalid page limit");
3650
+ const rows = after ? this.prepare(`SELECT id, type, seq, json_valid(data) AS valid
3651
+ FROM session_message
3652
+ WHERE session_id = ? AND (seq > ? OR (seq = ? AND id > ?))
3653
+ ORDER BY seq ASC, id ASC LIMIT ?`).all(sessionID, after.timeCreated, after.timeCreated, after.id, limit) : this.prepare(`SELECT id, type, seq, json_valid(data) AS valid
3654
+ FROM session_message
3655
+ WHERE session_id = ?
3656
+ ORDER BY seq ASC, id ASC LIMIT ?`).all(sessionID, limit);
3657
+ const rawTypes = new Set(RAW_MESSAGE_TYPES);
3658
+ return rows.map((row) => ({
3659
+ id: row.id,
3660
+ timeCreated: row.seq,
3661
+ contributesOrdinal: rawTypes.has(row.type),
3662
+ hasValidInfo: row.valid === 1
3663
+ }));
3664
+ });
3665
+ }
3666
+ range(sessionID, after, through) {
3667
+ return trackDecodeOperation("range", () => through <= after ? [] : this.all(sessionID, after, undefined, through));
3668
+ }
3669
+ spanRowStamps(sessionID, after, through) {
3670
+ if (!Number.isSafeInteger(after) || !Number.isSafeInteger(through))
3671
+ throw new Error("Invalid seq span");
3672
+ const rows = this.prepare(`SELECT seq, id, time_updated AS updated, length(CAST(data AS BLOB)) AS bytes
3673
+ FROM session_message WHERE session_id = ? AND seq > ? AND seq <= ?
3674
+ ORDER BY seq ASC`).all(sessionID, after, through);
3675
+ const stamps = new Map;
3676
+ for (const row of rows)
3677
+ stamps.set(row.seq, `${row.id}\x00${row.updated ?? ""}\x00${row.bytes ?? ""}`);
3678
+ return stamps;
3679
+ }
3680
+ rawRowsThrough(sessionID, throughSeq, limit) {
3681
+ return trackDecodeOperation("rawRowsThrough", () => {
3682
+ if (!Number.isSafeInteger(throughSeq))
3683
+ throw new Error("Invalid seq upper bound");
3684
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e4)
3685
+ throw new Error("Invalid page limit");
3686
+ const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
3687
+ return this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
3688
+ WHERE session_id = ? AND type IN (${rawTypes}) AND seq <= ?
3689
+ ORDER BY seq DESC LIMIT ?`).all(sessionID, ...RAW_MESSAGE_TYPES, throughSeq, limit).map(decode);
3690
+ });
3691
+ }
3692
+ instructionRowsThrough(sessionID, throughSeq) {
3693
+ return trackDecodeOperation("instructionRowsThrough", () => {
3694
+ if (!Number.isSafeInteger(throughSeq))
3695
+ throw new Error("Invalid seq upper bound");
3696
+ return this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
3697
+ WHERE session_id = ? AND type = 'system' AND seq <= ?
3698
+ ORDER BY seq ASC`).all(sessionID, throughSeq).map(decode);
3699
+ });
3700
+ }
3701
+ sequenceForId(sessionID, id) {
3702
+ if (!id)
3703
+ return;
3704
+ const row = this.prepare("SELECT seq FROM session_message WHERE session_id = ? AND id = ? LIMIT 1").get(sessionID, id);
3705
+ return typeof row?.seq === "number" ? row.seq : undefined;
3706
+ }
3707
+ syntheticMessageIDs(sessionID) {
3708
+ const rows = this.prepare("SELECT id FROM session_message WHERE session_id = ? AND type = 'synthetic'").all(sessionID);
3709
+ return new Set(rows.map((row) => row.id));
3710
+ }
3711
+ forkOrigin(sessionID) {
3712
+ const columns = new Set(this.prepare("PRAGMA table_info(session_v2)").all().map((column) => column.name));
3713
+ if (!columns.has("fork_session_id") || !columns.has("fork_boundary"))
3714
+ return null;
3715
+ const row = this.prepare("SELECT fork_session_id, fork_boundary FROM session_v2 WHERE id = ?").get(sessionID);
3716
+ if (!row?.fork_session_id || !row.fork_boundary)
3717
+ return null;
3718
+ try {
3719
+ const boundary = JSON.parse(row.fork_boundary);
3720
+ if (boundary.type !== "before" && boundary.type !== "through" || typeof boundary.messageID !== "string" || boundary.messageID.length === 0)
3721
+ return null;
3722
+ return {
3723
+ parentSessionID: row.fork_session_id,
3724
+ boundary: { type: boundary.type, messageID: boundary.messageID }
3725
+ };
3726
+ } catch {
3727
+ return null;
3728
+ }
3729
+ }
3730
+ sessionExists(sessionID) {
3731
+ return this.prepare("SELECT 1 FROM session_v2 WHERE id = ?").get(sessionID) != null;
3732
+ }
3733
+ rowStampsThrough(sessionID, throughSeq) {
3734
+ return this.prepare(`SELECT id, type, seq, time_created FROM session_message
3735
+ WHERE session_id = ? AND seq <= ? ORDER BY seq ASC`).all(sessionID, throughSeq);
3736
+ }
3737
+ latestSequenceForIds(sessionID, ids) {
3738
+ let latest = -1;
3739
+ for (let offset = 0;offset < ids.length; offset += 500) {
3740
+ const chunk = ids.slice(offset, offset + 500);
3741
+ const row = this.prepare(`SELECT MAX(seq) AS seq FROM session_message
3742
+ WHERE session_id = ? AND id IN (${chunk.map(() => "?").join(", ")})`).get(sessionID, ...chunk);
3743
+ if (typeof row?.seq === "number")
3744
+ latest = Math.max(latest, row.seq);
3745
+ }
3746
+ return latest;
3747
+ }
3748
+ compactionByStatus(sessionID, status) {
3749
+ const row = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
3750
+ WHERE session_id = ? AND type = 'compaction'
3751
+ AND json_extract(data, '$.status') = ?
3752
+ ORDER BY seq DESC LIMIT 1`).get(sessionID, status);
3753
+ return row ? decode(row) : undefined;
3754
+ }
3755
+ latestCompaction(sessionID) {
3756
+ return trackDecodeOperation("latestCompaction", () => this.compactionByStatus(sessionID, "completed"));
3757
+ }
3758
+ latestRunningCompaction(sessionID) {
3759
+ return trackDecodeOperation("latestRunningCompaction", () => this.compactionByStatus(sessionID, "running"));
3760
+ }
3761
+ idleRows(sessionID, after = -1) {
3762
+ return trackDecodeOperation("idleRows", () => this.all(sessionID, after, "idle"));
3763
+ }
3764
+ earliestSequence(sessionID) {
3765
+ const row = this.prepare("SELECT MIN(seq) AS seq FROM session_message WHERE session_id = ?").get(sessionID);
3766
+ return typeof row?.seq === "number" ? row.seq : undefined;
3767
+ }
3768
+ latestSequence(sessionID) {
3769
+ const row = this.prepare("SELECT MAX(seq) AS seq FROM session_message WHERE session_id = ?").get(sessionID);
3770
+ return typeof row?.seq === "number" ? row.seq : -1;
3771
+ }
3772
+ assistantSince(sessionID, afterSeq) {
3773
+ return trackDecodeOperation("assistantSince", () => {
3774
+ const rows = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
3775
+ WHERE session_id = ? AND type = 'assistant' AND seq > ?
3776
+ ORDER BY seq ASC`).all(sessionID, afterSeq);
3777
+ return rows.map((row) => decode(row));
3778
+ });
3779
+ }
3780
+ latestAssistant(sessionID) {
3781
+ return trackDecodeOperation("latestAssistant", () => {
3782
+ const row = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
3783
+ WHERE session_id = ? AND type = 'assistant'
3784
+ ORDER BY seq DESC LIMIT 1`).get(sessionID);
3785
+ return row ? decode(row) : undefined;
3786
+ });
3787
+ }
3788
+ latestIdle(sessionID) {
3789
+ return trackDecodeOperation("latestIdle", () => {
3790
+ const row = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
3791
+ WHERE session_id = ? AND type = 'idle'
3792
+ ORDER BY seq DESC LIMIT 1`).get(sessionID);
3793
+ return row ? decode(row) : undefined;
3794
+ });
3795
+ }
3796
+ window(sessionID) {
3797
+ return trackDecodeOperation("window", () => this.db.transaction(() => {
3798
+ const cut = this.latestCompaction(sessionID);
3799
+ return this.all(sessionID, cut ? cut.seq - 1 : -1);
3800
+ }).deferred());
3801
+ }
3802
+ history(sessionID) {
3803
+ return trackDecodeOperation("history", () => this.all(sessionID, -1));
3804
+ }
3805
+ all(sessionID, after, type, through) {
3806
+ const rows = [];
3807
+ for (;; ) {
3808
+ const page = this.page(sessionID, { after, through, type });
3809
+ rows.push(...page.rows);
3810
+ if (page.rows.length < 100 || page.cursor === undefined)
3811
+ return rows;
3812
+ after = page.cursor;
3813
+ }
3814
+ }
3815
+ }
3816
+
2832
3817
  // ../plugin/src/features/magic-context/resolve-subagent-fallback.ts
2833
3818
  function resolveIsSubagentFromOpenCodeDb(sessionId) {
2834
3819
  try {
@@ -2856,6 +3841,225 @@ function resolveIsSubagentFromOpenCode2Db(sessionId) {
2856
3841
  }
2857
3842
  }
2858
3843
 
3844
+ // ../plugin/src/features/magic-context/session-activity.ts
3845
+ var PREFIX = "retrospective_activity:";
3846
+ var INTERVAL_MS = 15000;
3847
+ var pending2 = new WeakMap;
3848
+ function sessionActivityKey(sessionId) {
3849
+ return `${PREFIX}${sessionId}`;
3850
+ }
3851
+ function deleteSessionActivity(db, sessionIds) {
3852
+ if (sessionIds.length === 0)
3853
+ return;
3854
+ const sessions = pending2.get(db);
3855
+ for (const sessionId of sessionIds) {
3856
+ const state = sessions?.get(sessionId);
3857
+ if (state?.timer)
3858
+ clearTimeout(state.timer);
3859
+ sessions?.delete(sessionId);
3860
+ }
3861
+ const placeholders = sessionIds.map(() => "?").join(", ");
3862
+ db.prepare(`DELETE FROM schema_migrations_meta WHERE key IN (${placeholders})`).run(...sessionIds.map(sessionActivityKey));
3863
+ deleteTagIdentityRevisions(db, sessionIds);
3864
+ }
3865
+ function readSessionActivity(db, sessionId) {
3866
+ const row = db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(sessionActivityKey(sessionId));
3867
+ const time = Number(row?.value);
3868
+ return row && Number.isFinite(time) ? time : undefined;
3869
+ }
3870
+ function advanceSessionActivity(db, sessionId, time) {
3871
+ if (!sessionId || !Number.isFinite(time) || time <= 0)
3872
+ return;
3873
+ db.prepare(`INSERT INTO schema_migrations_meta (key, value) VALUES (?, ?)
3874
+ ON CONFLICT(key) DO UPDATE SET value = CAST(MAX(CAST(value AS INTEGER), CAST(excluded.value AS INTEGER)) AS TEXT)`).run(sessionActivityKey(sessionId), String(Math.floor(time)));
3875
+ }
3876
+ function observeSessionActivity(db, sessionId, time = Date.now()) {
3877
+ if (!sessionId || !Number.isFinite(time) || time <= 0)
3878
+ return;
3879
+ let sessions = pending2.get(db);
3880
+ if (!sessions) {
3881
+ sessions = new Map;
3882
+ pending2.set(db, sessions);
3883
+ }
3884
+ const current = sessions.get(sessionId);
3885
+ if (!current || time - current.lastWrite >= INTERVAL_MS) {
3886
+ if (current?.timer)
3887
+ clearTimeout(current.timer);
3888
+ advanceSessionActivity(db, sessionId, Math.max(time, current?.latest ?? 0));
3889
+ sessions.set(sessionId, { lastWrite: time, latest: time });
3890
+ return;
3891
+ }
3892
+ current.latest = Math.max(current.latest, time);
3893
+ if (!current.timer) {
3894
+ current.timer = setTimeout(() => {
3895
+ current.timer = undefined;
3896
+ try {
3897
+ advanceSessionActivity(db, sessionId, current.latest);
3898
+ current.lastWrite = Date.now();
3899
+ } catch {
3900
+ sessions.delete(sessionId);
3901
+ }
3902
+ }, Math.max(1, INTERVAL_MS - (time - current.lastWrite)));
3903
+ current.timer.unref?.();
3904
+ }
3905
+ }
3906
+ async function backfillSessionActivity(db, harness, latestTime) {
3907
+ const completedKey = `retrospective_activity_backfill:${harness}:v1`;
3908
+ if (db.prepare("SELECT 1 FROM schema_migrations_meta WHERE key = ?").get(completedKey))
3909
+ return;
3910
+ let cursor = "";
3911
+ while (true) {
3912
+ const rows = db.prepare(`SELECT session_id FROM session_projects
3913
+ WHERE harness = ? AND session_id > ? ORDER BY session_id LIMIT 100`).all(harness, cursor);
3914
+ if (rows.length === 0)
3915
+ break;
3916
+ for (const row of rows) {
3917
+ const time = await latestTime(row.session_id);
3918
+ if (time !== undefined)
3919
+ advanceSessionActivity(db, row.session_id, time);
3920
+ }
3921
+ cursor = rows[rows.length - 1].session_id;
3922
+ await new Promise((resolve) => setTimeout(resolve, 0));
3923
+ }
3924
+ db.prepare("INSERT OR IGNORE INTO schema_migrations_meta (key, value) VALUES (?, 'completed')").run(completedKey);
3925
+ }
3926
+
3927
+ // ../plugin/src/features/magic-context/storage-session-tables.ts
3928
+ var SESSION_SCOPED_TABLES = [
3929
+ { table: "pending_ops", harnessScoped: true },
3930
+ { table: "source_contents", harnessScoped: true },
3931
+ { table: "tool_owner_backfill_state" },
3932
+ { table: "tags", harnessScoped: true },
3933
+ { table: "session_meta", harnessScoped: true },
3934
+ {
3935
+ table: "temporal_decisions",
3936
+ extraPredicate: "NOT EXISTS (SELECT 1 FROM session_meta AS remaining WHERE remaining.session_id = temporal_decisions.session_id)"
3937
+ },
3938
+ {
3939
+ table: "session_replay_decisions",
3940
+ extraPredicate: "NOT EXISTS (SELECT 1 FROM session_meta AS remaining WHERE remaining.session_id = session_replay_decisions.session_id)"
3941
+ },
3942
+ { table: "session_projects", harnessScoped: true },
3943
+ { table: "compartment_chunk_embeddings", harnessScoped: true },
3944
+ { table: "compartments", harnessScoped: true },
3945
+ {
3946
+ table: "compartment_history_versions",
3947
+ extraPredicate: "NOT EXISTS (SELECT 1 FROM compartments AS remaining WHERE remaining.session_id = compartment_history_versions.session_id)"
3948
+ },
3949
+ { table: "compression_depth", harnessScoped: true },
3950
+ { table: "session_facts", harnessScoped: true },
3951
+ { table: "compartment_state_lease" },
3952
+ { table: "notes", harnessScoped: true, extraPredicate: "type = 'session'" },
3953
+ { table: "recomp_compartments", harnessScoped: true },
3954
+ { table: "recomp_facts", harnessScoped: true },
3955
+ { table: "user_memory_candidates" },
3956
+ { table: "primer_candidates", harnessScoped: true },
3957
+ { table: "m0_mutation_log" },
3958
+ { table: "compartment_events", harnessScoped: true },
3959
+ { table: "subagent_invocations", harnessScoped: true },
3960
+ { table: "historian_runs", harnessScoped: true },
3961
+ { table: "plugin_messages" },
3962
+ { table: "transform_decisions", harnessScoped: true },
3963
+ { table: "synapse_batch_ledger" },
3964
+ { table: "embedding_measurement_corpus" },
3965
+ { table: "pending_session_cleanup", harnessScoped: true },
3966
+ { table: "message_history_fts" },
3967
+ { table: "message_fts_rowid_map" },
3968
+ { table: "message_history_source", harnessScoped: true },
3969
+ { table: "message_history_index", harnessScoped: true },
3970
+ { table: "lkg_slots" },
3971
+ { table: "lkg_slot_chunks" }
3972
+ ];
3973
+ var cleanupStatements = new WeakMap;
3974
+ function cleanupStatement(db, sql) {
3975
+ let cache = cleanupStatements.get(db);
3976
+ if (!cache) {
3977
+ cache = new Map;
3978
+ cleanupStatements.set(db, cache);
3979
+ }
3980
+ let statement = cache.get(sql);
3981
+ if (!statement) {
3982
+ if (cache.size >= 256)
3983
+ cache.clear();
3984
+ statement = prepareCachedStatement2(db, sql);
3985
+ cache.set(sql, statement);
3986
+ }
3987
+ return statement;
3988
+ }
3989
+ function deleteSessionScopedRows(db, sessionIds, harness, options = {}) {
3990
+ if (sessionIds.length === 0)
3991
+ return 0;
3992
+ let deletableSessionIds = [...sessionIds];
3993
+ if (options.rustModuleCleanupAcknowledged !== true) {
3994
+ const placeholders = sessionIds.map(() => "?").join(", ");
3995
+ const harnessPredicate = harness === undefined ? "" : " AND harness = ?";
3996
+ const protectedRows = cleanupStatement(db, `SELECT session_id
3997
+ FROM pending_session_cleanup
3998
+ WHERE session_id IN (${placeholders})
3999
+ AND harness LIKE '%:rust'${harnessPredicate}`).all(...sessionIds, ...harness === undefined ? [] : [`${harness}:rust`]);
4000
+ const protectedSessionIds = new Set(protectedRows.map((row) => row.session_id));
4001
+ deletableSessionIds = sessionIds.filter((sessionId) => !protectedSessionIds.has(sessionId));
4002
+ }
4003
+ if (deletableSessionIds.length === 0)
4004
+ return 0;
4005
+ const placeholders = deletableSessionIds.map(() => "?").join(", ");
4006
+ const harnessTables = SESSION_SCOPED_TABLES.filter((definition) => definition.harnessScoped);
4007
+ if (options.preserveTagRevisionTombstones) {
4008
+ const owners = cleanupStatement(db, harnessTables.map((definition) => `SELECT session_id, harness FROM ${definition.table} WHERE session_id IN (${placeholders})${definition.extraPredicate ? ` AND ${definition.extraPredicate}` : ""}`).join(" UNION ")).all(...harnessTables.flatMap(() => deletableSessionIds));
4009
+ const record = cleanupStatement(db, "INSERT OR IGNORE INTO schema_migrations_meta (key, value) VALUES (?, ?)");
4010
+ for (const owner of owners)
4011
+ record.run(tagTombstoneOwnerKey(owner.session_id, owner.harness), owner.harness);
4012
+ const fallback = cleanupStatement(db, `INSERT INTO schema_migrations_meta (key, value)
4013
+ SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM schema_migrations_meta WHERE key >= ? AND key < ?)`);
4014
+ for (const id of deletableSessionIds)
4015
+ fallback.run(tagTombstoneOwnerKey(id, getHarness2()), getHarness2(), ...tagTombstoneOwnerRange(id));
4016
+ }
4017
+ for (const sessionId of deletableSessionIds)
4018
+ deleteChunkEmbedBackoffForSession2(db, sessionId);
4019
+ for (const definition of SESSION_SCOPED_TABLES) {
4020
+ if (definition.table === "message_history_fts") {
4021
+ cleanupStatement(db, `DELETE FROM message_history_fts
4022
+ WHERE rowid IN (
4023
+ SELECT fts_rowid
4024
+ FROM message_fts_rowid_map
4025
+ WHERE session_id IN (${placeholders})
4026
+ )`).run(...deletableSessionIds);
4027
+ deleteUnmappedMessageFtsRows2(db, deletableSessionIds);
4028
+ continue;
4029
+ }
4030
+ const predicates = [`session_id IN (${placeholders})`];
4031
+ if (definition.extraPredicate)
4032
+ predicates.push(definition.extraPredicate);
4033
+ const bindHarness = harness !== undefined && definition.harnessScoped === true;
4034
+ if (bindHarness)
4035
+ predicates.push("harness = ?");
4036
+ const statement = cleanupStatement(db, `DELETE FROM ${definition.table} WHERE ${predicates.join(" AND ")}`);
4037
+ if (bindHarness)
4038
+ statement.run(...deletableSessionIds, harness);
4039
+ else
4040
+ statement.run(...deletableSessionIds);
4041
+ }
4042
+ deleteSessionActivity(db, deletableSessionIds);
4043
+ if (!options.preserveTagRevisionTombstones) {
4044
+ const retireOwner = cleanupStatement(db, harness === undefined ? "DELETE FROM schema_migrations_meta WHERE key >= ? AND key < ?" : "DELETE FROM schema_migrations_meta WHERE key = ?");
4045
+ const survivingRows = harnessTables.map((definition) => `EXISTS (SELECT 1 FROM ${definition.table} WHERE session_id = ?${definition.extraPredicate ? ` AND ${definition.extraPredicate}` : ""})`).join(" OR ");
4046
+ const retire = cleanupStatement(db, `DELETE FROM schema_migrations_meta WHERE key IN (?, ?)
4047
+ AND NOT (${survivingRows})
4048
+ AND NOT EXISTS (SELECT 1 FROM schema_migrations_meta AS owners WHERE owners.key >= ? AND owners.key < ?)`);
4049
+ for (const id of deletableSessionIds) {
4050
+ if (harness === undefined)
4051
+ retireOwner.run(...tagTombstoneOwnerRange(id));
4052
+ else
4053
+ retireOwner.run(tagTombstoneOwnerKey(id, harness));
4054
+ retire.run(tagIdentityRevisionKey(id), tagRevisionKey(id), ...harnessTables.map(() => id), ...tagTombstoneOwnerRange(id));
4055
+ }
4056
+ }
4057
+ if (!options.deferRecoveryFenceCleanup)
4058
+ for (const sessionId of deletableSessionIds)
4059
+ clearLkgRecoveryFence(sessionId);
4060
+ return deletableSessionIds.length;
4061
+ }
4062
+
2859
4063
  // ../plugin/src/features/magic-context/storage-meta-session.ts
2860
4064
  var SESSION_META_FALLBACK_SELECTS = {
2861
4065
  cache_ttl: "'5m' AS cache_ttl",
@@ -3390,8 +4594,8 @@ function isPartialCompartmentEnd(db, sessionId, messageId) {
3390
4594
  return Boolean(db.prepare("SELECT 1 FROM compartments WHERE session_id=? AND end_message_id=? AND end_block_index IS NOT NULL LIMIT 1").get(sessionId, messageId));
3391
4595
  }
3392
4596
  // ../plugin/src/features/magic-context/project-docs-hash.ts
3393
- import { createHash } from "node:crypto";
3394
- import { lstatSync, readFileSync as readFileSync6, statSync as statSync3 } from "node:fs";
4597
+ import { createHash as createHash4 } from "node:crypto";
4598
+ import { lstatSync as lstatSync2, readFileSync as readFileSync8, statSync as statSync4 } from "node:fs";
3395
4599
  import path from "node:path";
3396
4600
  var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
3397
4601
  var PROJECT_DOCS_DELIMITER = `
@@ -3410,7 +4614,7 @@ function canonicalizeDocContent(raw) {
3410
4614
  }
3411
4615
  function fingerprintFile(filePath) {
3412
4616
  try {
3413
- const stat = lstatSync(filePath);
4617
+ const stat = lstatSync2(filePath);
3414
4618
  const isReadableDoc = stat.isFile() && stat.size <= MAX_PROJECT_DOC_BYTES;
3415
4619
  return {
3416
4620
  exists: isReadableDoc,
@@ -3423,7 +4627,7 @@ function fingerprintFile(filePath) {
3423
4627
  }
3424
4628
  function readDirectoryMtimeMs(projectDirectory) {
3425
4629
  try {
3426
- return statSync3(projectDirectory).mtimeMs;
4630
+ return statSync4(projectDirectory).mtimeMs;
3427
4631
  } catch {
3428
4632
  return 0;
3429
4633
  }
@@ -3458,7 +4662,7 @@ function readCanonicalPieces(projectDirectory, files) {
3458
4662
  }
3459
4663
  let safeToRead = false;
3460
4664
  try {
3461
- const st = lstatSync(filePath);
4665
+ const st = lstatSync2(filePath);
3462
4666
  safeToRead = st.isFile() && st.size <= MAX_PROJECT_DOC_BYTES;
3463
4667
  } catch {
3464
4668
  safeToRead = false;
@@ -3466,7 +4670,7 @@ function readCanonicalPieces(projectDirectory, files) {
3466
4670
  if (!safeToRead) {
3467
4671
  continue;
3468
4672
  }
3469
- const canonicalContent = canonicalizeDocContent(readFileSync6(filePath, "utf8"));
4673
+ const canonicalContent = canonicalizeDocContent(readFileSync8(filePath, "utf8"));
3470
4674
  hashPieces.push(`file:${filename}
3471
4675
  ${canonicalContent}`);
3472
4676
  renderedSections.push(`<file name="${escapeXmlAttr(filename)}">
@@ -3489,7 +4693,7 @@ function hashCanonicalPieces(hashPieces) {
3489
4693
  if (hashPieces.length === 0) {
3490
4694
  return "";
3491
4695
  }
3492
- return createHash("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
4696
+ return createHash4("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
3493
4697
  }
3494
4698
  function readProjectDocsCanonical(projectDirectory) {
3495
4699
  canonicalReadCountForTests += 1;
@@ -3515,7 +4719,7 @@ function readProjectDocsCanonical(projectDirectory) {
3515
4719
  return { renderedBlock, canonicalHash };
3516
4720
  }
3517
4721
  // ../plugin/src/hooks/magic-context/lkg-slot.ts
3518
- import { createHash as createHash3 } from "node:crypto";
4722
+ import { createHash as createHash6 } from "node:crypto";
3519
4723
 
3520
4724
  // ../plugin/src/shared/provider-response-completion.ts
3521
4725
  function providerResponseFailed(input) {
@@ -3567,7 +4771,7 @@ function hasOnlySystemHashMaterialization(sessions, sessionId) {
3567
4771
  }
3568
4772
 
3569
4773
  // ../plugin/src/hooks/magic-context/system-prompt-delivery.ts
3570
- var pending2 = new BoundedSessionMap(1000);
4774
+ var pending3 = new BoundedSessionMap(1000);
3571
4775
  var retiredRequests = new WeakSet;
3572
4776
  var heldRequests = new WeakSet;
3573
4777
  var refreshOwners = new BoundedSessionMap(1000);
@@ -3583,11 +4787,11 @@ function recordSystemRefreshOwnership(sessionId, hash, ownsHistoryRefresh, histo
3583
4787
  function preparation(sessionId, request) {
3584
4788
  if (retiredRequests.has(request))
3585
4789
  return;
3586
- const previous = pending2.get(sessionId);
4790
+ const previous = pending3.get(sessionId);
3587
4791
  if (previous?.request === request)
3588
4792
  return previous;
3589
4793
  const next = { request, held: false };
3590
- pending2.set(sessionId, next);
4794
+ pending3.set(sessionId, next);
3591
4795
  return next;
3592
4796
  }
3593
4797
  function recordSystemPromptForRequest(sessionId, request, hash, db, ownsHistoryRefresh, history, materialization) {
@@ -3595,7 +4799,7 @@ function recordSystemPromptForRequest(sessionId, request, hash, db, ownsHistoryR
3595
4799
  return;
3596
4800
  if (ownsHistoryRefresh !== undefined)
3597
4801
  recordSystemRefreshOwnership(sessionId, hash, ownsHistoryRefresh, history, materialization);
3598
- const previous = pending2.get(sessionId);
4802
+ const previous = pending3.get(sessionId);
3599
4803
  if (previous?.request === request && previous.held && previous.hash && previous.hash !== hash) {
3600
4804
  retirePendingSystemPromptDelivery(sessionId);
3601
4805
  return;
@@ -3618,7 +4822,7 @@ function recordHeldHeadForRequest(sessionId, request, deferRefresh) {
3618
4822
  }
3619
4823
  }
3620
4824
  function bindSystemPromptResponse(sessionId, request, response) {
3621
- const saved = pending2.get(sessionId);
4825
+ const saved = pending3.get(sessionId);
3622
4826
  if (!saved || saved.request !== request || request?.kind !== "v2" || !response.responseId || response.responseId === request.previousResponseId || response.modelKey !== request.modelKey || !Number.isFinite(response.createdAt) || response.createdAt <= request.startedAt)
3623
4827
  return;
3624
4828
  if (saved.response && saved.response.id !== response.responseId)
@@ -3626,7 +4830,7 @@ function bindSystemPromptResponse(sessionId, request, response) {
3626
4830
  saved.response = { id: response.responseId, createdAt: response.createdAt };
3627
4831
  }
3628
4832
  function acknowledgeSystemPromptDelivery(args) {
3629
- const saved = pending2.get(args.sessionId);
4833
+ const saved = pending3.get(args.sessionId);
3630
4834
  if (!saved || saved.request !== args.request || !args.responseId)
3631
4835
  return;
3632
4836
  const request = saved.request;
@@ -3668,10 +4872,10 @@ function clearSystemPromptDelivery(sessionId) {
3668
4872
  refreshOwners.delete(sessionId);
3669
4873
  }
3670
4874
  function retirePendingSystemPromptDelivery(sessionId) {
3671
- const saved = pending2.get(sessionId);
4875
+ const saved = pending3.get(sessionId);
3672
4876
  if (saved)
3673
4877
  retiredRequests.add(saved.request);
3674
- pending2.delete(sessionId);
4878
+ pending3.delete(sessionId);
3675
4879
  }
3676
4880
 
3677
4881
  // ../plugin/src/hooks/magic-context/lkg-measured-request.ts
@@ -3683,7 +4887,7 @@ function clearCapturedLkgMeasurement(sessionId) {
3683
4887
  }
3684
4888
 
3685
4889
  // ../plugin/src/hooks/magic-context/lkg-persist.ts
3686
- import { createHash as createHash2 } from "node:crypto";
4890
+ import { createHash as createHash5 } from "node:crypto";
3687
4891
  function parseStringArray(value) {
3688
4892
  if (typeof value !== "string")
3689
4893
  return null;
@@ -3797,7 +5001,7 @@ function rememberFingerprint(db, sessionId, fingerprint) {
3797
5001
  saved.set(sessionId, fingerprint);
3798
5002
  }
3799
5003
  function slotFingerprint(slot) {
3800
- return createHash2("sha256").update(JSON.stringify([
5004
+ return createHash5("sha256").update(JSON.stringify([
3801
5005
  slot.jsonPrefix,
3802
5006
  slot.inputIdSeq,
3803
5007
  slot.inputContentDigests,
@@ -4461,7 +5665,7 @@ var DIGEST_CHUNK_BYTES = 64 * 1024;
4461
5665
  var digestChunk;
4462
5666
  function lkgContentDigestFromFields(fields) {
4463
5667
  lkgDigestsComputed += 1;
4464
- const hash = createHash3("sha256");
5668
+ const hash = createHash6("sha256");
4465
5669
  digestChunk ??= Buffer.allocUnsafe(DIGEST_CHUNK_BYTES);
4466
5670
  const chunk = digestChunk;
4467
5671
  let offset = 0;
@@ -4524,7 +5728,7 @@ function legacyLkgDigestFromFields(fields) {
4524
5728
  const value = typeof field === "symbol" ? field.description ?? "" : String(field);
4525
5729
  key += `${typeof field}:${value.length}:${value}\x00`;
4526
5730
  }
4527
- return createHash3("sha256").update(key).digest("base64url");
5731
+ return createHash6("sha256").update(key).digest("base64url");
4528
5732
  }
4529
5733
  function legacyLkgContentDigest(message) {
4530
5734
  const fields = flattenContentFields(withoutEmptyUserDiffSummary(message));
@@ -5001,17 +6205,17 @@ function isReservedLedgerControlEntry(entry) {
5001
6205
  }
5002
6206
 
5003
6207
  // ../plugin/src/features/magic-context/pi-content-decisions.ts
5004
- var PREFIX = "pi-content-replay-v1:";
6208
+ var PREFIX2 = "pi-content-replay-v1:";
5005
6209
  var PI_CONTENT_DECISION_LIMIT = 4096;
5006
6210
  var PI_IDENTITY_RECURRENCE_ALLOWANCE = 64;
5007
6211
  function encodePiContentDecision(kind, messageId) {
5008
- return PREFIX + JSON.stringify([kind, messageId]);
6212
+ return PREFIX2 + JSON.stringify([kind, messageId]);
5009
6213
  }
5010
6214
  function decodePiContentDecision(value) {
5011
- if (!value.startsWith(PREFIX))
6215
+ if (!value.startsWith(PREFIX2))
5012
6216
  return null;
5013
6217
  try {
5014
- const pair = JSON.parse(value.slice(PREFIX.length));
6218
+ const pair = JSON.parse(value.slice(PREFIX2.length));
5015
6219
  if (Array.isArray(pair) && pair.length === 2 && (pair[0] === "reminder-strip" || pair[0] === "seam-temporal-strip" || pair[0] === "tag-identity-repair-once" || pair[0] === "tag-identity-repair-pending" || pair[0] === "tag-identity-rebuild-failed" || pair[0] === "tag-identity-recurring") && typeof pair[1] === "string" && pair[1].length > 0)
5016
6220
  return [pair[0], pair[1]];
5017
6221
  } catch {}
@@ -6082,9 +7286,9 @@ function formatNoteNudge(args) {
6082
7286
  }
6083
7287
 
6084
7288
  // ../plugin/src/shared/prompt-surface-runtime.ts
6085
- import { createHash as createHash4 } from "node:crypto";
6086
- import { existsSync as existsSync5, readFileSync as readFileSync7, statSync as statSync4 } from "node:fs";
6087
- import { dirname as dirname4, isAbsolute as isAbsolute3, resolve as resolve2 } from "node:path";
7289
+ import { createHash as createHash7 } from "node:crypto";
7290
+ import { existsSync as existsSync5, readFileSync as readFileSync9, statSync as statSync5 } from "node:fs";
7291
+ import { dirname as dirname5, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
6088
7292
 
6089
7293
  // ../plugin/src/tools/light-descriptions.ts
6090
7294
  var CTX_REDUCE_LIGHT_DESCRIPTION = `Stamp an item as no longer needed for the work ahead. Not a delete: stamping QUEUES it, the item stays readable until Magic Context clears stamped items in one sweep, newest tags are protected, and a cleared item goes to the archive (recent: a [dropped §N§] placeholder; older: removed) recoverable via ctx_expand(tag=N). The question is "does this need to stay on my desk for what comes next?" — a file you keep editing stays, the grep that found it goes. Stamp used reads/searches/outputs, acted-on build/test output, redundant dumps, extracted pasted payloads; keep user messages, your own text, unresolved errors, raw evidence, exact wording that may matter. Look at each tag; never blanket-stamp "1-50". Grammar: "3-5", "1,2,9", "1-5,8,12-15".`;
@@ -6115,22 +7319,22 @@ function promptSurfaceHashMaterial(systemContent, preset = "full") {
6115
7319
  \x00magic-context-prompt-surface:${preset}`;
6116
7320
  }
6117
7321
  function systemPromptFingerprint(systemContent, preset = "full") {
6118
- return createHash4("md5").update(promptSurfaceHashMaterial(systemContent, preset)).digest("hex");
7322
+ return createHash7("md5").update(promptSurfaceHashMaterial(systemContent, preset)).digest("hex");
6119
7323
  }
6120
7324
  var PROMPT_SURFACE_TOOL_ID_SET = new Set(ACTIVE_TOOL_IDS);
6121
7325
  function resolveUserConfigDirectory(options) {
6122
7326
  if (options.userConfigDirectory)
6123
- return resolve2(options.userConfigDirectory);
7327
+ return resolve3(options.userConfigDirectory);
6124
7328
  const sharedBase = cortexKitUserConfigBasePath();
6125
7329
  const shared = detectConfigFile(sharedBase);
6126
7330
  if (shared.format !== "none")
6127
- return dirname4(shared.path);
7331
+ return dirname5(shared.path);
6128
7332
  if (options.harness) {
6129
7333
  const legacy = resolveLegacyConfigSourcesForHarness(options.directory ?? process.cwd(), options.harness === "omp" ? "pi" : options.harness === "opencode2" ? "opencode" : options.harness).user.find((source) => existsSync5(source.path));
6130
7334
  if (legacy)
6131
- return dirname4(legacy.path);
7335
+ return dirname5(legacy.path);
6132
7336
  }
6133
- return dirname4(sharedBase);
7337
+ return dirname5(sharedBase);
6134
7338
  }
6135
7339
  function markerCount(content) {
6136
7340
  return content.match(GUIDANCE_MARKER_LINE)?.length ?? 0;
@@ -6147,14 +7351,14 @@ function createPromptSurfaceRuntime(options) {
6147
7351
  const readGuidanceOverride = (configuredPath) => {
6148
7352
  if (!configuredPath)
6149
7353
  return;
6150
- const path = isAbsolute3(configuredPath) ? configuredPath : resolve2(userConfigDirectory, configuredPath);
7354
+ const path = isAbsolute3(configuredPath) ? configuredPath : resolve3(userConfigDirectory, configuredPath);
6151
7355
  let content;
6152
7356
  try {
6153
- if (!statSync4(path).isFile()) {
7357
+ if (!statSync5(path).isFile()) {
6154
7358
  warnOnce(`guidance-not-file:${path}`, `prompt_surface.guidance_override_path (${path}) is not a file; using built-in guidance.`);
6155
7359
  return;
6156
7360
  }
6157
- content = readFileSync7(path, "utf8");
7361
+ content = readFileSync9(path, "utf8");
6158
7362
  } catch (error) {
6159
7363
  const reason = error instanceof Error ? error.message : String(error);
6160
7364
  warnOnce(`guidance-unreadable:${path}:${reason}`, `prompt_surface.guidance_override_path (${path}) could not be read (${reason}); using built-in guidance.`);
@@ -6229,7 +7433,7 @@ function createPromptSurfaceGuidanceEpochCache(runtime) {
6229
7433
  }
6230
7434
 
6231
7435
  // src/read-session-pi.ts
6232
- import { createHash as createHash5 } from "node:crypto";
7436
+ import { createHash as createHash8 } from "node:crypto";
6233
7437
  var SYNTH_USER_ID_PREFIX = "synth-user-";
6234
7438
  function resolvePiStableId(msg, index, entryIds, entryIdByRef) {
6235
7439
  if (!msg || typeof msg !== "object")
@@ -6268,7 +7472,7 @@ function piContentFallbackIds(messages, resolveReal) {
6268
7472
  return;
6269
7473
  const m = message;
6270
7474
  const role = typeof m.role === "string" ? m.role : "unknown";
6271
- const digest = createHash5("sha256").update(stableStringify([
7475
+ const digest = createHash8("sha256").update(stableStringify([
6272
7476
  typeof m.responseId === "string" ? m.responseId : null,
6273
7477
  typeof m.timestamp === "number" || typeof m.timestamp === "string" ? m.timestamp : null,
6274
7478
  role,
@@ -7219,7 +8423,7 @@ function compareMemorySelectionPriority(left, right) {
7219
8423
  }
7220
8424
 
7221
8425
  // ../plugin/src/features/magic-context/mural/render-trigger.ts
7222
- import { createHash as createHash6 } from "node:crypto";
8426
+ import { createHash as createHash9 } from "node:crypto";
7223
8427
 
7224
8428
  // ../plugin/src/features/magic-context/mural/mural-selection.ts
7225
8429
  var DEFAULT_MURAL_MEMORY_BUDGET = 8000;
@@ -7908,7 +9112,7 @@ function ensureMuralRendered(db, projectIdentity, budgetTokens = DEFAULT_MURAL_M
7908
9112
  return { ...cached.result };
7909
9113
  }
7910
9114
  const plan = planMuralRender(entries);
7911
- const textHash = createHash6("sha256").update(plan.layout.text).digest("hex");
9115
+ const textHash = createHash9("sha256").update(plan.layout.text).digest("hex");
7912
9116
  if (existing && existing.contentHash === textHash && existing.width === plan.width && existing.height === plan.height) {
7913
9117
  return rememberRender(db, projectIdentity, key, existing.image, {
7914
9118
  hasMural: true,
@@ -7965,14 +9169,14 @@ function resolveMuralWire(db, projectIdentity, modelKey, enabled, budgetTokens =
7965
9169
  }
7966
9170
 
7967
9171
  // ../plugin/src/features/magic-context/compaction-marker.ts
7968
- import { createHash as createHash7 } from "node:crypto";
7969
- import { existsSync as existsSync6, statSync as statSync5 } from "node:fs";
9172
+ import { createHash as createHash10 } from "node:crypto";
9173
+ import { existsSync as existsSync6, statSync as statSync6 } from "node:fs";
7970
9174
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
7971
9175
  var ID_PREFIX_HEX_LENGTH = 12;
7972
9176
  var ID_SUFFIX_LENGTH = 14;
7973
9177
  var ID_PREFIX_MASK = (1n << BigInt(ID_PREFIX_HEX_LENGTH * 4)) - 1n;
7974
9178
  function deterministicBase62(seed, length) {
7975
- let value = BigInt(`0x${createHash7("sha256").update(seed).digest("hex")}`);
9179
+ let value = BigInt(`0x${createHash10("sha256").update(seed).digest("hex")}`);
7976
9180
  const chars = Array(length);
7977
9181
  for (let index = length - 1;index >= 0; index -= 1) {
7978
9182
  chars[index] = BASE62_CHARS[Number(value % 62n)];
@@ -8035,7 +9239,7 @@ function runMarkerWriteTransaction(db, site, operation) {
8035
9239
  function markerWalPages(db) {
8036
9240
  try {
8037
9241
  const row = db.prepare("PRAGMA page_size").get();
8038
- const bytes = statSync5(`${getOpenCodeDbPath()}-wal`).size;
9242
+ const bytes = statSync6(`${getOpenCodeDbPath()}-wal`).size;
8039
9243
  return Math.max(0, Math.floor((bytes - 32) / (row.page_size + 24)));
8040
9244
  } catch {
8041
9245
  return null;
@@ -9164,7 +10368,7 @@ function takeCurateSafetyRefusalCount(sessionId) {
9164
10368
  }
9165
10369
 
9166
10370
  // ../plugin/src/features/magic-context/smart-notes/wake-plane.ts
9167
- import { join as join4 } from "node:path";
10371
+ import { join as join6 } from "node:path";
9168
10372
  var WAKE_PLANE_CAPABILITY = "wake.create";
9169
10373
  var WAKE_PLANE_STATUS_TTL_MS = 5 * 60 * 1000;
9170
10374
  var WAKE_PLANE_HANDSHAKE_TIMEOUT_MS = 2000;
@@ -9173,7 +10377,7 @@ var inFlightProbe = null;
9173
10377
  var catalogProbe = probeWakePlaneCatalog;
9174
10378
  var now = () => Date.now();
9175
10379
  function connectionFile() {
9176
- return join4(getDataDir(), "cortexkit", "run", "subc-connection.json");
10380
+ return join6(getDataDir(), "cortexkit", "run", "subc-connection.json");
9177
10381
  }
9178
10382
  async function probeWakePlaneCatalog() {
9179
10383
  const file = connectionFile();
@@ -9221,10 +10425,10 @@ async function wakePlaneStatus() {
9221
10425
  }
9222
10426
 
9223
10427
  // src/embedding-bootstrap.ts
9224
- import { statSync as statSync6 } from "node:fs";
10428
+ import { statSync as statSync7 } from "node:fs";
9225
10429
 
9226
10430
  // ../plugin/src/plugin/embedding-bootstrap-helpers.ts
9227
- import { createHash as createHash8 } from "node:crypto";
10431
+ import { createHash as createHash11 } from "node:crypto";
9228
10432
  var EMBEDDING_AFFECTING_KEYS = new Set([
9229
10433
  "embedding.api_key",
9230
10434
  "embedding.endpoint",
@@ -9272,7 +10476,7 @@ var EMBEDDING_WARNING_TERMS = [
9272
10476
  ];
9273
10477
  var loggedFailureSignatures = new Map;
9274
10478
  function sha256Prefix(value, length = 16) {
9275
- return createHash8("sha256").update(value).digest("hex").slice(0, length);
10479
+ return createHash11("sha256").update(value).digest("hex").slice(0, length);
9276
10480
  }
9277
10481
  function warningLooksEmbeddingRelated(message) {
9278
10482
  const lower = message.toLowerCase();
@@ -9933,7 +11137,7 @@ function configCandidatePaths(directory, loadedPaths) {
9933
11137
  function configFingerprint(paths) {
9934
11138
  return paths.map((path) => {
9935
11139
  try {
9936
- const stat = statSync6(path);
11140
+ const stat = statSync7(path);
9937
11141
  return `${path}:${stat.size}:${stat.mtimeMs}`;
9938
11142
  } catch {
9939
11143
  return `${path}:missing`;
@@ -10025,8 +11229,8 @@ function restoreOmpMentions(value) {
10025
11229
  }
10026
11230
 
10027
11231
  // src/pi-harness-kind.ts
10028
- import { existsSync as existsSync8, readFileSync as readFileSync8, realpathSync as realpathSync2 } from "node:fs";
10029
- import { dirname as dirname5, join as join5, parse as parse2, resolve as resolve3 } from "node:path";
11232
+ import { existsSync as existsSync8, readFileSync as readFileSync10, realpathSync as realpathSync2 } from "node:fs";
11233
+ import { dirname as dirname6, join as join7, parse as parse2, resolve as resolve4 } from "node:path";
10030
11234
  import { pathToFileURL } from "node:url";
10031
11235
  var OMP_UTILS_MODULE = "@oh-my-pi/pi-utils";
10032
11236
  var OMP_HOST_PACKAGE = "@oh-my-pi/pi-coding-agent";
@@ -10042,7 +11246,7 @@ function hostEntries() {
10042
11246
  for (const candidate of [process.argv[1], process.execPath]) {
10043
11247
  if (!candidate)
10044
11248
  continue;
10045
- const requestedPath = resolve3(candidate);
11249
+ const requestedPath = resolve4(candidate);
10046
11250
  let resolvedPath;
10047
11251
  try {
10048
11252
  resolvedPath = realpathSync2(requestedPath);
@@ -10058,23 +11262,23 @@ function hostEntries() {
10058
11262
  }
10059
11263
  function readPackageJson(path) {
10060
11264
  try {
10061
- return JSON.parse(readFileSync8(path, "utf8"));
11265
+ return JSON.parse(readFileSync10(path, "utf8"));
10062
11266
  } catch {
10063
11267
  return;
10064
11268
  }
10065
11269
  }
10066
11270
  function nearestPackageName(entryPath) {
10067
- let directory = dirname5(entryPath);
11271
+ let directory = dirname6(entryPath);
10068
11272
  const root = parse2(directory).root;
10069
11273
  while (true) {
10070
- const packagePath = join5(directory, "package.json");
11274
+ const packagePath = join7(directory, "package.json");
10071
11275
  if (existsSync8(packagePath)) {
10072
11276
  const name = readPackageJson(packagePath)?.name;
10073
11277
  return typeof name === "string" ? name : undefined;
10074
11278
  }
10075
11279
  if (directory === root)
10076
11280
  return;
10077
- directory = dirname5(directory);
11281
+ directory = dirname6(directory);
10078
11282
  }
10079
11283
  }
10080
11284
  function packageNameDetection(entries) {
@@ -10091,15 +11295,15 @@ function packageNameDetection(entries) {
10091
11295
  }
10092
11296
  function dependencyPackageRoot(entryPath, moduleName) {
10093
11297
  const moduleParts = moduleName.split("/");
10094
- let directory = dirname5(entryPath);
11298
+ let directory = dirname6(entryPath);
10095
11299
  const root = parse2(directory).root;
10096
11300
  while (true) {
10097
- const packageRoot = join5(directory, "node_modules", ...moduleParts);
10098
- if (existsSync8(join5(packageRoot, "package.json")))
11301
+ const packageRoot = join7(directory, "node_modules", ...moduleParts);
11302
+ if (existsSync8(join7(packageRoot, "package.json")))
10099
11303
  return packageRoot;
10100
11304
  if (directory === root)
10101
11305
  return;
10102
- directory = dirname5(directory);
11306
+ directory = dirname6(directory);
10103
11307
  }
10104
11308
  }
10105
11309
  function importTarget(exportsValue) {
@@ -10118,11 +11322,11 @@ function hostModuleImportUrl(entryPath) {
10118
11322
  const packageRoot = dependencyPackageRoot(entryPath, OMP_UTILS_MODULE);
10119
11323
  if (!packageRoot)
10120
11324
  return;
10121
- const packageJson = readPackageJson(join5(packageRoot, "package.json"));
11325
+ const packageJson = readPackageJson(join7(packageRoot, "package.json"));
10122
11326
  const target = importTarget(packageJson?.exports) ?? (typeof packageJson?.module === "string" ? packageJson.module : typeof packageJson?.main === "string" ? packageJson.main : undefined);
10123
11327
  if (!target?.startsWith("./"))
10124
11328
  return;
10125
- return pathToFileURL(resolve3(packageRoot, target)).href;
11329
+ return pathToFileURL(resolve4(packageRoot, target)).href;
10126
11330
  }
10127
11331
  async function appNameDetection(entries) {
10128
11332
  for (const entry of entries) {
@@ -10545,7 +11749,7 @@ function resolveCtxExpandMode(args, domain) {
10545
11749
  }
10546
11750
 
10547
11751
  // ../plugin/src/tools/ctx-expand/render.ts
10548
- import { createHash as createHash9 } from "node:crypto";
11752
+ import { createHash as createHash12 } from "node:crypto";
10549
11753
  function isRecord3(value) {
10550
11754
  return value !== null && typeof value === "object" && !Array.isArray(value);
10551
11755
  }
@@ -10769,7 +11973,7 @@ function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
10769
11973
  const index = scoped ? Number(scoped[2]) : 0;
10770
11974
  const piText = message.parts.filter((part) => isRecord3(part) && part.type === "text");
10771
11975
  const part = message.parts[index];
10772
- const matching = derived ? piText.filter((part) => isRecord3(part) && typeof part.text === "string" && createHash9("sha256").update(part.text).digest("hex") === derived[3]) : [];
11976
+ const matching = derived ? piText.filter((part) => isRecord3(part) && typeof part.text === "string" && createHash12("sha256").update(part.text).digest("hex") === derived[3]) : [];
10773
11977
  const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" ? piText[index] : part;
10774
11978
  return selected ? renderPartFull(selected) ?? "" : `Tag ${number}'s original text part is no longer in stored history.`;
10775
11979
  }
@@ -11862,7 +13066,7 @@ import { isAbsolute as isAbsolute5 } from "node:path";
11862
13066
  // ../retina-local-fs/src/path-fence.ts
11863
13067
  import { lstat, realpath } from "node:fs/promises";
11864
13068
  import { homedir as homedir3 } from "node:os";
11865
- import { basename as basename3, dirname as dirname6, isAbsolute as isAbsolute4, join as join6, relative, resolve as resolve4, sep } from "node:path";
13069
+ import { basename as basename4, dirname as dirname7, isAbsolute as isAbsolute4, join as join8, relative, resolve as resolve5, sep } from "node:path";
11866
13070
 
11867
13071
  // ../retina-local-fs/src/errors.ts
11868
13072
  class ProviderError extends Error {
@@ -11877,8 +13081,8 @@ class ProviderError extends Error {
11877
13081
  // ../retina-local-fs/src/path-fence.ts
11878
13082
  async function resolveAndFenceProviderPath(configuredPath, options) {
11879
13083
  const { home, dataDirectory, aliases } = await resolveFenceRoots(options);
11880
- const expanded = configuredPath.startsWith("~/") ? join6(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
11881
- const absolute = isAbsolute4(expanded) ? resolve4(expanded) : resolve4(options.cwd ?? process.cwd(), expanded);
13084
+ const expanded = configuredPath.startsWith("~/") ? join8(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
13085
+ const absolute = isAbsolute4(expanded) ? resolve5(expanded) : resolve5(options.cwd ?? process.cwd(), expanded);
11882
13086
  const canonical = await canonicalPath(absolute, options.allowMissing);
11883
13087
  if (fenceCandidates(canonical, aliases).some((candidate) => isFencedPath(candidate, home, dataDirectory))) {
11884
13088
  throw new ProviderError("fenced_path", `Refusing fenced path: ${canonical}`);
@@ -11887,20 +13091,20 @@ async function resolveAndFenceProviderPath(configuredPath, options) {
11887
13091
  }
11888
13092
  var FENCED_CORTEXKIT_ROOTS = ["plexus", "claustrum", "staging", "run", "magic-context"];
11889
13093
  async function resolveFenceRoots(options) {
11890
- const configuredHomePath = resolve4(options.homeDirectory ?? process.env.HOME ?? homedir3());
13094
+ const configuredHomePath = resolve5(options.homeDirectory ?? process.env.HOME ?? homedir3());
11891
13095
  let home;
11892
13096
  try {
11893
13097
  home = await realpath(configuredHomePath);
11894
13098
  } catch (error) {
11895
13099
  throw fsError(configuredHomePath, error);
11896
13100
  }
11897
- const configuredDataDirectory = resolve4(options.dataDirectory ?? process.env.XDG_DATA_HOME ?? join6(home, ".local", "share"));
13101
+ const configuredDataDirectory = resolve5(options.dataDirectory ?? process.env.XDG_DATA_HOME ?? join8(home, ".local", "share"));
11898
13102
  const dataDirectory = await canonicalPath(configuredDataDirectory, true);
11899
13103
  const aliases = [];
11900
- const logicalCortexkit = join6(dataDirectory, "cortexkit");
13104
+ const logicalCortexkit = join8(dataDirectory, "cortexkit");
11901
13105
  for (const logical of [
11902
13106
  logicalCortexkit,
11903
- ...FENCED_CORTEXKIT_ROOTS.map((root) => join6(logicalCortexkit, root))
13107
+ ...FENCED_CORTEXKIT_ROOTS.map((root) => join8(logicalCortexkit, root))
11904
13108
  ]) {
11905
13109
  const canonical = await canonicalPath(logical, true);
11906
13110
  if (canonical !== logical)
@@ -11914,7 +13118,7 @@ function fenceCandidates(canonical, aliases) {
11914
13118
  const relativeToAlias = relative(alias.canonical, canonical);
11915
13119
  const inside = relativeToAlias === "" || relativeToAlias !== ".." && !relativeToAlias.startsWith(`..${sep}`) && !isAbsolute4(relativeToAlias);
11916
13120
  if (inside)
11917
- candidates.push(join6(alias.logical, relativeToAlias));
13121
+ candidates.push(join8(alias.logical, relativeToAlias));
11918
13122
  }
11919
13123
  return candidates;
11920
13124
  }
@@ -11938,14 +13142,14 @@ async function canonicalPath(path, allowMissing) {
11938
13142
  }
11939
13143
  if (symbolicLink)
11940
13144
  throw fsError(path, error);
11941
- const parent = dirname6(candidate);
13145
+ const parent = dirname7(candidate);
11942
13146
  if (parent === candidate) {
11943
13147
  throw fsError(path, error);
11944
13148
  }
11945
- suffix.unshift(basename3(candidate));
13149
+ suffix.unshift(basename4(candidate));
11946
13150
  candidate = parent;
11947
13151
  try {
11948
- return join6(await realpath(candidate), ...suffix);
13152
+ return join8(await realpath(candidate), ...suffix);
11949
13153
  } catch (parentError) {
11950
13154
  if (!isMissingError(parentError)) {
11951
13155
  throw fsError(path, parentError);
@@ -11954,13 +13158,13 @@ async function canonicalPath(path, allowMissing) {
11954
13158
  }
11955
13159
  }
11956
13160
  }
11957
- function isFencedPath(canonicalPath, homeDirectory, dataDirectory = process.env.XDG_DATA_HOME ?? join6(resolve4(homeDirectory), ".local", "share")) {
11958
- const cortexkitRoot = join6(resolve4(dataDirectory), "cortexkit");
13161
+ function isFencedPath(canonicalPath, homeDirectory, dataDirectory = process.env.XDG_DATA_HOME ?? join8(resolve5(homeDirectory), ".local", "share")) {
13162
+ const cortexkitRoot = join8(resolve5(dataDirectory), "cortexkit");
11959
13163
  const relativeToCortexkit = relative(cortexkitRoot, canonicalPath);
11960
13164
  const insideCortexkit = relativeToCortexkit !== "" && relativeToCortexkit !== ".." && !relativeToCortexkit.startsWith(`..${sep}`) && !isAbsolute4(relativeToCortexkit);
11961
13165
  const parts = insideCortexkit ? relativeToCortexkit.split(sep) : [];
11962
13166
  const pathParts = canonicalPath.split(sep).filter(Boolean);
11963
- const name = basename3(canonicalPath);
13167
+ const name = basename4(canonicalPath);
11964
13168
  const catalogDirectoryCarveIn = pathParts.includes("catalog");
11965
13169
  const moduleBinCarveIn = parts.length >= 2 && parts[1] === "bin";
11966
13170
  const catalogJsonCarveIn = name.endsWith(".json") && name.includes("catalog");
@@ -12422,7 +13626,7 @@ function err3(text) {
12422
13626
  }
12423
13627
  function captureAnchorOrdinal(db, sessionId) {
12424
13628
  try {
12425
- const ordinal = getLastIndexedOrdinal2(db, sessionId);
13629
+ const ordinal = getLastIndexedOrdinal(db, sessionId);
12426
13630
  return ordinal > 0 ? ordinal : null;
12427
13631
  } catch {
12428
13632
  return null;
@@ -13649,4 +14853,4 @@ function registerMagicContextTools(pi, opts) {
13649
14853
  }
13650
14854
  }
13651
14855
 
13652
- export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, formatConfigParseStatusLine, formatConfigParseNotice, claimConfigParseFailuresOnce, parseJsoncRecovering, detectConfigFile, OPENCODE_OUTPUT_CAP, MIN_PLAUSIBLE_CONTEXT_LIMIT, catalogOutputReserve, deriveWindowGeometry, hasTrustedAbsoluteWall, applyProvenInputFloor, formatWindowDerivationLine, formatWindowSource, isSaneLimit, resolveOutputReserve, getSdkWindowGeometry, getSdkContextLimit, getSdkOutputLimit, getSdkInputLimit, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, migrateMagicContextConfigLocations, getProtectedTokensTierOverrides, rememberUnpublishedAutoSearchNoHint, getUnpublishedAutoSearchNoHint, forgetUnpublishedAutoSearchNoHint, registerAutoSearchWork, cancelAutoSearchWork, readSessionMeta, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, isNoContentCompartment, HAS_COMPARTMENT_CONTENT_SQL, queueM0Mutation, getMaxM0MutationId, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getUncoveredCompartmentEndThrough, isPartialCompartmentEnd, readProjectDocsCanonical, providerResponseFailed, isSuccessfulProviderCompletion, requestPendingMaterialization, pendingMaterializationOrigin, hasPendingMaterializationOrigin, clearPendingMaterialization, recordSystemRefreshOwnership, recordSystemPromptForRequest, recordHeldHeadForRequest, bindSystemPromptResponse, acknowledgeSystemPromptDelivery, deferDeliveredSystemRefresh, clearSystemPromptDelivery, saveLkgSlotToDb, loadPersistedLkgSlot, drainStaleLkgSlots, createDbLkgPersistence, replayLkg, registerLkgPersistence, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, contentSnapshotValue, signatureForFields, lkgContentFields, lkgContentDigestFromFields, isLegacyLkgDigest, legacyLkgDigestFromFields, lkgFieldsMatchDigest, exactReusablePrefix, incrementalLkgContentDigests, lkgSlotRejection, captureSlot, getInMemorySlot, getSlot, dropSlot, TOOL_SWEEP_SCOPED_MARKER, encodePiContentDecision, decodePiContentDecision, getPiContentDecisions, freezePiContentDecision, getNativeReplayState, saveNativeToolInputs, addNativeReasoningIds, copySessionStateForClone, externalHistorianFailureReason, subprocessExitHistorianFailureReason, countHistorianRuns, recordHistorianRun, summarizeImportance, tallyFactsByCategory, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, noteTouchedAt, noteNudgePickIndex, formatNoteNudge, systemPromptFingerprint, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, resolvePiRealStableId, isPiContentFallbackId, isPiIndexFallbackId, piContentFallbackIds, readPiSessionSnapshot, readPiSessionMessages, readPiSessionMessagePage, findRestartModelSeedFromBranch, iterateEntriesToRawMessageRange, iterateAsyncEntriesToRawMessageRange, convertEntriesToRawMessages, convertPiAssistantEntryById, convertEntriesToRawMessagePage, countPiRawMessages, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getTaskScheduleState, getFailingDreamTasks, getSkippedDreamTasks, getMostRecentTaskRunAt, pruneNonCanonicalTaskRows, deleteTaskScheduleRowsForProject, seedTaskScheduleState, writeTaskScheduleState, isRetrospectiveWindowProcessed, recordRetrospectiveWindowProcessed, curateCategoryForMemoryCategory, peekCurateCategoryScope, beginCurateCategoryRun, curateTaskStateAfterSuccess, MEMORY_MURAL_BLOCK, buildMagicContextSection, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, MEMORY_RENDER_FORMAT_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, withCachedM0MemoryIds, readCachedM0MemoryIds, renderBudgetIdentityChanged, renderedBudgetSnapshot, renderedBudgetShrinkReason, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, TEMPORAL_MARKER_REPLAY_PATTERN, temporalMarkerPrefix, renderUserProfileContent, clearInjectionCache, getVisibleMemoryIds, orderHistorianMemories, renderHistorianMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, resetPrefixTrimFallbackState, isDirectiveShapedProjectRule, takeCurateSafetyRefusalCount, wakePlaneStatus, loadPiConfig, loadPiConfigDetailed, unregisterPiProjectEmbeddings, ensureProjectRegisteredFromPiDirectory, neutralizeOmpMentions, restoreOmpMentions, resolvePiHarnessDetection, resolvePiHarnessKind, resolvePiOrdinalAlignment, piRawOrdinalOffsetSource, resolvePiOrdinalAlignmentForContext, isPiOrdinalAlignmentUnanchored, clearPiOrdinalAlignmentSession, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, syncCtxMemoryToolEnabled, registerMagicContextTools };
14856
+ export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, formatConfigParseStatusLine, formatConfigParseNotice, claimConfigParseFailuresOnce, parseJsoncRecovering, detectConfigFile, OPENCODE_OUTPUT_CAP, MIN_PLAUSIBLE_CONTEXT_LIMIT, catalogOutputReserve, deriveWindowGeometry, hasTrustedAbsoluteWall, applyProvenInputFloor, formatWindowDerivationLine, formatWindowSource, isSaneLimit, resolveOutputReserve, getSdkWindowGeometry, getSdkContextLimit, getSdkOutputLimit, getSdkInputLimit, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, migrateMagicContextConfigLocations, getProtectedTokensTierOverrides, LkgRecoveryFenceError, clearLkgFenceProcessState, lkgFenceRequiresRebuild, lkgRecoveryFenceUnclean, ownsLkgDirtyFence, invalidateCleanLkgRecoveryFence, markLkgRecoveryDirty, rememberUnpublishedAutoSearchNoHint, getUnpublishedAutoSearchNoHint, forgetUnpublishedAutoSearchNoHint, registerAutoSearchWork, cancelAutoSearchWork, readSessionActivity, observeSessionActivity, backfillSessionActivity, readSessionMeta, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, isNoContentCompartment, HAS_COMPARTMENT_CONTENT_SQL, queueM0Mutation, getMaxM0MutationId, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getUncoveredCompartmentEndThrough, isPartialCompartmentEnd, readProjectDocsCanonical, providerResponseFailed, isSuccessfulProviderCompletion, requestPendingMaterialization, pendingMaterializationOrigin, hasPendingMaterializationOrigin, clearPendingMaterialization, recordSystemRefreshOwnership, recordSystemPromptForRequest, recordHeldHeadForRequest, bindSystemPromptResponse, acknowledgeSystemPromptDelivery, deferDeliveredSystemRefresh, clearSystemPromptDelivery, saveLkgSlotToDb, loadPersistedLkgSlot, drainStaleLkgSlots, createDbLkgPersistence, replayLkg, registerLkgPersistence, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, contentSnapshotValue, signatureForFields, lkgContentFields, lkgContentDigestFromFields, isLegacyLkgDigest, legacyLkgDigestFromFields, lkgFieldsMatchDigest, exactReusablePrefix, incrementalLkgContentDigests, lkgSlotRejection, captureSlot, getInMemorySlot, getSlot, dropSlot, TOOL_SWEEP_SCOPED_MARKER, encodePiContentDecision, decodePiContentDecision, getPiContentDecisions, freezePiContentDecision, getNativeReplayState, saveNativeToolInputs, addNativeReasoningIds, copySessionStateForClone, externalHistorianFailureReason, subprocessExitHistorianFailureReason, countHistorianRuns, recordHistorianRun, summarizeImportance, tallyFactsByCategory, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, noteTouchedAt, noteNudgePickIndex, formatNoteNudge, systemPromptFingerprint, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, resolvePiRealStableId, isPiContentFallbackId, isPiIndexFallbackId, piContentFallbackIds, readPiSessionSnapshot, readPiSessionMessages, readPiSessionMessagePage, findRestartModelSeedFromBranch, iterateEntriesToRawMessageRange, iterateAsyncEntriesToRawMessageRange, convertEntriesToRawMessages, convertPiAssistantEntryById, convertEntriesToRawMessagePage, countPiRawMessages, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getTaskScheduleState, getFailingDreamTasks, getSkippedDreamTasks, getMostRecentTaskRunAt, pruneNonCanonicalTaskRows, deleteTaskScheduleRowsForProject, seedTaskScheduleState, writeTaskScheduleState, isRetrospectiveWindowProcessed, recordRetrospectiveWindowProcessed, curateCategoryForMemoryCategory, peekCurateCategoryScope, beginCurateCategoryRun, curateTaskStateAfterSuccess, MEMORY_MURAL_BLOCK, buildMagicContextSection, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, MEMORY_RENDER_FORMAT_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, withCachedM0MemoryIds, readCachedM0MemoryIds, renderBudgetIdentityChanged, renderedBudgetSnapshot, renderedBudgetShrinkReason, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, TEMPORAL_MARKER_REPLAY_PATTERN, temporalMarkerPrefix, renderUserProfileContent, clearInjectionCache, getVisibleMemoryIds, orderHistorianMemories, renderHistorianMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, resetPrefixTrimFallbackState, isDirectiveShapedProjectRule, takeCurateSafetyRefusalCount, wakePlaneStatus, loadPiConfig, loadPiConfigDetailed, unregisterPiProjectEmbeddings, ensureProjectRegisteredFromPiDirectory, neutralizeOmpMentions, restoreOmpMentions, resolvePiHarnessDetection, resolvePiHarnessKind, resolvePiOrdinalAlignment, piRawOrdinalOffsetSource, resolvePiOrdinalAlignmentForContext, isPiOrdinalAlignmentUnanchored, clearPiOrdinalAlignmentSession, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, syncCtxMemoryToolEnabled, registerMagicContextTools };