@cortexkit/magic-context 0.49.10 → 0.49.12
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/index.js +1008 -538
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1726,6 +1726,15 @@ var init_test_temp_dir = __esm(() => {
|
|
|
1726
1726
|
});
|
|
1727
1727
|
|
|
1728
1728
|
// ../plugin/src/shared/data-path.ts
|
|
1729
|
+
import {
|
|
1730
|
+
existsSync as existsSync2,
|
|
1731
|
+
lstatSync,
|
|
1732
|
+
mkdirSync,
|
|
1733
|
+
readFileSync as readFileSync2,
|
|
1734
|
+
readlinkSync,
|
|
1735
|
+
realpathSync,
|
|
1736
|
+
writeFileSync
|
|
1737
|
+
} from "node:fs";
|
|
1729
1738
|
import * as os from "node:os";
|
|
1730
1739
|
import * as path from "node:path";
|
|
1731
1740
|
function getDataDir() {
|
|
@@ -1790,11 +1799,41 @@ function getMagicContextStorageResolution() {
|
|
|
1790
1799
|
function getMagicContextStorageDir() {
|
|
1791
1800
|
return getMagicContextStorageResolution().path;
|
|
1792
1801
|
}
|
|
1802
|
+
function canonicalizeStoragePath(value, seen = new Set) {
|
|
1803
|
+
const absolute = path.resolve(value);
|
|
1804
|
+
if (seen.has(absolute))
|
|
1805
|
+
return absolute;
|
|
1806
|
+
seen.add(absolute);
|
|
1807
|
+
try {
|
|
1808
|
+
return realpathSync.native(absolute);
|
|
1809
|
+
} catch {
|
|
1810
|
+
try {
|
|
1811
|
+
if (lstatSync(absolute).isSymbolicLink()) {
|
|
1812
|
+
const target = readlinkSync(absolute);
|
|
1813
|
+
const resolvedTarget = path.isAbsolute(target) ? target : path.resolve(path.dirname(absolute), target);
|
|
1814
|
+
return canonicalizeStoragePath(resolvedTarget, seen);
|
|
1815
|
+
}
|
|
1816
|
+
} catch {}
|
|
1817
|
+
const parent = path.dirname(absolute);
|
|
1818
|
+
if (parent === absolute)
|
|
1819
|
+
return absolute;
|
|
1820
|
+
const resolvedParent = canonicalizeStoragePath(parent, seen);
|
|
1821
|
+
return path.resolve(resolvedParent, path.basename(absolute));
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
function isMagicContextStorageOutsideEngram(storageDir = getMagicContextStorageDir(), backupDir = path.join(os.homedir(), ".local", "share", "cortexkit", "magic-context")) {
|
|
1825
|
+
const resolvedStorageDir = canonicalizeStoragePath(storageDir);
|
|
1826
|
+
const resolvedBackupDir = canonicalizeStoragePath(backupDir);
|
|
1827
|
+
const relative2 = path.relative(resolvedBackupDir, resolvedStorageDir);
|
|
1828
|
+
return path.isAbsolute(relative2) || relative2 === ".." || relative2.startsWith(`..${path.sep}`);
|
|
1829
|
+
}
|
|
1793
1830
|
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
1794
1831
|
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
1795
1832
|
}
|
|
1833
|
+
var STORAGE_BACKUP_WARNING_CHECKED;
|
|
1796
1834
|
var init_data_path = __esm(() => {
|
|
1797
1835
|
init_test_temp_dir();
|
|
1836
|
+
STORAGE_BACKUP_WARNING_CHECKED = Symbol.for("magic-context.storage-backup-warning-checked");
|
|
1798
1837
|
});
|
|
1799
1838
|
|
|
1800
1839
|
// ../plugin/src/shared/redaction.ts
|
|
@@ -2332,19 +2371,19 @@ import {
|
|
|
2332
2371
|
closeSync as closeSync2,
|
|
2333
2372
|
createWriteStream,
|
|
2334
2373
|
fsyncSync,
|
|
2335
|
-
lstatSync,
|
|
2336
|
-
mkdirSync as
|
|
2374
|
+
lstatSync as lstatSync2,
|
|
2375
|
+
mkdirSync as mkdirSync3,
|
|
2337
2376
|
openSync as openSync2,
|
|
2338
2377
|
readdirSync,
|
|
2339
|
-
readlinkSync,
|
|
2378
|
+
readlinkSync as readlinkSync2,
|
|
2340
2379
|
readSync as readSync2,
|
|
2341
2380
|
renameSync,
|
|
2342
2381
|
rmSync,
|
|
2343
2382
|
symlinkSync,
|
|
2344
|
-
writeFileSync,
|
|
2383
|
+
writeFileSync as writeFileSync2,
|
|
2345
2384
|
writeSync as writeSync2
|
|
2346
2385
|
} from "node:fs";
|
|
2347
|
-
import { dirname as
|
|
2386
|
+
import { dirname as dirname3, join as join2 } from "node:path";
|
|
2348
2387
|
function setStoragePrivatePermissionEnforcement(enforce) {
|
|
2349
2388
|
enforcePrivateStoragePermissions = enforce;
|
|
2350
2389
|
}
|
|
@@ -2353,7 +2392,7 @@ function shouldEnforcePrivateStoragePermissions() {
|
|
|
2353
2392
|
}
|
|
2354
2393
|
function ensureStorageDirectorySync(directory, forcePrivate = false, recursive = true) {
|
|
2355
2394
|
const privateMode = forcePrivate || shouldEnforcePrivateStoragePermissions();
|
|
2356
|
-
|
|
2395
|
+
mkdirSync3(directory, {
|
|
2357
2396
|
recursive,
|
|
2358
2397
|
...privateMode ? { mode: 448 } : {}
|
|
2359
2398
|
});
|
|
@@ -2361,13 +2400,13 @@ function ensureStorageDirectorySync(directory, forcePrivate = false, recursive =
|
|
|
2361
2400
|
function writeStorageFileSync(filePath, content, options = {}) {
|
|
2362
2401
|
const { forcePrivate = false, ...writeOptions } = options;
|
|
2363
2402
|
const privateMode = forcePrivate || shouldEnforcePrivateStoragePermissions();
|
|
2364
|
-
|
|
2403
|
+
writeFileSync2(filePath, content, {
|
|
2365
2404
|
...writeOptions,
|
|
2366
2405
|
...privateMode ? { mode: 384 } : {}
|
|
2367
2406
|
});
|
|
2368
2407
|
}
|
|
2369
2408
|
function writeStorageFileAtomicSync(filePath, content, forcePrivate = false) {
|
|
2370
|
-
ensureStorageDirectorySync(
|
|
2409
|
+
ensureStorageDirectorySync(dirname3(filePath), forcePrivate);
|
|
2371
2410
|
const tempPath = `${filePath}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
2372
2411
|
try {
|
|
2373
2412
|
writeStorageFileSync(tempPath, content, { flag: "wx", forcePrivate });
|
|
@@ -2378,7 +2417,7 @@ function writeStorageFileAtomicSync(filePath, content, forcePrivate = false) {
|
|
|
2378
2417
|
}
|
|
2379
2418
|
}
|
|
2380
2419
|
function copyStorageFileSync(sourcePath, destinationPath, forcePrivate = false) {
|
|
2381
|
-
ensureStorageDirectorySync(
|
|
2420
|
+
ensureStorageDirectorySync(dirname3(destinationPath), forcePrivate);
|
|
2382
2421
|
const privateMode = forcePrivate || shouldEnforcePrivateStoragePermissions();
|
|
2383
2422
|
const sourceFd = openSync2(sourcePath, "r");
|
|
2384
2423
|
let destinationFd;
|
|
@@ -2405,10 +2444,10 @@ function copyStorageFileSync(sourcePath, destinationPath, forcePrivate = false)
|
|
|
2405
2444
|
}
|
|
2406
2445
|
}
|
|
2407
2446
|
function copyStorageTreeSync(sourcePath, destinationPath, forcePrivate = false) {
|
|
2408
|
-
const stat =
|
|
2447
|
+
const stat = lstatSync2(sourcePath);
|
|
2409
2448
|
if (stat.isSymbolicLink()) {
|
|
2410
|
-
ensureStorageDirectorySync(
|
|
2411
|
-
symlinkSync(
|
|
2449
|
+
ensureStorageDirectorySync(dirname3(destinationPath), forcePrivate);
|
|
2450
|
+
symlinkSync(readlinkSync2(sourcePath), destinationPath);
|
|
2412
2451
|
return;
|
|
2413
2452
|
}
|
|
2414
2453
|
if (!stat.isDirectory()) {
|
|
@@ -2421,7 +2460,7 @@ function copyStorageTreeSync(sourcePath, destinationPath, forcePrivate = false)
|
|
|
2421
2460
|
}
|
|
2422
2461
|
}
|
|
2423
2462
|
function openStorageFileSync(filePath, flags, forcePrivate = false) {
|
|
2424
|
-
ensureStorageDirectorySync(
|
|
2463
|
+
ensureStorageDirectorySync(dirname3(filePath), forcePrivate);
|
|
2425
2464
|
const privateMode = forcePrivate || shouldEnforcePrivateStoragePermissions();
|
|
2426
2465
|
return openSync2(filePath, flags, privateMode ? 384 : 438);
|
|
2427
2466
|
}
|
|
@@ -2434,7 +2473,7 @@ function tightenStorageTreeSync(root) {
|
|
|
2434
2473
|
const visit = (entryPath) => {
|
|
2435
2474
|
let stat;
|
|
2436
2475
|
try {
|
|
2437
|
-
stat =
|
|
2476
|
+
stat = lstatSync2(entryPath);
|
|
2438
2477
|
} catch {
|
|
2439
2478
|
failures++;
|
|
2440
2479
|
return;
|
|
@@ -2813,9 +2852,9 @@ var init_jsonc_edit = __esm(() => {
|
|
|
2813
2852
|
});
|
|
2814
2853
|
|
|
2815
2854
|
// ../plugin/src/config/migrate-config-location.ts
|
|
2816
|
-
import { existsSync as
|
|
2855
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, rmSync as rmSync2, statSync as statSync2, unlinkSync } from "node:fs";
|
|
2817
2856
|
import { homedir as homedir3 } from "node:os";
|
|
2818
|
-
import { basename, dirname as
|
|
2857
|
+
import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute2, join as join3 } from "node:path";
|
|
2819
2858
|
function homeDir() {
|
|
2820
2859
|
if (process.platform === "win32") {
|
|
2821
2860
|
return process.env.USERPROFILE || process.env.HOME || homedir3();
|
|
@@ -3039,8 +3078,8 @@ function markLegacySourcesMovedAside(sources, targetPath, logger) {
|
|
|
3039
3078
|
for (const source of sources) {
|
|
3040
3079
|
const markerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
|
|
3041
3080
|
try {
|
|
3042
|
-
const original =
|
|
3043
|
-
atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath,
|
|
3081
|
+
const original = readFileSync3(source.path, "utf-8");
|
|
3082
|
+
atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath, basename2(source.path), original));
|
|
3044
3083
|
unlinkSync(source.path);
|
|
3045
3084
|
info?.(`Moved legacy Magic Context config ${source.path} aside to ${markerPath}; now reading ${targetPath}`);
|
|
3046
3085
|
} catch (err) {
|
|
@@ -3057,12 +3096,12 @@ function visibleConfigMigrationWarning(scope, targetPath, paths, reason) {
|
|
|
3057
3096
|
}
|
|
3058
3097
|
function migrateConfigFile(opts) {
|
|
3059
3098
|
const warnings = [];
|
|
3060
|
-
const existingSources = opts.legacySources.filter((source) =>
|
|
3099
|
+
const existingSources = opts.legacySources.filter((source) => existsSync3(source.path));
|
|
3061
3100
|
const info = opts.logger?.info ?? opts.logger?.log;
|
|
3062
3101
|
if (existingSources.length === 0) {
|
|
3063
3102
|
return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
|
|
3064
3103
|
}
|
|
3065
|
-
ensureStorageDirectorySync(
|
|
3104
|
+
ensureStorageDirectorySync(dirname4(opts.targetPath), true);
|
|
3066
3105
|
const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
|
|
3067
3106
|
if (!release) {
|
|
3068
3107
|
warnings.push(`Config migration for ${opts.scope} skipped this run (another instance is migrating); will retry on next start.`);
|
|
@@ -3071,10 +3110,10 @@ function migrateConfigFile(opts) {
|
|
|
3071
3110
|
try {
|
|
3072
3111
|
const sources = existingSources.map((source) => ({
|
|
3073
3112
|
...source,
|
|
3074
|
-
content:
|
|
3113
|
+
content: readFileSync3(source.path, "utf-8")
|
|
3075
3114
|
}));
|
|
3076
|
-
if (
|
|
3077
|
-
const targetContent =
|
|
3115
|
+
if (existsSync3(opts.targetPath)) {
|
|
3116
|
+
const targetContent = readFileSync3(opts.targetPath, "utf-8");
|
|
3078
3117
|
const differing = sources.filter((source) => !fileSemanticsMatch(source.content, targetContent));
|
|
3079
3118
|
if (differing.length > 0) {
|
|
3080
3119
|
const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, differing.map((source) => source.path), "the CortexKit target already exists with different settings");
|
|
@@ -9158,7 +9197,7 @@ var init_magic_context = __esm(() => {
|
|
|
9158
9197
|
max_tokens: 12000
|
|
9159
9198
|
})),
|
|
9160
9199
|
"evaluate-smart-notes": DreamTaskBaseConfigSchema.default(() => DreamTaskBaseConfigSchema.parse(defaultTaskConfig("evaluate-smart-notes"))),
|
|
9161
|
-
"review-user-memories": ReviewUserMemoriesTaskConfigSchema.default(() => ReviewUserMemoriesTaskConfigSchema.parse(defaultTaskConfig("review-user-memories"))),
|
|
9200
|
+
"review-user-memories": ReviewUserMemoriesTaskConfigSchema.default(() => ReviewUserMemoriesTaskConfigSchema.parse(defaultTaskConfig("review-user-memories"))).describe("Promote recurring user observations into the <user-profile> block. A non-empty schedule also makes the historian collect user observations, but only while the dreamer is runnable (dreamer.disable not true); collection and review follow that one gate and do not depend on memory.enabled."),
|
|
9162
9201
|
"promote-primers": PromotePrimersTaskConfigSchema.default(() => PromotePrimersTaskConfigSchema.parse(defaultTaskConfig("promote-primers"))),
|
|
9163
9202
|
"refresh-primers": DreamTaskBaseConfigSchema.default(() => DreamTaskBaseConfigSchema.parse(defaultTaskConfig("refresh-primers")))
|
|
9164
9203
|
}).describe("Harness-independent task metadata. schedule, promotion_threshold, and other task metadata remain here; execution settings live under dreamer.opencode.tasks, dreamer.pi.tasks, or dreamer.omp.tasks.");
|
|
@@ -9176,13 +9215,13 @@ var init_magic_context = __esm(() => {
|
|
|
9176
9215
|
maxTokens: true
|
|
9177
9216
|
});
|
|
9178
9217
|
DreamerConfigSchema = AgentMetadataSchema.extend({
|
|
9179
|
-
disable: boolean2().optional().describe("Disable
|
|
9218
|
+
disable: boolean2().optional().describe("Disable the dreamer: no scheduled or manual dream task runs. Also turns off smart notes (ctx_note drops surface_condition even with smart_notes.enabled true) and the historian's collection of user observations for review-user-memories. dreamer.inject_docs still applies."),
|
|
9180
9219
|
runner: _enum(["broca", "host"]).optional().describe(`Which side runs the dreamer completions the Rust module routes (classify-memories) in Rust transform mode: "host" runs them on this process's carrier, "broca" routes them to the Broca module. When unset, historian.runner applies, and when that is unset too the harness decides the same way it does for the historian. User-level config only.`),
|
|
9181
9220
|
opencode: DreamerOpenCodeHarnessBlockSchema.optional(),
|
|
9182
9221
|
pi: DreamerPiHarnessBlockSchema.optional(),
|
|
9183
9222
|
omp: DreamerOmpHarnessBlockSchema.optional(),
|
|
9184
9223
|
tasks: DreamTasksSchema.default(() => DreamTasksSchema.parse({})),
|
|
9185
|
-
inject_docs: boolean2().default(true).describe("Inject ARCHITECTURE.md and STRUCTURE.md into the m[0] `<project-docs>` block (default true)")
|
|
9224
|
+
inject_docs: boolean2().default(true).describe("Inject ARCHITECTURE.md and STRUCTURE.md into the m[0] `<project-docs>` block (default true). Not a dreamer setting despite its place under dreamer: it applies on every host, also with dreamer.disable true.")
|
|
9186
9225
|
});
|
|
9187
9226
|
HistorianConfigSchema = AgentMetadataSchema.extend({
|
|
9188
9227
|
expand_tools: record(string2(), union([
|
|
@@ -9313,9 +9352,9 @@ var init_magic_context = __esm(() => {
|
|
|
9313
9352
|
profile: string2().trim().min(1).optional().describe("Select a named user-owned model profile. A valid project name overrides this user default; an empty string, null, or other non-string project value is ignored with a warning so the user selection still applies. Unknown names warn and use the base configuration."),
|
|
9314
9353
|
profiles: ConfigProfilesSchema.optional().describe("User-level named model profiles. A profile may contain only historian/dreamer model, fallback_models, OpenCode variant, and Pi/OMP thinking_level fields; task execution policy (including timeout_minutes) is excluded. Project configs may select a name but cannot define profiles."),
|
|
9315
9354
|
historian: HistorianConfigSchema.describe("Historian metadata plus independent strict OpenCode, Pi, and OMP execution blocks. Retained metadata stays at historian; model, fallback_models, variant, and thinking_level belong only in historian.opencode, historian.pi, or historian.omp."),
|
|
9316
|
-
dreamer: DreamerConfigSchema.optional().describe("Dreamer metadata and scheduling plus independent strict OpenCode, Pi, and OMP execution blocks. schedule and promotion_threshold stay at dreamer.tasks; model, fallback_models, variant, thinking_level, and timeout_minutes belong only in the matching harness block."),
|
|
9355
|
+
dreamer: DreamerConfigSchema.optional().describe("Dreamer metadata and scheduling plus independent strict OpenCode, Pi, and OMP execution blocks. schedule and promotion_threshold stay at dreamer.tasks; model, fallback_models, variant, thinking_level, and timeout_minutes belong only in the matching harness block. Each task follows the setting it serves: memory tasks need memory.enabled, evaluate-smart-notes needs smart_notes.enabled, review-user-memories needs its schedule, maintain-docs only a runnable dreamer."),
|
|
9317
9356
|
smart_notes: object({
|
|
9318
|
-
enabled: boolean2().default(true).describe("Enable smart-note authoring and condition evaluation. User-level only: tool definitions are process-wide. Changes require a host restart and rebuild each session's cached prompt once. Pending notes remain stored and unchecked; already-ready notes still surface."),
|
|
9357
|
+
enabled: boolean2().default(true).describe("Enable smart-note authoring and condition evaluation. Needs a runnable dreamer, which evaluates the conditions: with dreamer.disable true (or no dreamer block) ctx_note offers no surface_condition whatever this says. User-level only: tool definitions are process-wide. Changes require a host restart and rebuild each session's cached prompt once. Pending notes remain stored and unchecked; already-ready notes still surface."),
|
|
9319
9358
|
retina_handoff: boolean2().default(false).describe("When true, dreamer skips smart notes whose surface conditions compiled to retina provider configs at authoring time. Default false keeps both paths active until the retina consumer is deployed.")
|
|
9320
9359
|
}).default({ enabled: true, retina_handoff: false }).describe("Smart-note ownership transition controls."),
|
|
9321
9360
|
cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard, then default). User and project settings, including an explicit "5m" or object default, apply on the next pass. Only built-in defaults are frozen per session, including across restarts: when unset, GPT-5.6 and later (including gpt-6*, through any provider prefix) use 30m, other models use 5m. /ctx-status shows the effective TTL and whether it comes from your config or a frozen built-in default. Editing the TTL does not itself rewrite prompt bytes; a lowered TTL rebuilds only after normal idle expiry. OpenAI documents at least 30 minutes since the latest write or reuse: https://developers.openai.com/api/docs/guides/prompt-caching (Cache lifetime and Summary of model differences). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).`),
|
|
@@ -9343,11 +9382,11 @@ var init_magic_context = __esm(() => {
|
|
|
9343
9382
|
object({ default: number2().int().min(0).max(1e6).optional() }).catchall(number2().int().min(0).max(1e6))
|
|
9344
9383
|
]).optional().describe("Reasoning tokens to keep on rebuilding passes. Number or per-model object; exact, shorter model keys, provider/*, then default. Omitted: fixed 10,000. 0 removes all eligible historical reasoning; newest and exempt steps always stay."),
|
|
9345
9384
|
history_budget_percentage: number2().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
|
|
9346
|
-
historian_timeout_ms: number2().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in both TypeScript and Rust transform modes, in milliseconds (default: 600000)"),
|
|
9385
|
+
historian_timeout_ms: number2().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in both TypeScript and Rust transform modes, in milliseconds (default: 600000). A historian setting kept at the top level for compatibility; no effect while historian.disable is true or compaction.enabled is false."),
|
|
9347
9386
|
commit_cluster_trigger: object({
|
|
9348
9387
|
enabled: boolean2().default(true).describe("Enable commit-cluster based historian triggering (default: true)"),
|
|
9349
9388
|
min_clusters: number2().min(1).default(3).describe("Minimum commit clusters required to trigger historian (min: 1, default: 3)")
|
|
9350
|
-
}).default({ enabled: true, min_clusters: 3 }).describe("Commit-cluster trigger: fire historian when enough commit clusters accumulate in the unsummarized tail"),
|
|
9389
|
+
}).default({ enabled: true, min_clusters: 3 }).describe("Commit-cluster trigger: fire historian when enough commit clusters accumulate in the unsummarized tail. A historian setting kept at the top level for compatibility; no effect while historian.disable is true or compaction.enabled is false."),
|
|
9351
9390
|
system_prompt_injection: object({
|
|
9352
9391
|
enabled: boolean2().default(true).describe("When false, NO injection happens for ANY agent — global escape hatch. (default: true)"),
|
|
9353
9392
|
skip_signatures: array(string2()).default(["<!-- magic-context: skip -->"]).describe(`Substring opt-out list. If the agent's system prompt contains any of these strings, skip ALL Magic Context injection for that call. Default "<!-- magic-context: skip -->" is meant to be added inside a user's custom agent prompt to opt that agent out.`)
|
|
@@ -9392,20 +9431,20 @@ var init_magic_context = __esm(() => {
|
|
|
9392
9431
|
min_chars: number2().min(100).max(1e4).default(500).describe("Text parts shorter than this (characters) stay untouched. Min 100, max 10000. Default: 500.")
|
|
9393
9432
|
}).default({ enabled: false, min_chars: 500 }).describe("Age-tier caveman compression for long user/assistant text parts. Active for primary sessions when enabled; never for subagents. Oldest 20% of eligible tags (outside protected tail) go to ultra, next 20% to full, next 20% to lite, newest 40% untouched. Graduated from experimental.caveman_text_compression; opt-in, default off (lossy)."),
|
|
9394
9433
|
memory: object({
|
|
9395
|
-
enabled: boolean2().default(true).describe("Enable cross-session memory (default: true). Does not affect history embedding or semantic ctx_search over session history; set embedding.provider to 'off' to stop all embedding."),
|
|
9434
|
+
enabled: boolean2().default(true).describe("Enable cross-session project memory (default: true). Also gates the dreamer's project-memory tasks: while false, map-memories, verify, verify-broad, curate, compress-cues, classify-memories, retrospective, promote-primers and refresh-primers neither run on schedule nor through /ctx-dream; maintain-docs, evaluate-smart-notes and review-user-memories still run. memory.auto_search and memory.git_commit_indexing do not depend on it. Does not affect history embedding or semantic ctx_search over session history; set embedding.provider to 'off' to stop all embedding."),
|
|
9396
9435
|
injection_budget_tokens: number2().min(500).max(20000).default(4000).describe("Token budget for memory injection on session start (min: 500, max: 20000, default: 4000)"),
|
|
9397
|
-
auto_promote: boolean2().default(true).describe("Automatically promote eligible session facts into memory (default: true)"),
|
|
9398
|
-
retrieval_count_promotion_threshold: number2().min(1).default(3).describe("
|
|
9436
|
+
auto_promote: boolean2().default(true).describe("Automatically promote eligible session facts into memory (default: true). No effect while memory.enabled is false."),
|
|
9437
|
+
retrieval_count_promotion_threshold: number2().min(1).default(3).describe("Currently has no effect: no code reads this value, and memories are not promoted to permanent by retrieval count. Kept so existing configs stay valid (min: 1, default: 3)."),
|
|
9399
9438
|
auto_search: object({
|
|
9400
|
-
enabled: boolean2().default(true).describe("Automatically append a compact <ctx-search-hint> to eligible user messages when relevant memories, conversation, or commits are found. Graduated from experimental.auto_search; on by default (set false to opt out). Independent of memory.enabled."),
|
|
9439
|
+
enabled: boolean2().default(true).describe("Automatically append a compact <ctx-search-hint> to eligible user messages when relevant memories, conversation, or commits are found. Graduated from experimental.auto_search; on by default (set false to opt out). Independent of memory.enabled despite its place under memory: with memory off it still searches past conversation and commits, only the memory source is skipped."),
|
|
9401
9440
|
score_threshold: number2().min(0.3).max(0.95).default(0.6).describe("Top hit score must exceed this threshold for the hint to fire (min: 0.3, max: 0.95, default: 0.60)"),
|
|
9402
9441
|
min_prompt_chars: number2().min(5).max(500).default(20).describe("Skip hint when user message is shorter than this (min: 5, max: 500, default: 20)")
|
|
9403
|
-
}).default({ enabled: true, score_threshold: 0.6, min_prompt_chars: 20 }).describe("Auto-search hint: transform-time ctx_search on each new user message; when the top hit clears the threshold, append a compact <ctx-search-hint> block of vague fragments to that user message. Does NOT inject full content. Graduated from experimental.auto_search; enabled by default (set enabled: false to opt out). Independent of memory.enabled."),
|
|
9442
|
+
}).default({ enabled: true, score_threshold: 0.6, min_prompt_chars: 20 }).describe("Auto-search hint: transform-time ctx_search on each new user message; when the top hit clears the threshold, append a compact <ctx-search-hint> block of vague fragments to that user message. Does NOT inject full content. Graduated from experimental.auto_search; enabled by default (set enabled: false to opt out). Independent of memory.enabled despite its place under memory: with memory off it still searches past conversation and commits."),
|
|
9404
9443
|
git_commit_indexing: object({
|
|
9405
|
-
enabled: boolean2().default(false).describe("Index HEAD git commits for ctx_search (git_commit source). Graduated from experimental.git_commit_indexing; opt-in, default off. Independent of memory.enabled."),
|
|
9444
|
+
enabled: boolean2().default(false).describe("Index HEAD git commits for ctx_search (git_commit source). Graduated from experimental.git_commit_indexing; opt-in, default off. Independent of memory.enabled despite its place under memory."),
|
|
9406
9445
|
since_days: number2().min(7).max(3650).default(365).describe("Days of HEAD history to index (min: 7, max: 3650, default: 365)"),
|
|
9407
9446
|
max_commits: number2().min(100).max(20000).default(2000).describe("Max commits kept per project; oldest evicted (min: 100, max: 20000, default: 2000)")
|
|
9408
|
-
}).default({ enabled: false, since_days: 365, max_commits: 2000 }).describe("Index git commit messages from HEAD into ctx_search. Commits become a 4th searchable source alongside memories and session history. Graduated from experimental.git_commit_indexing; opt-in, default off (per-project embedding cost). Independent of memory.enabled.")
|
|
9447
|
+
}).default({ enabled: false, since_days: 365, max_commits: 2000 }).describe("Index git commit messages from HEAD into ctx_search. Commits become a 4th searchable source alongside memories and session history. Graduated from experimental.git_commit_indexing; opt-in, default off (per-project embedding cost). Independent of memory.enabled despite its place under memory.")
|
|
9409
9448
|
}).default({
|
|
9410
9449
|
enabled: true,
|
|
9411
9450
|
injection_budget_tokens: 4000,
|
|
@@ -9413,7 +9452,7 @@ var init_magic_context = __esm(() => {
|
|
|
9413
9452
|
retrieval_count_promotion_threshold: 3,
|
|
9414
9453
|
auto_search: { enabled: true, score_threshold: 0.6, min_prompt_chars: 20 },
|
|
9415
9454
|
git_commit_indexing: { enabled: false, since_days: 365, max_commits: 2000 }
|
|
9416
|
-
}).describe("Cross-session memory configuration")
|
|
9455
|
+
}).describe("Cross-session memory configuration. auto_search and git_commit_indexing sit here for history but work with memory.enabled false.")
|
|
9417
9456
|
}).transform((data) => {
|
|
9418
9457
|
return {
|
|
9419
9458
|
...data,
|
|
@@ -10190,17 +10229,17 @@ function pruneNestedConfigLeaf(block, relativePath) {
|
|
|
10190
10229
|
// ../plugin/src/config/raw-loader.ts
|
|
10191
10230
|
import {
|
|
10192
10231
|
closeSync as closeSync3,
|
|
10193
|
-
existsSync as
|
|
10232
|
+
existsSync as existsSync4,
|
|
10194
10233
|
linkSync,
|
|
10195
10234
|
openSync as openSync3,
|
|
10196
|
-
readFileSync as
|
|
10197
|
-
realpathSync,
|
|
10235
|
+
readFileSync as readFileSync4,
|
|
10236
|
+
realpathSync as realpathSync2,
|
|
10198
10237
|
renameSync as renameSync2,
|
|
10199
10238
|
statSync as statSync3,
|
|
10200
10239
|
unlinkSync as unlinkSync2,
|
|
10201
|
-
writeFileSync as
|
|
10240
|
+
writeFileSync as writeFileSync3
|
|
10202
10241
|
} from "node:fs";
|
|
10203
|
-
import { basename as
|
|
10242
|
+
import { basename as basename3, dirname as dirname5, join as join4 } from "node:path";
|
|
10204
10243
|
function isRecord(value) {
|
|
10205
10244
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10206
10245
|
}
|
|
@@ -10394,7 +10433,7 @@ function writeExclusiveBackup(backupPath, bytes, mode) {
|
|
|
10394
10433
|
if (error.code !== "EEXIST")
|
|
10395
10434
|
throw error;
|
|
10396
10435
|
}
|
|
10397
|
-
const existingBytes =
|
|
10436
|
+
const existingBytes = readFileSync4(backupPath);
|
|
10398
10437
|
if (existingBytes.equals(bytes))
|
|
10399
10438
|
return;
|
|
10400
10439
|
if (bytes.subarray(0, existingBytes.length).equals(existingBytes)) {
|
|
@@ -10408,15 +10447,15 @@ function writeExclusiveBackup(backupPath, bytes, mode) {
|
|
|
10408
10447
|
}
|
|
10409
10448
|
}
|
|
10410
10449
|
function writeTemporaryCandidate(configPath, bytes, mode) {
|
|
10411
|
-
const directory =
|
|
10412
|
-
const stem =
|
|
10450
|
+
const directory = dirname5(configPath);
|
|
10451
|
+
const stem = basename3(configPath);
|
|
10413
10452
|
for (let attempt = 0;attempt < 32; attempt++) {
|
|
10414
10453
|
temporaryFileSequence += 1;
|
|
10415
10454
|
const path = join4(directory, `.${stem}.per-harness-${process.pid}-${temporaryFileSequence}.tmp`);
|
|
10416
10455
|
let descriptor;
|
|
10417
10456
|
try {
|
|
10418
10457
|
descriptor = openSync3(path, "wx", mode);
|
|
10419
|
-
|
|
10458
|
+
writeFileSync3(descriptor, bytes);
|
|
10420
10459
|
closeSync3(descriptor);
|
|
10421
10460
|
return path;
|
|
10422
10461
|
} catch (error) {
|
|
@@ -10438,11 +10477,11 @@ function migrationWarning(diagnostic) {
|
|
|
10438
10477
|
return diagnostic.message;
|
|
10439
10478
|
}
|
|
10440
10479
|
function loadRawConfigFile(options) {
|
|
10441
|
-
if (!
|
|
10480
|
+
if (!existsSync4(options.configPath))
|
|
10442
10481
|
return null;
|
|
10443
10482
|
let observedBytes;
|
|
10444
10483
|
try {
|
|
10445
|
-
observedBytes =
|
|
10484
|
+
observedBytes = readFileSync4(options.configPath);
|
|
10446
10485
|
} catch (error) {
|
|
10447
10486
|
throw new Error(`failed to read config: ${error instanceof Error ? error.message : String(error)}`);
|
|
10448
10487
|
}
|
|
@@ -10482,12 +10521,12 @@ function loadRawConfigFile(options) {
|
|
|
10482
10521
|
}
|
|
10483
10522
|
let temporaryPath;
|
|
10484
10523
|
try {
|
|
10485
|
-
const writePath =
|
|
10524
|
+
const writePath = realpathSync2(options.configPath);
|
|
10486
10525
|
const mode = options.tier === "user" ? 384 : statSync3(writePath).mode & 511;
|
|
10487
10526
|
writeExclusiveBackup(backupPath, observedBytes, mode);
|
|
10488
10527
|
temporaryPath = writeTemporaryCandidate(writePath, migration.bytes, mode);
|
|
10489
10528
|
options.afterTemporaryWrite?.();
|
|
10490
|
-
const currentBytes =
|
|
10529
|
+
const currentBytes = readFileSync4(options.configPath);
|
|
10491
10530
|
if (!hasFlatKeys(currentBytes)) {
|
|
10492
10531
|
unlinkSync2(temporaryPath);
|
|
10493
10532
|
return {
|
|
@@ -10597,9 +10636,9 @@ function resolveTransformMode(args) {
|
|
|
10597
10636
|
var RUST_COMPACTION_OFF_WARNING = "compaction-off mode does not support rust transform mode; using the TypeScript transform.", RUST_REQUIRES_USER_SUBC_WARNING = "rust mode requires user-level subc configuration; running ts.";
|
|
10598
10637
|
|
|
10599
10638
|
// ../plugin/src/config/variable.ts
|
|
10600
|
-
import { existsSync as
|
|
10639
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
|
|
10601
10640
|
import { homedir as homedir5 } from "node:os";
|
|
10602
|
-
import { dirname as
|
|
10641
|
+
import { dirname as dirname6, isAbsolute as isAbsolute3, resolve as resolve2 } from "node:path";
|
|
10603
10642
|
function sensitiveFilePathReason(resolvedPath) {
|
|
10604
10643
|
const home = homedir5();
|
|
10605
10644
|
const sensitiveDirs = [
|
|
@@ -10646,7 +10685,7 @@ function substituteConfigVariables(input) {
|
|
|
10646
10685
|
if (fileMatches.length === 0) {
|
|
10647
10686
|
return { text, warnings };
|
|
10648
10687
|
}
|
|
10649
|
-
const configDir = input.configPath ?
|
|
10688
|
+
const configDir = input.configPath ? dirname6(input.configPath) : process.cwd();
|
|
10650
10689
|
let output = "";
|
|
10651
10690
|
let cursor = 0;
|
|
10652
10691
|
for (const match of fileMatches) {
|
|
@@ -10672,13 +10711,13 @@ function substituteConfigVariables(input) {
|
|
|
10672
10711
|
if (sensitiveReason) {
|
|
10673
10712
|
warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
|
|
10674
10713
|
}
|
|
10675
|
-
if (!
|
|
10714
|
+
if (!existsSync5(filePath)) {
|
|
10676
10715
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
10677
10716
|
continue;
|
|
10678
10717
|
}
|
|
10679
10718
|
let contents;
|
|
10680
10719
|
try {
|
|
10681
|
-
contents =
|
|
10720
|
+
contents = readFileSync5(filePath, "utf-8").trim();
|
|
10682
10721
|
} catch (error) {
|
|
10683
10722
|
const message = error instanceof Error ? error.message : String(error);
|
|
10684
10723
|
warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
|
|
@@ -10697,7 +10736,7 @@ var init_variable = __esm(() => {
|
|
|
10697
10736
|
});
|
|
10698
10737
|
|
|
10699
10738
|
// ../plugin/src/config/index.ts
|
|
10700
|
-
import { existsSync as
|
|
10739
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
10701
10740
|
function getUserConfigBasePath() {
|
|
10702
10741
|
return cortexKitUserConfigBasePath();
|
|
10703
10742
|
}
|
|
@@ -10705,10 +10744,10 @@ function getProjectConfigBasePath(directory) {
|
|
|
10705
10744
|
return cortexKitProjectConfigBasePath(directory);
|
|
10706
10745
|
}
|
|
10707
10746
|
function resolveLegacyReadFallback(sources) {
|
|
10708
|
-
return { source: sources.find((s) =>
|
|
10747
|
+
return { source: sources.find((s) => existsSync6(s.path)) ?? null };
|
|
10709
10748
|
}
|
|
10710
10749
|
function loadConfigFileDetailed(configPath, source) {
|
|
10711
|
-
if (!
|
|
10750
|
+
if (!existsSync6(configPath)) {
|
|
10712
10751
|
return null;
|
|
10713
10752
|
}
|
|
10714
10753
|
let rawText;
|
|
@@ -11062,8 +11101,8 @@ function loadPluginConfigDetailed(directory, applyRuntimeGlobals = true) {
|
|
|
11062
11101
|
const harnessLegacy = resolveLegacyConfigSourcesForHarness(directory, "opencode");
|
|
11063
11102
|
const userLegacyFallback = userDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.user) : { source: null };
|
|
11064
11103
|
const projectLegacyFallback = projectDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.project) : { source: null };
|
|
11065
|
-
const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) =>
|
|
11066
|
-
const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) =>
|
|
11104
|
+
const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) => existsSync6(source.path));
|
|
11105
|
+
const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) => existsSync6(source.path));
|
|
11067
11106
|
const userLoaded = userDetected.format !== "none" ? loadConfigFileDetailed(userDetected.path, "user") : userLegacyFallback.source ? loadConfigFileDetailed(userLegacyFallback.source.path, "user") : null;
|
|
11068
11107
|
const projectLoaded = projectDetected.format !== "none" ? loadConfigFileDetailed(projectDetected.path, "project") : projectLegacyFallback.source ? loadConfigFileDetailed(projectLegacyFallback.source.path, "project") : null;
|
|
11069
11108
|
const allWarnings = [];
|
|
@@ -13724,17 +13763,17 @@ import {
|
|
|
13724
13763
|
accessSync,
|
|
13725
13764
|
chmodSync as chmodSync3,
|
|
13726
13765
|
constants,
|
|
13727
|
-
existsSync as
|
|
13728
|
-
mkdirSync as
|
|
13766
|
+
existsSync as existsSync7,
|
|
13767
|
+
mkdirSync as mkdirSync4,
|
|
13729
13768
|
mkdtempSync,
|
|
13730
|
-
readFileSync as
|
|
13769
|
+
readFileSync as readFileSync6,
|
|
13731
13770
|
renameSync as renameSync3,
|
|
13732
13771
|
rmSync as rmSync3,
|
|
13733
13772
|
statSync as statSync5,
|
|
13734
|
-
writeFileSync as
|
|
13773
|
+
writeFileSync as writeFileSync4
|
|
13735
13774
|
} from "node:fs";
|
|
13736
13775
|
import { homedir as homedir6, tmpdir as tmpdir2 } from "node:os";
|
|
13737
|
-
import { dirname as
|
|
13776
|
+
import { dirname as dirname7, join as join5 } from "node:path";
|
|
13738
13777
|
import { promisify } from "node:util";
|
|
13739
13778
|
import { gunzipSync } from "node:zlib";
|
|
13740
13779
|
function resolveDashboardChoice(argv, interactive) {
|
|
@@ -13883,7 +13922,7 @@ async function download(deps, asset) {
|
|
|
13883
13922
|
}
|
|
13884
13923
|
function readMacAppVersion(appPath) {
|
|
13885
13924
|
try {
|
|
13886
|
-
const plist =
|
|
13925
|
+
const plist = readFileSync6(join5(appPath, "Contents", "Info.plist"), "utf8");
|
|
13887
13926
|
const match = /<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(plist);
|
|
13888
13927
|
return match?.[1]?.trim() ?? null;
|
|
13889
13928
|
} catch {
|
|
@@ -13904,16 +13943,16 @@ async function detectInstalledDashboard(target, deps) {
|
|
|
13904
13943
|
case "macos":
|
|
13905
13944
|
for (const dir of macApplicationDirs(deps)) {
|
|
13906
13945
|
const location = join5(dir, DASHBOARD_MAC_APP_NAME);
|
|
13907
|
-
if (
|
|
13946
|
+
if (existsSync7(location))
|
|
13908
13947
|
return { location, version: readMacAppVersion(location) };
|
|
13909
13948
|
}
|
|
13910
13949
|
return null;
|
|
13911
13950
|
case "linux": {
|
|
13912
13951
|
const location = linuxAppImagePath(deps.homeDir);
|
|
13913
|
-
if (
|
|
13952
|
+
if (existsSync7(location)) {
|
|
13914
13953
|
let version = null;
|
|
13915
13954
|
try {
|
|
13916
|
-
const marker = JSON.parse(
|
|
13955
|
+
const marker = JSON.parse(readFileSync6(linuxVersionMarkerPath(deps.homeDir), "utf8"));
|
|
13917
13956
|
if (typeof marker.version === "string")
|
|
13918
13957
|
version = marker.version;
|
|
13919
13958
|
} catch {
|
|
@@ -13921,7 +13960,7 @@ async function detectInstalledDashboard(target, deps) {
|
|
|
13921
13960
|
}
|
|
13922
13961
|
return { location, version };
|
|
13923
13962
|
}
|
|
13924
|
-
if (
|
|
13963
|
+
if (existsSync7(deps.linuxSystemBinaryPath)) {
|
|
13925
13964
|
return { location: deps.linuxSystemBinaryPath, version: null };
|
|
13926
13965
|
}
|
|
13927
13966
|
return null;
|
|
@@ -14042,7 +14081,7 @@ function findUnsafeTarEntry(tar) {
|
|
|
14042
14081
|
async function installMac(data, deps, installed) {
|
|
14043
14082
|
let destinationDir;
|
|
14044
14083
|
if (installed) {
|
|
14045
|
-
destinationDir =
|
|
14084
|
+
destinationDir = dirname7(installed.location);
|
|
14046
14085
|
} else if (isWritableDir(deps.macSystemApplicationsDir)) {
|
|
14047
14086
|
destinationDir = deps.macSystemApplicationsDir;
|
|
14048
14087
|
} else {
|
|
@@ -14052,21 +14091,21 @@ async function installMac(data, deps, installed) {
|
|
|
14052
14091
|
const unsafe = findUnsafeTarEntry(gunzipSync(data));
|
|
14053
14092
|
if (unsafe)
|
|
14054
14093
|
throw new Error(`the app archive is unsafe to extract: ${unsafe}`);
|
|
14055
|
-
|
|
14094
|
+
mkdirSync4(destinationDir, { recursive: true });
|
|
14056
14095
|
const staging = mkdtempSync(join5(destinationDir, ".magic-context-dashboard-"));
|
|
14057
14096
|
try {
|
|
14058
14097
|
const archive = join5(staging, "dashboard.app.tar.gz");
|
|
14059
|
-
|
|
14098
|
+
writeFileSync4(archive, data);
|
|
14060
14099
|
const extractDir = join5(staging, "extracted");
|
|
14061
|
-
|
|
14100
|
+
mkdirSync4(extractDir);
|
|
14062
14101
|
await deps.extractTarGz(archive, extractDir);
|
|
14063
14102
|
const extracted = join5(extractDir, DASHBOARD_MAC_APP_NAME);
|
|
14064
|
-
if (!
|
|
14103
|
+
if (!existsSync7(extracted)) {
|
|
14065
14104
|
throw new Error(`the archive did not contain ${DASHBOARD_MAC_APP_NAME}`);
|
|
14066
14105
|
}
|
|
14067
14106
|
const finalPath = join5(destinationDir, DASHBOARD_MAC_APP_NAME);
|
|
14068
14107
|
const previous = join5(staging, "previous.app");
|
|
14069
|
-
const hadPrevious =
|
|
14108
|
+
const hadPrevious = existsSync7(finalPath);
|
|
14070
14109
|
if (hadPrevious)
|
|
14071
14110
|
renameSync3(finalPath, previous);
|
|
14072
14111
|
try {
|
|
@@ -14083,18 +14122,18 @@ async function installMac(data, deps, installed) {
|
|
|
14083
14122
|
}
|
|
14084
14123
|
function installLinux(data, version, deps) {
|
|
14085
14124
|
const finalPath = linuxAppImagePath(deps.homeDir);
|
|
14086
|
-
|
|
14125
|
+
mkdirSync4(dirname7(finalPath), { recursive: true });
|
|
14087
14126
|
const partial = `${finalPath}.partial-${process.pid}`;
|
|
14088
14127
|
try {
|
|
14089
|
-
|
|
14128
|
+
writeFileSync4(partial, data, { mode: 493 });
|
|
14090
14129
|
chmodSync3(partial, 493);
|
|
14091
14130
|
renameSync3(partial, finalPath);
|
|
14092
14131
|
} finally {
|
|
14093
14132
|
rmSync3(partial, { force: true });
|
|
14094
14133
|
}
|
|
14095
14134
|
const marker = linuxVersionMarkerPath(deps.homeDir);
|
|
14096
|
-
|
|
14097
|
-
|
|
14135
|
+
mkdirSync4(dirname7(marker), { recursive: true });
|
|
14136
|
+
writeFileSync4(marker, `${JSON.stringify({ version, path: finalPath }, null, 2)}
|
|
14098
14137
|
`);
|
|
14099
14138
|
return finalPath;
|
|
14100
14139
|
}
|
|
@@ -14102,7 +14141,7 @@ async function installWindows(data, asset, deps) {
|
|
|
14102
14141
|
const dir = mkdtempSync(join5(deps.tempRoot, "magic-context-dashboard-"));
|
|
14103
14142
|
try {
|
|
14104
14143
|
const installer = join5(dir, asset.name);
|
|
14105
|
-
|
|
14144
|
+
writeFileSync4(installer, data);
|
|
14106
14145
|
deps.log.info("Running the dashboard installer (per-user install, no administrator rights).");
|
|
14107
14146
|
await deps.runWindowsInstaller(installer);
|
|
14108
14147
|
} finally {
|
|
@@ -14258,7 +14297,7 @@ var init_dashboard_install = __esm(() => {
|
|
|
14258
14297
|
});
|
|
14259
14298
|
|
|
14260
14299
|
// src/lib/docs-proposal-gitignore.ts
|
|
14261
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
14300
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
|
|
14262
14301
|
import { join as join6 } from "node:path";
|
|
14263
14302
|
function coversProposalState(line) {
|
|
14264
14303
|
const rule = line.trim();
|
|
@@ -14268,16 +14307,16 @@ function coversProposalState(line) {
|
|
|
14268
14307
|
return COVERING_PATHS.has(normalized);
|
|
14269
14308
|
}
|
|
14270
14309
|
function ensureDocsProposalGitignore(projectDir) {
|
|
14271
|
-
if (!
|
|
14310
|
+
if (!existsSync8(join6(projectDir, ".git")))
|
|
14272
14311
|
return { status: "not-a-repository" };
|
|
14273
14312
|
const path = join6(projectDir, ".gitignore");
|
|
14274
14313
|
try {
|
|
14275
|
-
const text =
|
|
14314
|
+
const text = existsSync8(path) ? readFileSync7(path, "utf8") : "";
|
|
14276
14315
|
if (text.split(/\r?\n/).some(coversProposalState))
|
|
14277
14316
|
return { status: "covered" };
|
|
14278
14317
|
const nestedPath = join6(projectDir, ".cortexkit", ".gitignore");
|
|
14279
|
-
if (
|
|
14280
|
-
const nested =
|
|
14318
|
+
if (existsSync8(nestedPath)) {
|
|
14319
|
+
const nested = readFileSync7(nestedPath, "utf8").split(/\r?\n/);
|
|
14281
14320
|
if (nested.some((line) => /^\/?magic-context(\/(\*\*?)?)?$/.test(line.trim()))) {
|
|
14282
14321
|
return { status: "covered" };
|
|
14283
14322
|
}
|
|
@@ -14301,7 +14340,7 @@ var init_docs_proposal_gitignore = __esm(() => {
|
|
|
14301
14340
|
});
|
|
14302
14341
|
|
|
14303
14342
|
// src/lib/find-on-path.ts
|
|
14304
|
-
import { accessSync as accessSync2, constants as constants2, existsSync as
|
|
14343
|
+
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync9, statSync as statSync6 } from "node:fs";
|
|
14305
14344
|
import { delimiter, join as join7 } from "node:path";
|
|
14306
14345
|
function findOnPath(binary) {
|
|
14307
14346
|
const PATH = process.env.PATH;
|
|
@@ -14323,7 +14362,7 @@ function findOnPath(binary) {
|
|
|
14323
14362
|
}
|
|
14324
14363
|
function isExecutableFile(path, isWindows = process.platform === "win32") {
|
|
14325
14364
|
try {
|
|
14326
|
-
if (!
|
|
14365
|
+
if (!existsSync9(path))
|
|
14327
14366
|
return false;
|
|
14328
14367
|
const st = statSync6(path);
|
|
14329
14368
|
if (!st.isFile())
|
|
@@ -14340,9 +14379,9 @@ function isExecutableFile(path, isWindows = process.platform === "win32") {
|
|
|
14340
14379
|
var init_find_on_path = () => {};
|
|
14341
14380
|
|
|
14342
14381
|
// src/lib/paths.ts
|
|
14343
|
-
import { existsSync as
|
|
14382
|
+
import { existsSync as existsSync10, readdirSync as readdirSync2, statSync as statSync7 } from "node:fs";
|
|
14344
14383
|
import { homedir as homedir7 } from "node:os";
|
|
14345
|
-
import { delimiter as delimiter2, dirname as
|
|
14384
|
+
import { delimiter as delimiter2, dirname as dirname8, join as join8, resolve as resolve3 } from "node:path";
|
|
14346
14385
|
function getOpenCodeConfigDir() {
|
|
14347
14386
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
14348
14387
|
if (envDir)
|
|
@@ -14361,7 +14400,7 @@ function findOmoConfig(configDir) {
|
|
|
14361
14400
|
join8(configDir, "oh-my-opencode.json")
|
|
14362
14401
|
];
|
|
14363
14402
|
for (const loc of locations) {
|
|
14364
|
-
if (
|
|
14403
|
+
if (existsSync10(loc))
|
|
14365
14404
|
return loc;
|
|
14366
14405
|
}
|
|
14367
14406
|
return null;
|
|
@@ -14374,10 +14413,10 @@ function detectConfigPaths() {
|
|
|
14374
14413
|
let tuiConfigFormat;
|
|
14375
14414
|
const jsoncPath = join8(configDir, "opencode.jsonc");
|
|
14376
14415
|
const jsonPath = join8(configDir, "opencode.json");
|
|
14377
|
-
if (
|
|
14416
|
+
if (existsSync10(jsoncPath)) {
|
|
14378
14417
|
opencodeConfig = jsoncPath;
|
|
14379
14418
|
opencodeConfigFormat = "jsonc";
|
|
14380
|
-
} else if (
|
|
14419
|
+
} else if (existsSync10(jsonPath)) {
|
|
14381
14420
|
opencodeConfig = jsonPath;
|
|
14382
14421
|
opencodeConfigFormat = "json";
|
|
14383
14422
|
} else {
|
|
@@ -14386,10 +14425,10 @@ function detectConfigPaths() {
|
|
|
14386
14425
|
}
|
|
14387
14426
|
const tuiJsoncPath = join8(configDir, "tui.jsonc");
|
|
14388
14427
|
const tuiJsonPath = join8(configDir, "tui.json");
|
|
14389
|
-
if (
|
|
14428
|
+
if (existsSync10(tuiJsoncPath)) {
|
|
14390
14429
|
tuiConfig = tuiJsoncPath;
|
|
14391
14430
|
tuiConfigFormat = "jsonc";
|
|
14392
|
-
} else if (
|
|
14431
|
+
} else if (existsSync10(tuiJsonPath)) {
|
|
14393
14432
|
tuiConfig = tuiJsonPath;
|
|
14394
14433
|
tuiConfigFormat = "json";
|
|
14395
14434
|
} else {
|
|
@@ -14423,7 +14462,7 @@ function getPiSessionsRoot() {
|
|
|
14423
14462
|
return join8(getPiAgentDir(), "sessions");
|
|
14424
14463
|
}
|
|
14425
14464
|
function getPiCacheRoot() {
|
|
14426
|
-
return join8(
|
|
14465
|
+
return join8(dirname8(getPiAgentDir()), "cache");
|
|
14427
14466
|
}
|
|
14428
14467
|
function getPiUserConfigPath() {
|
|
14429
14468
|
return resolveCortexKitUserConfigPath();
|
|
@@ -14448,7 +14487,7 @@ function resolveOmpPaths() {
|
|
|
14448
14487
|
if (xdgDataHome) {
|
|
14449
14488
|
const appRoot = join8(xdgDataHome, "omp");
|
|
14450
14489
|
const candidate = profile ? join8(appRoot, "profiles", profile) : appRoot;
|
|
14451
|
-
if (
|
|
14490
|
+
if (existsSync10(candidate))
|
|
14452
14491
|
dataRoot = candidate;
|
|
14453
14492
|
}
|
|
14454
14493
|
}
|
|
@@ -14483,16 +14522,19 @@ function getOmpPackageDir() {
|
|
|
14483
14522
|
return resolve3(value);
|
|
14484
14523
|
}
|
|
14485
14524
|
function getOmpNonGlobalConfigSources(cwd = process.cwd()) {
|
|
14486
|
-
const sources =
|
|
14525
|
+
const sources = getOmpConfigOverlayPaths(cwd);
|
|
14526
|
+
const projectConfig = resolve3(cwd, ".omp", "config.yml");
|
|
14527
|
+
if (existsSync10(projectConfig))
|
|
14528
|
+
sources.push(projectConfig);
|
|
14529
|
+
return [...new Set(sources)];
|
|
14530
|
+
}
|
|
14531
|
+
function getOmpConfigOverlayPaths(cwd = process.cwd()) {
|
|
14532
|
+
return process.env.PI_CONFIG_FILES?.split(delimiter2).map((entry) => entry.trim()).filter(Boolean).map((entry) => {
|
|
14487
14533
|
if (entry === "~")
|
|
14488
14534
|
return envFirstHomeDir();
|
|
14489
14535
|
const expanded = entry.startsWith("~/") || entry.startsWith("~\\") ? join8(envFirstHomeDir(), entry.slice(2)) : entry;
|
|
14490
14536
|
return resolve3(cwd, expanded);
|
|
14491
14537
|
}) ?? [];
|
|
14492
|
-
const projectConfig = resolve3(cwd, ".omp", "config.yml");
|
|
14493
|
-
if (existsSync9(projectConfig))
|
|
14494
|
-
sources.push(projectConfig);
|
|
14495
|
-
return [...new Set(sources)];
|
|
14496
14538
|
}
|
|
14497
14539
|
function getOmpPluginsDir() {
|
|
14498
14540
|
return resolveOmpPaths().pluginsDir;
|
|
@@ -14660,7 +14702,7 @@ var init_pi_helpers = __esm(() => {
|
|
|
14660
14702
|
|
|
14661
14703
|
// src/lib/omp-helpers.ts
|
|
14662
14704
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
14663
|
-
import { existsSync as
|
|
14705
|
+
import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
|
|
14664
14706
|
import { homedir as homedir9 } from "node:os";
|
|
14665
14707
|
import { extname as extname2, join as join10 } from "node:path";
|
|
14666
14708
|
function detectOmpPackageCli() {
|
|
@@ -14670,11 +14712,11 @@ function detectOmpPackageCli() {
|
|
|
14670
14712
|
if (!findOnPath("bun"))
|
|
14671
14713
|
return null;
|
|
14672
14714
|
try {
|
|
14673
|
-
const manifest = JSON.parse(
|
|
14715
|
+
const manifest = JSON.parse(readFileSync8(join10(packageDir, "package.json"), "utf-8"));
|
|
14674
14716
|
if (manifest.name !== "@oh-my-pi/pi-coding-agent")
|
|
14675
14717
|
return null;
|
|
14676
14718
|
const cli = join10(packageDir, "dist", "cli.js");
|
|
14677
|
-
return
|
|
14719
|
+
return existsSync11(cli) ? cli : null;
|
|
14678
14720
|
} catch {
|
|
14679
14721
|
return null;
|
|
14680
14722
|
}
|
|
@@ -14818,7 +14860,7 @@ var init_omp_helpers = __esm(() => {
|
|
|
14818
14860
|
});
|
|
14819
14861
|
|
|
14820
14862
|
// src/adapters/omp.ts
|
|
14821
|
-
import { existsSync as
|
|
14863
|
+
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
|
|
14822
14864
|
import { join as join11 } from "node:path";
|
|
14823
14865
|
|
|
14824
14866
|
class OmpAdapter {
|
|
@@ -14920,7 +14962,7 @@ class OmpAdapter {
|
|
|
14920
14962
|
}
|
|
14921
14963
|
getPluginCacheInfo() {
|
|
14922
14964
|
const path = join11(getOmpPluginsDir(), "cache");
|
|
14923
|
-
return [{ path, exists:
|
|
14965
|
+
return [{ path, exists: existsSync12(path), sizeBytes: dirSizeBytes(path) }];
|
|
14924
14966
|
}
|
|
14925
14967
|
getLogPath() {
|
|
14926
14968
|
return getMagicContextLogPath2("omp");
|
|
@@ -14933,7 +14975,7 @@ class OmpAdapter {
|
|
|
14933
14975
|
}
|
|
14934
14976
|
readRuntimeEnabled(configPath) {
|
|
14935
14977
|
try {
|
|
14936
|
-
const lock = JSON.parse(
|
|
14978
|
+
const lock = JSON.parse(readFileSync9(configPath, "utf-8"));
|
|
14937
14979
|
const enabled = lock.plugins?.[OMP_PLUGIN_PACKAGE]?.enabled;
|
|
14938
14980
|
return typeof enabled === "boolean" ? enabled : undefined;
|
|
14939
14981
|
} catch {
|
|
@@ -14961,7 +15003,7 @@ var init_omp = __esm(() => {
|
|
|
14961
15003
|
});
|
|
14962
15004
|
|
|
14963
15005
|
// ../plugin/src/shared/opencode-db-path.ts
|
|
14964
|
-
import { existsSync as
|
|
15006
|
+
import { existsSync as existsSync13, readdirSync as readdirSync3, statSync as statSync8 } from "node:fs";
|
|
14965
15007
|
import { homedir as homedir10 } from "node:os";
|
|
14966
15008
|
import { isAbsolute as isAbsolute4, join as join12, resolve as resolve4 } from "node:path";
|
|
14967
15009
|
function openCodeHostGenerationFromVersion(version) {
|
|
@@ -15060,7 +15102,7 @@ function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
|
|
|
15060
15102
|
const dataDir = openCodeDataDir(env, options.dataHome);
|
|
15061
15103
|
const channel = options.channel ?? env.OPENCODE_CHANNEL;
|
|
15062
15104
|
const key = environmentKey(dataDir, hostGeneration, channel, env);
|
|
15063
|
-
if (cachedResolution?.key === key && (!cachedResolution.existed ||
|
|
15105
|
+
if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync13(cachedResolution.resolution.path))) {
|
|
15064
15106
|
if (cachedResolution.existed)
|
|
15065
15107
|
return cachedResolution.resolution;
|
|
15066
15108
|
}
|
|
@@ -15068,7 +15110,7 @@ function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
|
|
|
15068
15110
|
cachedResolution = {
|
|
15069
15111
|
key,
|
|
15070
15112
|
resolution,
|
|
15071
|
-
existed: resolution.path !== ":memory:" &&
|
|
15113
|
+
existed: resolution.path !== ":memory:" && existsSync13(resolution.path)
|
|
15072
15114
|
};
|
|
15073
15115
|
return resolution;
|
|
15074
15116
|
}
|
|
@@ -15108,7 +15150,7 @@ function assertOpenCodeStoreGeneration(db, expected, path, schema = "main") {
|
|
|
15108
15150
|
throw new Error(`OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`);
|
|
15109
15151
|
}
|
|
15110
15152
|
function openCodeDbPathExists(resolution = resolveOpenCodeDbPath()) {
|
|
15111
|
-
return resolution.path !== ":memory:" &&
|
|
15153
|
+
return resolution.path !== ":memory:" && existsSync13(resolution.path);
|
|
15112
15154
|
}
|
|
15113
15155
|
function getOpenCodeDbProbeDescriptions(resolution = resolveOpenCodeDbPath()) {
|
|
15114
15156
|
if (resolution.source === "OPENCODE_DB")
|
|
@@ -23027,7 +23069,7 @@ var init_project_directory_key = () => {};
|
|
|
23027
23069
|
|
|
23028
23070
|
// ../plugin/src/shared/rpc-utils.ts
|
|
23029
23071
|
import { execFile as execFile2, execFileSync as execFileSync2 } from "node:child_process";
|
|
23030
|
-
import { readFileSync as
|
|
23072
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
23031
23073
|
function isOwnRpcServerRecord(record) {
|
|
23032
23074
|
return record.pid === process.pid && record.instance_id !== undefined && ownRpcServerInstanceIds.has(record.instance_id);
|
|
23033
23075
|
}
|
|
@@ -23622,7 +23664,7 @@ var init_rpc_utils = __esm(() => {
|
|
|
23622
23664
|
"cljs/dist",
|
|
23623
23665
|
"dist/bundle/cli"
|
|
23624
23666
|
];
|
|
23625
|
-
rpcIdentityReadFileSync =
|
|
23667
|
+
rpcIdentityReadFileSync = readFileSync10;
|
|
23626
23668
|
rpcIdentityExecFileSync = execFileSync2;
|
|
23627
23669
|
rpcIdentityProcessKill = process.kill;
|
|
23628
23670
|
rpcProcessListExecFileSync = execFileSync2;
|
|
@@ -23663,7 +23705,7 @@ var init_opencode_plugin_registration = __esm(() => {
|
|
|
23663
23705
|
});
|
|
23664
23706
|
|
|
23665
23707
|
// src/lib/opencode-plugin-cache.ts
|
|
23666
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
23708
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync11 } from "node:fs";
|
|
23667
23709
|
import { join as join13 } from "node:path";
|
|
23668
23710
|
function getOpenCodePluginCacheRoots() {
|
|
23669
23711
|
const cacheDir = getOpenCodePluginCacheDir();
|
|
@@ -23766,7 +23808,7 @@ function readOpenCodeV2CachedPluginVersion(slot) {
|
|
|
23766
23808
|
if (!generation)
|
|
23767
23809
|
return;
|
|
23768
23810
|
try {
|
|
23769
|
-
const pkg = JSON.parse(
|
|
23811
|
+
const pkg = JSON.parse(readFileSync11(getOpenCodePluginPackageJsonPath(generation), "utf-8"));
|
|
23770
23812
|
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
23771
23813
|
} catch {
|
|
23772
23814
|
return;
|
|
@@ -23780,7 +23822,7 @@ var init_opencode_plugin_cache = __esm(() => {
|
|
|
23780
23822
|
});
|
|
23781
23823
|
|
|
23782
23824
|
// src/commands/doctor-windows-holders.ts
|
|
23783
|
-
import { existsSync as
|
|
23825
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
23784
23826
|
function assertWindowsStoresClosed(paths, processes) {
|
|
23785
23827
|
if (processes.pi.state !== "known" || processes.pi.processIds.length > 0 || (processes.pi.inconclusivePids?.length ?? 0) > 0 || processes.processSnapshot?.source !== "cim") {
|
|
23786
23828
|
throw new Error(`Windows process probe could not rule out OpenCode, Pi or ck-mc holders${processes.pi.processIds.length || processes.pi.inconclusivePids?.length ? ` (PID ${[...processes.pi.processIds, ...processes.pi.inconclusivePids ?? []].join(", ")})` : ""}`);
|
|
@@ -23796,7 +23838,7 @@ function assertWindowsStoresClosed(paths, processes) {
|
|
|
23796
23838
|
if (blockers.length)
|
|
23797
23839
|
throw new Error(`OpenCode, Pi or ck-mc process is running (${blockers.map(({ pid, imageName, commandLine }) => `${imageName ?? commandLine} PID ${pid}`).join(", ")})`);
|
|
23798
23840
|
for (const path of [...new Set(paths)]) {
|
|
23799
|
-
if (!
|
|
23841
|
+
if (!existsSync14(path))
|
|
23800
23842
|
continue;
|
|
23801
23843
|
let db;
|
|
23802
23844
|
let locked = false;
|
|
@@ -23820,7 +23862,7 @@ var init_doctor_windows_holders = __esm(async () => {
|
|
|
23820
23862
|
|
|
23821
23863
|
// src/commands/doctor-opencode2-cache.ts
|
|
23822
23864
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
23823
|
-
import { existsSync as
|
|
23865
|
+
import { existsSync as existsSync15, rmSync as rmSync4 } from "node:fs";
|
|
23824
23866
|
function runLsof(args, spawn) {
|
|
23825
23867
|
const result = spawn("lsof", args, { encoding: "utf-8", timeout: 15000, windowsHide: true });
|
|
23826
23868
|
if (result.error)
|
|
@@ -23835,7 +23877,7 @@ function probeHostProcessesUsing(targets, spawn = spawnSync3) {
|
|
|
23835
23877
|
if (process.platform === "win32") {
|
|
23836
23878
|
try {
|
|
23837
23879
|
assertWindowsStoresClosed(targets.files.filter((path) => !/-(?:wal|shm)$/.test(path)), inspectWindowsProcessesSync());
|
|
23838
|
-
if (targets.directories.some(
|
|
23880
|
+
if (targets.directories.some(existsSync15))
|
|
23839
23881
|
return {
|
|
23840
23882
|
status: "unknown",
|
|
23841
23883
|
reason: "Windows cannot rule out open files in plugin cache directories"
|
|
@@ -23848,8 +23890,8 @@ function probeHostProcessesUsing(targets, spawn = spawnSync3) {
|
|
|
23848
23890
|
};
|
|
23849
23891
|
}
|
|
23850
23892
|
}
|
|
23851
|
-
const files = targets.files.filter((file) =>
|
|
23852
|
-
const directories = targets.directories.filter((directory) =>
|
|
23893
|
+
const files = targets.files.filter((file) => existsSync15(file));
|
|
23894
|
+
const directories = targets.directories.filter((directory) => existsSync15(directory));
|
|
23853
23895
|
const queries = [];
|
|
23854
23896
|
if (files.length > 0)
|
|
23855
23897
|
queries.push(["-w", "-t", "--", ...files]);
|
|
@@ -23944,9 +23986,9 @@ function checkOpenCodeV2PluginCache(options, deps = {}) {
|
|
|
23944
23986
|
const slot = deps.slot ?? getOpenCodeV2PluginCacheSlot(undefined, distTag ?? "latest");
|
|
23945
23987
|
const tagged = distTag ? { distTag } : {};
|
|
23946
23988
|
if (options.referencedSpecs !== undefined && !options.referencedSpecs.has(distTag ?? "latest")) {
|
|
23947
|
-
return
|
|
23989
|
+
return existsSync15(slot) ? { action: "unused", slot, cached: readOpenCodeV2CachedPluginVersion(slot), ...tagged } : { action: "not_found", slot, unused: true, ...tagged };
|
|
23948
23990
|
}
|
|
23949
|
-
if (!
|
|
23991
|
+
if (!existsSync15(slot))
|
|
23950
23992
|
return { action: "not_found", slot, ...tagged };
|
|
23951
23993
|
const cached = readOpenCodeV2CachedPluginVersion(slot);
|
|
23952
23994
|
const latest = options.latestVersion ?? undefined;
|
|
@@ -24038,22 +24080,22 @@ var init_doctor_opencode2_cache = __esm(async () => {
|
|
|
24038
24080
|
// src/lib/atomic-write.ts
|
|
24039
24081
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
24040
24082
|
import {
|
|
24041
|
-
lstatSync as
|
|
24042
|
-
mkdirSync as
|
|
24043
|
-
readlinkSync as
|
|
24083
|
+
lstatSync as lstatSync3,
|
|
24084
|
+
mkdirSync as mkdirSync5,
|
|
24085
|
+
readlinkSync as readlinkSync3,
|
|
24044
24086
|
renameSync as renameSync4,
|
|
24045
24087
|
rmSync as rmSync5,
|
|
24046
24088
|
statSync as statSync9,
|
|
24047
|
-
writeFileSync as
|
|
24089
|
+
writeFileSync as writeFileSync5
|
|
24048
24090
|
} from "node:fs";
|
|
24049
|
-
import { dirname as
|
|
24091
|
+
import { dirname as dirname9, resolve as resolve5 } from "node:path";
|
|
24050
24092
|
function resolveWriteTarget(targetPath) {
|
|
24051
24093
|
let current = resolve5(targetPath);
|
|
24052
24094
|
for (let hop = 0;hop < MAX_SYMLINK_HOPS; hop++) {
|
|
24053
|
-
const stat =
|
|
24095
|
+
const stat = lstatSync3(current, { throwIfNoEntry: false });
|
|
24054
24096
|
if (!stat?.isSymbolicLink())
|
|
24055
24097
|
return current;
|
|
24056
|
-
current = resolve5(
|
|
24098
|
+
current = resolve5(dirname9(current), readlinkSync3(current));
|
|
24057
24099
|
}
|
|
24058
24100
|
throw new Error(`Too many levels of symbolic links resolving ${targetPath}`);
|
|
24059
24101
|
}
|
|
@@ -24063,12 +24105,12 @@ function writeFileAtomic(targetPath, data, options = {}) {
|
|
|
24063
24105
|
writeStorageFileAtomicSync(finalPath, data, true);
|
|
24064
24106
|
return;
|
|
24065
24107
|
}
|
|
24066
|
-
|
|
24108
|
+
mkdirSync5(dirname9(finalPath), { recursive: true });
|
|
24067
24109
|
const existing = statSync9(finalPath, { throwIfNoEntry: false });
|
|
24068
24110
|
const mode = existing?.isFile() ? existing.mode & 511 : undefined;
|
|
24069
24111
|
const tmpPath = `${finalPath}.${process.pid}.${randomBytes2(6).toString("hex")}.tmp`;
|
|
24070
24112
|
try {
|
|
24071
|
-
|
|
24113
|
+
writeFileSync5(tmpPath, data, {
|
|
24072
24114
|
encoding: "utf-8",
|
|
24073
24115
|
flag: "wx",
|
|
24074
24116
|
...mode !== undefined ? { mode } : {}
|
|
@@ -24085,7 +24127,7 @@ var init_atomic_write = __esm(() => {
|
|
|
24085
24127
|
});
|
|
24086
24128
|
|
|
24087
24129
|
// src/lib/jsonc-config.ts
|
|
24088
|
-
import { existsSync as
|
|
24130
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12 } from "node:fs";
|
|
24089
24131
|
function parseErrorLocation(content, error) {
|
|
24090
24132
|
const lines = content.split(`
|
|
24091
24133
|
`);
|
|
@@ -24101,9 +24143,9 @@ function parseErrorLocation(content, error) {
|
|
|
24101
24143
|
return { line: messageLine ? Number.parseInt(messageLine, 10) : 1, column: 1 };
|
|
24102
24144
|
}
|
|
24103
24145
|
function readJsoncConfig(path) {
|
|
24104
|
-
if (!
|
|
24146
|
+
if (!existsSync16(path))
|
|
24105
24147
|
return { kind: "missing" };
|
|
24106
|
-
const content =
|
|
24148
|
+
const content = readFileSync12(path, "utf-8");
|
|
24107
24149
|
try {
|
|
24108
24150
|
const rejectedKeyPaths = [];
|
|
24109
24151
|
const parsed = sanitizeParsedJson(import_comment_json.parse(content), {
|
|
@@ -24129,7 +24171,7 @@ function readJsoncConfigForUpdate(path) {
|
|
|
24129
24171
|
return result.value;
|
|
24130
24172
|
}
|
|
24131
24173
|
function readJsoncTextForEdit(configPath) {
|
|
24132
|
-
const raw =
|
|
24174
|
+
const raw = readFileSync12(configPath, "utf-8");
|
|
24133
24175
|
return raw.startsWith(BYTE_ORDER_MARK) ? { bom: BYTE_ORDER_MARK, text: raw.slice(BYTE_ORDER_MARK.length) } : { bom: "", text: raw };
|
|
24134
24176
|
}
|
|
24135
24177
|
function assertJsoncConfigsParseable(paths) {
|
|
@@ -24218,13 +24260,13 @@ var init_jsonc_config = __esm(() => {
|
|
|
24218
24260
|
});
|
|
24219
24261
|
|
|
24220
24262
|
// src/lib/opencode-detect.ts
|
|
24221
|
-
import { existsSync as
|
|
24263
|
+
import { existsSync as existsSync17, realpathSync as realpathSync3 } from "node:fs";
|
|
24222
24264
|
import { homedir as homedir11 } from "node:os";
|
|
24223
24265
|
import { join as join14 } from "node:path";
|
|
24224
24266
|
function defaultDeps(overrides = {}) {
|
|
24225
24267
|
const env = overrides.env ?? process.env;
|
|
24226
24268
|
return {
|
|
24227
|
-
exists: overrides.exists ??
|
|
24269
|
+
exists: overrides.exists ?? existsSync17,
|
|
24228
24270
|
isExecutable: overrides.isExecutable ?? isExecutableFile,
|
|
24229
24271
|
home: overrides.home ?? (env.HOME?.trim() || homedir11()),
|
|
24230
24272
|
platform: overrides.platform ?? process.platform,
|
|
@@ -24275,7 +24317,7 @@ function openChamberCliCandidates(d) {
|
|
|
24275
24317
|
}
|
|
24276
24318
|
function canonicalPath(d, path) {
|
|
24277
24319
|
try {
|
|
24278
|
-
return d.realpath ? d.realpath(path) :
|
|
24320
|
+
return d.realpath ? d.realpath(path) : realpathSync3(path);
|
|
24279
24321
|
} catch {
|
|
24280
24322
|
return path;
|
|
24281
24323
|
}
|
|
@@ -24438,8 +24480,8 @@ var OPENCODE_BINARY_ENV = "MAGIC_CONTEXT_OPENCODE_BINARY", OPENCODE_VERSION_PROB
|
|
|
24438
24480
|
var init_opencode_helpers = () => {};
|
|
24439
24481
|
|
|
24440
24482
|
// src/adapters/opencode.ts
|
|
24441
|
-
import { existsSync as
|
|
24442
|
-
import { dirname as
|
|
24483
|
+
import { existsSync as existsSync18, readFileSync as readFileSync13, statSync as statSync10 } from "node:fs";
|
|
24484
|
+
import { dirname as dirname10, isAbsolute as isAbsolute5, parse as parsePath, resolve as resolve6 } from "node:path";
|
|
24443
24485
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
24444
24486
|
|
|
24445
24487
|
class OpenCodeAdapter {
|
|
@@ -24470,7 +24512,7 @@ class OpenCodeAdapter {
|
|
|
24470
24512
|
if (paths.opencodeConfigFormat === "none")
|
|
24471
24513
|
return false;
|
|
24472
24514
|
try {
|
|
24473
|
-
const raw =
|
|
24515
|
+
const raw = readFileSync13(paths.opencodeConfig, "utf-8");
|
|
24474
24516
|
const cfg = import_comment_json2.parse(raw);
|
|
24475
24517
|
return readPluginEntries(cfg).some(({ entry }) => matchesPluginEntry(entry, OPENCODE_PLUGIN_NAME));
|
|
24476
24518
|
} catch {
|
|
@@ -24506,7 +24548,7 @@ class OpenCodeAdapter {
|
|
|
24506
24548
|
configPath: target
|
|
24507
24549
|
};
|
|
24508
24550
|
}
|
|
24509
|
-
const raw =
|
|
24551
|
+
const raw = readFileSync13(target, "utf-8");
|
|
24510
24552
|
const cfg = import_comment_json2.parse(raw);
|
|
24511
24553
|
if (cfg === null || typeof cfg !== "object") {
|
|
24512
24554
|
return {
|
|
@@ -24518,7 +24560,7 @@ class OpenCodeAdapter {
|
|
|
24518
24560
|
}
|
|
24519
24561
|
const entries = readPluginEntries(cfg);
|
|
24520
24562
|
const existing = entries.find(({ entry }) => matchesPluginEntry(entry, OPENCODE_PLUGIN_NAME));
|
|
24521
|
-
const existingDev = entries.find(({ entry }) => isDevPathPluginEntry(entry,
|
|
24563
|
+
const existingDev = entries.find(({ entry }) => isDevPathPluginEntry(entry, dirname10(target)));
|
|
24522
24564
|
if (!existing && !existingDev) {
|
|
24523
24565
|
const list = Array.isArray(cfg[this.writeKey]) ? cfg[this.writeKey] : [];
|
|
24524
24566
|
list.push(OPENCODE_PLUGIN_ENTRY_WITH_VERSION);
|
|
@@ -24581,7 +24623,7 @@ class OpenCodeAdapter {
|
|
|
24581
24623
|
};
|
|
24582
24624
|
}
|
|
24583
24625
|
try {
|
|
24584
|
-
const raw =
|
|
24626
|
+
const raw = readFileSync13(target, "utf-8");
|
|
24585
24627
|
const cfg = import_comment_json2.parse(raw);
|
|
24586
24628
|
if (cfg === null || typeof cfg !== "object") {
|
|
24587
24629
|
return {
|
|
@@ -24632,9 +24674,9 @@ class OpenCodeAdapter {
|
|
|
24632
24674
|
}
|
|
24633
24675
|
getPluginCacheInfo() {
|
|
24634
24676
|
const legacyPath = getOpenCodePluginCacheDir();
|
|
24635
|
-
const legacyExists =
|
|
24677
|
+
const legacyExists = existsSync18(legacyPath);
|
|
24636
24678
|
const slot = getOpenCodeV2PluginCacheSlot();
|
|
24637
|
-
const slotExists =
|
|
24679
|
+
const slotExists = existsSync18(slot);
|
|
24638
24680
|
const caches = [];
|
|
24639
24681
|
if (legacyExists || !slotExists) {
|
|
24640
24682
|
caches.push({
|
|
@@ -24692,7 +24734,7 @@ class OpenCodeAdapter {
|
|
|
24692
24734
|
if (paths.opencodeConfigFormat === "none")
|
|
24693
24735
|
return "latest";
|
|
24694
24736
|
try {
|
|
24695
|
-
const cfg = import_comment_json2.parse(
|
|
24737
|
+
const cfg = import_comment_json2.parse(readFileSync13(paths.opencodeConfig, "utf-8"));
|
|
24696
24738
|
return readConfiguredOpenCodePluginSpec(cfg);
|
|
24697
24739
|
} catch {
|
|
24698
24740
|
return "latest";
|
|
@@ -24704,10 +24746,10 @@ class OpenCodeAdapter {
|
|
|
24704
24746
|
return readOpenCodeV2CachedPluginVersion(slot) ?? null;
|
|
24705
24747
|
}
|
|
24706
24748
|
for (const candidate of getOpenCodePluginPackageJsonPaths()) {
|
|
24707
|
-
if (!
|
|
24749
|
+
if (!existsSync18(candidate))
|
|
24708
24750
|
continue;
|
|
24709
24751
|
try {
|
|
24710
|
-
const raw =
|
|
24752
|
+
const raw = readFileSync13(candidate, "utf-8");
|
|
24711
24753
|
const pkg = JSON.parse(raw);
|
|
24712
24754
|
if (typeof pkg.version === "string")
|
|
24713
24755
|
return pkg.version;
|
|
@@ -24746,15 +24788,15 @@ function isDevPathPluginEntry(entry, configDir) {
|
|
|
24746
24788
|
localPath = resolve6(configDir, candidate);
|
|
24747
24789
|
}
|
|
24748
24790
|
if (statSync10(localPath).isFile())
|
|
24749
|
-
localPath =
|
|
24791
|
+
localPath = dirname10(localPath);
|
|
24750
24792
|
const root = parsePath(localPath).root;
|
|
24751
24793
|
while (localPath !== root) {
|
|
24752
24794
|
const packagePath = resolve6(localPath, "package.json");
|
|
24753
|
-
if (
|
|
24754
|
-
const pkg = JSON.parse(
|
|
24795
|
+
if (existsSync18(packagePath)) {
|
|
24796
|
+
const pkg = JSON.parse(readFileSync13(packagePath, "utf8"));
|
|
24755
24797
|
return pkg.name === OPENCODE_PLUGIN_NAME;
|
|
24756
24798
|
}
|
|
24757
|
-
localPath =
|
|
24799
|
+
localPath = dirname10(localPath);
|
|
24758
24800
|
}
|
|
24759
24801
|
} catch {}
|
|
24760
24802
|
return false;
|
|
@@ -24770,8 +24812,8 @@ function matchesPluginEntry(entry, pkgName) {
|
|
|
24770
24812
|
return head === pkgName;
|
|
24771
24813
|
}
|
|
24772
24814
|
function ensureDir2(filePath) {
|
|
24773
|
-
const dir =
|
|
24774
|
-
if (!
|
|
24815
|
+
const dir = dirname10(filePath);
|
|
24816
|
+
if (!existsSync18(dir)) {
|
|
24775
24817
|
const { mkdirSync } = __require("node:fs");
|
|
24776
24818
|
mkdirSync(dir, { recursive: true });
|
|
24777
24819
|
}
|
|
@@ -24792,7 +24834,7 @@ var init_opencode = __esm(async () => {
|
|
|
24792
24834
|
});
|
|
24793
24835
|
|
|
24794
24836
|
// src/lib/pi-package-entry.ts
|
|
24795
|
-
import { existsSync as
|
|
24837
|
+
import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
|
|
24796
24838
|
import { isAbsolute as isAbsolute6, join as join15 } from "node:path";
|
|
24797
24839
|
function stripNpmPrefix(value) {
|
|
24798
24840
|
return value.startsWith("npm:") ? value.slice("npm:".length) : value;
|
|
@@ -24849,10 +24891,10 @@ function hasPiMagicContextPackage(entries, agentDir = getPiAgentConfigDir()) {
|
|
|
24849
24891
|
}
|
|
24850
24892
|
function isPiMagicContextPackageDir(dir) {
|
|
24851
24893
|
const packageJson = join15(dir, "package.json");
|
|
24852
|
-
if (!
|
|
24894
|
+
if (!existsSync19(packageJson))
|
|
24853
24895
|
return false;
|
|
24854
24896
|
try {
|
|
24855
|
-
const pkg = JSON.parse(
|
|
24897
|
+
const pkg = JSON.parse(readFileSync14(packageJson, "utf-8"));
|
|
24856
24898
|
return typeof pkg.name === "string" && pkg.name === PI_MAGIC_CONTEXT_PACKAGE_NAME;
|
|
24857
24899
|
} catch {
|
|
24858
24900
|
return false;
|
|
@@ -24888,8 +24930,8 @@ var init_pi_package_entry = __esm(() => {
|
|
|
24888
24930
|
});
|
|
24889
24931
|
|
|
24890
24932
|
// src/adapters/pi.ts
|
|
24891
|
-
import { existsSync as
|
|
24892
|
-
import { dirname as
|
|
24933
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
24934
|
+
import { dirname as dirname11 } from "node:path";
|
|
24893
24935
|
|
|
24894
24936
|
class PiAdapter {
|
|
24895
24937
|
kind = "pi";
|
|
@@ -25026,8 +25068,8 @@ function writePiSettings(settings) {
|
|
|
25026
25068
|
`);
|
|
25027
25069
|
}
|
|
25028
25070
|
function ensureDir3(filePath) {
|
|
25029
|
-
const dir =
|
|
25030
|
-
if (!
|
|
25071
|
+
const dir = dirname11(filePath);
|
|
25072
|
+
if (!existsSync20(dir)) {
|
|
25031
25073
|
const { mkdirSync } = __require("node:fs");
|
|
25032
25074
|
mkdirSync(dir, { recursive: true });
|
|
25033
25075
|
}
|
|
@@ -26609,7 +26651,7 @@ function installCompartmentHistoryVersions(db) {
|
|
|
26609
26651
|
|
|
26610
26652
|
// ../plugin/src/features/magic-context/memory/project-identity-cache.ts
|
|
26611
26653
|
import { createHash as createHash4 } from "node:crypto";
|
|
26612
|
-
import { readFileSync as
|
|
26654
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
26613
26655
|
import path4 from "node:path";
|
|
26614
26656
|
function cachePath(directory, storageDir = getMagicContextStorageDir()) {
|
|
26615
26657
|
const hash = createHash4("sha256").update(projectDirectoryKey(directory)).digest("hex");
|
|
@@ -26623,7 +26665,7 @@ function rememberGitIdentity(directory, identity) {
|
|
|
26623
26665
|
}
|
|
26624
26666
|
function readRememberedGitIdentity(directory, storageDir) {
|
|
26625
26667
|
try {
|
|
26626
|
-
const record = JSON.parse(
|
|
26668
|
+
const record = JSON.parse(readFileSync15(cachePath(directory, storageDir), "utf8"));
|
|
26627
26669
|
if (record.directory === projectDirectoryKey(directory) && /^git:[0-9a-f]{7,64}$/.test(record.identity))
|
|
26628
26670
|
return record.identity;
|
|
26629
26671
|
} catch {}
|
|
@@ -26635,12 +26677,171 @@ var init_project_identity_cache = __esm(() => {
|
|
|
26635
26677
|
init_storage_permissions();
|
|
26636
26678
|
});
|
|
26637
26679
|
|
|
26680
|
+
// ../plugin/src/features/magic-context/memory/unborn-head.ts
|
|
26681
|
+
import { readFileSync as readFileSync16, realpathSync as realpathSync4, statSync as statSync11 } from "node:fs";
|
|
26682
|
+
import path5 from "node:path";
|
|
26683
|
+
function errorCode(error) {
|
|
26684
|
+
if (error === null || typeof error !== "object" || !("code" in error))
|
|
26685
|
+
return;
|
|
26686
|
+
const code = error.code;
|
|
26687
|
+
return typeof code === "string" ? code : undefined;
|
|
26688
|
+
}
|
|
26689
|
+
function readText(file) {
|
|
26690
|
+
try {
|
|
26691
|
+
return { ok: true, text: readFileSync16(file, "utf8") };
|
|
26692
|
+
} catch (error) {
|
|
26693
|
+
return { ok: false, missing: errorCode(error) === "ENOENT" };
|
|
26694
|
+
}
|
|
26695
|
+
}
|
|
26696
|
+
function entryKind(entry) {
|
|
26697
|
+
try {
|
|
26698
|
+
const stat = statSync11(entry);
|
|
26699
|
+
if (stat.isFile())
|
|
26700
|
+
return "file";
|
|
26701
|
+
if (stat.isDirectory())
|
|
26702
|
+
return "directory";
|
|
26703
|
+
return "other";
|
|
26704
|
+
} catch (error) {
|
|
26705
|
+
return errorCode(error) === "ENOENT" ? "missing" : "error";
|
|
26706
|
+
}
|
|
26707
|
+
}
|
|
26708
|
+
function stripLineEnding(text) {
|
|
26709
|
+
return text.replace(/\r?\n$/u, "");
|
|
26710
|
+
}
|
|
26711
|
+
function resolveMetadataPath(baseDirectory, value) {
|
|
26712
|
+
return path5.resolve(baseDirectory, value);
|
|
26713
|
+
}
|
|
26714
|
+
function isPlainBranchName(name) {
|
|
26715
|
+
if (name.length === 0 || name.endsWith("/") || name.endsWith("."))
|
|
26716
|
+
return false;
|
|
26717
|
+
if (name.includes("..") || name.includes("//") || name.includes("@{"))
|
|
26718
|
+
return false;
|
|
26719
|
+
for (const character of name) {
|
|
26720
|
+
const code = character.charCodeAt(0);
|
|
26721
|
+
if (code <= 32 || code === 127 || "~^:?*[\\".includes(character))
|
|
26722
|
+
return false;
|
|
26723
|
+
}
|
|
26724
|
+
return name.split("/").every((component) => !component.startsWith(".") && !component.endsWith(".lock"));
|
|
26725
|
+
}
|
|
26726
|
+
function findGitDirectory(start) {
|
|
26727
|
+
let current = start;
|
|
26728
|
+
while (true) {
|
|
26729
|
+
const dotGit = path5.join(current, ".git");
|
|
26730
|
+
const kind = entryKind(dotGit);
|
|
26731
|
+
if (kind === "directory")
|
|
26732
|
+
return dotGit;
|
|
26733
|
+
if (kind === "file") {
|
|
26734
|
+
const read = readText(dotGit);
|
|
26735
|
+
if (!read.ok)
|
|
26736
|
+
return;
|
|
26737
|
+
const match = /^gitdir: (.+)$/u.exec(stripLineEnding(read.text));
|
|
26738
|
+
if (!match?.[1] || match[1].includes(`
|
|
26739
|
+
`))
|
|
26740
|
+
return;
|
|
26741
|
+
return resolveMetadataPath(current, match[1]);
|
|
26742
|
+
}
|
|
26743
|
+
if (kind !== "missing")
|
|
26744
|
+
return;
|
|
26745
|
+
const parent = path5.dirname(current);
|
|
26746
|
+
if (parent === current)
|
|
26747
|
+
return;
|
|
26748
|
+
current = parent;
|
|
26749
|
+
}
|
|
26750
|
+
}
|
|
26751
|
+
function packedRefsList(text, ref) {
|
|
26752
|
+
for (const rawLine of text.split(`
|
|
26753
|
+
`)) {
|
|
26754
|
+
const line = rawLine.replace(/\r$/u, "");
|
|
26755
|
+
if (line === "" || line.startsWith("#") || line.startsWith("^"))
|
|
26756
|
+
continue;
|
|
26757
|
+
const match = /^[0-9a-f]{40,64} (\S+)$/u.exec(line);
|
|
26758
|
+
if (!match)
|
|
26759
|
+
return;
|
|
26760
|
+
if (match[1] === ref)
|
|
26761
|
+
return true;
|
|
26762
|
+
}
|
|
26763
|
+
return false;
|
|
26764
|
+
}
|
|
26765
|
+
function isUnbornHeadInLayout(directory) {
|
|
26766
|
+
const gitDirectory = findGitDirectory(directory);
|
|
26767
|
+
if (gitDirectory === undefined)
|
|
26768
|
+
return false;
|
|
26769
|
+
let commonDirectory = gitDirectory;
|
|
26770
|
+
const commondir = readText(path5.join(gitDirectory, "commondir"));
|
|
26771
|
+
if (commondir.ok) {
|
|
26772
|
+
const value = stripLineEnding(commondir.text);
|
|
26773
|
+
if (value === "" || value.includes(`
|
|
26774
|
+
`))
|
|
26775
|
+
return false;
|
|
26776
|
+
commonDirectory = resolveMetadataPath(gitDirectory, value);
|
|
26777
|
+
} else if (!commondir.missing) {
|
|
26778
|
+
return false;
|
|
26779
|
+
}
|
|
26780
|
+
if (entryKind(path5.join(gitDirectory, "HEAD")) !== "file")
|
|
26781
|
+
return false;
|
|
26782
|
+
if (entryKind(path5.join(commonDirectory, "objects")) !== "directory")
|
|
26783
|
+
return false;
|
|
26784
|
+
if (entryKind(path5.join(commonDirectory, "refs")) !== "directory")
|
|
26785
|
+
return false;
|
|
26786
|
+
if (entryKind(path5.join(commonDirectory, "reftable")) !== "missing")
|
|
26787
|
+
return false;
|
|
26788
|
+
const config = readText(path5.join(commonDirectory, "config"));
|
|
26789
|
+
if (config.ok) {
|
|
26790
|
+
if (/refstorage/iu.test(config.text))
|
|
26791
|
+
return false;
|
|
26792
|
+
} else if (!config.missing) {
|
|
26793
|
+
return false;
|
|
26794
|
+
}
|
|
26795
|
+
const head = readText(path5.join(gitDirectory, "HEAD"));
|
|
26796
|
+
if (!head.ok)
|
|
26797
|
+
return false;
|
|
26798
|
+
const headMatch = /^ref: (refs\/heads\/(.+))$/u.exec(head.text.replace(/\s+$/u, ""));
|
|
26799
|
+
const ref = headMatch?.[1];
|
|
26800
|
+
const branch = headMatch?.[2];
|
|
26801
|
+
if (!ref || branch === undefined || !isPlainBranchName(branch))
|
|
26802
|
+
return false;
|
|
26803
|
+
const refSegments = ref.split("/");
|
|
26804
|
+
for (const base of new Set([commonDirectory, gitDirectory])) {
|
|
26805
|
+
if (entryKind(path5.join(base, ...refSegments)) !== "missing")
|
|
26806
|
+
return false;
|
|
26807
|
+
}
|
|
26808
|
+
const packed = readText(path5.join(commonDirectory, "packed-refs"));
|
|
26809
|
+
if (packed.ok) {
|
|
26810
|
+
if (packedRefsList(packed.text, ref) !== false)
|
|
26811
|
+
return false;
|
|
26812
|
+
} else if (!packed.missing) {
|
|
26813
|
+
return false;
|
|
26814
|
+
}
|
|
26815
|
+
return true;
|
|
26816
|
+
}
|
|
26817
|
+
function isUnbornHeadOnDisk(directory, env = process.env) {
|
|
26818
|
+
if (GIT_LOCATION_ENV_VARS.some((name) => env[name] !== undefined && env[name] !== "")) {
|
|
26819
|
+
return false;
|
|
26820
|
+
}
|
|
26821
|
+
let realDirectory;
|
|
26822
|
+
try {
|
|
26823
|
+
realDirectory = realpathSync4.native(path5.resolve(directory));
|
|
26824
|
+
} catch {
|
|
26825
|
+
return false;
|
|
26826
|
+
}
|
|
26827
|
+
return isUnbornHeadInLayout(realDirectory);
|
|
26828
|
+
}
|
|
26829
|
+
var GIT_LOCATION_ENV_VARS;
|
|
26830
|
+
var init_unborn_head = __esm(() => {
|
|
26831
|
+
GIT_LOCATION_ENV_VARS = [
|
|
26832
|
+
"GIT_DIR",
|
|
26833
|
+
"GIT_COMMON_DIR",
|
|
26834
|
+
"GIT_WORK_TREE",
|
|
26835
|
+
"GIT_CEILING_DIRECTORIES"
|
|
26836
|
+
];
|
|
26837
|
+
});
|
|
26838
|
+
|
|
26638
26839
|
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
26639
26840
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
26640
26841
|
import { createHash as createHash5 } from "node:crypto";
|
|
26641
|
-
import { existsSync as
|
|
26842
|
+
import { existsSync as existsSync21, realpathSync as realpathSync5, statSync as statSync12 } from "node:fs";
|
|
26642
26843
|
import { homedir as homedir12 } from "node:os";
|
|
26643
|
-
import
|
|
26844
|
+
import path6 from "node:path";
|
|
26644
26845
|
function asError(error) {
|
|
26645
26846
|
return error instanceof Error ? error : undefined;
|
|
26646
26847
|
}
|
|
@@ -26678,7 +26879,7 @@ function getErrorStderr(error) {
|
|
|
26678
26879
|
return "";
|
|
26679
26880
|
}
|
|
26680
26881
|
function directoryFallback(directory) {
|
|
26681
|
-
const canonical =
|
|
26882
|
+
const canonical = path6.resolve(directory);
|
|
26682
26883
|
const hash = createHash5("md5").update(canonical, "utf8").digest("hex").slice(0, 12);
|
|
26683
26884
|
return `dir:${hash}`;
|
|
26684
26885
|
}
|
|
@@ -26687,7 +26888,7 @@ function rememberedIdentityOrDirectoryFallback(canonical) {
|
|
|
26687
26888
|
}
|
|
26688
26889
|
function assertDirectoryUsable(canonicalDirectory, rawDirectory) {
|
|
26689
26890
|
try {
|
|
26690
|
-
const stat =
|
|
26891
|
+
const stat = statSync12(canonicalDirectory);
|
|
26691
26892
|
if (!stat.isDirectory()) {
|
|
26692
26893
|
throw new ProjectIdentityError("unknown", rawDirectory, `Project path is not a directory: ${canonicalDirectory}`);
|
|
26693
26894
|
}
|
|
@@ -26713,7 +26914,7 @@ function hasUnbornHead(directory) {
|
|
|
26713
26914
|
encoding: "utf8",
|
|
26714
26915
|
env: { ...process.env, LC_ALL: "C", LANG: "C" },
|
|
26715
26916
|
stdio: ["ignore", "pipe", "pipe"],
|
|
26716
|
-
timeout:
|
|
26917
|
+
timeout: gitTimeoutMs,
|
|
26717
26918
|
windowsHide: true
|
|
26718
26919
|
};
|
|
26719
26920
|
try {
|
|
@@ -26730,7 +26931,7 @@ function hasUnbornHead(directory) {
|
|
|
26730
26931
|
}
|
|
26731
26932
|
function classifyGitError(error, rawDirectory) {
|
|
26732
26933
|
if (isGitTimeoutError(error)) {
|
|
26733
|
-
return new ProjectIdentityError("git_timeout", rawDirectory, `git rev-list timed out after ${
|
|
26934
|
+
return new ProjectIdentityError("git_timeout", rawDirectory, `git rev-list timed out after ${gitTimeoutMs}ms`, asError(error));
|
|
26734
26935
|
}
|
|
26735
26936
|
const code = getErrorCode(error);
|
|
26736
26937
|
if (code === "ENOENT") {
|
|
@@ -26750,7 +26951,7 @@ function classifyGitError(error, rawDirectory) {
|
|
|
26750
26951
|
}
|
|
26751
26952
|
function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectPermission, options = {}) {
|
|
26752
26953
|
assertProjectAllowed(directory, allowHomeProject);
|
|
26753
|
-
const canonical =
|
|
26954
|
+
const canonical = path6.resolve(directory);
|
|
26754
26955
|
const cached = options.cache === false ? undefined : identityCache.get(canonical);
|
|
26755
26956
|
if (cached !== undefined) {
|
|
26756
26957
|
return cached;
|
|
@@ -26759,6 +26960,9 @@ function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectP
|
|
|
26759
26960
|
if (!hasGitDir(canonical)) {
|
|
26760
26961
|
throw new ProjectIdentityError("not_git_repo", directory, "Directory has no git metadata; caller may use directory fallback");
|
|
26761
26962
|
}
|
|
26963
|
+
if (isUnbornHeadOnDisk(canonical)) {
|
|
26964
|
+
throw new ProjectIdentityError("no_commits", directory, "Git repository has no commits yet");
|
|
26965
|
+
}
|
|
26762
26966
|
let output;
|
|
26763
26967
|
try {
|
|
26764
26968
|
output = execFileSyncForIdentity("git", ["rev-list", "--max-parents=0", "HEAD"], {
|
|
@@ -26766,7 +26970,7 @@ function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectP
|
|
|
26766
26970
|
encoding: "utf8",
|
|
26767
26971
|
env: { ...process.env, LC_ALL: "C", LANG: "C" },
|
|
26768
26972
|
stdio: ["ignore", "pipe", "pipe"],
|
|
26769
|
-
timeout:
|
|
26973
|
+
timeout: gitTimeoutMs,
|
|
26770
26974
|
windowsHide: true
|
|
26771
26975
|
});
|
|
26772
26976
|
} catch (error) {
|
|
@@ -26819,9 +27023,9 @@ function nearestLastKnownGitIdentity(canonical) {
|
|
|
26819
27023
|
const cached = lastKnownGitIdentity(current);
|
|
26820
27024
|
if (cached !== undefined)
|
|
26821
27025
|
return { identity: cached, source: current };
|
|
26822
|
-
if (
|
|
27026
|
+
if (existsSync21(path6.join(current, ".git")))
|
|
26823
27027
|
break;
|
|
26824
|
-
const parent =
|
|
27028
|
+
const parent = path6.dirname(current);
|
|
26825
27029
|
if (parent === current)
|
|
26826
27030
|
break;
|
|
26827
27031
|
current = parent;
|
|
@@ -26832,7 +27036,7 @@ function nearestLastKnownGitIdentity(canonical) {
|
|
|
26832
27036
|
if (exactOrAncestor)
|
|
26833
27037
|
return exactOrAncestor;
|
|
26834
27038
|
try {
|
|
26835
|
-
const realCanonical =
|
|
27039
|
+
const realCanonical = realpathSync5.native(canonical);
|
|
26836
27040
|
if (realCanonical !== canonical)
|
|
26837
27041
|
return walk(realCanonical);
|
|
26838
27042
|
} catch {}
|
|
@@ -26862,7 +27066,7 @@ function recordDubiousOwnershipFallback(canonical) {
|
|
|
26862
27066
|
function canonicalUserHomeDirectory() {
|
|
26863
27067
|
const homeDirectory = userHomeDirectoryForIdentity();
|
|
26864
27068
|
try {
|
|
26865
|
-
return
|
|
27069
|
+
return realpathSync5.native(homeDirectory);
|
|
26866
27070
|
} catch {
|
|
26867
27071
|
return homeDirectory;
|
|
26868
27072
|
}
|
|
@@ -26871,20 +27075,20 @@ function isUserHomeDirectory(directory) {
|
|
|
26871
27075
|
if (projectDirectoryKey(directory) === projectDirectoryKey(userHomeDirectoryForIdentity()))
|
|
26872
27076
|
return true;
|
|
26873
27077
|
try {
|
|
26874
|
-
return projectDirectoryKey(
|
|
27078
|
+
return projectDirectoryKey(realpathSync5.native(path6.resolve(directory))) === projectDirectoryKey(canonicalUserHomeDirectory());
|
|
26875
27079
|
} catch {
|
|
26876
27080
|
return false;
|
|
26877
27081
|
}
|
|
26878
27082
|
}
|
|
26879
27083
|
function assertProjectAllowed(directory, allowHomeProject) {
|
|
26880
|
-
const canonical =
|
|
27084
|
+
const canonical = path6.resolve(directory);
|
|
26881
27085
|
if (!allowHomeProject && (isUserHomeDirectory(directory) || isUserHomeDirectory(gitRootDirectory(canonical) ?? canonical))) {
|
|
26882
27086
|
throw new ProjectIdentityError("home_project_disabled", directory, "Home project memory is disabled; set allow_home_project to opt in");
|
|
26883
27087
|
}
|
|
26884
27088
|
}
|
|
26885
27089
|
function resolveProjectIdentity(directory, allowHomeProject = homeProjectPermission) {
|
|
26886
27090
|
assertProjectAllowed(directory, allowHomeProject);
|
|
26887
|
-
const canonical =
|
|
27091
|
+
const canonical = path6.resolve(directory);
|
|
26888
27092
|
const cachedFallback = directoryFallbackCache.get(canonical);
|
|
26889
27093
|
if (cachedFallback !== undefined) {
|
|
26890
27094
|
if (!hasGitDir(canonical)) {
|
|
@@ -26933,7 +27137,7 @@ function hasGitDir(canonical) {
|
|
|
26933
27137
|
return true;
|
|
26934
27138
|
}
|
|
26935
27139
|
try {
|
|
26936
|
-
const realCanonical =
|
|
27140
|
+
const realCanonical = realpathSync5.native(canonical);
|
|
26937
27141
|
return realCanonical !== canonical && hasGitDirInAncestorChain(realCanonical);
|
|
26938
27142
|
} catch {
|
|
26939
27143
|
return false;
|
|
@@ -26942,14 +27146,14 @@ function hasGitDir(canonical) {
|
|
|
26942
27146
|
function gitRootInAncestorChain(startDirectory) {
|
|
26943
27147
|
let current = startDirectory;
|
|
26944
27148
|
while (true) {
|
|
26945
|
-
if (
|
|
27149
|
+
if (existsSync21(path6.join(current, ".git"))) {
|
|
26946
27150
|
try {
|
|
26947
|
-
return
|
|
27151
|
+
return realpathSync5.native(current);
|
|
26948
27152
|
} catch {
|
|
26949
|
-
return
|
|
27153
|
+
return path6.resolve(current);
|
|
26950
27154
|
}
|
|
26951
27155
|
}
|
|
26952
|
-
const parent =
|
|
27156
|
+
const parent = path6.dirname(current);
|
|
26953
27157
|
if (parent === current) {
|
|
26954
27158
|
return null;
|
|
26955
27159
|
}
|
|
@@ -26964,16 +27168,17 @@ function gitRootDirectory(canonical) {
|
|
|
26964
27168
|
if (direct)
|
|
26965
27169
|
return direct;
|
|
26966
27170
|
try {
|
|
26967
|
-
const realCanonical =
|
|
27171
|
+
const realCanonical = realpathSync5.native(canonical);
|
|
26968
27172
|
return realCanonical === canonical ? null : gitRootInAncestorChain(realCanonical);
|
|
26969
27173
|
} catch {
|
|
26970
27174
|
return null;
|
|
26971
27175
|
}
|
|
26972
27176
|
}
|
|
26973
|
-
var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, sessionIdentityCache, homeProjectPermission = false, pausedIdentityReasons, pausedIdentityLogged, execFileSyncForIdentity, userHomeDirectoryForIdentity = () => homedir12(), nowMs = () => Date.now(), ProjectIdentityError;
|
|
27177
|
+
var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, sessionIdentityCache, homeProjectPermission = false, pausedIdentityReasons, pausedIdentityLogged, execFileSyncForIdentity, gitTimeoutMs, userHomeDirectoryForIdentity = () => homedir12(), nowMs = () => Date.now(), ProjectIdentityError;
|
|
26974
27178
|
var init_project_identity = __esm(() => {
|
|
26975
27179
|
init_logger();
|
|
26976
27180
|
init_project_identity_cache();
|
|
27181
|
+
init_unborn_head();
|
|
26977
27182
|
TRANSIENT_FAILURE_COOLDOWN_MS = 5 * 60 * 1000;
|
|
26978
27183
|
identityCache = new Map;
|
|
26979
27184
|
linkedGitWorktreeCache = new Map;
|
|
@@ -26988,6 +27193,7 @@ var init_project_identity = __esm(() => {
|
|
|
26988
27193
|
pausedIdentityReasons = new Map;
|
|
26989
27194
|
pausedIdentityLogged = new Set;
|
|
26990
27195
|
execFileSyncForIdentity = execFileSync4;
|
|
27196
|
+
gitTimeoutMs = GIT_TIMEOUT_MS;
|
|
26991
27197
|
ProjectIdentityError = class ProjectIdentityError extends Error {
|
|
26992
27198
|
errorClass;
|
|
26993
27199
|
rawDirectory;
|
|
@@ -30259,7 +30465,7 @@ var init_tool_definition_tokens = __esm(() => {
|
|
|
30259
30465
|
});
|
|
30260
30466
|
|
|
30261
30467
|
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
30262
|
-
import { existsSync as
|
|
30468
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
30263
30469
|
function resolveOpencodeDbPath() {
|
|
30264
30470
|
return resolveOpenCodeDbPath().path;
|
|
30265
30471
|
}
|
|
@@ -30296,7 +30502,7 @@ function runToolOwnerBackfill(db) {
|
|
|
30296
30502
|
return result;
|
|
30297
30503
|
}
|
|
30298
30504
|
const opencodeDbPath = resolveOpencodeDbPath();
|
|
30299
|
-
if (!
|
|
30505
|
+
if (!existsSync22(opencodeDbPath)) {
|
|
30300
30506
|
log(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
|
|
30301
30507
|
markAllUnbackfilledSessionsSkipped(db);
|
|
30302
30508
|
result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
|
|
@@ -31156,7 +31362,7 @@ function pickNearestPriorOwner(candidates, currentMessageId, times) {
|
|
|
31156
31362
|
}
|
|
31157
31363
|
return best?.id ?? null;
|
|
31158
31364
|
}
|
|
31159
|
-
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, getAssignableTagNumberByMessageIdStatements, hasPiFallbackMessageTagStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, recentTagOwnerStatements, RECLAIM_HINT_EXCLUDED_TOOLS, getActiveToolTagsForAgeReclaimStatements, scopedActiveTokenTotalStatements, updateTagTokenCountStatements, updateTagInputTokenCountStatements, tagOwnerSummaries, TAG_OWNER_COLUMNS = "id, type, message_id, tool_owner_message_id, tag_number, reasoning_token_count", TAG_OWNER_APPENDED_WITH_SHAPE_SQL, inertWhitespaceStatements, inertWhitespaceByNumberStatements, foldStatements, getOwnerScopedToolTagNumbersStatements, getMinMessageTagNumberForRawIdStatements, getActiveTagsBySessionStatements, getNullOwnerToolTagsBySessionStatements, getDroppedTagsBySessionStatements, getMaxDroppedTagNumberStatements, newestToolTagNumberStatements, droppedNumberStatements, tagByIdStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, getToolOwnerByTagIdStatements, deleteToolTagsByOwnerStatements;
|
|
31365
|
+
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, getAssignableTagNumberByMessageIdStatements, hasPiFallbackMessageTagStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, recentTagOwnerStatements, RECLAIM_HINT_EXCLUDED_TOOLS, getActiveToolTagsForAgeReclaimStatements, scopedActiveTokenTotalStatements, updateTagTokenCountStatements, updateTagInputTokenCountStatements, tagOwnerSummaries, TAG_OWNER_COLUMNS = "id, type, message_id, tool_owner_message_id, tag_number, reasoning_token_count", TAG_OWNER_APPENDED_WITH_SHAPE_SQL, droppedTagStatements, inertWhitespaceStatements, inertWhitespaceByNumberStatements, foldStatements, getOwnerScopedToolTagNumbersStatements, getMinMessageTagNumberForRawIdStatements, getActiveTagsBySessionStatements, getNullOwnerToolTagsBySessionStatements, getDroppedTagsBySessionStatements, getMaxDroppedTagNumberStatements, newestToolTagNumberStatements, droppedNumberStatements, tagByIdStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, getToolOwnerByTagIdStatements, deleteToolTagsByOwnerStatements;
|
|
31160
31366
|
var init_storage_tags = __esm(async () => {
|
|
31161
31367
|
init_emergency_drop();
|
|
31162
31368
|
init_tag_owner_id();
|
|
@@ -31197,6 +31403,7 @@ var init_storage_tags = __esm(async () => {
|
|
|
31197
31403
|
UNION ALL
|
|
31198
31404
|
SELECT NULL, NULL, NULL, NULL, NULL, NULL, 1, COUNT(*), MAX(id), (SELECT value FROM schema_migrations_meta WHERE key = ?)
|
|
31199
31405
|
FROM tags WHERE session_id = ?`;
|
|
31406
|
+
droppedTagStatements = new WeakMap;
|
|
31200
31407
|
inertWhitespaceStatements = new WeakMap;
|
|
31201
31408
|
inertWhitespaceByNumberStatements = new WeakMap;
|
|
31202
31409
|
foldStatements = new WeakMap;
|
|
@@ -31538,6 +31745,7 @@ function readRawSessionMessageIdOrdinalsForRangeFromDb(db, sessionId, fromOrdina
|
|
|
31538
31745
|
const to = Math.floor(toOrdinal);
|
|
31539
31746
|
if (to < from)
|
|
31540
31747
|
return new Map;
|
|
31748
|
+
exactOrdinalScansOnThisThread += 1;
|
|
31541
31749
|
const rows = db.prepare(`
|
|
31542
31750
|
SELECT id, data FROM message WHERE session_id = ?
|
|
31543
31751
|
AND CASE WHEN json_valid(data) THEN NOT (
|
|
@@ -32212,7 +32420,7 @@ function readRawSessionBoundaryEndpointsFromDb(db, sessionId, ids, blockIds = []
|
|
|
32212
32420
|
return new Map(wanted.map((id) => [id, endpoints.get(id) ?? null]));
|
|
32213
32421
|
}
|
|
32214
32422
|
}
|
|
32215
|
-
var RAW_MESSAGE_PARTS_BY_ID_SQL = "SELECT message_id, data, time_updated FROM part WHERE +session_id = ? AND likelihood(message_id = ?, 0.000001) ORDER BY time_created ASC, id ASC", RAW_METADATA_KEEP_CHARS = 16384, RAW_METADATA_KEPT_KEYS, RAW_PART_DATA_SQL, rawMessagePageRowsVisited = 0, RAW_SUMMARY_TEXT_MAX_CHARS = 8192, RAW_SUMMARY_ARG_MAX_CHARS = 512, RAW_SUMMARY_TOOL_INPUT_KEYS, RAW_SUMMARY_PART_DATA_SQL, ORDINAL_SUMMARY_FLAG_SQL = `(CASE WHEN json_valid(data) = 1
|
|
32423
|
+
var RAW_MESSAGE_PARTS_BY_ID_SQL = "SELECT message_id, data, time_updated FROM part WHERE +session_id = ? AND likelihood(message_id = ?, 0.000001) ORDER BY time_created ASC, id ASC", RAW_METADATA_KEEP_CHARS = 16384, RAW_METADATA_KEPT_KEYS, RAW_PART_DATA_SQL, rawMessagePageRowsVisited = 0, RAW_SUMMARY_TEXT_MAX_CHARS = 8192, RAW_SUMMARY_ARG_MAX_CHARS = 512, RAW_SUMMARY_TOOL_INPUT_KEYS, RAW_SUMMARY_PART_DATA_SQL, exactOrdinalScansOnThisThread = 0, ORDINAL_SUMMARY_FLAG_SQL = `(CASE WHEN json_valid(data) = 1
|
|
32216
32424
|
THEN COALESCE(json_extract(data, '$.summary'), 0)
|
|
32217
32425
|
ELSE 0 END = 1)`, ORDINAL_STOP_FLAG_SQL = `(CASE WHEN json_valid(data) = 1
|
|
32218
32426
|
THEN COALESCE(json_extract(data, '$.finish'), '')
|
|
@@ -32404,6 +32612,8 @@ function runSessionWarmupWorker(input, options) {
|
|
|
32404
32612
|
finish({ inserted: reply.inserted, measurements: reply.measurements });
|
|
32405
32613
|
else if (reply.kind === "orphan-sweep")
|
|
32406
32614
|
finish({ orphanSweep: reply.result });
|
|
32615
|
+
else if (reply.kind === "exact-ordinal-ids")
|
|
32616
|
+
finish({ exactOrdinalIds: reply.ids });
|
|
32407
32617
|
else
|
|
32408
32618
|
finish({ failure: "worker-error", detail: reply.error });
|
|
32409
32619
|
});
|
|
@@ -32489,19 +32699,20 @@ var init_raw_ordinal_warmup = __esm(async () => {
|
|
|
32489
32699
|
function openCodeDbExists() {
|
|
32490
32700
|
return harnessOwnsOpenCodeStore() && openCodeDbPathExists(resolveOpenCodeDbPath());
|
|
32491
32701
|
}
|
|
32492
|
-
function closeCachedReadOnlyDb() {
|
|
32493
|
-
|
|
32702
|
+
function closeCachedReadOnlyDb(generation) {
|
|
32703
|
+
const cached = cachedReadOnlyDbs[generation];
|
|
32704
|
+
if (!cached) {
|
|
32494
32705
|
return;
|
|
32495
32706
|
}
|
|
32496
32707
|
try {
|
|
32497
|
-
closeQuietly(
|
|
32708
|
+
closeQuietly(cached.db);
|
|
32498
32709
|
} catch (error) {
|
|
32499
32710
|
log("[magic-context] failed to close cached OpenCode read-only DB:", error);
|
|
32500
32711
|
} finally {
|
|
32501
|
-
|
|
32712
|
+
cachedReadOnlyDbs[generation] = null;
|
|
32502
32713
|
}
|
|
32503
32714
|
}
|
|
32504
|
-
function getReadOnlySessionDb() {
|
|
32715
|
+
function getReadOnlySessionDb(generation = "v1") {
|
|
32505
32716
|
if (!harnessOwnsOpenCodeStore()) {
|
|
32506
32717
|
throw new Error("OpenCode session database is not readable from a Pi-compatible process; its history lives in Pi sessions");
|
|
32507
32718
|
}
|
|
@@ -32510,18 +32721,19 @@ function getReadOnlySessionDb() {
|
|
|
32510
32721
|
if (!openCodeDbPathExists(resolution)) {
|
|
32511
32722
|
throw new Error(`OpenCode session database is unavailable at ${dbPath} (source=${resolution.source})`);
|
|
32512
32723
|
}
|
|
32513
|
-
|
|
32514
|
-
|
|
32724
|
+
const cached = cachedReadOnlyDbs[generation];
|
|
32725
|
+
if (cached?.path === dbPath) {
|
|
32726
|
+
return cached.db;
|
|
32515
32727
|
}
|
|
32516
|
-
closeCachedReadOnlyDb();
|
|
32728
|
+
closeCachedReadOnlyDb(generation);
|
|
32517
32729
|
const db = new Database(dbPath, { readonly: true });
|
|
32518
32730
|
try {
|
|
32519
|
-
assertOpenCodeStoreGeneration(db,
|
|
32731
|
+
assertOpenCodeStoreGeneration(db, generation, dbPath);
|
|
32520
32732
|
} catch (error) {
|
|
32521
32733
|
closeQuietly(db);
|
|
32522
32734
|
throw error;
|
|
32523
32735
|
}
|
|
32524
|
-
|
|
32736
|
+
cachedReadOnlyDbs[generation] = { path: dbPath, db };
|
|
32525
32737
|
clearOpenCodeDbReadFailure();
|
|
32526
32738
|
return db;
|
|
32527
32739
|
}
|
|
@@ -32547,21 +32759,20 @@ function getMessageTimesFromOpenCodeDb(sessionId, messageIds) {
|
|
|
32547
32759
|
if (messageIds.length === 0 || !harnessOwnsOpenCodeStore())
|
|
32548
32760
|
return result;
|
|
32549
32761
|
try {
|
|
32550
|
-
|
|
32551
|
-
|
|
32552
|
-
|
|
32553
|
-
|
|
32554
|
-
|
|
32555
|
-
|
|
32556
|
-
}
|
|
32762
|
+
const placeholders = messageIds.map(() => "?").join(",");
|
|
32763
|
+
const rows = getHarness() === "opencode2" ? getReadOnlySessionDb("v2").prepare(`SELECT id, COALESCE(time_created, json_extract(data, '$.time.created')) AS time_created
|
|
32764
|
+
FROM session_message WHERE +session_id = ? AND id IN (${placeholders})`).all(sessionId, ...messageIds) : withReadOnlySessionDb((db) => db.prepare(`SELECT id, time_created FROM message WHERE +session_id = ? AND id IN (${placeholders})`).all(sessionId, ...messageIds));
|
|
32765
|
+
for (const row of rows) {
|
|
32766
|
+
if (typeof row.id === "string" && typeof row.time_created === "number") {
|
|
32767
|
+
result.set(row.id, row.time_created);
|
|
32557
32768
|
}
|
|
32558
|
-
}
|
|
32769
|
+
}
|
|
32559
32770
|
} catch (error) {
|
|
32560
32771
|
logProbeFailureOnce(resolveOpenCodeDbPath(), error);
|
|
32561
32772
|
}
|
|
32562
32773
|
return result;
|
|
32563
32774
|
}
|
|
32564
|
-
var
|
|
32775
|
+
var cachedReadOnlyDbs, trackedSessions, pendingParts, probeLogObserverForTests;
|
|
32565
32776
|
var init_read_session_db = __esm(async () => {
|
|
32566
32777
|
init_logger();
|
|
32567
32778
|
init_opencode_db_path();
|
|
@@ -32569,6 +32780,10 @@ var init_read_session_db = __esm(async () => {
|
|
|
32569
32780
|
init_sqlite(),
|
|
32570
32781
|
init_read_session_raw()
|
|
32571
32782
|
]);
|
|
32783
|
+
cachedReadOnlyDbs = {
|
|
32784
|
+
v1: null,
|
|
32785
|
+
v2: null
|
|
32786
|
+
};
|
|
32572
32787
|
trackedSessions = new Map;
|
|
32573
32788
|
pendingParts = new Map;
|
|
32574
32789
|
});
|
|
@@ -34179,14 +34394,14 @@ var init_message_time_backfill = __esm(async () => {
|
|
|
34179
34394
|
|
|
34180
34395
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
34181
34396
|
import {
|
|
34182
|
-
existsSync as
|
|
34397
|
+
existsSync as existsSync23,
|
|
34183
34398
|
readdirSync as readdirSync5,
|
|
34184
|
-
readFileSync as
|
|
34399
|
+
readFileSync as readFileSync17,
|
|
34185
34400
|
rmdirSync,
|
|
34186
|
-
statSync as
|
|
34401
|
+
statSync as statSync13,
|
|
34187
34402
|
unlinkSync as unlinkSync3
|
|
34188
34403
|
} from "node:fs";
|
|
34189
|
-
import { basename as
|
|
34404
|
+
import { basename as basename4, dirname as dirname12, join as join16, resolve as resolve7 } from "node:path";
|
|
34190
34405
|
function ensureSecureStorageDir(dir) {
|
|
34191
34406
|
ensureStorageDirectorySync(dir);
|
|
34192
34407
|
}
|
|
@@ -34207,17 +34422,17 @@ function installBootBusyTimeout(db, dbPath, timeoutMs, report = log) {
|
|
|
34207
34422
|
}
|
|
34208
34423
|
function resolveDatabasePath(dbPathOverride) {
|
|
34209
34424
|
if (dbPathOverride) {
|
|
34210
|
-
return { dbDir:
|
|
34425
|
+
return { dbDir: dirname12(dbPathOverride), dbPath: dbPathOverride };
|
|
34211
34426
|
}
|
|
34212
34427
|
const dbDir = getMagicContextStorageDir();
|
|
34213
34428
|
return { dbDir, dbPath: join16(dbDir, "context.db") };
|
|
34214
34429
|
}
|
|
34215
34430
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
34216
|
-
if (
|
|
34431
|
+
if (existsSync23(targetDbPath))
|
|
34217
34432
|
return;
|
|
34218
34433
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
34219
34434
|
const legacyDbPath = join16(legacyDir, "context.db");
|
|
34220
|
-
if (!
|
|
34435
|
+
if (!existsSync23(legacyDbPath))
|
|
34221
34436
|
return;
|
|
34222
34437
|
log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
34223
34438
|
ensureSecureStorageDir(targetDbDir);
|
|
@@ -34235,7 +34450,7 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
34235
34450
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
34236
34451
|
const src = `${legacyDbPath}${suffix}`;
|
|
34237
34452
|
const dst = join16(targetDbDir, `context.db${suffix}`);
|
|
34238
|
-
if (
|
|
34453
|
+
if (existsSync23(src)) {
|
|
34239
34454
|
try {
|
|
34240
34455
|
copyStorageFileSync(src, dst);
|
|
34241
34456
|
} catch (error) {
|
|
@@ -34245,7 +34460,7 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
34245
34460
|
}
|
|
34246
34461
|
const legacyModelsDir = join16(legacyDir, "models");
|
|
34247
34462
|
const targetModelsDir = join16(targetDbDir, "models");
|
|
34248
|
-
if (
|
|
34463
|
+
if (existsSync23(legacyModelsDir) && !existsSync23(targetModelsDir)) {
|
|
34249
34464
|
try {
|
|
34250
34465
|
copyStorageTreeSync(legacyModelsDir, targetModelsDir);
|
|
34251
34466
|
} catch (error) {
|
|
@@ -34407,7 +34622,7 @@ function inspectRpcServerDiscovery(storageDir, processes, options) {
|
|
|
34407
34622
|
continue;
|
|
34408
34623
|
return unreadableDiscovery(portFile, "io");
|
|
34409
34624
|
}
|
|
34410
|
-
const filename =
|
|
34625
|
+
const filename = basename4(portFile);
|
|
34411
34626
|
const pidFromName = /^port-(\d+)/.exec(filename)?.[1];
|
|
34412
34627
|
const fallbackPid = pidFromName ? Number(pidFromName) : 0;
|
|
34413
34628
|
const record = parseRpcPortFile(raw, fallbackPid);
|
|
@@ -34511,8 +34726,8 @@ function removeRpcDiscoveryRecords(storageDir, files) {
|
|
|
34511
34726
|
const removed = [];
|
|
34512
34727
|
const failed = [];
|
|
34513
34728
|
for (const file of files) {
|
|
34514
|
-
const projectDir =
|
|
34515
|
-
if (
|
|
34729
|
+
const projectDir = dirname12(resolve7(file));
|
|
34730
|
+
if (dirname12(projectDir) !== rpcRoot || !basename4(file).startsWith("port")) {
|
|
34516
34731
|
failed.push({ file, error: "not an RPC discovery record" });
|
|
34517
34732
|
continue;
|
|
34518
34733
|
}
|
|
@@ -34669,7 +34884,7 @@ function finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion)
|
|
|
34669
34884
|
}
|
|
34670
34885
|
setDatabase(db);
|
|
34671
34886
|
loadToolDefinitionMeasurements(db);
|
|
34672
|
-
tightenStorageTree(
|
|
34887
|
+
tightenStorageTree(dirname12(dbPath));
|
|
34673
34888
|
databases.set(dbPath, db);
|
|
34674
34889
|
pathByDatabase.set(db, dbPath);
|
|
34675
34890
|
persistenceByDatabase.set(db, true);
|
|
@@ -35964,7 +36179,7 @@ function openDatabase(dbPathOrOptions) {
|
|
|
35964
36179
|
}
|
|
35965
36180
|
ensureSecureStorageDir(dbDir);
|
|
35966
36181
|
tightenStorageTree(dbDir);
|
|
35967
|
-
if (!
|
|
36182
|
+
if (!existsSync23(dbPath) && shouldEnforcePrivateStoragePermissions()) {
|
|
35968
36183
|
try {
|
|
35969
36184
|
writeStorageFileSync(dbPath, new Uint8Array, { flag: "wx" });
|
|
35970
36185
|
} catch (error) {
|
|
@@ -36051,8 +36266,8 @@ var init_storage_db = __esm(async () => {
|
|
|
36051
36266
|
RPC_DISCOVERY_PARSE_GRACE_MS = 10 * 60 * 1000;
|
|
36052
36267
|
defaultRpcDiscoveryFs = {
|
|
36053
36268
|
readdirSync: (path, options) => options?.withFileTypes ? readdirSync5(path, { withFileTypes: true }) : readdirSync5(path),
|
|
36054
|
-
readFileSync: (path, encoding) => String(
|
|
36055
|
-
statSync: (path) => ({ mtimeMs:
|
|
36269
|
+
readFileSync: (path, encoding) => String(readFileSync17(path, encoding)),
|
|
36270
|
+
statSync: (path) => ({ mtimeMs: statSync13(path).mtimeMs }),
|
|
36056
36271
|
unlinkSync: (path) => unlinkSync3(path),
|
|
36057
36272
|
rmdirSync: (path) => rmdirSync(path)
|
|
36058
36273
|
};
|
|
@@ -36066,14 +36281,14 @@ var init_storage_db = __esm(async () => {
|
|
|
36066
36281
|
});
|
|
36067
36282
|
|
|
36068
36283
|
// src/lib/database-access.ts
|
|
36069
|
-
import { existsSync as
|
|
36070
|
-
import { dirname as
|
|
36284
|
+
import { existsSync as existsSync24, rmSync as rmSync6 } from "node:fs";
|
|
36285
|
+
import { dirname as dirname13 } from "node:path";
|
|
36071
36286
|
import { pathToFileURL } from "node:url";
|
|
36072
36287
|
function getPersistedSchemaVersion2(db) {
|
|
36073
36288
|
return getPersistedSchemaVersion(db);
|
|
36074
36289
|
}
|
|
36075
36290
|
function openExistingDatabase(path, options) {
|
|
36076
|
-
if (!
|
|
36291
|
+
if (!existsSync24(path))
|
|
36077
36292
|
return null;
|
|
36078
36293
|
if (options.readonly) {
|
|
36079
36294
|
const db = new Database(path, { readonly: true });
|
|
@@ -36122,7 +36337,7 @@ function openExistingContextDatabaseForMutation(path) {
|
|
|
36122
36337
|
async function backupDatabaseSnapshot(db, sourcePath, destination) {
|
|
36123
36338
|
const serializable = db;
|
|
36124
36339
|
if (typeof serializable.serialize === "function") {
|
|
36125
|
-
ensureStorageDirectorySync(
|
|
36340
|
+
ensureStorageDirectorySync(dirname13(destination));
|
|
36126
36341
|
writeStorageFileSync(destination, serializable.serialize(), { flag: "wx" });
|
|
36127
36342
|
return;
|
|
36128
36343
|
}
|
|
@@ -36131,7 +36346,7 @@ async function backupDatabaseSnapshot(db, sourcePath, destination) {
|
|
|
36131
36346
|
if (typeof sqlite.backup !== "function") {
|
|
36132
36347
|
throw new Error("The active SQLite runtime does not provide a snapshot backup API");
|
|
36133
36348
|
}
|
|
36134
|
-
if (
|
|
36349
|
+
if (existsSync24(destination)) {
|
|
36135
36350
|
throw new Error(`Refusing to overwrite existing backup ${destination}`);
|
|
36136
36351
|
}
|
|
36137
36352
|
const reader = new Database(sourcePath, { readonly: true });
|
|
@@ -36241,7 +36456,7 @@ var init_config_location_migration = __esm(() => {
|
|
|
36241
36456
|
function availableDreamTasks(smartNotesEnabled = true) {
|
|
36242
36457
|
return CANONICAL_DREAM_TASKS.filter((task) => smartNotesEnabled || task !== "evaluate-smart-notes");
|
|
36243
36458
|
}
|
|
36244
|
-
var CANONICAL_DREAM_TASKS, DREAM_TOOL_LOOP_TOKEN_BUDGETS, MEMORY_DOMAIN_TASKS, MEMORY_DOMAIN_SET;
|
|
36459
|
+
var CANONICAL_DREAM_TASKS, DREAM_TOOL_LOOP_TOKEN_BUDGETS, MEMORY_DOMAIN_TASKS, MEMORY_DOMAIN_SET, PROJECT_MEMORY_DREAM_TASKS, PROJECT_MEMORY_DREAM_TASK_SET;
|
|
36245
36460
|
var init_task_registry = __esm(() => {
|
|
36246
36461
|
CANONICAL_DREAM_TASKS = [
|
|
36247
36462
|
"map-memories",
|
|
@@ -36278,6 +36493,18 @@ var init_task_registry = __esm(() => {
|
|
|
36278
36493
|
"refresh-primers"
|
|
36279
36494
|
];
|
|
36280
36495
|
MEMORY_DOMAIN_SET = new Set(MEMORY_DOMAIN_TASKS);
|
|
36496
|
+
PROJECT_MEMORY_DREAM_TASKS = [
|
|
36497
|
+
"map-memories",
|
|
36498
|
+
"verify",
|
|
36499
|
+
"verify-broad",
|
|
36500
|
+
"curate",
|
|
36501
|
+
"compress-cues",
|
|
36502
|
+
"classify-memories",
|
|
36503
|
+
"retrospective",
|
|
36504
|
+
"promote-primers",
|
|
36505
|
+
"refresh-primers"
|
|
36506
|
+
];
|
|
36507
|
+
PROJECT_MEMORY_DREAM_TASK_SET = new Set(PROJECT_MEMORY_DREAM_TASKS);
|
|
36281
36508
|
});
|
|
36282
36509
|
|
|
36283
36510
|
// src/lib/model-picker.ts
|
|
@@ -36417,11 +36644,11 @@ var init_dreamer_setup = __esm(() => {
|
|
|
36417
36644
|
});
|
|
36418
36645
|
|
|
36419
36646
|
// src/commands/setup-pi.ts
|
|
36420
|
-
import { existsSync as
|
|
36421
|
-
import { dirname as
|
|
36647
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync6 } from "node:fs";
|
|
36648
|
+
import { dirname as dirname14 } from "node:path";
|
|
36422
36649
|
function ensureDir4(path) {
|
|
36423
|
-
if (!
|
|
36424
|
-
|
|
36650
|
+
if (!existsSync25(path))
|
|
36651
|
+
mkdirSync6(path, { recursive: true });
|
|
36425
36652
|
}
|
|
36426
36653
|
async function getDefaultPrompts() {
|
|
36427
36654
|
await Promise.resolve().then(() => init_prompts());
|
|
@@ -36453,7 +36680,7 @@ function comparePiVersion(a, b) {
|
|
|
36453
36680
|
}
|
|
36454
36681
|
function writePiSettingsPackage(settingsPath, packageSource = PI_PACKAGE_SOURCE) {
|
|
36455
36682
|
const settings = readJsoncConfigForUpdate(settingsPath);
|
|
36456
|
-
ensureDir4(
|
|
36683
|
+
ensureDir4(dirname14(settingsPath));
|
|
36457
36684
|
if (settings.packages !== undefined && !Array.isArray(settings.packages)) {
|
|
36458
36685
|
throw new Error(`Refusing to rewrite ${settingsPath}: "packages" is ${typeof settings.packages}, expected an array. Fix it by hand, then rerun setup.`);
|
|
36459
36686
|
}
|
|
@@ -36484,7 +36711,7 @@ function removePiSettingsPackage(settingsPath, packageSource = PI_PACKAGE_SOURCE
|
|
|
36484
36711
|
}
|
|
36485
36712
|
function writeMagicContextConfig(configPath, options) {
|
|
36486
36713
|
const config = readMagicContextConfigForSetup(configPath);
|
|
36487
|
-
ensureDir4(
|
|
36714
|
+
ensureDir4(dirname14(configPath));
|
|
36488
36715
|
if (!config.$schema) {
|
|
36489
36716
|
config.$schema = "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json";
|
|
36490
36717
|
}
|
|
@@ -37177,7 +37404,7 @@ var init_conflict_detector = __esm(() => {
|
|
|
37177
37404
|
});
|
|
37178
37405
|
|
|
37179
37406
|
// ../plugin/src/shared/conflict-fixer.ts
|
|
37180
|
-
import { existsSync as
|
|
37407
|
+
import { existsSync as existsSync26, readFileSync as readFileSync18, writeFileSync as writeFileSync6 } from "node:fs";
|
|
37181
37408
|
import { homedir as homedir15 } from "node:os";
|
|
37182
37409
|
import { join as join19 } from "node:path";
|
|
37183
37410
|
function isRecord3(value) {
|
|
@@ -37187,11 +37414,11 @@ function asStringArray(value) {
|
|
|
37187
37414
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
37188
37415
|
}
|
|
37189
37416
|
function readConfig(filePath) {
|
|
37190
|
-
if (!
|
|
37417
|
+
if (!existsSync26(filePath)) {
|
|
37191
37418
|
return null;
|
|
37192
37419
|
}
|
|
37193
37420
|
try {
|
|
37194
|
-
const text =
|
|
37421
|
+
const text = readFileSync18(filePath, "utf-8");
|
|
37195
37422
|
const parsed = import_comment_json5.parse(text);
|
|
37196
37423
|
return isRecord3(parsed) ? { config: parsed, text } : null;
|
|
37197
37424
|
} catch {
|
|
@@ -37199,18 +37426,18 @@ function readConfig(filePath) {
|
|
|
37199
37426
|
}
|
|
37200
37427
|
}
|
|
37201
37428
|
function writeConfig(filePath, text) {
|
|
37202
|
-
|
|
37429
|
+
writeFileSync6(filePath, text);
|
|
37203
37430
|
}
|
|
37204
37431
|
function resolveUserOpenCodeConfigPath() {
|
|
37205
37432
|
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
37206
|
-
if (
|
|
37433
|
+
if (existsSync26(paths.configJsonc))
|
|
37207
37434
|
return paths.configJsonc;
|
|
37208
37435
|
return paths.configJson;
|
|
37209
37436
|
}
|
|
37210
37437
|
function collectOpenCodeConfigPaths(directory) {
|
|
37211
37438
|
const paths = new Set;
|
|
37212
37439
|
const userConfig = resolveUserOpenCodeConfigPath();
|
|
37213
|
-
if (
|
|
37440
|
+
if (existsSync26(userConfig)) {
|
|
37214
37441
|
paths.add(userConfig);
|
|
37215
37442
|
}
|
|
37216
37443
|
for (const filePath of [
|
|
@@ -37219,7 +37446,7 @@ function collectOpenCodeConfigPaths(directory) {
|
|
|
37219
37446
|
join19(directory, "opencode.jsonc"),
|
|
37220
37447
|
join19(directory, "opencode.json")
|
|
37221
37448
|
]) {
|
|
37222
|
-
if (
|
|
37449
|
+
if (existsSync26(filePath)) {
|
|
37223
37450
|
paths.add(filePath);
|
|
37224
37451
|
}
|
|
37225
37452
|
}
|
|
@@ -37231,10 +37458,10 @@ function collectOmoConfigPaths(directory) {
|
|
|
37231
37458
|
for (const fileName of OMO_CONFIG_NAMES) {
|
|
37232
37459
|
const userPath = join19(configDir, fileName);
|
|
37233
37460
|
const projectPath = join19(directory, fileName);
|
|
37234
|
-
if (
|
|
37461
|
+
if (existsSync26(userPath)) {
|
|
37235
37462
|
paths.add(userPath);
|
|
37236
37463
|
}
|
|
37237
|
-
if (
|
|
37464
|
+
if (existsSync26(projectPath)) {
|
|
37238
37465
|
paths.add(projectPath);
|
|
37239
37466
|
}
|
|
37240
37467
|
}
|
|
@@ -37242,13 +37469,13 @@ function collectOmoConfigPaths(directory) {
|
|
|
37242
37469
|
const omoHomeDir = join19(homeDir, ".omo");
|
|
37243
37470
|
for (const name of OMO_UNIFIED_NAMES) {
|
|
37244
37471
|
const userPath = join19(omoHomeDir, name);
|
|
37245
|
-
if (
|
|
37472
|
+
if (existsSync26(userPath)) {
|
|
37246
37473
|
paths.add(userPath);
|
|
37247
37474
|
}
|
|
37248
37475
|
}
|
|
37249
37476
|
for (const name of OMO_UNIFIED_NAMES) {
|
|
37250
37477
|
const projectPath = join19(directory, ".omo", name);
|
|
37251
|
-
if (
|
|
37478
|
+
if (existsSync26(projectPath)) {
|
|
37252
37479
|
paths.add(projectPath);
|
|
37253
37480
|
}
|
|
37254
37481
|
}
|
|
@@ -37376,8 +37603,8 @@ var init_conflict_fixer = __esm(() => {
|
|
|
37376
37603
|
});
|
|
37377
37604
|
|
|
37378
37605
|
// src/commands/setup-opencode.ts
|
|
37379
|
-
import { existsSync as
|
|
37380
|
-
import { basename as
|
|
37606
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
37607
|
+
import { basename as basename5, dirname as dirname15 } from "node:path";
|
|
37381
37608
|
function resolveCompactionEnabledForWriter() {
|
|
37382
37609
|
try {
|
|
37383
37610
|
const config = loadPluginConfig(process.cwd());
|
|
@@ -37392,7 +37619,7 @@ function isPlainObject5(value) {
|
|
|
37392
37619
|
}
|
|
37393
37620
|
function planOpenCodeConfigUpdate(configPath, removeDcp = false, compactionEnabled = true, hostGeneration = "v1") {
|
|
37394
37621
|
const registrationKey = pluginConfigKeyFor(hostGeneration);
|
|
37395
|
-
const existsAtCommit =
|
|
37622
|
+
const existsAtCommit = existsSync27(configPath);
|
|
37396
37623
|
const existing = existsAtCommit ? readJsoncConfigForUpdate(configPath) : {};
|
|
37397
37624
|
if (!existsAtCommit) {
|
|
37398
37625
|
const created = { [registrationKey]: [OPENCODE_PLUGIN_ENTRY_WITH_VERSION] };
|
|
@@ -37407,7 +37634,7 @@ function planOpenCodeConfigUpdate(configPath, removeDcp = false, compactionEnabl
|
|
|
37407
37634
|
let changed = false;
|
|
37408
37635
|
const rawPlugins = readPluginEntries(existing).map(({ entry }) => entry);
|
|
37409
37636
|
const retainedPlugins = removeDcp ? rawPlugins.filter((plugin) => !matchesPluginEntry(plugin, DCP_PLUGIN_NAME)) : rawPlugins;
|
|
37410
|
-
if (retainedPlugins.some((plugin) => isLocalPathPluginEntry(plugin) && String(plugin).includes("magic-context") && !isDevPathPluginEntry(plugin,
|
|
37637
|
+
if (retainedPlugins.some((plugin) => isLocalPathPluginEntry(plugin) && String(plugin).includes("magic-context") && !isDevPathPluginEntry(plugin, dirname15(configPath)))) {
|
|
37411
37638
|
log3.warn("An unverifiable local OpenCode plugin path was ignored; its package name is not Magic Context.");
|
|
37412
37639
|
}
|
|
37413
37640
|
if (removeDcp) {
|
|
@@ -37422,7 +37649,7 @@ function planOpenCodeConfigUpdate(configPath, removeDcp = false, compactionEnabl
|
|
|
37422
37649
|
}
|
|
37423
37650
|
}
|
|
37424
37651
|
const hasNpmEntry = retainedPlugins.some((plugin) => matchesPluginEntry(plugin, OPENCODE_PLUGIN_NAME));
|
|
37425
|
-
const hasDevEntry = retainedPlugins.some((plugin) => isDevPathPluginEntry(plugin,
|
|
37652
|
+
const hasDevEntry = retainedPlugins.some((plugin) => isDevPathPluginEntry(plugin, dirname15(configPath)));
|
|
37426
37653
|
if (!hasNpmEntry && !hasDevEntry) {
|
|
37427
37654
|
text = Array.isArray(existing[registrationKey]) ? appendJsoncArrayValues(text, [registrationKey], [OPENCODE_PLUGIN_ENTRY_WITH_VERSION]) : setJsoncValue(text, [registrationKey], [OPENCODE_PLUGIN_ENTRY_WITH_VERSION]);
|
|
37428
37655
|
changed = true;
|
|
@@ -37448,18 +37675,18 @@ function planOpenCodeConfigUpdate(configPath, removeDcp = false, compactionEnabl
|
|
|
37448
37675
|
return changed ? document.bom + text : null;
|
|
37449
37676
|
}
|
|
37450
37677
|
function planTuiConfigUpdate(configPath) {
|
|
37451
|
-
const existsAtCommit =
|
|
37678
|
+
const existsAtCommit = existsSync27(configPath);
|
|
37452
37679
|
const existing = existsAtCommit ? readJsoncConfigForUpdate(configPath) : {};
|
|
37453
37680
|
if (!existsAtCommit) {
|
|
37454
37681
|
return `${import_comment_json6.stringify({ plugin: [OPENCODE_PLUGIN_ENTRY_WITH_VERSION] }, null, 2)}
|
|
37455
37682
|
`;
|
|
37456
37683
|
}
|
|
37457
37684
|
const rawPlugins = Array.isArray(existing.plugin) ? existing.plugin : [];
|
|
37458
|
-
if (rawPlugins.some((plugin) => isLocalPathPluginEntry(plugin) && String(plugin).includes("magic-context") && !isDevPathPluginEntry(plugin,
|
|
37685
|
+
if (rawPlugins.some((plugin) => isLocalPathPluginEntry(plugin) && String(plugin).includes("magic-context") && !isDevPathPluginEntry(plugin, dirname15(configPath)))) {
|
|
37459
37686
|
log3.warn("An unverifiable local TUI plugin path was ignored; its package name is not Magic Context.");
|
|
37460
37687
|
}
|
|
37461
37688
|
const hasNpmEntry = rawPlugins.some((plugin) => matchesPluginEntry(plugin, OPENCODE_PLUGIN_NAME));
|
|
37462
|
-
const hasDevEntry = rawPlugins.some((plugin) => isDevPathPluginEntry(plugin,
|
|
37689
|
+
const hasDevEntry = rawPlugins.some((plugin) => isDevPathPluginEntry(plugin, dirname15(configPath)));
|
|
37463
37690
|
if (hasNpmEntry || hasDevEntry)
|
|
37464
37691
|
return null;
|
|
37465
37692
|
const document = readJsoncTextForEdit(configPath);
|
|
@@ -37575,7 +37802,7 @@ async function runSetup3(dryRun = false) {
|
|
|
37575
37802
|
log3.warn("You can configure models manually in magic-context.jsonc later");
|
|
37576
37803
|
}
|
|
37577
37804
|
const paths = detectConfigPaths();
|
|
37578
|
-
const hadExistingSetup = paths.opencodeConfigFormat !== "none" ||
|
|
37805
|
+
const hadExistingSetup = paths.opencodeConfigFormat !== "none" || existsSync27(paths.magicContextConfig) || paths.tuiConfigFormat !== "none";
|
|
37579
37806
|
if (!dryRun) {
|
|
37580
37807
|
try {
|
|
37581
37808
|
assertJsoncConfigsParseable([
|
|
@@ -37687,7 +37914,7 @@ async function runSetup3(dryRun = false) {
|
|
|
37687
37914
|
}
|
|
37688
37915
|
log3.success(`Config written to ${paths.magicContextConfig}`);
|
|
37689
37916
|
if (hostGeneration === "v1") {
|
|
37690
|
-
log3.success(`TUI sidebar plugin added to ${
|
|
37917
|
+
log3.success(`TUI sidebar plugin added to ${basename5(paths.tuiConfig)}`);
|
|
37691
37918
|
} else {
|
|
37692
37919
|
log3.info("TUI sidebar loads from the plugin entry on OpenCode 2 (tui.json not used)");
|
|
37693
37920
|
}
|
|
@@ -37868,8 +38095,8 @@ var init_setup = __esm(async () => {
|
|
|
37868
38095
|
});
|
|
37869
38096
|
|
|
37870
38097
|
// src/lib/disk-space.ts
|
|
37871
|
-
import { existsSync as
|
|
37872
|
-
import { dirname as
|
|
38098
|
+
import { existsSync as existsSync28, statfsSync, statSync as statSync14 } from "node:fs";
|
|
38099
|
+
import { dirname as dirname16, resolve as resolve9 } from "node:path";
|
|
37873
38100
|
function availableDiskBytes(path) {
|
|
37874
38101
|
const filesystem = statfsSync(path);
|
|
37875
38102
|
return filesystem.bavail * filesystem.bsize;
|
|
@@ -37886,9 +38113,9 @@ function checkDiskSpace(path, bytes, freeBytes) {
|
|
|
37886
38113
|
function existingDirectoryAncestor(path) {
|
|
37887
38114
|
let current = resolve9(path);
|
|
37888
38115
|
for (;; ) {
|
|
37889
|
-
if (
|
|
38116
|
+
if (existsSync28(current) && statSync14(current).isDirectory())
|
|
37890
38117
|
return current;
|
|
37891
|
-
const parent =
|
|
38118
|
+
const parent = dirname16(current);
|
|
37892
38119
|
if (parent === current)
|
|
37893
38120
|
throw new Error(`No existing directory for ${path}`);
|
|
37894
38121
|
current = parent;
|
|
@@ -37939,14 +38166,14 @@ var init_types = __esm(() => {
|
|
|
37939
38166
|
// ../plugin/src/hooks/auto-update-checker/checker.ts
|
|
37940
38167
|
import {
|
|
37941
38168
|
accessSync as accessSync3,
|
|
37942
|
-
existsSync as
|
|
38169
|
+
existsSync as existsSync29,
|
|
37943
38170
|
constants as fsConstants,
|
|
37944
|
-
readFileSync as
|
|
38171
|
+
readFileSync as readFileSync19,
|
|
37945
38172
|
renameSync as renameSync5,
|
|
37946
|
-
statSync as
|
|
37947
|
-
writeFileSync as
|
|
38173
|
+
statSync as statSync15,
|
|
38174
|
+
writeFileSync as writeFileSync7
|
|
37948
38175
|
} from "node:fs";
|
|
37949
|
-
import { dirname as
|
|
38176
|
+
import { dirname as dirname17, isAbsolute as isAbsolute7, join as join21, resolve as resolve10 } from "node:path";
|
|
37950
38177
|
function warn(message) {
|
|
37951
38178
|
log(`WARN: ${message}`);
|
|
37952
38179
|
}
|
|
@@ -37972,7 +38199,7 @@ function parseJsonConfig(content) {
|
|
|
37972
38199
|
}
|
|
37973
38200
|
function getSurfaceConfigPaths(directory, surface) {
|
|
37974
38201
|
const name = surface === "server" ? "opencode" : "tui";
|
|
37975
|
-
const globalDir =
|
|
38202
|
+
const globalDir = dirname17(USER_OPENCODE_CONFIG);
|
|
37976
38203
|
const dirs = [
|
|
37977
38204
|
globalDir,
|
|
37978
38205
|
directory,
|
|
@@ -37993,9 +38220,9 @@ function getWinningConfig(directory, surface) {
|
|
|
37993
38220
|
let winner = null;
|
|
37994
38221
|
for (const path of getSurfaceConfigPaths(directory, surface)) {
|
|
37995
38222
|
try {
|
|
37996
|
-
if (!
|
|
38223
|
+
if (!existsSync29(path))
|
|
37997
38224
|
continue;
|
|
37998
|
-
const parsed = parseJsonConfig(
|
|
38225
|
+
const parsed = parseJsonConfig(readFileSync19(path, "utf-8"));
|
|
37999
38226
|
const entries = getPluginEntries(parsed);
|
|
38000
38227
|
if (entries.some((entry) => entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))) {
|
|
38001
38228
|
if (winner) {
|
|
@@ -38032,14 +38259,14 @@ var init_checker = __esm(async () => {
|
|
|
38032
38259
|
});
|
|
38033
38260
|
|
|
38034
38261
|
// src/lib/opencode-plugin-schema-fence.ts
|
|
38035
|
-
import { existsSync as
|
|
38262
|
+
import { existsSync as existsSync30, readdirSync as readdirSync6, readFileSync as readFileSync20 } from "node:fs";
|
|
38036
38263
|
import { join as join22 } from "node:path";
|
|
38037
38264
|
import { gunzipSync as gunzipSync2 } from "node:zlib";
|
|
38038
38265
|
function readPackageVersion(packageJsonPath) {
|
|
38039
38266
|
try {
|
|
38040
|
-
if (!
|
|
38267
|
+
if (!existsSync30(packageJsonPath))
|
|
38041
38268
|
return null;
|
|
38042
|
-
const packageJson = JSON.parse(
|
|
38269
|
+
const packageJson = JSON.parse(readFileSync20(packageJsonPath, "utf-8"));
|
|
38043
38270
|
if (packageJson.name !== OPENCODE_PLUGIN_NAME || typeof packageJson.version !== "string") {
|
|
38044
38271
|
return null;
|
|
38045
38272
|
}
|
|
@@ -38059,7 +38286,7 @@ function readFenceValue(text) {
|
|
|
38059
38286
|
}
|
|
38060
38287
|
function readFenceFromDist(packageDirectory) {
|
|
38061
38288
|
const distDirectory = join22(packageDirectory, "dist");
|
|
38062
|
-
if (!
|
|
38289
|
+
if (!existsSync30(distDirectory))
|
|
38063
38290
|
return null;
|
|
38064
38291
|
const pending = [distDirectory];
|
|
38065
38292
|
const fenceValues = new Set;
|
|
@@ -38076,7 +38303,7 @@ function readFenceFromDist(packageDirectory) {
|
|
|
38076
38303
|
}
|
|
38077
38304
|
if (!entry.isFile() || !/\.(?:[cm]?js|ts)$/.test(entry.name))
|
|
38078
38305
|
continue;
|
|
38079
|
-
const fence = readFenceValue(
|
|
38306
|
+
const fence = readFenceValue(readFileSync20(path, "utf-8"));
|
|
38080
38307
|
if (fence !== null)
|
|
38081
38308
|
fenceValues.add(fence);
|
|
38082
38309
|
}
|
|
@@ -38245,13 +38472,13 @@ var init_opencode_plugin_schema_fence = __esm(async () => {
|
|
|
38245
38472
|
});
|
|
38246
38473
|
|
|
38247
38474
|
// src/commands/doctor-opencode-cache.ts
|
|
38248
|
-
import { existsSync as
|
|
38475
|
+
import { existsSync as existsSync31, readFileSync as readFileSync21, rmSync as rmSync7 } from "node:fs";
|
|
38249
38476
|
function readCachedPluginVersion(pluginCacheDir) {
|
|
38250
38477
|
try {
|
|
38251
38478
|
const installedPkgPath = getOpenCodePluginPackageJsonPath(pluginCacheDir);
|
|
38252
|
-
if (!
|
|
38479
|
+
if (!existsSync31(installedPkgPath))
|
|
38253
38480
|
return;
|
|
38254
|
-
const pkg = JSON.parse(
|
|
38481
|
+
const pkg = JSON.parse(readFileSync21(installedPkgPath, "utf-8"));
|
|
38255
38482
|
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
38256
38483
|
} catch {
|
|
38257
38484
|
return;
|
|
@@ -38278,7 +38505,7 @@ function readOpenCodePluginConfigUse(config, configDir) {
|
|
|
38278
38505
|
async function clearPluginCache(options = {}, deps = {}) {
|
|
38279
38506
|
const remove = deps.remove ?? ((path) => rmSync7(path, { recursive: true, force: true }));
|
|
38280
38507
|
const pluginCacheRoots = getOpenCodePluginCacheRoots();
|
|
38281
|
-
const existingRoots = pluginCacheRoots.filter((root) =>
|
|
38508
|
+
const existingRoots = pluginCacheRoots.filter((root) => existsSync31(root));
|
|
38282
38509
|
if (existingRoots.length === 0) {
|
|
38283
38510
|
return { action: "not_found", path: pluginCacheRoots[0] ?? "" };
|
|
38284
38511
|
}
|
|
@@ -38375,8 +38602,8 @@ var init_doctor_opencode_cache = __esm(async () => {
|
|
|
38375
38602
|
});
|
|
38376
38603
|
|
|
38377
38604
|
// src/commands/doctor-cached-plugin-fence.ts
|
|
38378
|
-
import { existsSync as
|
|
38379
|
-
import { dirname as
|
|
38605
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
38606
|
+
import { dirname as dirname18 } from "node:path";
|
|
38380
38607
|
function isReferenced(sources, host, spec) {
|
|
38381
38608
|
const specs = sources.referencedSpecs?.[host];
|
|
38382
38609
|
return specs === undefined || specs.has(spec);
|
|
@@ -38386,13 +38613,13 @@ function listCachedOpenCodePluginFences(sources = {}) {
|
|
|
38386
38613
|
const v1Referenced = isReferenced(sources, "opencode1", "latest");
|
|
38387
38614
|
for (const root of v1Referenced ? sources.openCodeV1Roots ?? getOpenCodePluginCacheRoots() : []) {
|
|
38388
38615
|
const packageJson = getOpenCodePluginPackageJsonPath(root);
|
|
38389
|
-
if (!
|
|
38616
|
+
if (!existsSync32(packageJson))
|
|
38390
38617
|
continue;
|
|
38391
38618
|
fences.push({
|
|
38392
38619
|
host: "opencode1",
|
|
38393
38620
|
directory: root,
|
|
38394
38621
|
version: readCachedPluginVersion(root),
|
|
38395
|
-
supportedVersion: readFenceFromDist(
|
|
38622
|
+
supportedVersion: readFenceFromDist(dirname18(packageJson))
|
|
38396
38623
|
});
|
|
38397
38624
|
}
|
|
38398
38625
|
for (const slot of listOpenCodeV2PluginCacheSlots(sources.openCodeV2NpmCacheDir)) {
|
|
@@ -38408,7 +38635,7 @@ function listCachedOpenCodePluginFences(sources = {}) {
|
|
|
38408
38635
|
directory: slot.slot,
|
|
38409
38636
|
spec: slot.spec,
|
|
38410
38637
|
version: slot.version,
|
|
38411
|
-
supportedVersion: readFenceFromDist(
|
|
38638
|
+
supportedVersion: readFenceFromDist(dirname18(getOpenCodePluginPackageJsonPath(generation)))
|
|
38412
38639
|
});
|
|
38413
38640
|
}
|
|
38414
38641
|
return fences;
|
|
@@ -38591,11 +38818,11 @@ var init_doctor_prune_discovery = __esm(async () => {
|
|
|
38591
38818
|
|
|
38592
38819
|
// src/commands/doctor-storage-holders.ts
|
|
38593
38820
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
38594
|
-
import { readFileSync as
|
|
38821
|
+
import { readFileSync as readFileSync22, realpathSync as realpathSync6 } from "node:fs";
|
|
38595
38822
|
import { join as join23, resolve as resolve11 } from "node:path";
|
|
38596
38823
|
function canonicalStoragePath(path) {
|
|
38597
38824
|
try {
|
|
38598
|
-
return
|
|
38825
|
+
return realpathSync6(path);
|
|
38599
38826
|
} catch {
|
|
38600
38827
|
return resolve11(path);
|
|
38601
38828
|
}
|
|
@@ -38619,7 +38846,7 @@ function processReferencesStorage(pid, storageDir) {
|
|
|
38619
38846
|
if (process.platform === "linux") {
|
|
38620
38847
|
for (const name of ["cmdline", "environ"]) {
|
|
38621
38848
|
try {
|
|
38622
|
-
texts.push(
|
|
38849
|
+
texts.push(readFileSync22(`/proc/${pid}/${name}`, "utf8"));
|
|
38623
38850
|
} catch {}
|
|
38624
38851
|
}
|
|
38625
38852
|
} else {
|
|
@@ -38641,9 +38868,9 @@ var init_doctor_storage_holders = () => {};
|
|
|
38641
38868
|
|
|
38642
38869
|
// src/commands/doctor-repair-db.ts
|
|
38643
38870
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
38644
|
-
import { closeSync as closeSync4, existsSync as
|
|
38871
|
+
import { closeSync as closeSync4, existsSync as existsSync33, openSync as openSync4, renameSync as renameSync6, rmSync as rmSync8, statSync as statSync16 } from "node:fs";
|
|
38645
38872
|
import { homedir as homedir17 } from "node:os";
|
|
38646
|
-
import { dirname as
|
|
38873
|
+
import { dirname as dirname19, join as join24 } from "node:path";
|
|
38647
38874
|
function defaultInspectHolders(storageDir, overrides = {}) {
|
|
38648
38875
|
const deps = {
|
|
38649
38876
|
defaultStorageDir: join24(homedir17(), ".local", "share", "cortexkit", "magic-context"),
|
|
@@ -38709,11 +38936,11 @@ function timestamp(date) {
|
|
|
38709
38936
|
return date.toISOString().replaceAll("-", "").replaceAll(":", "").replace(".", "");
|
|
38710
38937
|
}
|
|
38711
38938
|
function uniqueBase(preferred) {
|
|
38712
|
-
if (!DATABASE_SUFFIXES.some((suffix) =>
|
|
38939
|
+
if (!DATABASE_SUFFIXES.some((suffix) => existsSync33(`${preferred}${suffix}`)))
|
|
38713
38940
|
return preferred;
|
|
38714
38941
|
for (let attempt = 1;attempt < 1e4; attempt++) {
|
|
38715
38942
|
const candidate = `${preferred}-${attempt}`;
|
|
38716
|
-
if (!DATABASE_SUFFIXES.some((suffix) =>
|
|
38943
|
+
if (!DATABASE_SUFFIXES.some((suffix) => existsSync33(`${candidate}${suffix}`)))
|
|
38717
38944
|
return candidate;
|
|
38718
38945
|
}
|
|
38719
38946
|
throw new Error(`Could not allocate a unique recovery path beside ${preferred}`);
|
|
@@ -38727,8 +38954,8 @@ function databaseBundleSizeBytes(sourceBase) {
|
|
|
38727
38954
|
let size = 0;
|
|
38728
38955
|
for (const suffix of DATABASE_SUFFIXES) {
|
|
38729
38956
|
const source = `${sourceBase}${suffix}`;
|
|
38730
|
-
if (
|
|
38731
|
-
size +=
|
|
38957
|
+
if (existsSync33(source))
|
|
38958
|
+
size += statSync16(source).size;
|
|
38732
38959
|
}
|
|
38733
38960
|
return size;
|
|
38734
38961
|
}
|
|
@@ -38736,7 +38963,7 @@ function copyDatabaseBundle(sourceBase, destinationBase, forcePrivate = false) {
|
|
|
38736
38963
|
const copiedPaths = [];
|
|
38737
38964
|
for (const suffix of DATABASE_SUFFIXES) {
|
|
38738
38965
|
const source = `${sourceBase}${suffix}`;
|
|
38739
|
-
if (!
|
|
38966
|
+
if (!existsSync33(source))
|
|
38740
38967
|
continue;
|
|
38741
38968
|
const destination = `${destinationBase}${suffix}`;
|
|
38742
38969
|
copyStorageFileSync(source, destination, forcePrivate);
|
|
@@ -38958,7 +39185,7 @@ function activateReplacement(dbPath, replacementPath, originalAsidePath) {
|
|
|
38958
39185
|
try {
|
|
38959
39186
|
for (const suffix of DATABASE_SUFFIXES) {
|
|
38960
39187
|
const from = `${dbPath}${suffix}`;
|
|
38961
|
-
if (!
|
|
39188
|
+
if (!existsSync33(from))
|
|
38962
39189
|
continue;
|
|
38963
39190
|
const to = `${originalAsidePath}${suffix}`;
|
|
38964
39191
|
renameSync6(from, to);
|
|
@@ -38968,7 +39195,7 @@ function activateReplacement(dbPath, replacementPath, originalAsidePath) {
|
|
|
38968
39195
|
return movedOriginals.map(({ to }) => to);
|
|
38969
39196
|
} catch (error) {
|
|
38970
39197
|
for (const moved of movedOriginals.reverse()) {
|
|
38971
|
-
if (
|
|
39198
|
+
if (existsSync33(moved.to) && !existsSync33(moved.from))
|
|
38972
39199
|
renameSync6(moved.to, moved.from);
|
|
38973
39200
|
}
|
|
38974
39201
|
throw error;
|
|
@@ -38999,12 +39226,12 @@ function printHelp() {
|
|
|
38999
39226
|
async function runRepairDb(options = {}) {
|
|
39000
39227
|
const prompts = options.prompts ?? promptIO;
|
|
39001
39228
|
const deps = { ...DEFAULT_DEPS3, ...options.deps };
|
|
39002
|
-
const storageDir = options.storageDir ??
|
|
39229
|
+
const storageDir = options.storageDir ?? dirname19(options.dbPath ?? join24(getMagicContextStorageDir(), "context.db"));
|
|
39003
39230
|
const dbPath = options.dbPath ?? join24(storageDir, "context.db");
|
|
39004
39231
|
const stamp = timestamp(deps.now());
|
|
39005
39232
|
prompts.intro("Magic Context — Repair shared database");
|
|
39006
39233
|
prompts.log.info(`Database: ${dbPath}`);
|
|
39007
|
-
if (!
|
|
39234
|
+
if (!existsSync33(dbPath)) {
|
|
39008
39235
|
prompts.log.error(`Database not found: ${dbPath}`);
|
|
39009
39236
|
prompts.log.info("Backup: not created (database does not exist)");
|
|
39010
39237
|
prompts.outro("Database repair failed");
|
|
@@ -39214,13 +39441,13 @@ var init_doctor_repair_db = __esm(async () => {
|
|
|
39214
39441
|
|
|
39215
39442
|
// src/commands/doctor-single-store-repair.ts
|
|
39216
39443
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
39217
|
-
import { existsSync as
|
|
39444
|
+
import { existsSync as existsSync34, statfsSync as statfsSync2, statSync as statSync17 } from "node:fs";
|
|
39218
39445
|
import { homedir as homedir18 } from "node:os";
|
|
39219
|
-
import { dirname as
|
|
39446
|
+
import { dirname as dirname20, join as join25, resolve as resolve12 } from "node:path";
|
|
39220
39447
|
function existingAncestor(path) {
|
|
39221
39448
|
let current = resolve12(path);
|
|
39222
|
-
while (!
|
|
39223
|
-
current =
|
|
39449
|
+
while (!existsSync34(current))
|
|
39450
|
+
current = dirname20(current);
|
|
39224
39451
|
return current;
|
|
39225
39452
|
}
|
|
39226
39453
|
function describe2(plan, print) {
|
|
@@ -39256,13 +39483,13 @@ function runDoctorSingleStoreRepair(options, overrides = {}) {
|
|
|
39256
39483
|
try {
|
|
39257
39484
|
const { dbPath: context, dbDir: data } = resolveDatabasePath();
|
|
39258
39485
|
const store = join25(data, "store.db");
|
|
39259
|
-
if (!
|
|
39486
|
+
if (!existsSync34(context) || !existsSync34(store))
|
|
39260
39487
|
return refuse("repair_missing_database", `Both ${context} and ${store} must exist.`);
|
|
39261
39488
|
if (!options.fromBackup)
|
|
39262
39489
|
return refuse("repair_usage", "--from-backup <dir> is required");
|
|
39263
39490
|
const fromBackup = resolve12(options.fromBackup);
|
|
39264
39491
|
for (const name of ["context.db", "store.db"])
|
|
39265
|
-
if (!
|
|
39492
|
+
if (!existsSync34(join25(fromBackup, name)))
|
|
39266
39493
|
return refuse("repair_backup_missing", `${join25(fromBackup, name)} does not exist`);
|
|
39267
39494
|
const sessions = options.sessions ?? [];
|
|
39268
39495
|
if (options.live && sessions.length === 0)
|
|
@@ -39291,7 +39518,7 @@ function runDoctorSingleStoreRepair(options, overrides = {}) {
|
|
|
39291
39518
|
deps.print(`Repairing while hosts hold the stores (--live): ${blockers.join("; ") || "holders unknown"}`);
|
|
39292
39519
|
}
|
|
39293
39520
|
const backupRoot = resolve12(options.backupRoot ?? join25(data, "backups"));
|
|
39294
|
-
const need = Math.ceil((
|
|
39521
|
+
const need = Math.ceil((statSync17(context).size + statSync17(store).size) * 1.1);
|
|
39295
39522
|
const volume = existingAncestor(backupRoot);
|
|
39296
39523
|
const have = deps.freeBytes(volume);
|
|
39297
39524
|
if (have < need)
|
|
@@ -39387,7 +39614,7 @@ var init_doctor_single_store_repair = __esm(async () => {
|
|
|
39387
39614
|
|
|
39388
39615
|
// src/commands/doctor-single-store.ts
|
|
39389
39616
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
39390
|
-
import { existsSync as
|
|
39617
|
+
import { existsSync as existsSync35, realpathSync as realpathSync7, statSync as statSync18 } from "node:fs";
|
|
39391
39618
|
import { homedir as homedir19 } from "node:os";
|
|
39392
39619
|
import { join as join26, resolve as resolve13 } from "node:path";
|
|
39393
39620
|
function engineContextPath() {
|
|
@@ -39421,7 +39648,7 @@ function runDoctorSingleStore(options = {}, overrides = {}) {
|
|
|
39421
39648
|
try {
|
|
39422
39649
|
const { dbPath: context, dbDir: data } = resolveDatabasePath();
|
|
39423
39650
|
const store = join26(data, "store.db");
|
|
39424
|
-
if (!
|
|
39651
|
+
if (!existsSync35(context) || !existsSync35(store))
|
|
39425
39652
|
return refuse("single_store_missing_database", `Both ${context} and ${store} must exist.`);
|
|
39426
39653
|
const probe = probeHostProcessesUsing({ files: [context, store].flatMap((p) => SUFFIXES2.map((s) => p + s)), directories: [] }, deps.lsofSpawn);
|
|
39427
39654
|
const holders = deps.inspectHolders(data);
|
|
@@ -39436,7 +39663,7 @@ function runDoctorSingleStore(options = {}, overrides = {}) {
|
|
|
39436
39663
|
return refuse("single_store_files_in_use", [...lines, STOP].join(`
|
|
39437
39664
|
`));
|
|
39438
39665
|
}
|
|
39439
|
-
if (!
|
|
39666
|
+
if (!existsSync35(engineContextPath()) || realpathSync7(context) !== realpathSync7(engineContextPath()))
|
|
39440
39667
|
return refuse("single_store_path_mismatch", `CLI ${context}; engine ${engineContextPath()}`);
|
|
39441
39668
|
const backupRoot = resolve13(options.backupRoot ?? join26(data, "backups"));
|
|
39442
39669
|
const contextDb = new Database(context, { readonly: true });
|
|
@@ -39465,10 +39692,10 @@ function runDoctorSingleStore(options = {}, overrides = {}) {
|
|
|
39465
39692
|
}
|
|
39466
39693
|
if (contextVersion > LATEST_SUPPORTED_VERSION || storeVersion !== 60)
|
|
39467
39694
|
return refuse("single_store_version_mismatch", `context.db v${contextVersion}; store.db v${storeVersion}; need context.db v${LATEST_SUPPORTED_VERSION} and store.db v60 (apply current plugin migrations to context.db; upgrade store.db with ck-mc first)`);
|
|
39468
|
-
const backupBytes =
|
|
39469
|
-
const workingBytes = 2 *
|
|
39695
|
+
const backupBytes = statSync18(context).size + statSync18(store).size;
|
|
39696
|
+
const workingBytes = 2 * statSync18(store).size;
|
|
39470
39697
|
const backupVolume = existingDirectoryAncestor(backupRoot);
|
|
39471
|
-
const sameVolume =
|
|
39698
|
+
const sameVolume = statSync18(data).dev === statSync18(backupVolume).dev;
|
|
39472
39699
|
const dataSpace = checkDiskSpace(data, workingBytes + (sameVolume ? backupBytes : 0), deps.freeBytes);
|
|
39473
39700
|
if (!dataSpace.sufficient)
|
|
39474
39701
|
return refuse("single_store_disk_space", `need ${dataSpace.requiredBytes} bytes; have ${dataSpace.availableBytes} bytes on ${data}`);
|
|
@@ -39979,17 +40206,17 @@ var init_storage_identity_merge = __esm(() => {
|
|
|
39979
40206
|
// src/commands/doctor-identity-splits.ts
|
|
39980
40207
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
39981
40208
|
import { createHash as createHash6 } from "node:crypto";
|
|
39982
|
-
import { existsSync as
|
|
39983
|
-
import { dirname as
|
|
40209
|
+
import { existsSync as existsSync36, readdirSync as readdirSync7, realpathSync as realpathSync8, statSync as statSync19 } from "node:fs";
|
|
40210
|
+
import { dirname as dirname21, join as join27, resolve as resolve14 } from "node:path";
|
|
39984
40211
|
function tableExists5(db, table) {
|
|
39985
40212
|
return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table);
|
|
39986
40213
|
}
|
|
39987
40214
|
function hasGitMetadataInAncestors(directory) {
|
|
39988
40215
|
let current = resolve14(directory);
|
|
39989
40216
|
while (true) {
|
|
39990
|
-
if (
|
|
40217
|
+
if (existsSync36(join27(current, ".git")))
|
|
39991
40218
|
return true;
|
|
39992
|
-
const parent =
|
|
40219
|
+
const parent = dirname21(current);
|
|
39993
40220
|
if (parent === current)
|
|
39994
40221
|
return false;
|
|
39995
40222
|
current = parent;
|
|
@@ -39998,7 +40225,7 @@ function hasGitMetadataInAncestors(directory) {
|
|
|
39998
40225
|
function orphanedPathReason(directory) {
|
|
39999
40226
|
let entries;
|
|
40000
40227
|
try {
|
|
40001
|
-
if (!
|
|
40228
|
+
if (!statSync19(directory).isDirectory())
|
|
40002
40229
|
return "path is no longer a directory";
|
|
40003
40230
|
entries = readdirSync7(directory);
|
|
40004
40231
|
} catch (error) {
|
|
@@ -40020,7 +40247,7 @@ function findIdentitySplits(db, host, includeSingles = false) {
|
|
|
40020
40247
|
return cached;
|
|
40021
40248
|
let canonical = directory;
|
|
40022
40249
|
try {
|
|
40023
|
-
canonical =
|
|
40250
|
+
canonical = realpathSync8.native(directory);
|
|
40024
40251
|
} catch {}
|
|
40025
40252
|
canonicalDirectories.set(directory, canonical);
|
|
40026
40253
|
return canonical;
|
|
@@ -40168,8 +40395,8 @@ var init_doctor_identity_splits = __esm(async () => {
|
|
|
40168
40395
|
// src/commands/doctor-merge-identity.ts
|
|
40169
40396
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
40170
40397
|
import { createHash as createHash7 } from "node:crypto";
|
|
40171
|
-
import { existsSync as
|
|
40172
|
-
import { dirname as
|
|
40398
|
+
import { existsSync as existsSync37, mkdtempSync as mkdtempSync2, readdirSync as readdirSync8, readFileSync as readFileSync23, statSync as statSync20 } from "node:fs";
|
|
40399
|
+
import { dirname as dirname22, join as join28, resolve as resolve15 } from "node:path";
|
|
40173
40400
|
function parseMergeIdentityArgs(args) {
|
|
40174
40401
|
const values = {};
|
|
40175
40402
|
const switches = new Set(["--apply", "--force", "--dry-run", "--yes", "--verbose"]);
|
|
@@ -40219,7 +40446,7 @@ function printReport(report) {
|
|
|
40219
40446
|
console.log(" No writes. Review this preview, then repeat with --apply to confirm.");
|
|
40220
40447
|
}
|
|
40221
40448
|
function resolveReadOnly(directory) {
|
|
40222
|
-
if (!
|
|
40449
|
+
if (!existsSync37(directory))
|
|
40223
40450
|
return;
|
|
40224
40451
|
try {
|
|
40225
40452
|
const roots = execFileSync7("git", ["rev-list", "--max-parents=0", "HEAD"], {
|
|
@@ -40253,7 +40480,7 @@ function canonicalIdentity(directory, storageDir) {
|
|
|
40253
40480
|
}
|
|
40254
40481
|
function directoryDoesNotExist(directory) {
|
|
40255
40482
|
try {
|
|
40256
|
-
|
|
40483
|
+
statSync20(directory);
|
|
40257
40484
|
} catch (error) {
|
|
40258
40485
|
return error.code === "ENOENT";
|
|
40259
40486
|
}
|
|
@@ -40376,12 +40603,12 @@ function observations(db, hostPath, storageDir) {
|
|
|
40376
40603
|
row.identities.push({ identity, sessions: 0, memories: 0, notes: 0, dreamer: 0 });
|
|
40377
40604
|
};
|
|
40378
40605
|
const sidecars = join28(storageDir, "project-identities");
|
|
40379
|
-
if (
|
|
40606
|
+
if (existsSync37(sidecars))
|
|
40380
40607
|
for (const file of readdirSync8(sidecars)) {
|
|
40381
40608
|
if (!file.endsWith(".json"))
|
|
40382
40609
|
continue;
|
|
40383
40610
|
try {
|
|
40384
|
-
const record = JSON.parse(
|
|
40611
|
+
const record = JSON.parse(readFileSync23(join28(sidecars, file), "utf8"));
|
|
40385
40612
|
if (typeof record.directory === "string" && typeof record.identity === "string")
|
|
40386
40613
|
add(record.directory, record.identity);
|
|
40387
40614
|
} catch {}
|
|
@@ -40393,7 +40620,7 @@ function observations(db, hostPath, storageDir) {
|
|
|
40393
40620
|
function runMergeIdentityCli(args, deps = {}) {
|
|
40394
40621
|
const options = parseMergeIdentityArgs(args);
|
|
40395
40622
|
const dbPath = options.dbPath ?? join28(getMagicContextStorageDir(), "context.db");
|
|
40396
|
-
const storageDir =
|
|
40623
|
+
const storageDir = dirname22(dbPath);
|
|
40397
40624
|
const hostPath = options.hostPath ?? (options.dbPath ? join28(storageDir, "host.db") : resolveOpenCodeDbPath().path);
|
|
40398
40625
|
let db = openExistingContextDatabase(dbPath, {
|
|
40399
40626
|
readonly: true,
|
|
@@ -40448,8 +40675,8 @@ function runMergeIdentityCli(args, deps = {}) {
|
|
|
40448
40675
|
const backupRoot = resolve15(options.backupRoot ?? storageDir);
|
|
40449
40676
|
const backupVolume = existingDirectoryAncestor(backupRoot);
|
|
40450
40677
|
const sidecarRoot = join28(storageDir, "project-identities");
|
|
40451
|
-
const sidecarEntries =
|
|
40452
|
-
const sidecarBytes = sidecarEntries.reduce((size, entry) => size +
|
|
40678
|
+
const sidecarEntries = existsSync37(sidecarRoot) ? readdirSync8(sidecarRoot).filter((entry) => entry.endsWith(".json")) : [];
|
|
40679
|
+
const sidecarBytes = sidecarEntries.reduce((size, entry) => size + statSync20(join28(sidecarRoot, entry)).size, 0);
|
|
40453
40680
|
const diskSpace = checkDiskSpace(backupVolume, databaseBundleSizeBytes(dbPath) + sidecarBytes, deps.freeBytes ?? availableDiskBytes);
|
|
40454
40681
|
if (!diskSpace.sufficient)
|
|
40455
40682
|
throw new Error(`merge_identity_disk_space: refusing identity merge: backup needs ${diskSpace.requiredBytes} bytes; have ${diskSpace.availableBytes} bytes on ${backupVolume}. Use --backup-root <dir> to choose a volume with enough free space.`);
|
|
@@ -40462,13 +40689,13 @@ function runMergeIdentityCli(args, deps = {}) {
|
|
|
40462
40689
|
ensureStorageDirectorySync(sidecarBackup, true);
|
|
40463
40690
|
let backupBytes = 0;
|
|
40464
40691
|
for (const entry of sidecarEntries) {
|
|
40465
|
-
const content =
|
|
40692
|
+
const content = readFileSync23(join28(sidecarRoot, entry));
|
|
40466
40693
|
writeStorageFileAtomicSync(join28(sidecarBackup, entry), content, true);
|
|
40467
40694
|
backupBytes += content.byteLength;
|
|
40468
40695
|
}
|
|
40469
40696
|
console.log(`Restore identity sidecars too: rm -rf ${quote(sidecarRoot)}; cp -R ${quote(sidecarBackup)} ${quote(sidecarRoot)}`);
|
|
40470
40697
|
const copiedDatabaseFiles = copyDatabaseBundle(dbPath, join28(backup, "context.db"), true);
|
|
40471
|
-
backupBytes += copiedDatabaseFiles.reduce((size, path) => size +
|
|
40698
|
+
backupBytes += copiedDatabaseFiles.reduce((size, path) => size + statSync20(path).size, 0);
|
|
40472
40699
|
db = openExistingDatabase(dbPath, { readonly: false });
|
|
40473
40700
|
if (!db)
|
|
40474
40701
|
throw new Error(`Context database disappeared: ${dbPath}`);
|
|
@@ -40512,7 +40739,7 @@ var init_doctor_merge_identity = __esm(async () => {
|
|
|
40512
40739
|
});
|
|
40513
40740
|
|
|
40514
40741
|
// src/commands/doctor-git-fts-map.ts
|
|
40515
|
-
import { existsSync as
|
|
40742
|
+
import { existsSync as existsSync38, mkdtempSync as mkdtempSync3, statSync as statSync21 } from "node:fs";
|
|
40516
40743
|
import { join as join29, resolve as resolve16 } from "node:path";
|
|
40517
40744
|
function inspectGitFtsMap(db) {
|
|
40518
40745
|
const has = (name) => Boolean(db.prepare("SELECT 1 FROM sqlite_master WHERE name=? AND type='table'").get(name));
|
|
@@ -40589,9 +40816,9 @@ function runDoctorGitFtsMap(options = {}, overrides = {}) {
|
|
|
40589
40816
|
deps.print(`Stop every host, then run \`${GIT_FTS_MAP_REPAIR_COMMAND}\`. The repair backs up context.db and store.db first.`);
|
|
40590
40817
|
return damaged ? 1 : 0;
|
|
40591
40818
|
}
|
|
40592
|
-
if (!
|
|
40819
|
+
if (!existsSync38(context) || !existsSync38(store))
|
|
40593
40820
|
throw new Error("Both context.db and store.db must exist before paired-backup repair; no replacement store will be created");
|
|
40594
|
-
const cstat =
|
|
40821
|
+
const cstat = statSync21(context), sstat = statSync21(store);
|
|
40595
40822
|
if (cstat.dev === sstat.dev && cstat.ino === sstat.ino)
|
|
40596
40823
|
throw new Error("context.db and store.db must be distinct files");
|
|
40597
40824
|
const holders = deps.inspectHolders(deps.storageDir);
|
|
@@ -40792,8 +41019,8 @@ var SINGLE_STORE_REQUIRED = "Magic Context's Rust mode needs a one-time migratio
|
|
|
40792
41019
|
|
|
40793
41020
|
// src/commands/migrate.ts
|
|
40794
41021
|
import { createHash as createHash8, randomBytes as randomBytes3 } from "node:crypto";
|
|
40795
|
-
import { existsSync as
|
|
40796
|
-
import { dirname as
|
|
41022
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync7, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "node:fs";
|
|
41023
|
+
import { dirname as dirname23, join as join30 } from "node:path";
|
|
40797
41024
|
function defaultOpenCodeDbPath() {
|
|
40798
41025
|
return getOpenCodeDatabasePath();
|
|
40799
41026
|
}
|
|
@@ -40804,7 +41031,7 @@ function defaultPiSessionsRoot() {
|
|
|
40804
41031
|
return getPiSessionsRoot();
|
|
40805
41032
|
}
|
|
40806
41033
|
function defaultFs() {
|
|
40807
|
-
return { writeFileAtomic, unlinkSync: unlinkSync4, existsSync:
|
|
41034
|
+
return { writeFileAtomic, unlinkSync: unlinkSync4, existsSync: existsSync39, renameSync: renameSync7, mkdirSync: mkdirSync7 };
|
|
40808
41035
|
}
|
|
40809
41036
|
function stmt(db, sql) {
|
|
40810
41037
|
return db.prepare(sql);
|
|
@@ -40858,7 +41085,7 @@ function sweepPendingMigrations(db, fs = defaultFs()) {
|
|
|
40858
41085
|
}
|
|
40859
41086
|
if (row.phase === "db_committed") {
|
|
40860
41087
|
if (fs.existsSync(row.stage_path)) {
|
|
40861
|
-
fs.mkdirSync(
|
|
41088
|
+
fs.mkdirSync(dirname23(row.final_path), { recursive: true });
|
|
40862
41089
|
fs.renameSync(row.stage_path, row.final_path);
|
|
40863
41090
|
stmt(db, "DELETE FROM migration_pending WHERE migration_key = ?").run(row.migration_key);
|
|
40864
41091
|
report.rolledForward += 1;
|
|
@@ -41424,7 +41651,7 @@ function migrateOpenCodeSessionToPi(opts) {
|
|
|
41424
41651
|
sourceSessionId: session.id,
|
|
41425
41652
|
targetHarness,
|
|
41426
41653
|
finalPathFor: (id) => join30(outputDir, `${formatPiFilenameTimestamp(now)}_${id}.jsonl`),
|
|
41427
|
-
stageDir: join30(
|
|
41654
|
+
stageDir: join30(dirname23(piSessionsRoot), MIGRATION_STAGE_DIRNAME),
|
|
41428
41655
|
now: now.getTime()
|
|
41429
41656
|
});
|
|
41430
41657
|
piSessionId = claimed.row.pi_session_id;
|
|
@@ -41476,7 +41703,7 @@ function migrateOpenCodeSessionToPi(opts) {
|
|
|
41476
41703
|
commitStagedChecksum(cortexkitDb, migrationKey, contentSha256);
|
|
41477
41704
|
fs.writeFileAtomic(stagePath, jsonl);
|
|
41478
41705
|
plan.commit(migrationKey);
|
|
41479
|
-
fs.mkdirSync(
|
|
41706
|
+
fs.mkdirSync(dirname23(finalPath), { recursive: true });
|
|
41480
41707
|
fs.renameSync(stagePath, finalPath);
|
|
41481
41708
|
stmt(cortexkitDb, "DELETE FROM migration_pending WHERE migration_key = ?").run(migrationKey);
|
|
41482
41709
|
} else {
|
|
@@ -43151,15 +43378,15 @@ class SubcClient {
|
|
|
43151
43378
|
}
|
|
43152
43379
|
}
|
|
43153
43380
|
notSentCallError(message, cause) {
|
|
43154
|
-
return new SubcCallError("not_sent", `${message}${causeMessage(cause)}`,
|
|
43381
|
+
return new SubcCallError("not_sent", `${message}${causeMessage(cause)}`, errorCode2(cause), cause);
|
|
43155
43382
|
}
|
|
43156
43383
|
outcomeUnknownCallError(message, cause) {
|
|
43157
|
-
return new SubcCallError("outcome_unknown", `${message}${causeMessage(cause)}`,
|
|
43384
|
+
return new SubcCallError("outcome_unknown", `${message}${causeMessage(cause)}`, errorCode2(cause), cause);
|
|
43158
43385
|
}
|
|
43159
43386
|
terminalCallError(message, cause) {
|
|
43160
43387
|
if (cause instanceof SubcCallError)
|
|
43161
43388
|
return cause;
|
|
43162
|
-
return new SubcCallError("terminal", `${message}${causeMessage(cause)}`,
|
|
43389
|
+
return new SubcCallError("terminal", `${message}${causeMessage(cause)}`, errorCode2(cause), cause);
|
|
43163
43390
|
}
|
|
43164
43391
|
notSentRecoveryError(message, cause) {
|
|
43165
43392
|
if (cause instanceof SubcCallError)
|
|
@@ -43228,7 +43455,7 @@ function isConsumerReconnectTransient(err) {
|
|
|
43228
43455
|
return true;
|
|
43229
43456
|
if (err instanceof SubcError || err instanceof ConnectionFileError)
|
|
43230
43457
|
return false;
|
|
43231
|
-
const code =
|
|
43458
|
+
const code = errorCode2(err);
|
|
43232
43459
|
return code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "ETIMEDOUT" || code === "ENOENT";
|
|
43233
43460
|
}
|
|
43234
43461
|
function isRouteOpenRefusal(err) {
|
|
@@ -43293,7 +43520,7 @@ function routeOpenConsumerIdentity(opts = {}) {
|
|
|
43293
43520
|
return;
|
|
43294
43521
|
return { module_id: moduleId, launch_nonce: launchNonce };
|
|
43295
43522
|
}
|
|
43296
|
-
function
|
|
43523
|
+
function errorCode2(err) {
|
|
43297
43524
|
if (typeof err === "object" && err !== null && "code" in err) {
|
|
43298
43525
|
const code = err.code;
|
|
43299
43526
|
if (typeof code === "string")
|
|
@@ -43781,7 +44008,7 @@ var init_store_ahead_refusal = __esm(() => {
|
|
|
43781
44008
|
});
|
|
43782
44009
|
|
|
43783
44010
|
// ../plugin/src/hooks/magic-context/module-transport.ts
|
|
43784
|
-
import { realpathSync as
|
|
44011
|
+
import { realpathSync as realpathSync9 } from "node:fs";
|
|
43785
44012
|
import { join as join31 } from "node:path";
|
|
43786
44013
|
function monotonicNow() {
|
|
43787
44014
|
return monotonicClockForTests?.() ?? performance.now();
|
|
@@ -44283,7 +44510,7 @@ class SubcModuleTransport {
|
|
|
44283
44510
|
}
|
|
44284
44511
|
let resolved = root;
|
|
44285
44512
|
try {
|
|
44286
|
-
resolved =
|
|
44513
|
+
resolved = realpathSync9.native(root);
|
|
44287
44514
|
} catch {}
|
|
44288
44515
|
this.canonicalRootCache.set(root, resolved);
|
|
44289
44516
|
while (this.canonicalRootCache.size > CANONICAL_ROOT_CACHE_MAX_ENTRIES) {
|
|
@@ -44396,9 +44623,9 @@ var init_module_transport = __esm(async () => {
|
|
|
44396
44623
|
});
|
|
44397
44624
|
|
|
44398
44625
|
// src/commands/migrate-session.ts
|
|
44399
|
-
import { existsSync as
|
|
44626
|
+
import { existsSync as existsSync40, realpathSync as realpathSync10 } from "node:fs";
|
|
44400
44627
|
import { homedir as homedir20 } from "node:os";
|
|
44401
|
-
import
|
|
44628
|
+
import path7, { join as join32 } from "node:path";
|
|
44402
44629
|
function existingSessionColumns(db) {
|
|
44403
44630
|
const rows = db.prepare("PRAGMA table_info(session)").all();
|
|
44404
44631
|
return new Set(rows.map((r) => r.name).filter((n) => typeof n === "string"));
|
|
@@ -44453,7 +44680,7 @@ function planMigrateSession(sessionId, rawTargetDirectory, deps) {
|
|
|
44453
44680
|
ocProjectId = "global";
|
|
44454
44681
|
ocWorktree = globalRow.worktree || "/";
|
|
44455
44682
|
}
|
|
44456
|
-
const sessionPath =
|
|
44683
|
+
const sessionPath = path7.relative(ocWorktree, targetDirectory);
|
|
44457
44684
|
const ownershipRow = deps.contextDb.prepare("SELECT project_path FROM session_projects WHERE session_id = ? AND harness = 'opencode'").get(sessionId);
|
|
44458
44685
|
const fromMcIdentity = ownershipRow?.project_path ?? (sessionRow.directory ? deps.resolveIdentity(sessionRow.directory) : "");
|
|
44459
44686
|
const toMcIdentity = deps.resolveIdentity(targetDirectory);
|
|
@@ -44586,8 +44813,8 @@ function realDeps(opencodeDb, contextDb) {
|
|
|
44586
44813
|
opencodeDb,
|
|
44587
44814
|
contextDb,
|
|
44588
44815
|
resolveIdentity: resolveProjectIdentity,
|
|
44589
|
-
hasGitDir: (dir) =>
|
|
44590
|
-
realpath: (p) =>
|
|
44816
|
+
hasGitDir: (dir) => existsSync40(join32(dir, ".git")),
|
|
44817
|
+
realpath: (p) => realpathSync10(p)
|
|
44591
44818
|
};
|
|
44592
44819
|
}
|
|
44593
44820
|
function valueAfter(args, flag) {
|
|
@@ -44665,7 +44892,7 @@ async function runMigrateSessionCli(args) {
|
|
|
44665
44892
|
return 1;
|
|
44666
44893
|
}
|
|
44667
44894
|
const expandedTo = toDir.startsWith("~") ? join32(homedir20(), toDir.slice(1).replace(/^[/\\]/, "")) : toDir;
|
|
44668
|
-
if (!
|
|
44895
|
+
if (!existsSync40(expandedTo)) {
|
|
44669
44896
|
console.error(`Target directory does not exist: ${expandedTo}`);
|
|
44670
44897
|
return 1;
|
|
44671
44898
|
}
|
|
@@ -44819,8 +45046,8 @@ var init_migrate_session = __esm(async () => {
|
|
|
44819
45046
|
|
|
44820
45047
|
// ../plugin/src/features/magic-context/v22-deferred-backfill.ts
|
|
44821
45048
|
import { createHash as createHash10 } from "node:crypto";
|
|
44822
|
-
import { realpathSync as
|
|
44823
|
-
import
|
|
45049
|
+
import { realpathSync as realpathSync11 } from "node:fs";
|
|
45050
|
+
import path8 from "node:path";
|
|
44824
45051
|
function readMeta(db, key) {
|
|
44825
45052
|
const row = db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(key);
|
|
44826
45053
|
return row?.value ?? null;
|
|
@@ -44863,9 +45090,9 @@ function resolveBackfillIdentity(rawProjectPath) {
|
|
|
44863
45090
|
function computeLegacyRustDirIdentity(rawProjectPath) {
|
|
44864
45091
|
let canonical;
|
|
44865
45092
|
try {
|
|
44866
|
-
canonical =
|
|
45093
|
+
canonical = realpathSync11(rawProjectPath);
|
|
44867
45094
|
} catch {
|
|
44868
|
-
canonical =
|
|
45095
|
+
canonical = path8.isAbsolute(rawProjectPath) ? rawProjectPath : path8.join(process.cwd(), rawProjectPath);
|
|
44869
45096
|
}
|
|
44870
45097
|
return `dir:${createHash10("sha256").update(canonical, "utf8").digest("hex")}`;
|
|
44871
45098
|
}
|
|
@@ -45088,7 +45315,7 @@ var init_tick_failure = __esm(() => {
|
|
|
45088
45315
|
});
|
|
45089
45316
|
|
|
45090
45317
|
// ../pi-plugin/src/config/index.ts
|
|
45091
|
-
import { existsSync as
|
|
45318
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
45092
45319
|
function getProjectConfigPaths(cwd) {
|
|
45093
45320
|
const basePath = cortexKitProjectConfigBasePath(cwd);
|
|
45094
45321
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
@@ -45098,10 +45325,10 @@ function getUserConfigPaths() {
|
|
|
45098
45325
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
45099
45326
|
}
|
|
45100
45327
|
function resolveFirstExisting(paths) {
|
|
45101
|
-
return paths.find((path) =>
|
|
45328
|
+
return paths.find((path) => existsSync41(path));
|
|
45102
45329
|
}
|
|
45103
45330
|
function resolvePiLegacyFallback(sources) {
|
|
45104
|
-
return sources.find((source) =>
|
|
45331
|
+
return sources.find((source) => existsSync41(source.path)) ?? null;
|
|
45105
45332
|
}
|
|
45106
45333
|
function loadConfigFile(path, scope) {
|
|
45107
45334
|
let raw;
|
|
@@ -45412,7 +45639,7 @@ function loadPiConfigDetailed(opts = {}, applyRuntimeGlobals = true) {
|
|
|
45412
45639
|
if (loaded)
|
|
45413
45640
|
loadedFiles.push(loaded);
|
|
45414
45641
|
}
|
|
45415
|
-
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) =>
|
|
45642
|
+
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync41(source.path));
|
|
45416
45643
|
const userPath = resolveFirstExisting(getUserConfigPaths());
|
|
45417
45644
|
const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
|
|
45418
45645
|
const userReadPath = userPath ?? userLegacyFallback?.path;
|
|
@@ -45421,7 +45648,7 @@ function loadPiConfigDetailed(opts = {}, applyRuntimeGlobals = true) {
|
|
|
45421
45648
|
if (loaded)
|
|
45422
45649
|
loadedFiles.push(loaded);
|
|
45423
45650
|
}
|
|
45424
|
-
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) =>
|
|
45651
|
+
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync41(source.path));
|
|
45425
45652
|
if (userLegacyFallback) {
|
|
45426
45653
|
warnings.push(`[user config] reading legacy config from ${userLegacyFallback.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
|
|
45427
45654
|
} else if (legacyUserUnmigrated) {
|
|
@@ -45559,7 +45786,7 @@ var DATABASE_REPAIR_COMMAND = "bunx @cortexkit/magic-context@latest doctor repai
|
|
|
45559
45786
|
|
|
45560
45787
|
// src/lib/github-issue.ts
|
|
45561
45788
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
45562
|
-
import { readFileSync as
|
|
45789
|
+
import { readFileSync as readFileSync24 } from "node:fs";
|
|
45563
45790
|
function runGhCommand(args) {
|
|
45564
45791
|
try {
|
|
45565
45792
|
const result = spawnSync7("gh", args, {
|
|
@@ -45586,7 +45813,7 @@ function failed(result) {
|
|
|
45586
45813
|
function submitGithubIssue(title, bodyPath, runner = runGhCommand) {
|
|
45587
45814
|
let body;
|
|
45588
45815
|
try {
|
|
45589
|
-
body =
|
|
45816
|
+
body = readFileSync24(bodyPath, "utf-8");
|
|
45590
45817
|
} catch (error) {
|
|
45591
45818
|
return {
|
|
45592
45819
|
ok: false,
|
|
@@ -45644,7 +45871,7 @@ var MAX_GITHUB_ISSUE_BODY_CHARS = 65536;
|
|
|
45644
45871
|
var init_github_issue = () => {};
|
|
45645
45872
|
|
|
45646
45873
|
// src/lib/log-lines.ts
|
|
45647
|
-
import { existsSync as
|
|
45874
|
+
import { existsSync as existsSync42, readFileSync as readFileSync25, statSync as statSync22 } from "node:fs";
|
|
45648
45875
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
45649
45876
|
import { join as join33 } from "node:path";
|
|
45650
45877
|
function tokenize(input, limit = Number.POSITIVE_INFINITY) {
|
|
@@ -45941,11 +46168,11 @@ function getMagicContextLogPaths(harness, options = {}) {
|
|
|
45941
46168
|
].filter((path, index, paths) => paths.indexOf(path) === index);
|
|
45942
46169
|
}
|
|
45943
46170
|
function inspectLogFile(path) {
|
|
45944
|
-
if (!
|
|
46171
|
+
if (!existsSync42(path)) {
|
|
45945
46172
|
return { path, exists: false, sizeKb: 0, lineCount: 0, grammar: "unknown" };
|
|
45946
46173
|
}
|
|
45947
46174
|
try {
|
|
45948
|
-
const content =
|
|
46175
|
+
const content = readFileSync25(path, "utf8");
|
|
45949
46176
|
const lines = content.split(/\r?\n/).filter((line) => line.length > 0);
|
|
45950
46177
|
const grammars = new Set(lines.flatMap((line) => {
|
|
45951
46178
|
const parsed = parseLogLine(line);
|
|
@@ -45955,7 +46182,7 @@ function inspectLogFile(path) {
|
|
|
45955
46182
|
return {
|
|
45956
46183
|
path,
|
|
45957
46184
|
exists: true,
|
|
45958
|
-
sizeKb: Math.round(
|
|
46185
|
+
sizeKb: Math.round(statSync22(path).size / 1024),
|
|
45959
46186
|
lineCount: lines.length,
|
|
45960
46187
|
grammar
|
|
45961
46188
|
};
|
|
@@ -45972,7 +46199,7 @@ function readLogLines(files) {
|
|
|
45972
46199
|
return [];
|
|
45973
46200
|
try {
|
|
45974
46201
|
let precedingTimestamp = "";
|
|
45975
|
-
return
|
|
46202
|
+
return readFileSync25(file.path, "utf8").split(/\r?\n/).filter((line) => line.length > 0).map((line, lineIndex) => {
|
|
45976
46203
|
precedingTimestamp = parseLogLine(line)?.ts ?? precedingTimestamp;
|
|
45977
46204
|
return { line, timestamp: precedingTimestamp, fileIndex, lineIndex };
|
|
45978
46205
|
});
|
|
@@ -46137,6 +46364,7 @@ class IssuePrivacy {
|
|
|
46137
46364
|
"plugin",
|
|
46138
46365
|
"manifest",
|
|
46139
46366
|
"Shared storage",
|
|
46367
|
+
"Magic Context storage",
|
|
46140
46368
|
"context DB",
|
|
46141
46369
|
"SQLite integrity_check",
|
|
46142
46370
|
"Background maintenance",
|
|
@@ -46478,11 +46706,235 @@ var init_issue_body = __esm(() => {
|
|
|
46478
46706
|
];
|
|
46479
46707
|
});
|
|
46480
46708
|
|
|
46709
|
+
// src/lib/omp-hide-secrets.ts
|
|
46710
|
+
import { existsSync as existsSync43, readdirSync as readdirSync9, readFileSync as readFileSync26, statSync as statSync23 } from "node:fs";
|
|
46711
|
+
import { join as join34, resolve as resolve17 } from "node:path";
|
|
46712
|
+
function stripYamlComment(line) {
|
|
46713
|
+
let quote = null;
|
|
46714
|
+
for (let index = 0;index < line.length; index += 1) {
|
|
46715
|
+
const char = line[index];
|
|
46716
|
+
if (quote) {
|
|
46717
|
+
if (char === quote)
|
|
46718
|
+
quote = null;
|
|
46719
|
+
} else if (char === '"' || char === "'") {
|
|
46720
|
+
quote = char;
|
|
46721
|
+
} else if (char === "#" && (index === 0 || /\s/.test(line[index - 1] ?? ""))) {
|
|
46722
|
+
return line.slice(0, index).trimEnd();
|
|
46723
|
+
}
|
|
46724
|
+
}
|
|
46725
|
+
return line.trimEnd();
|
|
46726
|
+
}
|
|
46727
|
+
function indentOf(line) {
|
|
46728
|
+
return line.length - line.trimStart().length;
|
|
46729
|
+
}
|
|
46730
|
+
function yamlBoolean(raw) {
|
|
46731
|
+
const value = raw.trim();
|
|
46732
|
+
if (value === "true" || value === "True" || value === "TRUE")
|
|
46733
|
+
return { kind: "on" };
|
|
46734
|
+
if (value === "false" || value === "False" || value === "FALSE")
|
|
46735
|
+
return { kind: "off" };
|
|
46736
|
+
if (value === "" || value === "~" || value === "null" || value === "Null" || value === "NULL")
|
|
46737
|
+
return { kind: "absent" };
|
|
46738
|
+
return UNRECOGNIZED;
|
|
46739
|
+
}
|
|
46740
|
+
function keyPattern(key) {
|
|
46741
|
+
return new RegExp(`^(?:${key}|"${key}"|'${key}')\\s*:(?:\\s+(.*))?$`);
|
|
46742
|
+
}
|
|
46743
|
+
function flowMapEnabled(flow) {
|
|
46744
|
+
if (!flow.endsWith("}"))
|
|
46745
|
+
return UNRECOGNIZED;
|
|
46746
|
+
const body = flow.slice(1, -1);
|
|
46747
|
+
if (/[{}[\]&*!]/.test(body))
|
|
46748
|
+
return UNRECOGNIZED;
|
|
46749
|
+
const matches = body.split(",").map((entry) => entry.trim().match(/^(?:enabled|"enabled"|'enabled')\s*:\s*(.*)$/)).filter((match) => match !== null);
|
|
46750
|
+
if (matches.length > 1)
|
|
46751
|
+
return UNRECOGNIZED;
|
|
46752
|
+
return matches.length === 0 ? { kind: "absent" } : yamlBoolean(matches[0]?.[1] ?? "");
|
|
46753
|
+
}
|
|
46754
|
+
function readHideSecretsFromYaml(text) {
|
|
46755
|
+
const lines = text.replace(/^\uFEFF/, "").split(/\r?\n/).map(stripYamlComment);
|
|
46756
|
+
const content = lines.filter((line) => line.trim() !== "");
|
|
46757
|
+
const first = content[0]?.trim();
|
|
46758
|
+
if (first?.startsWith("{") || first?.startsWith("["))
|
|
46759
|
+
return UNRECOGNIZED;
|
|
46760
|
+
if (content.some((line) => /^\s*\t/.test(line)))
|
|
46761
|
+
return UNRECOGNIZED;
|
|
46762
|
+
const starts = lines.flatMap((line, index) => indentOf(line) === 0 && SECRETS_KEY.test(line) ? [index] : []);
|
|
46763
|
+
if (starts.length === 0)
|
|
46764
|
+
return { kind: "absent" };
|
|
46765
|
+
if (starts.length > 1)
|
|
46766
|
+
return UNRECOGNIZED;
|
|
46767
|
+
const start = starts[0];
|
|
46768
|
+
const inline = (lines[start]?.match(SECRETS_KEY)?.[1] ?? "").trim();
|
|
46769
|
+
if (inline.startsWith("{"))
|
|
46770
|
+
return flowMapEnabled(inline);
|
|
46771
|
+
if (inline === "~" || inline === "null" || inline === "Null" || inline === "NULL")
|
|
46772
|
+
return { kind: "absent" };
|
|
46773
|
+
if (inline !== "")
|
|
46774
|
+
return UNRECOGNIZED;
|
|
46775
|
+
const children = [];
|
|
46776
|
+
for (const line of lines.slice(start + 1)) {
|
|
46777
|
+
if (line.trim() === "")
|
|
46778
|
+
continue;
|
|
46779
|
+
if (indentOf(line) === 0)
|
|
46780
|
+
break;
|
|
46781
|
+
children.push(line);
|
|
46782
|
+
}
|
|
46783
|
+
if (children.length === 0)
|
|
46784
|
+
return { kind: "absent" };
|
|
46785
|
+
const childIndent = indentOf(children[0]);
|
|
46786
|
+
if (children[0]?.trimStart().startsWith("-"))
|
|
46787
|
+
return UNRECOGNIZED;
|
|
46788
|
+
let found = null;
|
|
46789
|
+
for (let index = 0;index < children.length; index += 1) {
|
|
46790
|
+
const line = children[index];
|
|
46791
|
+
const indent = indentOf(line);
|
|
46792
|
+
if (indent < childIndent)
|
|
46793
|
+
return UNRECOGNIZED;
|
|
46794
|
+
if (indent > childIndent)
|
|
46795
|
+
continue;
|
|
46796
|
+
const match = line.trim().match(ENABLED_KEY);
|
|
46797
|
+
if (!match)
|
|
46798
|
+
continue;
|
|
46799
|
+
if (found)
|
|
46800
|
+
return UNRECOGNIZED;
|
|
46801
|
+
const nextIndent = children[index + 1] ? indentOf(children[index + 1]) : 0;
|
|
46802
|
+
if ((match[1] ?? "").trim() === "" && nextIndent > childIndent)
|
|
46803
|
+
return UNRECOGNIZED;
|
|
46804
|
+
found = yamlBoolean(match[1] ?? "");
|
|
46805
|
+
}
|
|
46806
|
+
return found ?? { kind: "absent" };
|
|
46807
|
+
}
|
|
46808
|
+
function readHideSecretsFromJson(text) {
|
|
46809
|
+
let parsed;
|
|
46810
|
+
try {
|
|
46811
|
+
parsed = JSON.parse(text);
|
|
46812
|
+
} catch {
|
|
46813
|
+
return { kind: "unreadable", reason: "file is not valid JSON" };
|
|
46814
|
+
}
|
|
46815
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
46816
|
+
return { kind: "absent" };
|
|
46817
|
+
const secrets = parsed.secrets;
|
|
46818
|
+
if (secrets === undefined || secrets === null)
|
|
46819
|
+
return { kind: "absent" };
|
|
46820
|
+
if (typeof secrets !== "object" || Array.isArray(secrets))
|
|
46821
|
+
return UNRECOGNIZED;
|
|
46822
|
+
const enabled = secrets.enabled;
|
|
46823
|
+
if (enabled === true)
|
|
46824
|
+
return { kind: "on" };
|
|
46825
|
+
if (enabled === false)
|
|
46826
|
+
return { kind: "off" };
|
|
46827
|
+
if (enabled === undefined || enabled === null)
|
|
46828
|
+
return { kind: "absent" };
|
|
46829
|
+
return UNRECOGNIZED;
|
|
46830
|
+
}
|
|
46831
|
+
function readSource(layer, path, format) {
|
|
46832
|
+
let text;
|
|
46833
|
+
try {
|
|
46834
|
+
text = readFileSync26(path, "utf-8");
|
|
46835
|
+
} catch (error) {
|
|
46836
|
+
const code = error.code;
|
|
46837
|
+
return {
|
|
46838
|
+
layer,
|
|
46839
|
+
path,
|
|
46840
|
+
value: {
|
|
46841
|
+
kind: "unreadable",
|
|
46842
|
+
reason: `file could not be read${code ? ` (${code})` : ""}`
|
|
46843
|
+
}
|
|
46844
|
+
};
|
|
46845
|
+
}
|
|
46846
|
+
return {
|
|
46847
|
+
layer,
|
|
46848
|
+
path,
|
|
46849
|
+
value: format === "json" ? readHideSecretsFromJson(text) : readHideSecretsFromYaml(text)
|
|
46850
|
+
};
|
|
46851
|
+
}
|
|
46852
|
+
function isNonEmptyDirectory(path) {
|
|
46853
|
+
try {
|
|
46854
|
+
return statSync23(path).isDirectory() && readdirSync9(path).length > 0;
|
|
46855
|
+
} catch {
|
|
46856
|
+
return false;
|
|
46857
|
+
}
|
|
46858
|
+
}
|
|
46859
|
+
function collectHideSecretsSources(cwd, home = envFirstHomeDir()) {
|
|
46860
|
+
const sources = [];
|
|
46861
|
+
const agentDir = getOmpAgentDir();
|
|
46862
|
+
const mainConfig = ["config.yml", "config.yaml"].map((name) => join34(agentDir, name)).find((path) => existsSync43(path));
|
|
46863
|
+
if (mainConfig)
|
|
46864
|
+
sources.push(readSource("user", mainConfig, "yaml"));
|
|
46865
|
+
const projectDir = join34(cwd, ".omp");
|
|
46866
|
+
if (resolve17(cwd) !== resolve17(home) && isNonEmptyDirectory(projectDir)) {
|
|
46867
|
+
for (const [name, format] of [
|
|
46868
|
+
["settings.json", "json"],
|
|
46869
|
+
["config.yml", "yaml"]
|
|
46870
|
+
]) {
|
|
46871
|
+
const path = join34(projectDir, name);
|
|
46872
|
+
if (existsSync43(path))
|
|
46873
|
+
sources.push(readSource("project", path, format));
|
|
46874
|
+
}
|
|
46875
|
+
}
|
|
46876
|
+
for (const path of getOmpConfigOverlayPaths(cwd)) {
|
|
46877
|
+
if (existsSync43(path))
|
|
46878
|
+
sources.push(readSource("overlay", path, "yaml"));
|
|
46879
|
+
}
|
|
46880
|
+
return sources;
|
|
46881
|
+
}
|
|
46882
|
+
function checkOmpHideSecrets(sources) {
|
|
46883
|
+
let effective = null;
|
|
46884
|
+
let effectiveIndex = -1;
|
|
46885
|
+
for (const [index, source] of sources.entries()) {
|
|
46886
|
+
if (source.value.kind === "on" || source.value.kind === "off") {
|
|
46887
|
+
effective = source;
|
|
46888
|
+
effectiveIndex = index;
|
|
46889
|
+
}
|
|
46890
|
+
}
|
|
46891
|
+
if (effective?.value.kind === "on") {
|
|
46892
|
+
const explain = `OMP masks secrets after Magic Context prepares a turn, so some turns are refused; turn it off for Magic Context sessions, see ${OMP_HIDE_SECRETS_DOCS_URL} (${UNDETECTABLE})`;
|
|
46893
|
+
const label = LAYER_LABEL[effective.layer];
|
|
46894
|
+
return [
|
|
46895
|
+
{
|
|
46896
|
+
status: "warn",
|
|
46897
|
+
message: `${SETTING} is on in ${label} (${effective.path}): ${explain}`,
|
|
46898
|
+
issueMessage: `${SETTING} is on in ${label}: ${explain}`
|
|
46899
|
+
}
|
|
46900
|
+
];
|
|
46901
|
+
}
|
|
46902
|
+
const unreadable = sources.flatMap((source, index) => index > effectiveIndex && source.value.kind === "unreadable" ? [{ source, reason: source.value.reason }] : []);
|
|
46903
|
+
if (unreadable.length > 0) {
|
|
46904
|
+
return unreadable.map(({ source, reason }) => {
|
|
46905
|
+
const tail = `${reason}; if Hide Secrets is on, see ${OMP_HIDE_SECRETS_DOCS_URL} (${UNDETECTABLE})`;
|
|
46906
|
+
const label = LAYER_LABEL[source.layer];
|
|
46907
|
+
return {
|
|
46908
|
+
status: "warn",
|
|
46909
|
+
message: `Could not check ${SETTING} in ${label} (${source.path}): ${tail}`,
|
|
46910
|
+
issueMessage: `Could not check ${SETTING} in ${label}: ${tail}`
|
|
46911
|
+
};
|
|
46912
|
+
});
|
|
46913
|
+
}
|
|
46914
|
+
const message = effective?.value.kind === "off" ? `${SETTING} is off in OMP settings files (${UNDETECTABLE})` : `${SETTING} is not set in OMP settings files; OMP's default is off (${UNDETECTABLE})`;
|
|
46915
|
+
return [{ status: "pass", message, issueMessage: message }];
|
|
46916
|
+
}
|
|
46917
|
+
var OMP_HIDE_SECRETS_DOCS_URL = "https://docs.cortexkit.io/magic-context/help/compatibility/#omp-hide-secrets", LAYER_LABEL, UNDETECTABLE = "CLI flags and live settings toggles can't be detected", SETTING = "OMP Hide Secrets (secrets.enabled)", UNRECOGNIZED, SECRETS_KEY, ENABLED_KEY;
|
|
46918
|
+
var init_omp_hide_secrets = __esm(() => {
|
|
46919
|
+
init_paths();
|
|
46920
|
+
LAYER_LABEL = {
|
|
46921
|
+
user: "OMP user settings",
|
|
46922
|
+
project: "OMP project settings",
|
|
46923
|
+
overlay: "an OMP config overlay (PI_CONFIG_FILES)"
|
|
46924
|
+
};
|
|
46925
|
+
UNRECOGNIZED = {
|
|
46926
|
+
kind: "unreadable",
|
|
46927
|
+
reason: "secrets.enabled could not be interpreted"
|
|
46928
|
+
};
|
|
46929
|
+
SECRETS_KEY = keyPattern("secrets");
|
|
46930
|
+
ENABLED_KEY = keyPattern("enabled");
|
|
46931
|
+
});
|
|
46932
|
+
|
|
46481
46933
|
// src/commands/doctor-omp.ts
|
|
46482
46934
|
import { execFileSync as execFileSync8, spawnSync as spawnSync8 } from "node:child_process";
|
|
46483
|
-
import { existsSync as
|
|
46935
|
+
import { existsSync as existsSync44, readFileSync as readFileSync27 } from "node:fs";
|
|
46484
46936
|
import { createRequire as createRequire3 } from "node:module";
|
|
46485
|
-
import { isAbsolute as isAbsolute8, join as
|
|
46937
|
+
import { isAbsolute as isAbsolute8, join as join35, resolve as resolve18 } from "node:path";
|
|
46486
46938
|
function parseSemver(value) {
|
|
46487
46939
|
const match = value?.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
46488
46940
|
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
@@ -46524,10 +46976,10 @@ function selfVersion() {
|
|
|
46524
46976
|
return "unknown";
|
|
46525
46977
|
}
|
|
46526
46978
|
function readConfig2(path) {
|
|
46527
|
-
if (!
|
|
46979
|
+
if (!existsSync44(path))
|
|
46528
46980
|
return {};
|
|
46529
46981
|
try {
|
|
46530
|
-
const parsed = import_comment_json8.parse(
|
|
46982
|
+
const parsed = import_comment_json8.parse(readFileSync27(path, "utf-8"));
|
|
46531
46983
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? {} : { error: "top level is not an object" };
|
|
46532
46984
|
} catch (error) {
|
|
46533
46985
|
return { error: error instanceof Error ? error.message : String(error) };
|
|
@@ -46537,7 +46989,7 @@ function pluginDeclaresOmp(path) {
|
|
|
46537
46989
|
if (!path)
|
|
46538
46990
|
return null;
|
|
46539
46991
|
try {
|
|
46540
|
-
const pkg = JSON.parse(
|
|
46992
|
+
const pkg = JSON.parse(readFileSync27(join35(path, "package.json"), "utf-8"));
|
|
46541
46993
|
return Array.isArray(pkg.omp?.extensions) || Array.isArray(pkg.pi?.extensions);
|
|
46542
46994
|
} catch {
|
|
46543
46995
|
return null;
|
|
@@ -46604,6 +47056,8 @@ async function runHealthChecks(options) {
|
|
|
46604
47056
|
repairPlan.disableMemory = true;
|
|
46605
47057
|
} else
|
|
46606
47058
|
add(results, "fail", "Could not read OMP memory.backend");
|
|
47059
|
+
for (const check of checkOmpHideSecrets(collectHideSecretsSources(options.cwd)))
|
|
47060
|
+
results.push(check);
|
|
46607
47061
|
const nonGlobalSources = getOmpNonGlobalConfigSources(options.cwd);
|
|
46608
47062
|
if (nonGlobalSources.length > 0 && (repairPlan.disableCompaction || repairPlan.disableMemory)) {
|
|
46609
47063
|
add(results, "warn", "OMP project/overlay config owns effective conflicting settings; automatic global repair is disabled: " + nonGlobalSources.join(", "));
|
|
@@ -46612,8 +47066,8 @@ async function runHealthChecks(options) {
|
|
|
46612
47066
|
if (!reportedAgentDir.ok) {
|
|
46613
47067
|
add(results, "warn", "Could not verify OMP active agent directory");
|
|
46614
47068
|
} else {
|
|
46615
|
-
const reportedPath =
|
|
46616
|
-
const expectedPath =
|
|
47069
|
+
const reportedPath = resolve18(reportedAgentDir.stdout);
|
|
47070
|
+
const expectedPath = resolve18(getOmpAgentDir());
|
|
46617
47071
|
if (reportedPath === expectedPath) {
|
|
46618
47072
|
add(results, "pass", `OMP agent directory resolved to ${getOmpAgentDir()}`);
|
|
46619
47073
|
} else {
|
|
@@ -46624,7 +47078,7 @@ async function runHealthChecks(options) {
|
|
|
46624
47078
|
}
|
|
46625
47079
|
}
|
|
46626
47080
|
const userConfigPath = getOmpUserConfigPath();
|
|
46627
|
-
if (!
|
|
47081
|
+
if (!existsSync44(userConfigPath)) {
|
|
46628
47082
|
add(results, "warn", `No Magic Context user config at ${userConfigPath}`);
|
|
46629
47083
|
repairPlan.writeUserConfig = true;
|
|
46630
47084
|
} else {
|
|
@@ -46641,9 +47095,12 @@ async function runHealthChecks(options) {
|
|
|
46641
47095
|
for (const warning of loaded.warnings.slice(0, 5))
|
|
46642
47096
|
add(results, "warn", warning);
|
|
46643
47097
|
const storage = getMagicContextStorageResolution();
|
|
46644
|
-
const dbPath =
|
|
47098
|
+
const dbPath = join35(storage.path, "context.db");
|
|
47099
|
+
if (isMagicContextStorageOutsideEngram(storage.path)) {
|
|
47100
|
+
add(results, "warn", `Magic Context storage is at ${storage.path}, outside the folder Engram backs up (~/.local/share/cortexkit/magic-context). It is not included in CortexKit backups.`);
|
|
47101
|
+
}
|
|
46645
47102
|
add(results, "info", `Shared storage: ${storage.path} (source: ${storage.source})`);
|
|
46646
|
-
if (!
|
|
47103
|
+
if (!existsSync44(dbPath))
|
|
46647
47104
|
add(results, "info", `Shared context DB will be created at ${dbPath}`);
|
|
46648
47105
|
else {
|
|
46649
47106
|
let db = null;
|
|
@@ -46708,7 +47165,7 @@ function writeDefaultConfig(path) {
|
|
|
46708
47165
|
}
|
|
46709
47166
|
async function repair(plan, deps, prompts, cwd) {
|
|
46710
47167
|
let fixed = 0;
|
|
46711
|
-
if (plan.writeUserConfig && !
|
|
47168
|
+
if (plan.writeUserConfig && !existsSync44(getOmpUserConfigPath())) {
|
|
46712
47169
|
writeDefaultConfig(getOmpUserConfigPath());
|
|
46713
47170
|
prompts.log.success(`Wrote default Magic Context config to ${getOmpUserConfigPath()}`);
|
|
46714
47171
|
fixed += 1;
|
|
@@ -46764,7 +47221,7 @@ function ompIssueBody(description, report, logLines, sessionFilter, cwd) {
|
|
|
46764
47221
|
"",
|
|
46765
47222
|
"## OMP diagnostics",
|
|
46766
47223
|
`- Magic Context CLI: v${selfVersion()}`,
|
|
46767
|
-
...report.results.map((result) => `- ${result.status.toUpperCase()}: ${privacy.healthMessage(result.message)}`),
|
|
47224
|
+
...report.results.map((result) => `- ${result.status.toUpperCase()}: ${result.issueMessage ?? privacy.healthMessage(result.message)}`),
|
|
46768
47225
|
"",
|
|
46769
47226
|
"## Recent errors (last 20, sanitized)",
|
|
46770
47227
|
recentErrorLines.length === 0 ? "_No error-shaped log lines found in recent history._" : ["```", recentErrorLines.join(`
|
|
@@ -46821,7 +47278,7 @@ function runGhCommandWithDeps(deps, args) {
|
|
|
46821
47278
|
async function runIssueFlow(options) {
|
|
46822
47279
|
if (options.reportPath) {
|
|
46823
47280
|
const report = await runHealthChecks({ ...options, quiet: true });
|
|
46824
|
-
const path = isAbsolute8(options.reportPath) ? options.reportPath :
|
|
47281
|
+
const path = isAbsolute8(options.reportPath) ? options.reportPath : join35(options.cwd, options.reportPath);
|
|
46825
47282
|
const bundle = writeOmpIssueReport(path, ompIssueBody("Generated non-interactively by `doctor --issue --report`.", report, readLogLines(report.logFiles), null, options.cwd));
|
|
46826
47283
|
options.prompts.log.success(bundle.fullPath ? `Sanitized report written to ${bundle.path}; full report at ${bundle.fullPath}` : `Sanitized report written to ${bundle.path}`);
|
|
46827
47284
|
return 0;
|
|
@@ -46848,7 +47305,7 @@ async function runIssueFlow(options) {
|
|
|
46848
47305
|
]);
|
|
46849
47306
|
sessionFilter = choice === "__all__" ? null : choice;
|
|
46850
47307
|
}
|
|
46851
|
-
const path =
|
|
47308
|
+
const path = join35(options.cwd, `magic-context-omp-issue-${timestamp2(options.deps.now())}.md`);
|
|
46852
47309
|
const bundle = writeOmpIssueReport(path, ompIssueBody(description, report, logLines, sessionFilter, options.cwd));
|
|
46853
47310
|
options.prompts.log.success(bundle.fullPath ? `Sanitized report written to ${bundle.path}; full report at ${bundle.fullPath}` : `Sanitized report written to ${bundle.path}`);
|
|
46854
47311
|
if (await options.prompts.confirm("Submit this issue on GitHub now?", false)) {
|
|
@@ -46903,6 +47360,7 @@ var init_doctor_omp = __esm(async () => {
|
|
|
46903
47360
|
init_issue_body();
|
|
46904
47361
|
init_log_lines();
|
|
46905
47362
|
init_omp_helpers();
|
|
47363
|
+
init_omp_hide_secrets();
|
|
46906
47364
|
init_paths();
|
|
46907
47365
|
init_prompts();
|
|
46908
47366
|
await init_database_access();
|
|
@@ -47819,12 +48277,12 @@ function listShadowBackfillStalls(db, projectIdentity) {
|
|
|
47819
48277
|
var SHADOW_BACKFILL_PROVENANCE_KEY = "_magicContextShadowBackfill";
|
|
47820
48278
|
|
|
47821
48279
|
// ../plugin/src/shared/auto-update-provenance.ts
|
|
47822
|
-
import { existsSync as
|
|
48280
|
+
import { existsSync as existsSync45, readFileSync as readFileSync28 } from "node:fs";
|
|
47823
48281
|
function readAutoUpdateCheckState(path) {
|
|
47824
|
-
if (!
|
|
48282
|
+
if (!existsSync45(path))
|
|
47825
48283
|
return null;
|
|
47826
48284
|
try {
|
|
47827
|
-
const value = JSON.parse(
|
|
48285
|
+
const value = JSON.parse(readFileSync28(path, "utf-8"));
|
|
47828
48286
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
47829
48287
|
return null;
|
|
47830
48288
|
const raw = value;
|
|
@@ -47852,14 +48310,14 @@ var init_auto_update_provenance = () => {};
|
|
|
47852
48310
|
// ../plugin/src/shared/tui-config.ts
|
|
47853
48311
|
import {
|
|
47854
48312
|
chmodSync as chmodSync4,
|
|
47855
|
-
existsSync as
|
|
47856
|
-
mkdirSync as
|
|
47857
|
-
readFileSync as
|
|
48313
|
+
existsSync as existsSync46,
|
|
48314
|
+
mkdirSync as mkdirSync8,
|
|
48315
|
+
readFileSync as readFileSync29,
|
|
47858
48316
|
renameSync as renameSync8,
|
|
47859
|
-
statSync as
|
|
47860
|
-
writeFileSync as
|
|
48317
|
+
statSync as statSync24,
|
|
48318
|
+
writeFileSync as writeFileSync8
|
|
47861
48319
|
} from "node:fs";
|
|
47862
|
-
import { dirname as
|
|
48320
|
+
import { dirname as dirname24, join as join36 } from "node:path";
|
|
47863
48321
|
function pluginEntryId(entry) {
|
|
47864
48322
|
if (typeof entry === "string")
|
|
47865
48323
|
return entry;
|
|
@@ -47890,21 +48348,21 @@ function writeTuiConfigAtomic(configPath, config) {
|
|
|
47890
48348
|
const body = `${import_comment_json9.stringify(config, null, 2)}
|
|
47891
48349
|
`;
|
|
47892
48350
|
const tmpPath = `${configPath}.tmp`;
|
|
47893
|
-
|
|
48351
|
+
writeFileSync8(tmpPath, body);
|
|
47894
48352
|
try {
|
|
47895
|
-
if (
|
|
47896
|
-
chmodSync4(tmpPath,
|
|
48353
|
+
if (statSync24(configPath, { throwIfNoEntry: false })?.isFile()) {
|
|
48354
|
+
chmodSync4(tmpPath, statSync24(configPath).mode & 511);
|
|
47897
48355
|
}
|
|
47898
48356
|
} catch {}
|
|
47899
48357
|
renameSync8(tmpPath, configPath);
|
|
47900
48358
|
}
|
|
47901
48359
|
function resolveTuiConfigPath(configDirOverride) {
|
|
47902
48360
|
const configDir = configDirOverride ?? getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
47903
|
-
const jsoncPath =
|
|
47904
|
-
const jsonPath =
|
|
47905
|
-
if (
|
|
48361
|
+
const jsoncPath = join36(configDir, "tui.jsonc");
|
|
48362
|
+
const jsonPath = join36(configDir, "tui.json");
|
|
48363
|
+
if (existsSync46(jsoncPath))
|
|
47906
48364
|
return jsoncPath;
|
|
47907
|
-
if (
|
|
48365
|
+
if (existsSync46(jsonPath))
|
|
47908
48366
|
return jsonPath;
|
|
47909
48367
|
return jsoncPath;
|
|
47910
48368
|
}
|
|
@@ -47912,8 +48370,8 @@ function ensureTuiPluginEntry(options = {}) {
|
|
|
47912
48370
|
try {
|
|
47913
48371
|
const configPath = resolveTuiConfigPath(options.configDir);
|
|
47914
48372
|
let config = {};
|
|
47915
|
-
if (
|
|
47916
|
-
const raw =
|
|
48373
|
+
if (existsSync46(configPath)) {
|
|
48374
|
+
const raw = readFileSync29(configPath, "utf-8");
|
|
47917
48375
|
config = import_comment_json9.parse(raw) ?? {};
|
|
47918
48376
|
}
|
|
47919
48377
|
const plugins = Array.isArray(config.plugin) ? [...config.plugin] : [];
|
|
@@ -47947,7 +48405,7 @@ function ensureTuiPluginEntry(options = {}) {
|
|
|
47947
48405
|
}
|
|
47948
48406
|
}
|
|
47949
48407
|
config.plugin = plugins;
|
|
47950
|
-
|
|
48408
|
+
mkdirSync8(dirname24(configPath), { recursive: true });
|
|
47951
48409
|
writeTuiConfigAtomic(configPath, config);
|
|
47952
48410
|
log(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
47953
48411
|
return true;
|
|
@@ -47965,9 +48423,9 @@ var init_tui_config = __esm(() => {
|
|
|
47965
48423
|
});
|
|
47966
48424
|
|
|
47967
48425
|
// src/lib/diagnostics-opencode.ts
|
|
47968
|
-
import { existsSync as
|
|
48426
|
+
import { existsSync as existsSync47, readdirSync as readdirSync10, readFileSync as readFileSync30, statSync as statSync25 } from "node:fs";
|
|
47969
48427
|
import { createRequire as createRequire4 } from "node:module";
|
|
47970
|
-
import { join as
|
|
48428
|
+
import { join as join37 } from "node:path";
|
|
47971
48429
|
function getSelfVersion() {
|
|
47972
48430
|
const require2 = createRequire4(import.meta.url);
|
|
47973
48431
|
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
@@ -47982,7 +48440,7 @@ function getSelfVersion() {
|
|
|
47982
48440
|
}
|
|
47983
48441
|
function readLegacyCachedVersion(root) {
|
|
47984
48442
|
try {
|
|
47985
|
-
const pkg = JSON.parse(
|
|
48443
|
+
const pkg = JSON.parse(readFileSync30(getOpenCodePluginPackageJsonPath(root), "utf-8"));
|
|
47986
48444
|
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
47987
48445
|
} catch {
|
|
47988
48446
|
return;
|
|
@@ -47991,7 +48449,7 @@ function readLegacyCachedVersion(root) {
|
|
|
47991
48449
|
function collectOpenCodePluginCacheReport(hostGeneration, opencodeConfig) {
|
|
47992
48450
|
const installs = [];
|
|
47993
48451
|
for (const root of getOpenCodePluginCacheRoots()) {
|
|
47994
|
-
if (!
|
|
48452
|
+
if (!existsSync47(root))
|
|
47995
48453
|
continue;
|
|
47996
48454
|
const spec = root.endsWith("@latest") ? "latest" : "(bare)";
|
|
47997
48455
|
installs.push({
|
|
@@ -48025,7 +48483,7 @@ function getStorageResolution() {
|
|
|
48025
48483
|
}
|
|
48026
48484
|
function fileSize(path) {
|
|
48027
48485
|
try {
|
|
48028
|
-
return
|
|
48486
|
+
return existsSync47(path) ? statSync25(path).size : 0;
|
|
48029
48487
|
} catch {
|
|
48030
48488
|
return 0;
|
|
48031
48489
|
}
|
|
@@ -48037,10 +48495,10 @@ function sanitizeValue(value) {
|
|
|
48037
48495
|
return sanitizeConfigValue(value);
|
|
48038
48496
|
}
|
|
48039
48497
|
function readConfig3(path) {
|
|
48040
|
-
if (!
|
|
48498
|
+
if (!existsSync47(path))
|
|
48041
48499
|
return { value: null };
|
|
48042
48500
|
try {
|
|
48043
|
-
const raw =
|
|
48501
|
+
const raw = readFileSync30(path, "utf-8");
|
|
48044
48502
|
const value = import_comment_json10.parse(raw);
|
|
48045
48503
|
return { value };
|
|
48046
48504
|
} catch (error) {
|
|
@@ -48065,7 +48523,7 @@ function configHasPluginEntry(config) {
|
|
|
48065
48523
|
}
|
|
48066
48524
|
function parseHistorianDumpMeta(path) {
|
|
48067
48525
|
try {
|
|
48068
|
-
const xml =
|
|
48526
|
+
const xml = readFileSync30(path, "utf-8");
|
|
48069
48527
|
const parsed = parseCompartmentOutput(xml);
|
|
48070
48528
|
const factCountByCategory = {};
|
|
48071
48529
|
for (const fact of parsed.facts) {
|
|
@@ -48098,11 +48556,11 @@ function parseHistorianDumpMeta(path) {
|
|
|
48098
48556
|
}
|
|
48099
48557
|
}
|
|
48100
48558
|
function listDumpsInDir(dir, limit) {
|
|
48101
|
-
if (!
|
|
48559
|
+
if (!existsSync47(dir))
|
|
48102
48560
|
return { count: 0, recent: [] };
|
|
48103
48561
|
try {
|
|
48104
|
-
const entries =
|
|
48105
|
-
const stat =
|
|
48562
|
+
const entries = readdirSync10(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
48563
|
+
const stat = statSync25(join37(dir, name));
|
|
48106
48564
|
return {
|
|
48107
48565
|
name,
|
|
48108
48566
|
mtime: stat.mtimeMs,
|
|
@@ -48111,7 +48569,7 @@ function listDumpsInDir(dir, limit) {
|
|
|
48111
48569
|
}).sort((a, b) => b.mtime - a.mtime);
|
|
48112
48570
|
const now = Date.now();
|
|
48113
48571
|
const recent = entries.slice(0, limit).map((entry) => {
|
|
48114
|
-
const meta = parseHistorianDumpMeta(
|
|
48572
|
+
const meta = parseHistorianDumpMeta(join37(dir, entry.name));
|
|
48115
48573
|
const summary = {
|
|
48116
48574
|
name: entry.name,
|
|
48117
48575
|
ageMinutes: Math.round((now - entry.mtime) / 60000),
|
|
@@ -48222,7 +48680,7 @@ function collectRecentSessionsFromDatabase(database) {
|
|
|
48222
48680
|
});
|
|
48223
48681
|
}
|
|
48224
48682
|
async function collectDatabaseRows(path, read) {
|
|
48225
|
-
if (!
|
|
48683
|
+
if (!existsSync47(path))
|
|
48226
48684
|
return { available: false, reason: "path missing" };
|
|
48227
48685
|
let backend;
|
|
48228
48686
|
try {
|
|
@@ -48254,7 +48712,7 @@ async function collectRecentSessions(resolution, hostGeneration) {
|
|
|
48254
48712
|
});
|
|
48255
48713
|
}
|
|
48256
48714
|
async function collectHistorianFailures(storageDirPath) {
|
|
48257
|
-
return collectDatabaseRows(
|
|
48715
|
+
return collectDatabaseRows(join37(storageDirPath, "context.db"), (db) => {
|
|
48258
48716
|
const rows = db.prepare("SELECT session_id, historian_failure_count, historian_last_error, historian_last_failure_at FROM session_meta WHERE historian_failure_count > 0 ORDER BY historian_last_failure_at DESC LIMIT 10").all();
|
|
48259
48717
|
return rows.map((row) => {
|
|
48260
48718
|
const sessionId = typeof row.session_id === "string" ? row.session_id : "<unknown>";
|
|
@@ -48267,7 +48725,7 @@ async function collectHistorianFailures(storageDirPath) {
|
|
|
48267
48725
|
});
|
|
48268
48726
|
}
|
|
48269
48727
|
async function collectHistorianRuns(storageDirPath) {
|
|
48270
|
-
return collectDatabaseRows(
|
|
48728
|
+
return collectDatabaseRows(join37(storageDirPath, "context.db"), (db) => {
|
|
48271
48729
|
const aggRows = db.prepare(`SELECT session_id,
|
|
48272
48730
|
COUNT(*) AS total,
|
|
48273
48731
|
SUM(CASE WHEN status='success' THEN 1 ELSE 0 END) AS success,
|
|
@@ -48322,7 +48780,7 @@ async function collectDiagnostics() {
|
|
|
48322
48780
|
const magicContextConfig = readConfig3(configPaths.magicContextConfig);
|
|
48323
48781
|
const storageResolution = getStorageResolution();
|
|
48324
48782
|
const storageDirPath = storageResolution.path;
|
|
48325
|
-
const contextDbPath =
|
|
48783
|
+
const contextDbPath = join37(storageDirPath, "context.db");
|
|
48326
48784
|
let compactionEnabled = false;
|
|
48327
48785
|
try {
|
|
48328
48786
|
compactionEnabled = isCompactionEnabled(loadPluginConfig(process.cwd()));
|
|
@@ -48354,7 +48812,7 @@ async function collectDiagnostics() {
|
|
|
48354
48812
|
opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
|
|
48355
48813
|
tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
|
|
48356
48814
|
magicContextConfig: {
|
|
48357
|
-
exists:
|
|
48815
|
+
exists: existsSync47(configPaths.magicContextConfig),
|
|
48358
48816
|
...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
|
|
48359
48817
|
flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
|
|
48360
48818
|
},
|
|
@@ -48362,7 +48820,7 @@ async function collectDiagnostics() {
|
|
|
48362
48820
|
storageDir: {
|
|
48363
48821
|
path: storageDirPath,
|
|
48364
48822
|
source: storageResolution.source,
|
|
48365
|
-
exists:
|
|
48823
|
+
exists: existsSync47(storageDirPath),
|
|
48366
48824
|
contextDbSizeBytes: fileSize(contextDbPath)
|
|
48367
48825
|
},
|
|
48368
48826
|
openCodeDatabase: {
|
|
@@ -48422,6 +48880,7 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
48422
48880
|
exists: report.storageDir.exists,
|
|
48423
48881
|
context_db_size: formatBytes(report.storageDir.contextDbSizeBytes)
|
|
48424
48882
|
};
|
|
48883
|
+
const storageBackupWarning = isMagicContextStorageOutsideEngram(report.storageDir.path) ? `- Warning: Magic Context storage is at ${sanitizeString(report.storageDir.path)}, outside the folder Engram backs up (~/.local/share/cortexkit/magic-context). It is not included in CortexKit backups.` : null;
|
|
48425
48884
|
const openCodeInstallations = report.opencodeInstallations ?? [];
|
|
48426
48885
|
const openCodeInstallationTable = openCodeInstallations.length > 1 ? [
|
|
48427
48886
|
"",
|
|
@@ -48484,6 +48943,7 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
48484
48943
|
"```",
|
|
48485
48944
|
"",
|
|
48486
48945
|
"### Storage",
|
|
48946
|
+
...storageBackupWarning ? [storageBackupWarning] : [],
|
|
48487
48947
|
"```json",
|
|
48488
48948
|
JSON.stringify(storage, null, 2),
|
|
48489
48949
|
"```",
|
|
@@ -48616,9 +49076,9 @@ var init_embedding_local = __esm(async () => {
|
|
|
48616
49076
|
|
|
48617
49077
|
// src/lib/embedding-runtime.ts
|
|
48618
49078
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
48619
|
-
import { existsSync as
|
|
49079
|
+
import { existsSync as existsSync48, readFileSync as readFileSync31 } from "node:fs";
|
|
48620
49080
|
import { createRequire as createRequire5 } from "node:module";
|
|
48621
|
-
import { dirname as
|
|
49081
|
+
import { dirname as dirname25, join as join38, sep as sep2 } from "node:path";
|
|
48622
49082
|
function describeError(error) {
|
|
48623
49083
|
const message = error instanceof Error ? error.message : String(error ?? "unknown error");
|
|
48624
49084
|
const code = error?.code;
|
|
@@ -48760,11 +49220,11 @@ function expectedBinaryRelPath(platform, arch) {
|
|
|
48760
49220
|
const supportedArch = arch === "x64" || arch === "arm64";
|
|
48761
49221
|
if (!supportedPlatform || !supportedArch)
|
|
48762
49222
|
return null;
|
|
48763
|
-
return
|
|
49223
|
+
return join38("bin", "napi-v6", platform, arch, "onnxruntime_binding.node");
|
|
48764
49224
|
}
|
|
48765
49225
|
function onnxRuntimeNodeVersion(packageDir) {
|
|
48766
49226
|
try {
|
|
48767
|
-
const parsed = JSON.parse(
|
|
49227
|
+
const parsed = JSON.parse(readFileSync31(join38(packageDir, "package.json"), "utf8"));
|
|
48768
49228
|
return typeof parsed.version === "string" ? parsed.version : undefined;
|
|
48769
49229
|
} catch {
|
|
48770
49230
|
return;
|
|
@@ -48813,7 +49273,7 @@ function formatLocalEmbeddingRuntimeWasmSelected(status) {
|
|
|
48813
49273
|
function requireNodeWasmBundle(probe, candidates) {
|
|
48814
49274
|
if (probe.state === "failed")
|
|
48815
49275
|
return probe;
|
|
48816
|
-
const bundlePath = candidates.find((candidate) =>
|
|
49276
|
+
const bundlePath = candidates.find((candidate) => existsSync48(candidate));
|
|
48817
49277
|
return bundlePath ? probe : {
|
|
48818
49278
|
state: "failed",
|
|
48819
49279
|
reason: `functional Node WASM Transformers bundle is missing (checked ${candidates.join(", ")})`
|
|
@@ -48821,13 +49281,13 @@ function requireNodeWasmBundle(probe, candidates) {
|
|
|
48821
49281
|
}
|
|
48822
49282
|
function nodeWasmBundleCandidates(installRoot) {
|
|
48823
49283
|
return [
|
|
48824
|
-
|
|
48825
|
-
|
|
48826
|
-
|
|
49284
|
+
join38(installRoot, "dist", "transformers-node-wasm.js"),
|
|
49285
|
+
join38(installRoot, "node_modules", "@cortexkit", "opencode-magic-context", "dist", "transformers-node-wasm.js"),
|
|
49286
|
+
join38(installRoot, "node_modules", "@cortexkit", "pi-magic-context", "dist", "transformers-node-wasm.js")
|
|
48827
49287
|
];
|
|
48828
49288
|
}
|
|
48829
49289
|
function probeWasmRuntimeAt(installRoot) {
|
|
48830
|
-
const requireFn = createRequire5(
|
|
49290
|
+
const requireFn = createRequire5(join38(installRoot, "package.json"));
|
|
48831
49291
|
return requireNodeWasmBundle(probeWasmRuntimeFromRequire(requireFn), nodeWasmBundleCandidates(installRoot));
|
|
48832
49292
|
}
|
|
48833
49293
|
function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform, arch = process.arch, runtimePreference = "auto", host) {
|
|
@@ -48836,9 +49296,9 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
|
|
|
48836
49296
|
const wasm = probeWasmRuntimeAt(installRoot);
|
|
48837
49297
|
return wasm.state === "ok" ? { state: "wasm-selected", wasmPath: wasm.wasmPath } : { state: "wasm-broken", wasmReason: wasm.reason };
|
|
48838
49298
|
}
|
|
48839
|
-
const packageDir =
|
|
49299
|
+
const packageDir = join38(installRoot, "node_modules", "onnxruntime-node");
|
|
48840
49300
|
let native;
|
|
48841
|
-
if (!
|
|
49301
|
+
if (!existsSync48(join38(packageDir, "package.json"))) {
|
|
48842
49302
|
native = { state: "package-missing", packageDir };
|
|
48843
49303
|
} else {
|
|
48844
49304
|
const rel = expectedBinaryRelPath(platform, arch);
|
|
@@ -48848,8 +49308,8 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
|
|
|
48848
49308
|
binaryPath: packageDir
|
|
48849
49309
|
};
|
|
48850
49310
|
} else {
|
|
48851
|
-
const binaryPath =
|
|
48852
|
-
native =
|
|
49311
|
+
const binaryPath = join38(packageDir, rel);
|
|
49312
|
+
native = existsSync48(binaryPath) ? probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath } : {
|
|
48853
49313
|
state: "binary-missing",
|
|
48854
49314
|
packageDir,
|
|
48855
49315
|
expectedBinary: binaryPath,
|
|
@@ -48860,7 +49320,7 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
|
|
|
48860
49320
|
return withWasmFallback(native, () => probeWasmRuntimeAt(installRoot));
|
|
48861
49321
|
}
|
|
48862
49322
|
function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, arch = process.arch, runtimePreference = "auto", host) {
|
|
48863
|
-
const existing = installRoots.filter((root) =>
|
|
49323
|
+
const existing = installRoots.filter((root) => existsSync48(root));
|
|
48864
49324
|
if (existing.length === 0) {
|
|
48865
49325
|
return {
|
|
48866
49326
|
state: "unknown",
|
|
@@ -48884,21 +49344,21 @@ function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, a
|
|
|
48884
49344
|
return firstFallback ?? firstFailure ?? { state: "unknown", reason: "no candidate roots" };
|
|
48885
49345
|
}
|
|
48886
49346
|
function packageDirFromResolved(resolvedPath, packageName) {
|
|
48887
|
-
const marker = `node_modules${
|
|
49347
|
+
const marker = `node_modules${sep2}${packageName.split("/").join(sep2)}`;
|
|
48888
49348
|
const idx = resolvedPath.indexOf(marker);
|
|
48889
|
-
return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) :
|
|
49349
|
+
return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname25(resolvedPath);
|
|
48890
49350
|
}
|
|
48891
49351
|
function probeWasmRuntimeByResolution(pluginDir) {
|
|
48892
49352
|
try {
|
|
48893
|
-
const reqPlugin = createRequire5(
|
|
49353
|
+
const reqPlugin = createRequire5(join38(pluginDir, "package.json"));
|
|
48894
49354
|
const direct = probeWasmRuntimeFromRequire(reqPlugin);
|
|
48895
49355
|
let probe = direct;
|
|
48896
49356
|
if (direct.state === "failed" && direct.reason.startsWith("onnxruntime-web is not resolvable")) {
|
|
48897
49357
|
const tfResolved = reqPlugin.resolve("@huggingface/transformers");
|
|
48898
49358
|
const tfDir = packageDirFromResolved(tfResolved, "@huggingface/transformers");
|
|
48899
|
-
probe = probeWasmRuntimeFromRequire(createRequire5(
|
|
49359
|
+
probe = probeWasmRuntimeFromRequire(createRequire5(join38(tfDir, "package.json")));
|
|
48900
49360
|
}
|
|
48901
|
-
return requireNodeWasmBundle(probe, [
|
|
49361
|
+
return requireNodeWasmBundle(probe, [join38(pluginDir, "dist", "transformers-node-wasm.js")]);
|
|
48902
49362
|
} catch (error) {
|
|
48903
49363
|
return {
|
|
48904
49364
|
state: "failed",
|
|
@@ -48907,7 +49367,7 @@ function probeWasmRuntimeByResolution(pluginDir) {
|
|
|
48907
49367
|
}
|
|
48908
49368
|
}
|
|
48909
49369
|
function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.platform, arch = process.arch, runtimePreference = "auto", host) {
|
|
48910
|
-
if (!
|
|
49370
|
+
if (!existsSync48(join38(pluginDir, "package.json"))) {
|
|
48911
49371
|
return { state: "unknown", reason: "plugin package dir not found" };
|
|
48912
49372
|
}
|
|
48913
49373
|
const selectedRuntime = resolveLocalEmbeddingWorkerRuntime(runtimePreference, host);
|
|
@@ -48918,13 +49378,13 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
|
|
|
48918
49378
|
let onnxDir = null;
|
|
48919
49379
|
let resolveError;
|
|
48920
49380
|
try {
|
|
48921
|
-
const reqPlugin = createRequire5(
|
|
49381
|
+
const reqPlugin = createRequire5(join38(pluginDir, "package.json"));
|
|
48922
49382
|
try {
|
|
48923
49383
|
onnxDir = packageDirFromResolved(reqPlugin.resolve("onnxruntime-node"), "onnxruntime-node");
|
|
48924
49384
|
} catch {
|
|
48925
49385
|
const tfResolved = reqPlugin.resolve("@huggingface/transformers");
|
|
48926
49386
|
const tfDir = packageDirFromResolved(tfResolved, "@huggingface/transformers");
|
|
48927
|
-
const reqTf = createRequire5(
|
|
49387
|
+
const reqTf = createRequire5(join38(tfDir, "package.json"));
|
|
48928
49388
|
onnxDir = packageDirFromResolved(reqTf.resolve("onnxruntime-node"), "onnxruntime-node");
|
|
48929
49389
|
}
|
|
48930
49390
|
} catch (error) {
|
|
@@ -48932,7 +49392,7 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
|
|
|
48932
49392
|
if (resolveError === "ERR_MODULE_NOT_FOUND" || resolveError === "MODULE_NOT_FOUND") {
|
|
48933
49393
|
return withWasmFallback({
|
|
48934
49394
|
state: "package-missing",
|
|
48935
|
-
packageDir:
|
|
49395
|
+
packageDir: join38(pluginDir, "node_modules", "onnxruntime-node")
|
|
48936
49396
|
}, () => probeWasmRuntimeByResolution(pluginDir));
|
|
48937
49397
|
}
|
|
48938
49398
|
return {
|
|
@@ -48948,8 +49408,8 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
|
|
|
48948
49408
|
if (rel === null) {
|
|
48949
49409
|
native = probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
|
|
48950
49410
|
} else {
|
|
48951
|
-
const binaryPath =
|
|
48952
|
-
native =
|
|
49411
|
+
const binaryPath = join38(onnxDir, rel);
|
|
49412
|
+
native = existsSync48(binaryPath) ? probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath } : {
|
|
48953
49413
|
state: "binary-missing",
|
|
48954
49414
|
packageDir: onnxDir,
|
|
48955
49415
|
expectedBinary: binaryPath,
|
|
@@ -48984,8 +49444,8 @@ var init_embedding_runtime = __esm(async () => {
|
|
|
48984
49444
|
});
|
|
48985
49445
|
|
|
48986
49446
|
// src/lib/logs-opencode.ts
|
|
48987
|
-
import { mkdirSync as
|
|
48988
|
-
import { dirname as
|
|
49447
|
+
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
49448
|
+
import { dirname as dirname26, join as join39 } from "node:path";
|
|
48989
49449
|
function formatTimestamp(date) {
|
|
48990
49450
|
const pad = (value) => String(value).padStart(2, "0");
|
|
48991
49451
|
return [
|
|
@@ -49074,13 +49534,13 @@ async function bundleIssueReport(report, description, title, sessionFilter = nul
|
|
|
49074
49534
|
const bodyMarkdown = capBodyToGithubLimit(rawBodyMarkdown);
|
|
49075
49535
|
const truncated = bodyMarkdown !== rawBodyMarkdown;
|
|
49076
49536
|
const timestamp = formatTimestamp(new Date);
|
|
49077
|
-
const path = options.outputPath ??
|
|
49078
|
-
|
|
49079
|
-
|
|
49537
|
+
const path = options.outputPath ?? join39(process.cwd(), `magic-context-issue-${timestamp}.md`);
|
|
49538
|
+
mkdirSync9(dirname26(path), { recursive: true });
|
|
49539
|
+
writeFileSync9(path, `${bodyMarkdown}
|
|
49080
49540
|
`);
|
|
49081
|
-
const fullPath = truncated ? options.outputPath ? `${options.outputPath}.full.md` :
|
|
49541
|
+
const fullPath = truncated ? options.outputPath ? `${options.outputPath}.full.md` : join39(process.cwd(), `magic-context-issue-${timestamp}-full.md`) : undefined;
|
|
49082
49542
|
if (fullPath)
|
|
49083
|
-
|
|
49543
|
+
writeFileSync9(fullPath, `${rawBodyMarkdown}
|
|
49084
49544
|
`);
|
|
49085
49545
|
return { path, bodyMarkdown, ...fullPath ? { fullPath } : {}, truncated };
|
|
49086
49546
|
}
|
|
@@ -49891,10 +50351,10 @@ function removeDeprecatedReasoningAge(config) {
|
|
|
49891
50351
|
|
|
49892
50352
|
// src/commands/doctor-opencode.ts
|
|
49893
50353
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
49894
|
-
import { existsSync as
|
|
50354
|
+
import { existsSync as existsSync49, mkdtempSync as mkdtempSync4, readFileSync as readFileSync32, rmSync as rmSync9 } from "node:fs";
|
|
49895
50355
|
import { createRequire as createRequire6 } from "node:module";
|
|
49896
50356
|
import { homedir as homedir21, tmpdir as tmpdir4 } from "node:os";
|
|
49897
|
-
import { dirname as
|
|
50357
|
+
import { dirname as dirname27, join as join40, resolve as resolve19 } from "node:path";
|
|
49898
50358
|
function formatSharedDbRowCounts(db) {
|
|
49899
50359
|
return SHARED_DB_ROW_COUNT_TABLES.map((table) => {
|
|
49900
50360
|
try {
|
|
@@ -49965,7 +50425,7 @@ function checkConfiguredVariantCatalog(config, hostGeneration, warn, run = (args
|
|
|
49965
50425
|
}
|
|
49966
50426
|
if (models.length === 0)
|
|
49967
50427
|
return;
|
|
49968
|
-
const tempRoot = mkdtempSync4(
|
|
50428
|
+
const tempRoot = mkdtempSync4(join40(tmpdir4(), "magic-context-opencode-catalog-"));
|
|
49969
50429
|
try {
|
|
49970
50430
|
const command = hostGeneration === "v2" ? ["api", "model.list", "--param", `directory=${projectDir}`] : ["models", "--verbose"];
|
|
49971
50431
|
const guidance = `opencode ${command.join(" ")}`;
|
|
@@ -50141,7 +50601,7 @@ function getSelfVersion2() {
|
|
|
50141
50601
|
function describeAutoUpdateStall(specifier, autoUpdateEnabled, storageDir = getMagicContextStorageDir()) {
|
|
50142
50602
|
if (!autoUpdateEnabled || !isPinnedOpenCodePluginSpecifier(specifier))
|
|
50143
50603
|
return null;
|
|
50144
|
-
const state = readAutoUpdateCheckState(
|
|
50604
|
+
const state = readAutoUpdateCheckState(join40(storageDir, AUTO_UPDATE_CHECK_STATE_FILENAME));
|
|
50145
50605
|
const owner = isUpdaterPinnedSpec(state, specifier) ? "updater" : "you";
|
|
50146
50606
|
return `auto-update: stalled — config pinned to ${specifier} (by ${owner})`;
|
|
50147
50607
|
}
|
|
@@ -50150,15 +50610,15 @@ function getUserNpmrcPath() {
|
|
|
50150
50610
|
if (custom)
|
|
50151
50611
|
return custom;
|
|
50152
50612
|
const home = process.env.HOME?.trim();
|
|
50153
|
-
return
|
|
50613
|
+
return join40(home || homedir21(), ".npmrc");
|
|
50154
50614
|
}
|
|
50155
50615
|
function collectNpmReleaseAgeWarnings() {
|
|
50156
50616
|
const ageWarnings = [];
|
|
50157
50617
|
const npmrcPath = getUserNpmrcPath();
|
|
50158
|
-
if (!
|
|
50618
|
+
if (!existsSync49(npmrcPath))
|
|
50159
50619
|
return ageWarnings;
|
|
50160
50620
|
try {
|
|
50161
|
-
const npmrc =
|
|
50621
|
+
const npmrc = readFileSync32(npmrcPath, "utf-8");
|
|
50162
50622
|
for (const line of npmrc.split(`
|
|
50163
50623
|
`)) {
|
|
50164
50624
|
const trimmed = line.trim();
|
|
@@ -50199,7 +50659,7 @@ async function runIssueFlow2(options = {}, deps = { collectDiagnostics }) {
|
|
|
50199
50659
|
if (options.reportPath) {
|
|
50200
50660
|
try {
|
|
50201
50661
|
const report = await deps.collectDiagnostics();
|
|
50202
|
-
const bundled = await bundleIssueReport(report, "Generated non-interactively by `doctor --issue --report`.", "Magic Context diagnostic report", null, { outputPath:
|
|
50662
|
+
const bundled = await bundleIssueReport(report, "Generated non-interactively by `doctor --issue --report`.", "Magic Context diagnostic report", null, { outputPath: resolve19(process.cwd(), options.reportPath) });
|
|
50203
50663
|
log3.info(bundled.fullPath ? `Report written to ${bundled.path}; full bundle at ${bundled.fullPath}` : `Report written to ${bundled.path}`);
|
|
50204
50664
|
return 0;
|
|
50205
50665
|
} catch (error) {
|
|
@@ -50293,7 +50753,7 @@ function checkLocalEmbeddingRuntimeForDoctor(runtimePreference = "auto") {
|
|
|
50293
50753
|
return { issues: 0 };
|
|
50294
50754
|
}
|
|
50295
50755
|
async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
50296
|
-
if (!
|
|
50756
|
+
if (!existsSync49(magicContextConfigPath)) {
|
|
50297
50757
|
return checkLocalEmbeddingRuntimeForDoctor();
|
|
50298
50758
|
}
|
|
50299
50759
|
let rawText;
|
|
@@ -50468,7 +50928,7 @@ async function runDoctor2(options = {}) {
|
|
|
50468
50928
|
const v22Result = await runV22BackfillCommands({
|
|
50469
50929
|
name: "OpenCode",
|
|
50470
50930
|
openDatabase: (readonly = true) => {
|
|
50471
|
-
const dbPath =
|
|
50931
|
+
const dbPath = join40(getMagicContextStorageDir(), "context.db");
|
|
50472
50932
|
v22Db = readonly ? openExistingContextDatabase(dbPath, { readonly: true }) : openExistingContextDatabaseForMutation(dbPath);
|
|
50473
50933
|
return v22Db;
|
|
50474
50934
|
},
|
|
@@ -50500,7 +50960,11 @@ async function runDoctor2(options = {}) {
|
|
|
50500
50960
|
failCount++;
|
|
50501
50961
|
issues++;
|
|
50502
50962
|
};
|
|
50503
|
-
const
|
|
50963
|
+
const storageDir = getMagicContextStorageDir();
|
|
50964
|
+
if (isMagicContextStorageOutsideEngram(storageDir)) {
|
|
50965
|
+
warn(`Magic Context storage is at ${storageDir}, outside the folder Engram backs up (~/.local/share/cortexkit/magic-context). It is not included in CortexKit backups.`);
|
|
50966
|
+
}
|
|
50967
|
+
const authorityDbPath = join40(getMagicContextStorageDir(), "context.db");
|
|
50504
50968
|
let authorityDb = null;
|
|
50505
50969
|
try {
|
|
50506
50970
|
authorityDb = openExistingContextDatabase(authorityDbPath, { readonly: true });
|
|
@@ -50539,8 +51003,8 @@ async function runDoctor2(options = {}) {
|
|
|
50539
51003
|
let magicContextStatusKnown = paths.opencodeConfigFormat === "none";
|
|
50540
51004
|
if (!magicContextStatusKnown) {
|
|
50541
51005
|
try {
|
|
50542
|
-
const config = import_comment_json11.parse(
|
|
50543
|
-
magicContextInstalled = isOpenCodePluginRegistered(config,
|
|
51006
|
+
const config = import_comment_json11.parse(readFileSync32(paths.opencodeConfig, "utf-8"));
|
|
51007
|
+
magicContextInstalled = isOpenCodePluginRegistered(config, dirname27(paths.opencodeConfig));
|
|
50544
51008
|
magicContextStatusKnown = true;
|
|
50545
51009
|
} catch {}
|
|
50546
51010
|
}
|
|
@@ -50675,7 +51139,7 @@ async function runDoctor2(options = {}) {
|
|
|
50675
51139
|
pass(`OpenCode config: ${paths.opencodeConfig}`);
|
|
50676
51140
|
}
|
|
50677
51141
|
let autoUpdateEnabled = true;
|
|
50678
|
-
if (
|
|
51142
|
+
if (existsSync49(paths.magicContextConfig)) {
|
|
50679
51143
|
pass(`Magic Context config: ${paths.magicContextConfig}`);
|
|
50680
51144
|
try {
|
|
50681
51145
|
const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
|
|
@@ -50711,7 +51175,7 @@ async function runDoctor2(options = {}) {
|
|
|
50711
51175
|
warn(`No magic-context.jsonc found — using defaults`);
|
|
50712
51176
|
log3.info(" Run 'setup' to create one with model recommendations");
|
|
50713
51177
|
}
|
|
50714
|
-
if (
|
|
51178
|
+
if (existsSync49(paths.magicContextConfig)) {
|
|
50715
51179
|
try {
|
|
50716
51180
|
const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
|
|
50717
51181
|
if (!raw)
|
|
@@ -50851,10 +51315,10 @@ async function runDoctor2(options = {}) {
|
|
|
50851
51315
|
};
|
|
50852
51316
|
if (paths.opencodeConfigFormat !== "none") {
|
|
50853
51317
|
try {
|
|
50854
|
-
const raw =
|
|
51318
|
+
const raw = readFileSync32(paths.opencodeConfig, "utf-8");
|
|
50855
51319
|
const config = import_comment_json11.parse(raw);
|
|
50856
51320
|
const configName = paths.opencodeConfigFormat === "jsonc" ? "opencode.jsonc" : "opencode.json";
|
|
50857
|
-
const configDir =
|
|
51321
|
+
const configDir = dirname27(paths.opencodeConfig);
|
|
50858
51322
|
magicContextInstalled = isOpenCodePluginRegistered(config, configDir);
|
|
50859
51323
|
magicContextStatusKnown = true;
|
|
50860
51324
|
if (magicContextInstalled) {
|
|
@@ -50944,11 +51408,11 @@ async function runDoctor2(options = {}) {
|
|
|
50944
51408
|
pass("Added TUI sidebar plugin to tui.json");
|
|
50945
51409
|
warn("Restart OpenCode to see the sidebar");
|
|
50946
51410
|
fixed++;
|
|
50947
|
-
} else if (
|
|
51411
|
+
} else if (existsSync49(paths.tuiConfig)) {
|
|
50948
51412
|
try {
|
|
50949
|
-
const tuiRaw =
|
|
51413
|
+
const tuiRaw = readFileSync32(paths.tuiConfig, "utf-8");
|
|
50950
51414
|
const tuiConfig = import_comment_json11.parse(tuiRaw);
|
|
50951
|
-
const tuiConfigDir =
|
|
51415
|
+
const tuiConfigDir = dirname27(paths.tuiConfig);
|
|
50952
51416
|
const tuiRawPlugins = Array.isArray(tuiConfig?.plugin) ? tuiConfig.plugin : [];
|
|
50953
51417
|
const tuiIdx = tuiRawPlugins.findIndex((entry) => matchesPluginEntry(entry, OPENCODE_PLUGIN_NAME) || isDevPathPluginEntry(entry, tuiConfigDir));
|
|
50954
51418
|
if (tuiRawPlugins.some((entry) => isLocalPathPluginEntry(entry) && String(entry).includes("magic-context") && !isDevPathPluginEntry(entry, tuiConfigDir))) {
|
|
@@ -50985,7 +51449,7 @@ async function runDoctor2(options = {}) {
|
|
|
50985
51449
|
fail("Could not create or verify the TUI sidebar config");
|
|
50986
51450
|
}
|
|
50987
51451
|
}
|
|
50988
|
-
if (
|
|
51452
|
+
if (existsSync49(paths.magicContextConfig)) {
|
|
50989
51453
|
try {
|
|
50990
51454
|
const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
|
|
50991
51455
|
if (!raw)
|
|
@@ -51007,9 +51471,9 @@ async function runDoctor2(options = {}) {
|
|
|
51007
51471
|
else
|
|
51008
51472
|
passCount++;
|
|
51009
51473
|
const storage = getMagicContextStorageResolution();
|
|
51010
|
-
const dbPath =
|
|
51474
|
+
const dbPath = join40(storage.path, "context.db");
|
|
51011
51475
|
log3.info(`Shared storage: ${storage.path} (source: ${storage.source})`);
|
|
51012
|
-
if (!
|
|
51476
|
+
if (!existsSync49(dbPath)) {
|
|
51013
51477
|
log3.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
|
|
51014
51478
|
} else {
|
|
51015
51479
|
log3.info(`Shared context DB exists at ${dbPath}`);
|
|
@@ -51092,7 +51556,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
|
|
|
51092
51556
|
let pluginConfigUse;
|
|
51093
51557
|
if (paths.opencodeConfigFormat !== "none") {
|
|
51094
51558
|
try {
|
|
51095
|
-
pluginConfigUse = readOpenCodePluginConfigUse(import_comment_json11.parse(
|
|
51559
|
+
pluginConfigUse = readOpenCodePluginConfigUse(import_comment_json11.parse(readFileSync32(paths.opencodeConfig, "utf-8")), dirname27(paths.opencodeConfig));
|
|
51096
51560
|
} catch {}
|
|
51097
51561
|
}
|
|
51098
51562
|
const cacheResult = await clearPluginCache({
|
|
@@ -51144,7 +51608,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
|
|
|
51144
51608
|
let v2DistTag;
|
|
51145
51609
|
if (paths.opencodeConfigFormat !== "none") {
|
|
51146
51610
|
try {
|
|
51147
|
-
v2DistTag = configuredOpenCodeV2DistTag(import_comment_json11.parse(
|
|
51611
|
+
v2DistTag = configuredOpenCodeV2DistTag(import_comment_json11.parse(readFileSync32(paths.opencodeConfig, "utf-8")));
|
|
51148
51612
|
} catch {}
|
|
51149
51613
|
}
|
|
51150
51614
|
const v2Cache = reportOpenCodeV2PluginCache(checkOpenCodeV2PluginCache({
|
|
@@ -51413,6 +51877,7 @@ function buildDreamTaskRuntimeConfigs(dreamer, harness, language, smartNotesEnab
|
|
|
51413
51877
|
});
|
|
51414
51878
|
}
|
|
51415
51879
|
var init_task_config = __esm(() => {
|
|
51880
|
+
init_agent_disable();
|
|
51416
51881
|
init_task_registry();
|
|
51417
51882
|
});
|
|
51418
51883
|
|
|
@@ -51525,9 +51990,9 @@ var init_model_chain_health = __esm(() => {
|
|
|
51525
51990
|
});
|
|
51526
51991
|
|
|
51527
51992
|
// src/lib/diagnostics-pi.ts
|
|
51528
|
-
import { existsSync as
|
|
51993
|
+
import { existsSync as existsSync50, readdirSync as readdirSync11, readFileSync as readFileSync33, statSync as statSync26 } from "node:fs";
|
|
51529
51994
|
import { createRequire as createRequire7 } from "node:module";
|
|
51530
|
-
import { join as
|
|
51995
|
+
import { join as join41 } from "node:path";
|
|
51531
51996
|
function getSelfVersion3() {
|
|
51532
51997
|
const req = createRequire7(import.meta.url);
|
|
51533
51998
|
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
@@ -51542,7 +52007,7 @@ function getSelfVersion3() {
|
|
|
51542
52007
|
}
|
|
51543
52008
|
function fileSize2(path) {
|
|
51544
52009
|
try {
|
|
51545
|
-
return
|
|
52010
|
+
return existsSync50(path) ? statSync26(path).size : 0;
|
|
51546
52011
|
} catch {
|
|
51547
52012
|
return 0;
|
|
51548
52013
|
}
|
|
@@ -51554,11 +52019,11 @@ function sanitizeValue2(value) {
|
|
|
51554
52019
|
return sanitizeConfigValue(value);
|
|
51555
52020
|
}
|
|
51556
52021
|
function readJsonc(path) {
|
|
51557
|
-
if (!
|
|
52022
|
+
if (!existsSync50(path))
|
|
51558
52023
|
return { value: {} };
|
|
51559
52024
|
try {
|
|
51560
52025
|
return {
|
|
51561
|
-
value: import_comment_json12.parse(
|
|
52026
|
+
value: import_comment_json12.parse(readFileSync33(path, "utf-8"))
|
|
51562
52027
|
};
|
|
51563
52028
|
} catch (error) {
|
|
51564
52029
|
return {
|
|
@@ -51574,7 +52039,7 @@ function readConfigDiagnostic(path) {
|
|
|
51574
52039
|
const parsed = readJsonc(path);
|
|
51575
52040
|
return {
|
|
51576
52041
|
path,
|
|
51577
|
-
exists:
|
|
52042
|
+
exists: existsSync50(path),
|
|
51578
52043
|
...parsed.parseError ? { parseError: parsed.parseError } : {},
|
|
51579
52044
|
flags: sanitizeValue2(parsed.value)
|
|
51580
52045
|
};
|
|
@@ -51592,25 +52057,25 @@ function reverseSlugToDirectory(slug) {
|
|
|
51592
52057
|
}
|
|
51593
52058
|
function collectPiRecentSessions() {
|
|
51594
52059
|
const sessionsRoot = getPiSessionsRoot();
|
|
51595
|
-
if (!
|
|
52060
|
+
if (!existsSync50(sessionsRoot))
|
|
51596
52061
|
return [];
|
|
51597
52062
|
try {
|
|
51598
|
-
const slugs =
|
|
52063
|
+
const slugs = readdirSync11(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
51599
52064
|
const candidates = [];
|
|
51600
52065
|
for (const slug of slugs) {
|
|
51601
52066
|
const directory = reverseSlugToDirectory(slug);
|
|
51602
52067
|
if (!directory)
|
|
51603
52068
|
continue;
|
|
51604
|
-
const slugDir =
|
|
52069
|
+
const slugDir = join41(sessionsRoot, slug);
|
|
51605
52070
|
let files;
|
|
51606
52071
|
try {
|
|
51607
|
-
files =
|
|
52072
|
+
files = readdirSync11(slugDir).filter((name) => name.endsWith(".jsonl"));
|
|
51608
52073
|
} catch {
|
|
51609
52074
|
continue;
|
|
51610
52075
|
}
|
|
51611
52076
|
for (const file of files) {
|
|
51612
52077
|
try {
|
|
51613
|
-
const mtime =
|
|
52078
|
+
const mtime = statSync26(join41(slugDir, file)).mtimeMs;
|
|
51614
52079
|
const sessionId = file.replace(/\.jsonl$/, "");
|
|
51615
52080
|
candidates.push({ sessionId, directory, mtime });
|
|
51616
52081
|
} catch {}
|
|
@@ -51628,7 +52093,7 @@ function collectPiRecentSessions() {
|
|
|
51628
52093
|
}
|
|
51629
52094
|
function parseHistorianDumpMeta2(path) {
|
|
51630
52095
|
try {
|
|
51631
|
-
const xml =
|
|
52096
|
+
const xml = readFileSync33(path, "utf-8");
|
|
51632
52097
|
const parsed = parseCompartmentOutput(xml);
|
|
51633
52098
|
const factCountByCategory = {};
|
|
51634
52099
|
for (const fact of parsed.facts) {
|
|
@@ -51661,11 +52126,11 @@ function parseHistorianDumpMeta2(path) {
|
|
|
51661
52126
|
}
|
|
51662
52127
|
}
|
|
51663
52128
|
function listDumpsInDir2(dir, limit) {
|
|
51664
|
-
if (!
|
|
52129
|
+
if (!existsSync50(dir))
|
|
51665
52130
|
return { count: 0, recent: [] };
|
|
51666
52131
|
try {
|
|
51667
|
-
const entries =
|
|
51668
|
-
const stat =
|
|
52132
|
+
const entries = readdirSync11(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
52133
|
+
const stat = statSync26(join41(dir, name));
|
|
51669
52134
|
return {
|
|
51670
52135
|
name,
|
|
51671
52136
|
mtime: stat.mtimeMs,
|
|
@@ -51674,7 +52139,7 @@ function listDumpsInDir2(dir, limit) {
|
|
|
51674
52139
|
}).sort((a, b) => b.mtime - a.mtime);
|
|
51675
52140
|
const now = Date.now();
|
|
51676
52141
|
const recent = entries.slice(0, limit).map((entry) => {
|
|
51677
|
-
const meta = parseHistorianDumpMeta2(
|
|
52142
|
+
const meta = parseHistorianDumpMeta2(join41(dir, entry.name));
|
|
51678
52143
|
const summary = {
|
|
51679
52144
|
name: entry.name,
|
|
51680
52145
|
ageMinutes: Math.round((now - entry.mtime) / 60000),
|
|
@@ -51738,7 +52203,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
51738
52203
|
const loaded = loadPiConfig({ cwd });
|
|
51739
52204
|
const storageResolution = getMagicContextStorageResolution();
|
|
51740
52205
|
const storageDirPath = storageResolution.path;
|
|
51741
|
-
const dbPath =
|
|
52206
|
+
const dbPath = join41(storageDirPath, "context.db");
|
|
51742
52207
|
const logFiles = inspectMagicContextLogs("pi");
|
|
51743
52208
|
const primaryLog = logFiles.find((file) => file.exists) ?? logFiles[0];
|
|
51744
52209
|
const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
|
|
@@ -51755,7 +52220,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
51755
52220
|
piVersion: pi ? getPiVersion(pi.path) : null,
|
|
51756
52221
|
settings: {
|
|
51757
52222
|
path: settingsPath,
|
|
51758
|
-
exists:
|
|
52223
|
+
exists: existsSync50(settingsPath),
|
|
51759
52224
|
...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
|
|
51760
52225
|
hasMagicContextPackage: hasPiMagicContextPackage(packages),
|
|
51761
52226
|
packages: sanitizeValue2(packages)
|
|
@@ -51772,7 +52237,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
51772
52237
|
storageDir: {
|
|
51773
52238
|
path: storageDirPath,
|
|
51774
52239
|
source: storageResolution.source,
|
|
51775
|
-
exists:
|
|
52240
|
+
exists: existsSync50(storageDirPath),
|
|
51776
52241
|
contextDbSizeBytes: fileSize2(dbPath)
|
|
51777
52242
|
},
|
|
51778
52243
|
conflicts: {
|
|
@@ -51807,6 +52272,7 @@ function renderDiagnosticsMarkdown2(report) {
|
|
|
51807
52272
|
exists: report.storageDir.exists,
|
|
51808
52273
|
context_db_size: formatBytes2(report.storageDir.contextDbSizeBytes)
|
|
51809
52274
|
};
|
|
52275
|
+
const storageBackupWarning = isMagicContextStorageOutsideEngram(report.storageDir.path) ? `- Warning: Magic Context storage is at ${sanitizeString2(report.storageDir.path)}, outside the folder Engram backs up (~/.local/share/cortexkit/magic-context). It is not included in CortexKit backups.` : null;
|
|
51810
52276
|
return [
|
|
51811
52277
|
`- Timestamp: ${report.timestamp}`,
|
|
51812
52278
|
`- Pi plugin: v${report.pluginVersion}`,
|
|
@@ -51847,6 +52313,7 @@ function renderDiagnosticsMarkdown2(report) {
|
|
|
51847
52313
|
`),
|
|
51848
52314
|
"",
|
|
51849
52315
|
"### Shared storage",
|
|
52316
|
+
...storageBackupWarning ? [storageBackupWarning] : [],
|
|
51850
52317
|
"```json",
|
|
51851
52318
|
JSON.stringify(storage, null, 2),
|
|
51852
52319
|
"```",
|
|
@@ -51877,8 +52344,8 @@ var init_diagnostics_pi = __esm(() => {
|
|
|
51877
52344
|
});
|
|
51878
52345
|
|
|
51879
52346
|
// src/lib/logs-pi.ts
|
|
51880
|
-
import { mkdirSync as
|
|
51881
|
-
import { dirname as
|
|
52347
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "node:fs";
|
|
52348
|
+
import { dirname as dirname28, join as join42 } from "node:path";
|
|
51882
52349
|
function formatTimestamp2(date) {
|
|
51883
52350
|
const pad = (value) => String(value).padStart(2, "0");
|
|
51884
52351
|
return [
|
|
@@ -51932,13 +52399,13 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
51932
52399
|
const truncated = bodyMarkdown !== rawBodyMarkdown;
|
|
51933
52400
|
const cwd = options.cwd ?? process.cwd();
|
|
51934
52401
|
const timestamp = formatTimestamp2(options.now ?? new Date);
|
|
51935
|
-
const path = options.outputPath ??
|
|
51936
|
-
|
|
51937
|
-
|
|
52402
|
+
const path = options.outputPath ?? join42(cwd, `magic-context-pi-issue-${timestamp}.md`);
|
|
52403
|
+
mkdirSync10(dirname28(path), { recursive: true });
|
|
52404
|
+
writeFileSync10(path, `${bodyMarkdown}
|
|
51938
52405
|
`);
|
|
51939
|
-
const fullPath = truncated ? options.outputPath ? `${options.outputPath}.full.md` :
|
|
52406
|
+
const fullPath = truncated ? options.outputPath ? `${options.outputPath}.full.md` : join42(cwd, `magic-context-pi-issue-${timestamp}-full.md`) : undefined;
|
|
51940
52407
|
if (fullPath)
|
|
51941
|
-
|
|
52408
|
+
writeFileSync10(fullPath, `${rawBodyMarkdown}
|
|
51942
52409
|
`);
|
|
51943
52410
|
return { path, bodyMarkdown, ...fullPath ? { fullPath } : {}, truncated };
|
|
51944
52411
|
}
|
|
@@ -51950,10 +52417,10 @@ var init_logs_pi = __esm(() => {
|
|
|
51950
52417
|
|
|
51951
52418
|
// src/commands/doctor-pi.ts
|
|
51952
52419
|
import { execFileSync as execFileSync9, spawnSync as spawnSync11 } from "node:child_process";
|
|
51953
|
-
import { existsSync as
|
|
52420
|
+
import { existsSync as existsSync51, readdirSync as readdirSync12, readFileSync as readFileSync34, rmSync as rmSync10, statSync as statSync27 } from "node:fs";
|
|
51954
52421
|
import { createRequire as createRequire8 } from "node:module";
|
|
51955
52422
|
import { homedir as homedir22 } from "node:os";
|
|
51956
|
-
import { isAbsolute as isAbsolute9, join as
|
|
52423
|
+
import { isAbsolute as isAbsolute9, join as join43 } from "node:path";
|
|
51957
52424
|
function depsFrom(options) {
|
|
51958
52425
|
return {
|
|
51959
52426
|
...DEFAULT_DEPS5,
|
|
@@ -52045,7 +52512,7 @@ function summarize(results) {
|
|
|
52045
52512
|
function readJsonc2(path) {
|
|
52046
52513
|
try {
|
|
52047
52514
|
return {
|
|
52048
|
-
value: import_comment_json13.parse(
|
|
52515
|
+
value: import_comment_json13.parse(readFileSync34(path, "utf-8"))
|
|
52049
52516
|
};
|
|
52050
52517
|
} catch (error) {
|
|
52051
52518
|
return {
|
|
@@ -52095,15 +52562,15 @@ function piPluginDirCandidates(packages, cwd) {
|
|
|
52095
52562
|
if (resolved)
|
|
52096
52563
|
dirs.push(resolved);
|
|
52097
52564
|
}
|
|
52098
|
-
dirs.push(
|
|
52099
|
-
dirs.push(
|
|
52100
|
-
return dirs.filter((dir) =>
|
|
52565
|
+
dirs.push(join43(agentDir, "npm", "node_modules", PACKAGE_NAME2));
|
|
52566
|
+
dirs.push(join43(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME2));
|
|
52567
|
+
return dirs.filter((dir) => existsSync51(join43(dir, "package.json")));
|
|
52101
52568
|
}
|
|
52102
52569
|
function projectConfigPath(cwd) {
|
|
52103
52570
|
return resolveCortexKitProjectConfigPath(cwd);
|
|
52104
52571
|
}
|
|
52105
52572
|
function readConfigForEmbedding(path, isProjectConfig) {
|
|
52106
|
-
if (!
|
|
52573
|
+
if (!existsSync51(path))
|
|
52107
52574
|
return null;
|
|
52108
52575
|
try {
|
|
52109
52576
|
const raw = loadRawConfigFile({
|
|
@@ -52189,35 +52656,35 @@ function pinnedVersionFromPackageSpecifier(specifier) {
|
|
|
52189
52656
|
}
|
|
52190
52657
|
function cacheRoots(cwd) {
|
|
52191
52658
|
const home = process.env.HOME?.trim();
|
|
52192
|
-
const cacheHome = process.env.XDG_CACHE_HOME ||
|
|
52659
|
+
const cacheHome = process.env.XDG_CACHE_HOME || join43(home || homedir22(), ".cache");
|
|
52193
52660
|
const piCacheRoot = getPiCacheRoot();
|
|
52194
52661
|
return [
|
|
52195
|
-
|
|
52196
|
-
|
|
52197
|
-
|
|
52198
|
-
|
|
52199
|
-
|
|
52200
|
-
|
|
52201
|
-
|
|
52662
|
+
join43(piCacheRoot, "extensions"),
|
|
52663
|
+
join43(piCacheRoot, "packages"),
|
|
52664
|
+
join43(cacheHome, "pi", "extensions"),
|
|
52665
|
+
join43(cacheHome, "pi", "packages"),
|
|
52666
|
+
join43(getPiAgentConfigDir(), "cache", "extensions"),
|
|
52667
|
+
join43(getPiAgentConfigDir(), "npm", "node_modules", PACKAGE_NAME2),
|
|
52668
|
+
join43(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME2)
|
|
52202
52669
|
];
|
|
52203
52670
|
}
|
|
52204
52671
|
function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
|
|
52205
52672
|
const found = new Map;
|
|
52206
52673
|
const visit = (path, depth) => {
|
|
52207
|
-
if (depth < 0 || !
|
|
52674
|
+
if (depth < 0 || !existsSync51(path))
|
|
52208
52675
|
return;
|
|
52209
52676
|
let stat;
|
|
52210
52677
|
try {
|
|
52211
|
-
stat =
|
|
52678
|
+
stat = statSync27(path);
|
|
52212
52679
|
} catch {
|
|
52213
52680
|
return;
|
|
52214
52681
|
}
|
|
52215
52682
|
if (!stat.isDirectory())
|
|
52216
52683
|
return;
|
|
52217
|
-
const packageJson =
|
|
52218
|
-
if (
|
|
52684
|
+
const packageJson = join43(path, "package.json");
|
|
52685
|
+
if (existsSync51(packageJson)) {
|
|
52219
52686
|
try {
|
|
52220
|
-
const pkg = JSON.parse(
|
|
52687
|
+
const pkg = JSON.parse(readFileSync34(packageJson, "utf-8"));
|
|
52221
52688
|
const name = typeof pkg.name === "string" ? pkg.name : "";
|
|
52222
52689
|
const version = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
52223
52690
|
if (name === PACKAGE_NAME2) {
|
|
@@ -52232,12 +52699,12 @@ function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
|
|
|
52232
52699
|
}
|
|
52233
52700
|
let entries = [];
|
|
52234
52701
|
try {
|
|
52235
|
-
entries =
|
|
52702
|
+
entries = readdirSync12(path);
|
|
52236
52703
|
} catch {
|
|
52237
52704
|
return;
|
|
52238
52705
|
}
|
|
52239
52706
|
for (const entry of entries)
|
|
52240
|
-
visit(
|
|
52707
|
+
visit(join43(path, entry), depth - 1);
|
|
52241
52708
|
};
|
|
52242
52709
|
for (const root of cacheRoots(cwd))
|
|
52243
52710
|
visit(root, 5);
|
|
@@ -52298,7 +52765,7 @@ async function runHealthChecks2(options) {
|
|
|
52298
52765
|
const settingsPath = getPiUserExtensionsPath();
|
|
52299
52766
|
let packages = [];
|
|
52300
52767
|
let piPluginInstalled = false;
|
|
52301
|
-
if (!
|
|
52768
|
+
if (!existsSync51(settingsPath)) {
|
|
52302
52769
|
if (pi) {
|
|
52303
52770
|
add2(results, "info", `${piVersion ? `Pi ${piVersion}` : "Pi"} found; Magic Context is not installed there (run setup to add it)`);
|
|
52304
52771
|
}
|
|
@@ -52340,7 +52807,7 @@ async function runHealthChecks2(options) {
|
|
|
52340
52807
|
["user", userConfigPath, true],
|
|
52341
52808
|
["project", projectPath, false]
|
|
52342
52809
|
]) {
|
|
52343
|
-
if (!
|
|
52810
|
+
if (!existsSync51(path)) {
|
|
52344
52811
|
if (required) {
|
|
52345
52812
|
add2(results, "warn", `No ${label} magic-context.jsonc found at ${path}`);
|
|
52346
52813
|
if (userConfigMigrationRefused) {
|
|
@@ -52386,9 +52853,12 @@ async function runHealthChecks2(options) {
|
|
|
52386
52853
|
checkPiModelChains(results, pi, loadedConfig.config, options.deps);
|
|
52387
52854
|
const storage = getMagicContextStorageResolution();
|
|
52388
52855
|
const storageDir = storage.path;
|
|
52389
|
-
const dbPath =
|
|
52856
|
+
const dbPath = join43(storageDir, "context.db");
|
|
52857
|
+
if (isMagicContextStorageOutsideEngram(storageDir)) {
|
|
52858
|
+
add2(results, "warn", `Magic Context storage is at ${storageDir}, outside the folder Engram backs up (~/.local/share/cortexkit/magic-context). It is not included in CortexKit backups.`);
|
|
52859
|
+
}
|
|
52390
52860
|
add2(results, "info", `Shared storage: ${storageDir} (source: ${storage.source})`);
|
|
52391
|
-
const existedBeforeOpen =
|
|
52861
|
+
const existedBeforeOpen = existsSync51(dbPath);
|
|
52392
52862
|
if (existedBeforeOpen)
|
|
52393
52863
|
add2(results, "pass", `Shared context DB exists at ${dbPath}`);
|
|
52394
52864
|
else
|
|
@@ -52617,7 +53087,7 @@ function writeDefaultMagicContextConfig(path) {
|
|
|
52617
53087
|
function repair2(plan, prompts) {
|
|
52618
53088
|
let fixed = 0;
|
|
52619
53089
|
for (const path of plan.reasoningAgeConfigPaths) {
|
|
52620
|
-
const content =
|
|
53090
|
+
const content = readFileSync34(path, "utf8");
|
|
52621
53091
|
const parsed = readJsonc2(path);
|
|
52622
53092
|
if (parsed.error)
|
|
52623
53093
|
continue;
|
|
@@ -52643,7 +53113,7 @@ function repair2(plan, prompts) {
|
|
|
52643
53113
|
}
|
|
52644
53114
|
if (plan.writeUserConfig) {
|
|
52645
53115
|
const configPath = getPiUserConfigPath();
|
|
52646
|
-
if (!
|
|
53116
|
+
if (!existsSync51(configPath)) {
|
|
52647
53117
|
try {
|
|
52648
53118
|
writeDefaultMagicContextConfig(configPath);
|
|
52649
53119
|
prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
|
|
@@ -52697,7 +53167,7 @@ async function runIssueFlow3(options) {
|
|
|
52697
53167
|
if (options.reportPath) {
|
|
52698
53168
|
try {
|
|
52699
53169
|
const report = await options.deps.collectDiagnostics(options.cwd);
|
|
52700
|
-
const outputPath = isAbsolute9(options.reportPath) ? options.reportPath :
|
|
53170
|
+
const outputPath = isAbsolute9(options.reportPath) ? options.reportPath : join43(options.cwd, options.reportPath);
|
|
52701
53171
|
const bundled = await bundleIssueReport2(report, "Generated non-interactively by `doctor --issue --report`.", "Magic Context diagnostic report", { cwd: options.cwd, now: options.deps.now(), outputPath });
|
|
52702
53172
|
options.prompts.log.info(`Report written to ${bundled.path}`);
|
|
52703
53173
|
return 0;
|
|
@@ -52781,7 +53251,7 @@ async function runDoctor3(options = {}) {
|
|
|
52781
53251
|
const v22Result = await runV22BackfillCommands({
|
|
52782
53252
|
name: "Pi",
|
|
52783
53253
|
openDatabase: (readonly = true) => {
|
|
52784
|
-
const dbPath =
|
|
53254
|
+
const dbPath = join43(getMagicContextStorageDir(), "context.db");
|
|
52785
53255
|
v22Db = readonly ? openExistingContextDatabase(dbPath, { readonly: true }) : openExistingContextDatabaseForMutation(dbPath);
|
|
52786
53256
|
return v22Db;
|
|
52787
53257
|
},
|
|
@@ -52899,8 +53369,8 @@ var init_doctor_pi = __esm(async () => {
|
|
|
52899
53369
|
});
|
|
52900
53370
|
|
|
52901
53371
|
// src/commands/doctor.ts
|
|
52902
|
-
import { existsSync as
|
|
52903
|
-
import { join as
|
|
53372
|
+
import { existsSync as existsSync52, rmSync as rmSync11 } from "node:fs";
|
|
53373
|
+
import { join as join44 } from "node:path";
|
|
52904
53374
|
async function runDoctor4(options) {
|
|
52905
53375
|
if (options.clear)
|
|
52906
53376
|
return runClear();
|
|
@@ -52918,7 +53388,7 @@ async function runDoctor4(options) {
|
|
|
52918
53388
|
const result = await runV22BackfillCommands({
|
|
52919
53389
|
name: "Magic Context",
|
|
52920
53390
|
openDatabase: (readonly = true) => {
|
|
52921
|
-
const dbPath =
|
|
53391
|
+
const dbPath = join44(getMagicContextStorageDir(), "context.db");
|
|
52922
53392
|
v22Db = readonly ? openExistingContextDatabase(dbPath, { readonly: true }) : openExistingContextDatabaseForMutation(dbPath);
|
|
52923
53393
|
return v22Db;
|
|
52924
53394
|
},
|
|
@@ -52938,7 +53408,7 @@ async function runDoctor4(options) {
|
|
|
52938
53408
|
log3.warn(`Identity split check unavailable: ${error instanceof Error ? error.message : String(error)}`);
|
|
52939
53409
|
}
|
|
52940
53410
|
await init_migrate();
|
|
52941
|
-
const sweepDbPath =
|
|
53411
|
+
const sweepDbPath = join44(getMagicContextStorageDir(), "context.db");
|
|
52942
53412
|
let sweepDb = null;
|
|
52943
53413
|
try {
|
|
52944
53414
|
sweepDb = openExistingContextDatabaseForMutation(sweepDbPath);
|
|
@@ -53055,7 +53525,7 @@ async function runClear() {
|
|
|
53055
53525
|
failed += 1;
|
|
53056
53526
|
continue;
|
|
53057
53527
|
}
|
|
53058
|
-
} else if (
|
|
53528
|
+
} else if (existsSync52(item.path)) {
|
|
53059
53529
|
rmSync11(item.path, { recursive: true, force: true });
|
|
53060
53530
|
}
|
|
53061
53531
|
s.stop(`Cleared ${item.path}`);
|