@cortexkit/pi-magic-context 0.47.0 → 0.49.0
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 +27 -22
- package/dist/embedding-activity-ew6dshfd.js +10 -0
- package/dist/embedding-backfill-b71dvfs8.js +20 -0
- package/dist/embedding-cache-7rp4gqzr.js +16 -0
- package/dist/embedding-worker.js +11 -8
- package/dist/harness-9872e0ym.js +10 -0
- package/dist/historian-calibration-extension.js +30 -4
- package/dist/index-041ex0cj.js +519 -0
- package/dist/index-0h2mkab2.js +17 -0
- package/dist/{index-2p1e8706.js → index-0vrkp1jq.js} +3 -3
- package/dist/index-135e8hvg.js +43 -0
- package/dist/{index-vgcemg0n.js → index-1evzceyw.js} +151 -2452
- package/dist/index-21v1kfs7.js +2309 -0
- package/dist/{index-n3g5mwa8.js → index-290tzwp1.js} +3 -3
- package/dist/{index-0qejsd7f.js → index-3cgbv47m.js} +289 -45
- package/dist/{index-xpbh1ypk.js → index-3mgf68pn.js} +38 -741
- package/dist/index-3rea6zd9.js +2396 -0
- package/dist/index-674f6qs2.js +16 -0
- package/dist/index-8976mezv.js +209 -0
- package/dist/index-904reqtg.js +152 -0
- package/dist/index-9p40dgkm.js +22 -0
- package/dist/index-9x1f96r8.js +11 -0
- package/dist/index-bejpsj10.js +1060 -0
- package/dist/{index-spk5vrhy.js → index-bgmv2kaf.js} +1 -16
- package/dist/{index-k3ezsjng.js → index-ehybv5nr.js} +14657 -13951
- package/dist/index-fapenpch.js +13 -0
- package/dist/index-hwqb3s7f.js +3804 -0
- package/dist/index-kjd1fj55.js +3106 -0
- package/dist/{index-td885aah.js → index-mcgehvgw.js} +181 -230
- package/dist/index-r024r8da.js +171 -0
- package/dist/{index-266qrgss.js → index-r56xgha8.js} +301 -27
- package/dist/{index-kztsbkqq.js → index-t7xfqtg6.js} +171 -168
- package/dist/index-vakawmbc.js +1262 -0
- package/dist/{index-7n8gb6j3.js → index-x3dcnxh0.js} +34 -33
- package/dist/index-xjqheg7a.js +931 -0
- package/dist/index-yarjn32j.js +3026 -0
- package/dist/index-yhzhdp3m.js +143 -0
- package/dist/index-yzcjxnt2.js +787 -0
- package/dist/{index-w76x3af7.js → index-zh1jw8qp.js} +107 -4
- package/dist/index.js +4926 -2437
- package/dist/logger-j6tecd1h.js +19 -0
- package/dist/message-index-bounded-qz5dz2se.js +120 -0
- package/dist/{message-time-backfill-d3db2etr.js → message-time-backfill-05ppypkz.js} +7 -6
- package/dist/migration-worker.js +20 -14
- package/dist/project-embedding-registry-ky7wrkr1.js +85 -0
- package/dist/raw-ordinal-warmup-worker.js +60 -0
- package/dist/{read-session-chunk-atxsyfqv.js → read-session-chunk-24sd89tf.js} +14 -6
- package/dist/read-session-raw-npx3920c.js +57 -0
- package/dist/{safe-notification-target-6cn3z99t.js → safe-notification-target-vn9kpmv4.js} +3 -2
- package/dist/search-jbh28nwy.js +40 -0
- package/dist/sqlite-3yye76ht.js +44 -0
- package/dist/sqlite-context-pragmas-gcgch6qz.js +6 -0
- package/dist/storage-memory-1z20y55x.js +71 -0
- package/dist/storage-tags-kjnsqbdb.js +127 -0
- package/dist/subagent-entry.js +35 -17
- package/dist/transformers-node-wasm.js +18415 -18415
- package/package.json +3 -3
- package/dist/index-7s8vw2y0.js +0 -5207
- package/dist/index-qaa5j277.js +0 -8544
- /package/dist/{index-en1k8h8m.js → index-5prbx026.js} +0 -0
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getMagicContextStorageDir,
|
|
3
|
+
log2
|
|
4
|
+
} from "./index-x3dcnxh0.js";
|
|
5
|
+
import {
|
|
6
|
+
writeStorageFileAtomicSync
|
|
7
|
+
} from "./index-vf38qhee.js";
|
|
8
|
+
|
|
9
|
+
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
12
|
+
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
13
|
+
import { homedir } from "node:os";
|
|
14
|
+
import path3 from "node:path";
|
|
15
|
+
|
|
16
|
+
// ../plugin/src/features/magic-context/memory/project-identity-cache.ts
|
|
17
|
+
import { createHash } from "node:crypto";
|
|
18
|
+
import { readFileSync } from "node:fs";
|
|
19
|
+
import path2 from "node:path";
|
|
20
|
+
|
|
21
|
+
// ../plugin/src/shared/project-directory-key.ts
|
|
22
|
+
import path from "node:path";
|
|
23
|
+
function projectDirectoryKey(directory) {
|
|
24
|
+
const slashed = directory.replaceAll("\\", "/").replace(/^\/\/\?\/UNC\//i, "//").replace(/^\/\/\?\//, "");
|
|
25
|
+
if (/^[a-z]:\//i.test(slashed) || slashed.startsWith("//")) {
|
|
26
|
+
return path.win32.normalize(slashed).replaceAll("\\", "/").replace(/\/$/, "").toLowerCase();
|
|
27
|
+
}
|
|
28
|
+
return path.resolve(directory);
|
|
29
|
+
}
|
|
30
|
+
function sameProjectDirectory(a, b) {
|
|
31
|
+
if (a.length === 0 || b.length === 0)
|
|
32
|
+
return false;
|
|
33
|
+
return projectDirectoryKey(a) === projectDirectoryKey(b);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ../plugin/src/features/magic-context/memory/project-identity-cache.ts
|
|
37
|
+
function cachePath(directory, storageDir = getMagicContextStorageDir()) {
|
|
38
|
+
const hash = createHash("sha256").update(projectDirectoryKey(directory)).digest("hex");
|
|
39
|
+
return path2.join(storageDir, "project-identities", `${hash}.json`);
|
|
40
|
+
}
|
|
41
|
+
function rememberGitIdentity(directory, identity) {
|
|
42
|
+
try {
|
|
43
|
+
const destination = cachePath(directory);
|
|
44
|
+
writeStorageFileAtomicSync(destination, JSON.stringify({ directory: projectDirectoryKey(directory), identity }));
|
|
45
|
+
} catch {}
|
|
46
|
+
}
|
|
47
|
+
function readRememberedGitIdentity(directory, storageDir) {
|
|
48
|
+
try {
|
|
49
|
+
const record = JSON.parse(readFileSync(cachePath(directory, storageDir), "utf8"));
|
|
50
|
+
if (record.directory === projectDirectoryKey(directory) && /^git:[0-9a-f]{7,64}$/.test(record.identity))
|
|
51
|
+
return record.identity;
|
|
52
|
+
} catch {}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
57
|
+
var GIT_TIMEOUT_MS = 5000;
|
|
58
|
+
var TRANSIENT_FAILURE_COOLDOWN_MS = 5 * 60 * 1000;
|
|
59
|
+
var identityCache = new Map;
|
|
60
|
+
var linkedGitWorktreeCache = new Map;
|
|
61
|
+
var lastKnownGitIdentityCache = new Map;
|
|
62
|
+
var directoryFallbackCache = new Map;
|
|
63
|
+
var transientFailureCooldown = new Map;
|
|
64
|
+
var dubiousOwnershipFallbackDirectories = new Set;
|
|
65
|
+
var dubiousOwnershipLoggedDirectories = new Set;
|
|
66
|
+
var dubiousOwnershipWarnedDirectories = new Set;
|
|
67
|
+
var transientGitIdentityReuseLoggedDirectories = new Set;
|
|
68
|
+
var sessionIdentityCache = new Map;
|
|
69
|
+
var homeProjectPermission = false;
|
|
70
|
+
var pausedIdentityReasons = new Map;
|
|
71
|
+
var pausedIdentityLogged = new Set;
|
|
72
|
+
function setHomeProjectPermission(allowed) {
|
|
73
|
+
homeProjectPermission = allowed;
|
|
74
|
+
}
|
|
75
|
+
var execFileSyncForIdentity = execFileSync;
|
|
76
|
+
var userHomeDirectoryForIdentity = () => homedir();
|
|
77
|
+
var nowMs = () => Date.now();
|
|
78
|
+
var filesystemProbeObserverForTests;
|
|
79
|
+
|
|
80
|
+
class ProjectIdentityError extends Error {
|
|
81
|
+
errorClass;
|
|
82
|
+
rawDirectory;
|
|
83
|
+
constructor(errorClass, rawDirectory, message, cause) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.name = "ProjectIdentityError";
|
|
86
|
+
this.errorClass = errorClass;
|
|
87
|
+
this.rawDirectory = rawDirectory;
|
|
88
|
+
if (cause) {
|
|
89
|
+
this.cause = cause;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function asError(error) {
|
|
94
|
+
return error instanceof Error ? error : undefined;
|
|
95
|
+
}
|
|
96
|
+
function getErrorCode(error) {
|
|
97
|
+
if (error === null || typeof error !== "object" || !("code" in error)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const code = error.code;
|
|
101
|
+
return typeof code === "string" ? code : undefined;
|
|
102
|
+
}
|
|
103
|
+
function getErrorSignal(error) {
|
|
104
|
+
if (error === null || typeof error !== "object" || !("signal" in error)) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const signal = error.signal;
|
|
108
|
+
return typeof signal === "string" ? signal : undefined;
|
|
109
|
+
}
|
|
110
|
+
function getErrorKilled(error) {
|
|
111
|
+
if (error === null || typeof error !== "object" || !("killed" in error)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return error.killed === true;
|
|
115
|
+
}
|
|
116
|
+
function getErrorStderr(error) {
|
|
117
|
+
if (error === null || typeof error !== "object" || !("stderr" in error)) {
|
|
118
|
+
return "";
|
|
119
|
+
}
|
|
120
|
+
const stderr = error.stderr;
|
|
121
|
+
if (typeof stderr === "string") {
|
|
122
|
+
return stderr;
|
|
123
|
+
}
|
|
124
|
+
if (Buffer.isBuffer(stderr)) {
|
|
125
|
+
return stderr.toString("utf8");
|
|
126
|
+
}
|
|
127
|
+
return "";
|
|
128
|
+
}
|
|
129
|
+
function directoryFallback(directory) {
|
|
130
|
+
const canonical = path3.resolve(directory);
|
|
131
|
+
const hash = createHash2("md5").update(canonical, "utf8").digest("hex").slice(0, 12);
|
|
132
|
+
return `dir:${hash}`;
|
|
133
|
+
}
|
|
134
|
+
function rememberedIdentityOrDirectoryFallback(canonical) {
|
|
135
|
+
return readRememberedGitIdentity(canonical) ?? directoryFallback(canonical);
|
|
136
|
+
}
|
|
137
|
+
function assertDirectoryUsable(canonicalDirectory, rawDirectory) {
|
|
138
|
+
try {
|
|
139
|
+
const stat = statSync(canonicalDirectory);
|
|
140
|
+
if (!stat.isDirectory()) {
|
|
141
|
+
throw new ProjectIdentityError("unknown", rawDirectory, `Project path is not a directory: ${canonicalDirectory}`);
|
|
142
|
+
}
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (error instanceof ProjectIdentityError) {
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
const code = getErrorCode(error);
|
|
148
|
+
if (code === "EACCES" || code === "EPERM") {
|
|
149
|
+
throw new ProjectIdentityError("permission_denied", rawDirectory, `Permission denied while accessing project directory: ${canonicalDirectory}`, asError(error));
|
|
150
|
+
}
|
|
151
|
+
throw new ProjectIdentityError("unknown", rawDirectory, `Unable to access project directory: ${canonicalDirectory}`, asError(error));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function isGitTimeoutError(error) {
|
|
155
|
+
const code = getErrorCode(error);
|
|
156
|
+
const signal = getErrorSignal(error);
|
|
157
|
+
return code === "ETIMEDOUT" || signal === "SIGTERM" || signal === "SIGKILL" || getErrorKilled(error);
|
|
158
|
+
}
|
|
159
|
+
function hasUnbornHead(directory) {
|
|
160
|
+
const options = {
|
|
161
|
+
cwd: directory,
|
|
162
|
+
encoding: "utf8",
|
|
163
|
+
env: { ...process.env, LC_ALL: "C", LANG: "C" },
|
|
164
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
165
|
+
timeout: GIT_TIMEOUT_MS,
|
|
166
|
+
windowsHide: true
|
|
167
|
+
};
|
|
168
|
+
try {
|
|
169
|
+
execFileSyncForIdentity("git", ["rev-parse", "--git-dir"], options);
|
|
170
|
+
try {
|
|
171
|
+
execFileSyncForIdentity("git", ["rev-parse", "--verify", "--quiet", "HEAD"], options);
|
|
172
|
+
return false;
|
|
173
|
+
} catch (error) {
|
|
174
|
+
return !isGitTimeoutError(error) && typeof error === "object" && error !== null && "status" in error && error.status === 1 && getErrorStderr(error) === "";
|
|
175
|
+
}
|
|
176
|
+
} catch {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function classifyGitError(error, rawDirectory) {
|
|
181
|
+
if (isGitTimeoutError(error)) {
|
|
182
|
+
return new ProjectIdentityError("git_timeout", rawDirectory, `git rev-list timed out after ${GIT_TIMEOUT_MS}ms`, asError(error));
|
|
183
|
+
}
|
|
184
|
+
const code = getErrorCode(error);
|
|
185
|
+
if (code === "ENOENT") {
|
|
186
|
+
return new ProjectIdentityError("git_missing", rawDirectory, "git binary is not available in PATH", asError(error));
|
|
187
|
+
}
|
|
188
|
+
if (code === "EACCES" || code === "EPERM") {
|
|
189
|
+
return new ProjectIdentityError("permission_denied", rawDirectory, "Permission denied while spawning git", asError(error));
|
|
190
|
+
}
|
|
191
|
+
const stderr = getErrorStderr(error).toLowerCase();
|
|
192
|
+
if (stderr.includes("detected dubious ownership")) {
|
|
193
|
+
return new ProjectIdentityError("dubious_ownership", rawDirectory, "git refused to read the repository because it detected dubious ownership", asError(error));
|
|
194
|
+
}
|
|
195
|
+
if (stderr.includes("not a git repository") || stderr.includes("does not have any commits yet") || stderr.includes("ambiguous argument 'head'") || stderr.includes("unknown revision or path")) {
|
|
196
|
+
return new ProjectIdentityError("not_git_repo", rawDirectory, "Directory has no git root commit; caller may use directory fallback", asError(error));
|
|
197
|
+
}
|
|
198
|
+
return new ProjectIdentityError("unknown", rawDirectory, "git rev-list failed while resolving project identity", asError(error));
|
|
199
|
+
}
|
|
200
|
+
function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectPermission) {
|
|
201
|
+
assertProjectAllowed(directory, allowHomeProject);
|
|
202
|
+
const canonical = path3.resolve(directory);
|
|
203
|
+
const cached = identityCache.get(canonical);
|
|
204
|
+
if (cached !== undefined) {
|
|
205
|
+
return cached;
|
|
206
|
+
}
|
|
207
|
+
assertDirectoryUsable(canonical, directory);
|
|
208
|
+
if (!hasGitDir(canonical)) {
|
|
209
|
+
throw new ProjectIdentityError("not_git_repo", directory, "Directory has no git metadata; caller may use directory fallback");
|
|
210
|
+
}
|
|
211
|
+
let output;
|
|
212
|
+
try {
|
|
213
|
+
output = execFileSyncForIdentity("git", ["rev-list", "--max-parents=0", "HEAD"], {
|
|
214
|
+
cwd: canonical,
|
|
215
|
+
encoding: "utf8",
|
|
216
|
+
env: { ...process.env, LC_ALL: "C", LANG: "C" },
|
|
217
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
218
|
+
timeout: GIT_TIMEOUT_MS,
|
|
219
|
+
windowsHide: true
|
|
220
|
+
});
|
|
221
|
+
} catch (error) {
|
|
222
|
+
const classified = classifyGitError(error, directory);
|
|
223
|
+
if (classified.errorClass === "not_git_repo" && hasUnbornHead(canonical)) {
|
|
224
|
+
throw new ProjectIdentityError("no_commits", directory, "Git repository has no commits yet");
|
|
225
|
+
}
|
|
226
|
+
throw classified;
|
|
227
|
+
}
|
|
228
|
+
const rootCommit = output.split(`
|
|
229
|
+
`).map((line) => line.trim().slice(0, 64)).filter((line) => /^[0-9a-f]{7,64}$/.test(line)).sort()[0];
|
|
230
|
+
if (!rootCommit) {
|
|
231
|
+
throw new ProjectIdentityError("unknown", directory, "git rev-list returned no valid root commit hash");
|
|
232
|
+
}
|
|
233
|
+
const identity = `git:${rootCommit}`;
|
|
234
|
+
identityCache.set(canonical, identity);
|
|
235
|
+
lastKnownGitIdentityCache.set(canonical, identity);
|
|
236
|
+
rememberGitIdentity(canonical, identity);
|
|
237
|
+
const root = gitRootDirectory(canonical);
|
|
238
|
+
if (root && root !== canonical)
|
|
239
|
+
rememberGitIdentity(root, identity);
|
|
240
|
+
transientFailureCooldown.delete(canonical);
|
|
241
|
+
dubiousOwnershipFallbackDirectories.delete(canonical);
|
|
242
|
+
transientGitIdentityReuseLoggedDirectories.delete(canonical);
|
|
243
|
+
return identity;
|
|
244
|
+
}
|
|
245
|
+
function shouldUseDirectoryFallback(error) {
|
|
246
|
+
return error.errorClass !== "home_project_disabled";
|
|
247
|
+
}
|
|
248
|
+
function getActiveCooldown(canonical) {
|
|
249
|
+
const until = transientFailureCooldown.get(canonical);
|
|
250
|
+
if (until === undefined)
|
|
251
|
+
return;
|
|
252
|
+
if (nowMs() < until)
|
|
253
|
+
return until;
|
|
254
|
+
transientFailureCooldown.delete(canonical);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
function lastKnownGitIdentity(canonical) {
|
|
258
|
+
return lastKnownGitIdentityCache.get(canonical) ?? identityCache.get(canonical) ?? readRememberedGitIdentity(canonical);
|
|
259
|
+
}
|
|
260
|
+
function nearestLastKnownGitIdentity(canonical) {
|
|
261
|
+
const visited = new Set;
|
|
262
|
+
const walk = (start) => {
|
|
263
|
+
let current = start;
|
|
264
|
+
while (!visited.has(current)) {
|
|
265
|
+
visited.add(current);
|
|
266
|
+
const cached = lastKnownGitIdentity(current);
|
|
267
|
+
if (cached !== undefined)
|
|
268
|
+
return { identity: cached, source: current };
|
|
269
|
+
if (existsSync(path3.join(current, ".git")))
|
|
270
|
+
break;
|
|
271
|
+
const parent = path3.dirname(current);
|
|
272
|
+
if (parent === current)
|
|
273
|
+
break;
|
|
274
|
+
current = parent;
|
|
275
|
+
}
|
|
276
|
+
return;
|
|
277
|
+
};
|
|
278
|
+
const exactOrAncestor = walk(canonical);
|
|
279
|
+
if (exactOrAncestor)
|
|
280
|
+
return exactOrAncestor;
|
|
281
|
+
try {
|
|
282
|
+
const realCanonical = realpathSync.native(canonical);
|
|
283
|
+
if (realCanonical !== canonical)
|
|
284
|
+
return walk(realCanonical);
|
|
285
|
+
} catch {}
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
function reuseLastKnownGitIdentity(canonical) {
|
|
289
|
+
const cached = nearestLastKnownGitIdentity(canonical);
|
|
290
|
+
if (cached === undefined)
|
|
291
|
+
return;
|
|
292
|
+
if (!transientGitIdentityReuseLoggedDirectories.has(canonical)) {
|
|
293
|
+
transientGitIdentityReuseLoggedDirectories.add(canonical);
|
|
294
|
+
const sourceNote = cached.source === canonical ? "" : ` from ancestor ${cached.source}`;
|
|
295
|
+
log2(`[magic-context] git identity resolution is temporarily unavailable for ${canonical}; reusing the last successful project identity${sourceNote} to avoid splitting project-scoped memory`);
|
|
296
|
+
}
|
|
297
|
+
return cached.identity;
|
|
298
|
+
}
|
|
299
|
+
function formatDubiousOwnershipWarning(canonical) {
|
|
300
|
+
return `Magic Context: git refused to read ${canonical} (dubious ownership — the repo is owned by a different user). Memory features are paused unless a previous git identity is available. Fix: git config --global --add safe.directory ${canonical}`;
|
|
301
|
+
}
|
|
302
|
+
function recordDubiousOwnershipFallback(canonical) {
|
|
303
|
+
dubiousOwnershipFallbackDirectories.add(canonical);
|
|
304
|
+
if (dubiousOwnershipLoggedDirectories.has(canonical))
|
|
305
|
+
return;
|
|
306
|
+
dubiousOwnershipLoggedDirectories.add(canonical);
|
|
307
|
+
log2(`[magic-context] ${formatDubiousOwnershipWarning(canonical)}`);
|
|
308
|
+
}
|
|
309
|
+
function canonicalUserHomeDirectory() {
|
|
310
|
+
const homeDirectory = userHomeDirectoryForIdentity();
|
|
311
|
+
try {
|
|
312
|
+
return realpathSync.native(homeDirectory);
|
|
313
|
+
} catch {
|
|
314
|
+
return homeDirectory;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function isUserHomeDirectory(directory) {
|
|
318
|
+
if (projectDirectoryKey(directory) === projectDirectoryKey(userHomeDirectoryForIdentity()))
|
|
319
|
+
return true;
|
|
320
|
+
try {
|
|
321
|
+
return projectDirectoryKey(realpathSync.native(path3.resolve(directory))) === projectDirectoryKey(canonicalUserHomeDirectory());
|
|
322
|
+
} catch {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function assertProjectAllowed(directory, allowHomeProject) {
|
|
327
|
+
const canonical = path3.resolve(directory);
|
|
328
|
+
if (!allowHomeProject && (isUserHomeDirectory(directory) || isUserHomeDirectory(gitRootDirectory(canonical) ?? canonical))) {
|
|
329
|
+
throw new ProjectIdentityError("home_project_disabled", directory, "Home project memory is disabled; set allow_home_project to opt in");
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function resolveProjectIdentity(directory, allowHomeProject = homeProjectPermission) {
|
|
333
|
+
assertProjectAllowed(directory, allowHomeProject);
|
|
334
|
+
const canonical = path3.resolve(directory);
|
|
335
|
+
const cachedFallback = directoryFallbackCache.get(canonical);
|
|
336
|
+
if (cachedFallback !== undefined) {
|
|
337
|
+
if (!hasGitDir(canonical)) {
|
|
338
|
+
return cachedFallback;
|
|
339
|
+
}
|
|
340
|
+
directoryFallbackCache.delete(canonical);
|
|
341
|
+
}
|
|
342
|
+
if (getActiveCooldown(canonical) !== undefined) {
|
|
343
|
+
if (hasGitDir(canonical)) {
|
|
344
|
+
const cachedGitIdentity = reuseLastKnownGitIdentity(canonical);
|
|
345
|
+
if (cachedGitIdentity !== undefined) {
|
|
346
|
+
return cachedGitIdentity;
|
|
347
|
+
}
|
|
348
|
+
throw new ProjectIdentityError("git_identity_unavailable", directory, "Git identity unavailable; memory features paused until the retry cooldown expires");
|
|
349
|
+
}
|
|
350
|
+
return rememberedIdentityOrDirectoryFallback(canonical);
|
|
351
|
+
}
|
|
352
|
+
try {
|
|
353
|
+
return resolveProjectIdentityStrict(directory, allowHomeProject);
|
|
354
|
+
} catch (error) {
|
|
355
|
+
if (error instanceof ProjectIdentityError && shouldUseDirectoryFallback(error)) {
|
|
356
|
+
if (error.errorClass === "no_commits")
|
|
357
|
+
return directoryFallback(canonical);
|
|
358
|
+
if (!hasGitDir(canonical)) {
|
|
359
|
+
if (error.errorClass === "permission_denied")
|
|
360
|
+
throw error;
|
|
361
|
+
const resolved = rememberedIdentityOrDirectoryFallback(canonical);
|
|
362
|
+
directoryFallbackCache.set(canonical, resolved);
|
|
363
|
+
transientFailureCooldown.delete(canonical);
|
|
364
|
+
return resolved;
|
|
365
|
+
}
|
|
366
|
+
transientFailureCooldown.set(canonical, nowMs() + TRANSIENT_FAILURE_COOLDOWN_MS);
|
|
367
|
+
const cachedGitIdentity = reuseLastKnownGitIdentity(canonical);
|
|
368
|
+
if (error.errorClass === "dubious_ownership")
|
|
369
|
+
recordDubiousOwnershipFallback(canonical);
|
|
370
|
+
if (cachedGitIdentity !== undefined) {
|
|
371
|
+
return cachedGitIdentity;
|
|
372
|
+
}
|
|
373
|
+
throw error;
|
|
374
|
+
}
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
function resolveProjectIdentityOrFallback(directory, allowHomeProject = homeProjectPermission) {
|
|
379
|
+
try {
|
|
380
|
+
return resolveProjectIdentity(directory, allowHomeProject);
|
|
381
|
+
} catch (error) {
|
|
382
|
+
const canonical = path3.resolve(directory);
|
|
383
|
+
if (hasGitDir(canonical) || error instanceof ProjectIdentityError && error.errorClass === "home_project_disabled")
|
|
384
|
+
throw error;
|
|
385
|
+
const fallback = rememberedIdentityOrDirectoryFallback(canonical);
|
|
386
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
387
|
+
log2(`[magic-context] project identity resolution failed for ${canonical}; using directory fallback ${fallback}: ${message}`);
|
|
388
|
+
return fallback;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function hasGitDir(canonical) {
|
|
392
|
+
if (hasGitDirInAncestorChain(canonical)) {
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
const realCanonical = realpathSync.native(canonical);
|
|
397
|
+
return realCanonical !== canonical && hasGitDirInAncestorChain(realCanonical);
|
|
398
|
+
} catch {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function gitRootInAncestorChain(startDirectory) {
|
|
403
|
+
let current = startDirectory;
|
|
404
|
+
while (true) {
|
|
405
|
+
if (existsSync(path3.join(current, ".git"))) {
|
|
406
|
+
try {
|
|
407
|
+
return realpathSync.native(current);
|
|
408
|
+
} catch {
|
|
409
|
+
return path3.resolve(current);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
const parent = path3.dirname(current);
|
|
413
|
+
if (parent === current) {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
current = parent;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function hasGitDirInAncestorChain(startDirectory) {
|
|
420
|
+
return gitRootInAncestorChain(startDirectory) !== null;
|
|
421
|
+
}
|
|
422
|
+
function gitRootDirectory(canonical) {
|
|
423
|
+
const direct = gitRootInAncestorChain(canonical);
|
|
424
|
+
if (direct)
|
|
425
|
+
return direct;
|
|
426
|
+
try {
|
|
427
|
+
const realCanonical = realpathSync.native(canonical);
|
|
428
|
+
return realCanonical === canonical ? null : gitRootInAncestorChain(realCanonical);
|
|
429
|
+
} catch {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
function directoryHasGitMetadata(directory) {
|
|
434
|
+
return gitRootDirectory(path3.resolve(directory)) !== null;
|
|
435
|
+
}
|
|
436
|
+
function isUsableProjectIdentity(identity) {
|
|
437
|
+
return typeof identity === "string" && identity.trim().length > 0;
|
|
438
|
+
}
|
|
439
|
+
function resolveProjectIdentityForSession(directory, allowHomeProject = homeProjectPermission) {
|
|
440
|
+
const resolvedDirectory = path3.resolve(directory);
|
|
441
|
+
const cacheKey = `${allowHomeProject ? "1" : "0"}\x00${resolvedDirectory}`;
|
|
442
|
+
const cached = sessionIdentityCache.get(cacheKey);
|
|
443
|
+
if (cached && (cached.revalidateAt === null || nowMs() < cached.revalidateAt) && !(cached.identity?.startsWith("dir:") && hasGitDir(resolvedDirectory))) {
|
|
444
|
+
return cached.identity;
|
|
445
|
+
}
|
|
446
|
+
sessionIdentityCache.delete(cacheKey);
|
|
447
|
+
filesystemProbeObserverForTests?.();
|
|
448
|
+
const canonicalDirectory = (() => {
|
|
449
|
+
try {
|
|
450
|
+
filesystemProbeObserverForTests?.();
|
|
451
|
+
return realpathSync.native(resolvedDirectory);
|
|
452
|
+
} catch {
|
|
453
|
+
return resolvedDirectory;
|
|
454
|
+
}
|
|
455
|
+
})();
|
|
456
|
+
filesystemProbeObserverForTests?.();
|
|
457
|
+
const homeRoot = gitRootDirectory(canonicalDirectory);
|
|
458
|
+
const inheritsHomeRepository = homeRoot !== null && isUserHomeDirectory(homeRoot);
|
|
459
|
+
let identity;
|
|
460
|
+
if (!allowHomeProject && (isUserHomeDirectory(directory) || inheritsHomeRepository)) {
|
|
461
|
+
identity = undefined;
|
|
462
|
+
} else {
|
|
463
|
+
try {
|
|
464
|
+
identity = resolveProjectIdentityOrFallback(isUserHomeDirectory(directory) ? canonicalUserHomeDirectory() : directory, allowHomeProject);
|
|
465
|
+
} catch (error) {
|
|
466
|
+
if (!(error instanceof ProjectIdentityError))
|
|
467
|
+
throw error;
|
|
468
|
+
const reason = error.errorClass === "git_identity_unavailable" ? pausedIdentityReasons.get(resolvedDirectory) ?? error.errorClass : error.errorClass;
|
|
469
|
+
pausedIdentityReasons.set(resolvedDirectory, reason);
|
|
470
|
+
const logKey = `${resolvedDirectory}\x00${reason}`;
|
|
471
|
+
if (!pausedIdentityLogged.has(logKey)) {
|
|
472
|
+
pausedIdentityLogged.add(logKey);
|
|
473
|
+
log2(`[magic-context] memory features paused for ${resolvedDirectory}: ${reason}`);
|
|
474
|
+
}
|
|
475
|
+
identity = undefined;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (identity !== undefined)
|
|
479
|
+
pausedIdentityReasons.delete(resolvedDirectory);
|
|
480
|
+
sessionIdentityCache.set(cacheKey, {
|
|
481
|
+
identity,
|
|
482
|
+
revalidateAt: identity?.startsWith("git:") === true ? null : nowMs() + TRANSIENT_FAILURE_COOLDOWN_MS
|
|
483
|
+
});
|
|
484
|
+
return identity;
|
|
485
|
+
}
|
|
486
|
+
function normalizeStoredProjectPath(rawOrStored) {
|
|
487
|
+
if (rawOrStored.startsWith("git:") || rawOrStored.startsWith("dir:")) {
|
|
488
|
+
return rawOrStored;
|
|
489
|
+
}
|
|
490
|
+
try {
|
|
491
|
+
return resolveProjectIdentity(rawOrStored);
|
|
492
|
+
} catch {
|
|
493
|
+
return rawOrStored;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
function storedPathBelongsToIdentity(storedProjectPath, projectIdentity) {
|
|
497
|
+
return storedProjectPath === projectIdentity || normalizeStoredProjectPath(storedProjectPath) === projectIdentity;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// ../plugin/src/plugin/boot-quiet.ts
|
|
501
|
+
var BOOT_QUIET_MS = 120000;
|
|
502
|
+
var bootQuietUntilMs = 0;
|
|
503
|
+
function beginBootQuietPeriod(now = Date.now()) {
|
|
504
|
+
if (bootQuietUntilMs === 0)
|
|
505
|
+
bootQuietUntilMs = now + BOOT_QUIET_MS;
|
|
506
|
+
}
|
|
507
|
+
function bootQuietRemainingMs(now = Date.now()) {
|
|
508
|
+
return Math.max(0, bootQuietUntilMs - now);
|
|
509
|
+
}
|
|
510
|
+
function scheduleAfterBootQuiet(task, additionalDelayMs = 0) {
|
|
511
|
+
const timer = setTimeout(task, bootQuietRemainingMs() + Math.max(0, additionalDelayMs));
|
|
512
|
+
timer.unref?.();
|
|
513
|
+
return timer;
|
|
514
|
+
}
|
|
515
|
+
function setBootQuietPeriodForTests(startAtMs) {
|
|
516
|
+
bootQuietUntilMs = startAtMs === null ? 0 : startAtMs + BOOT_QUIET_MS;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export { sameProjectDirectory, setHomeProjectPermission, ProjectIdentityError, resolveProjectIdentityStrict, isUserHomeDirectory, resolveProjectIdentity, directoryHasGitMetadata, isUsableProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, setBootQuietPeriodForTests };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// ../plugin/src/shared/harness.ts
|
|
2
|
+
var currentHarness = "opencode";
|
|
3
|
+
var harnessLocked = false;
|
|
4
|
+
function setHarness2(value) {
|
|
5
|
+
if (harnessLocked && currentHarness !== value) {
|
|
6
|
+
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
7
|
+
}
|
|
8
|
+
currentHarness = value;
|
|
9
|
+
harnessLocked = true;
|
|
10
|
+
}
|
|
11
|
+
function getHarness2() {
|
|
12
|
+
return currentHarness;
|
|
13
|
+
}
|
|
14
|
+
function harnessOwnsOpenCodeStore2(harness = currentHarness) {
|
|
15
|
+
return harness === "opencode" || harness === "opencode2";
|
|
16
|
+
}
|
|
17
|
+
export { setHarness2, getHarness2, harnessOwnsOpenCodeStore2 };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./index-
|
|
2
|
+
log2
|
|
3
|
+
} from "./index-x3dcnxh0.js";
|
|
4
4
|
|
|
5
5
|
// ../plugin/src/shared/write-transaction-timing.ts
|
|
6
6
|
var SLOW_WRITE_TRANSACTION_THRESHOLD_MS = 1000;
|
|
@@ -10,7 +10,7 @@ function logSlowWriteTransaction(site, startedAt, thresholdMs = SLOW_WRITE_TRANS
|
|
|
10
10
|
if (durationMs < thresholdMs)
|
|
11
11
|
return;
|
|
12
12
|
const detail = steps ? Object.entries(steps).map(([name, ms]) => `${name}=${ms.toFixed(1)}ms`).join(" ") : "";
|
|
13
|
-
|
|
13
|
+
log2(`[magic-context] slow write transaction: site=${site} held=${durationMs.toFixed(1)}ms${detail ? ` ${detail}` : ""}`);
|
|
14
14
|
} catch {}
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// ../plugin/src/features/magic-context/memory/constants.ts
|
|
2
|
+
var V2_MEMORY_CATEGORIES = [
|
|
3
|
+
"PROJECT_RULES",
|
|
4
|
+
"ARCHITECTURE",
|
|
5
|
+
"CONSTRAINTS",
|
|
6
|
+
"CONFIG_VALUES",
|
|
7
|
+
"NAMING"
|
|
8
|
+
];
|
|
9
|
+
var PROMOTABLE_CATEGORIES = [
|
|
10
|
+
...V2_MEMORY_CATEGORIES,
|
|
11
|
+
"ARCHITECTURE_DECISIONS",
|
|
12
|
+
"CONFIG_DEFAULTS",
|
|
13
|
+
"USER_PREFERENCES",
|
|
14
|
+
"USER_DIRECTIVES",
|
|
15
|
+
"ENVIRONMENT",
|
|
16
|
+
"WORKFLOW_RULES",
|
|
17
|
+
"KNOWN_ISSUES"
|
|
18
|
+
];
|
|
19
|
+
var CATEGORY_PRIORITY = [
|
|
20
|
+
...V2_MEMORY_CATEGORIES,
|
|
21
|
+
"USER_DIRECTIVES",
|
|
22
|
+
"USER_PREFERENCES",
|
|
23
|
+
"CONFIG_DEFAULTS",
|
|
24
|
+
"ARCHITECTURE_DECISIONS",
|
|
25
|
+
"ENVIRONMENT",
|
|
26
|
+
"WORKFLOW_RULES",
|
|
27
|
+
"KNOWN_ISSUES"
|
|
28
|
+
];
|
|
29
|
+
var MEMORY_CATEGORY_ORDER_UNKNOWN = 99;
|
|
30
|
+
var MEMORY_CATEGORY_ORDER_PRIORITY = CATEGORY_PRIORITY.reduce((acc, category, index) => {
|
|
31
|
+
acc[category] = index;
|
|
32
|
+
return acc;
|
|
33
|
+
}, {});
|
|
34
|
+
var MEMORY_CATEGORY_ORDER_SQL = `CASE category ${CATEGORY_PRIORITY.map((category, index) => `WHEN '${category}' THEN ${index}`).join(" ")} ELSE ${MEMORY_CATEGORY_ORDER_UNKNOWN} END`;
|
|
35
|
+
function getMemoryCategoryOrder(category) {
|
|
36
|
+
return MEMORY_CATEGORY_ORDER_PRIORITY[category] ?? MEMORY_CATEGORY_ORDER_UNKNOWN;
|
|
37
|
+
}
|
|
38
|
+
var CATEGORY_DEFAULT_TTL = {
|
|
39
|
+
WORKFLOW_RULES: 90 * 24 * 60 * 60 * 1000,
|
|
40
|
+
KNOWN_ISSUES: 30 * 24 * 60 * 60 * 1000
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export { V2_MEMORY_CATEGORIES, PROMOTABLE_CATEGORIES, CATEGORY_PRIORITY, MEMORY_CATEGORY_ORDER_SQL, getMemoryCategoryOrder, CATEGORY_DEFAULT_TTL };
|