@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.
- package/dist/auto-search-worker.js +4 -4
- package/dist/chunk-embedding-write-worker.js +8 -9
- package/dist/{compartment-chunk-embedding-vt6afvdm.js → compartment-chunk-embedding-pkk5beqp.js} +3 -3
- package/dist/{embedding-backfill-jc5fqt5s.js → embedding-backfill-25fp3b8w.js} +7 -7
- package/dist/{index-0dr64gsy.js → index-0s14xaca.js} +2 -2
- package/dist/{index-n8e5e9fp.js → index-0x1c054v.js} +1 -1
- package/dist/{index-hxp6q5f8.js → index-48twbev2.js} +50 -36
- package/dist/{index-j3pz3a1b.js → index-4zemngt7.js} +1 -1
- package/dist/{index-r1hvaza0.js → index-5d506f7y.js} +719 -23
- package/dist/{index-z24d75tz.js → index-6981g1xv.js} +0 -2
- package/dist/{index-zpmz6x24.js → index-bkcwcghx.js} +1308 -104
- package/dist/{index-g0d51qzc.js → index-bvpar0bg.js} +2 -5
- package/dist/{index-w1avzkdt.js → index-g026ztby.js} +1 -1
- package/dist/{index-rjnc6kkf.js → index-kagezf2h.js} +3 -3
- package/dist/{index-dnadppqx.js → index-kmk3xpf9.js} +1 -1
- package/dist/{index-zz7dnyh6.js → index-sdsnb5b6.js} +8 -8
- package/dist/index-v0ht940m.js +488 -0
- package/dist/{index-kbswhkc8.js → index-vea2d9ka.js} +1 -1
- package/dist/{index-w5v0ntbw.js → index-wjbqw6r1.js} +1 -1
- package/dist/{index-z6k6jsmh.js → index-xa90f88m.js} +3 -3
- package/dist/{index-wpy2rzb2.js → index-xw070axm.js} +3 -3
- package/dist/index.js +499 -440
- package/dist/{message-fts-rowid-map-xe3ss2g3.js → message-fts-rowid-map-3mbvdgn9.js} +2 -4
- package/dist/{message-index-bounded-2zffszp9.js → message-index-bounded-avbaa7wa.js} +19 -22
- package/dist/migration-worker.js +7 -8
- package/dist/{project-embedding-registry-bn9ts1h0.js → project-embedding-registry-hc4ahjdt.js} +6 -6
- package/dist/raw-ordinal-warmup-worker.js +7 -30
- package/dist/{read-session-chunk-p0cexvvs.js → read-session-chunk-1rfprgc1.js} +4 -4
- package/dist/{read-session-raw-mq03ws9v.js → read-session-raw-g9b1zdn5.js} +1 -1
- package/dist/{search-archive-jw2wm4tw.js → search-archive-mpjeecwj.js} +5 -5
- package/dist/{search-vmcbbwm5.js → search-vkkfg27q.js} +13 -14
- package/dist/{storage-tags-r48vxthe.js → storage-tags-9qaasrky.js} +2 -2
- package/dist/subagent-entry.js +17 -18
- package/dist/tag-snapshot-worker-pi.js +9 -10
- package/package.json +1 -1
- package/dist/index-87xm7z44.js +0 -2100
- package/dist/index-n4wyxcgr.js +0 -712
- package/dist/index-wrr9rp9a.js +0 -16
- 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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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-
|
|
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-
|
|
144
|
+
} from "./index-xa90f88m.js";
|
|
140
145
|
import {
|
|
141
|
-
|
|
142
|
-
} from "./index-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
4790
|
+
const previous = pending3.get(sessionId);
|
|
3587
4791
|
if (previous?.request === request)
|
|
3588
4792
|
return previous;
|
|
3589
4793
|
const next = { request, held: false };
|
|
3590
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
4875
|
+
const saved = pending3.get(sessionId);
|
|
3672
4876
|
if (saved)
|
|
3673
4877
|
retiredRequests.add(saved.request);
|
|
3674
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
6212
|
+
return PREFIX2 + JSON.stringify([kind, messageId]);
|
|
5009
6213
|
}
|
|
5010
6214
|
function decodePiContentDecision(value) {
|
|
5011
|
-
if (!value.startsWith(
|
|
6215
|
+
if (!value.startsWith(PREFIX2))
|
|
5012
6216
|
return null;
|
|
5013
6217
|
try {
|
|
5014
|
-
const pair = JSON.parse(value.slice(
|
|
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
|
|
6086
|
-
import { existsSync as existsSync5, readFileSync as
|
|
6087
|
-
import { dirname as
|
|
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
|
|
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
|
|
7327
|
+
return resolve3(options.userConfigDirectory);
|
|
6124
7328
|
const sharedBase = cortexKitUserConfigBasePath();
|
|
6125
7329
|
const shared = detectConfigFile(sharedBase);
|
|
6126
7330
|
if (shared.format !== "none")
|
|
6127
|
-
return
|
|
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
|
|
7335
|
+
return dirname5(legacy.path);
|
|
6132
7336
|
}
|
|
6133
|
-
return
|
|
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 :
|
|
7354
|
+
const path = isAbsolute3(configuredPath) ? configuredPath : resolve3(userConfigDirectory, configuredPath);
|
|
6151
7355
|
let content;
|
|
6152
7356
|
try {
|
|
6153
|
-
if (!
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
7969
|
-
import { existsSync as existsSync6, statSync as
|
|
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${
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
10428
|
+
import { statSync as statSync7 } from "node:fs";
|
|
9225
10429
|
|
|
9226
10430
|
// ../plugin/src/plugin/embedding-bootstrap-helpers.ts
|
|
9227
|
-
import { createHash as
|
|
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
|
|
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 =
|
|
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
|
|
10029
|
-
import { dirname as
|
|
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 =
|
|
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(
|
|
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 =
|
|
11271
|
+
let directory = dirname6(entryPath);
|
|
10068
11272
|
const root = parse2(directory).root;
|
|
10069
11273
|
while (true) {
|
|
10070
|
-
const packagePath =
|
|
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 =
|
|
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 =
|
|
11298
|
+
let directory = dirname6(entryPath);
|
|
10095
11299
|
const root = parse2(directory).root;
|
|
10096
11300
|
while (true) {
|
|
10097
|
-
const packageRoot =
|
|
10098
|
-
if (existsSync8(
|
|
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 =
|
|
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(
|
|
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(
|
|
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
|
|
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" &&
|
|
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
|
|
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("~/") ?
|
|
11881
|
-
const absolute = isAbsolute4(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 =
|
|
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 =
|
|
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 =
|
|
13104
|
+
const logicalCortexkit = join8(dataDirectory, "cortexkit");
|
|
11901
13105
|
for (const logical of [
|
|
11902
13106
|
logicalCortexkit,
|
|
11903
|
-
...FENCED_CORTEXKIT_ROOTS.map((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(
|
|
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 =
|
|
13145
|
+
const parent = dirname7(candidate);
|
|
11942
13146
|
if (parent === candidate) {
|
|
11943
13147
|
throw fsError(path, error);
|
|
11944
13148
|
}
|
|
11945
|
-
suffix.unshift(
|
|
13149
|
+
suffix.unshift(basename4(candidate));
|
|
11946
13150
|
candidate = parent;
|
|
11947
13151
|
try {
|
|
11948
|
-
return
|
|
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 ??
|
|
11958
|
-
const cortexkitRoot =
|
|
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 =
|
|
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 =
|
|
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 };
|