@cortexkit/opencode-magic-context 0.30.6 → 0.30.7
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/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/open-opencode-db.d.ts +3 -1
- package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-backfill.d.ts +31 -0
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +749 -531
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15446,6 +15446,340 @@ var init_magic_context = __esm(() => {
|
|
|
15446
15446
|
});
|
|
15447
15447
|
});
|
|
15448
15448
|
|
|
15449
|
+
// src/shared/error-message.ts
|
|
15450
|
+
function getErrorMessage(error51) {
|
|
15451
|
+
return error51 instanceof Error ? error51.message : String(error51);
|
|
15452
|
+
}
|
|
15453
|
+
function readString(value) {
|
|
15454
|
+
if (typeof value === "string" && value.length > 0)
|
|
15455
|
+
return value;
|
|
15456
|
+
if (typeof value === "number")
|
|
15457
|
+
return String(value);
|
|
15458
|
+
return;
|
|
15459
|
+
}
|
|
15460
|
+
function clip(value, max) {
|
|
15461
|
+
if (value.length <= max)
|
|
15462
|
+
return value;
|
|
15463
|
+
return `${value.slice(0, max)}…`;
|
|
15464
|
+
}
|
|
15465
|
+
function describeError(error51) {
|
|
15466
|
+
const stringForm = clip(safeString(error51), 400);
|
|
15467
|
+
if (!(error51 instanceof Error) && !(error51 && typeof error51 === "object")) {
|
|
15468
|
+
return {
|
|
15469
|
+
name: typeof error51,
|
|
15470
|
+
message: "",
|
|
15471
|
+
stringForm,
|
|
15472
|
+
brief: stringForm || "<empty>"
|
|
15473
|
+
};
|
|
15474
|
+
}
|
|
15475
|
+
const obj = error51;
|
|
15476
|
+
const nameFromField = readString(obj.name);
|
|
15477
|
+
const nameFromCtor = error51?.constructor?.name;
|
|
15478
|
+
const name = nameFromField ?? nameFromCtor ?? "Error";
|
|
15479
|
+
const message = readString(obj.message) ?? "";
|
|
15480
|
+
const status = readString(obj.status) ?? readString(obj.statusCode);
|
|
15481
|
+
const code = readString(obj.code);
|
|
15482
|
+
let causeName;
|
|
15483
|
+
const cause = obj.cause;
|
|
15484
|
+
if (cause && typeof cause === "object") {
|
|
15485
|
+
const causeRecord = cause;
|
|
15486
|
+
causeName = readString(causeRecord.name) ?? cause.constructor?.name;
|
|
15487
|
+
}
|
|
15488
|
+
const stack = readString(obj.stack);
|
|
15489
|
+
const stackHead = stack ? stack.split(`
|
|
15490
|
+
`).slice(0, 4).map((l) => l.trim()).filter((l) => l.length > 0).join(" | ") : undefined;
|
|
15491
|
+
const briefParts = [];
|
|
15492
|
+
if (name)
|
|
15493
|
+
briefParts.push(name);
|
|
15494
|
+
if (message)
|
|
15495
|
+
briefParts.push(`message="${clip(message, 200)}"`);
|
|
15496
|
+
if (status)
|
|
15497
|
+
briefParts.push(`status=${status}`);
|
|
15498
|
+
if (code)
|
|
15499
|
+
briefParts.push(`code=${code}`);
|
|
15500
|
+
if (causeName)
|
|
15501
|
+
briefParts.push(`cause=${causeName}`);
|
|
15502
|
+
if (!message && stringForm && stringForm !== name) {
|
|
15503
|
+
briefParts.push(`str="${clip(stringForm, 200)}"`);
|
|
15504
|
+
}
|
|
15505
|
+
const brief = briefParts.join(" ") || stringForm || name;
|
|
15506
|
+
return {
|
|
15507
|
+
name,
|
|
15508
|
+
message,
|
|
15509
|
+
...status ? { status } : {},
|
|
15510
|
+
...code ? { code } : {},
|
|
15511
|
+
...causeName ? { causeName } : {},
|
|
15512
|
+
...stackHead ? { stackHead } : {},
|
|
15513
|
+
stringForm,
|
|
15514
|
+
brief
|
|
15515
|
+
};
|
|
15516
|
+
}
|
|
15517
|
+
function safeString(value) {
|
|
15518
|
+
try {
|
|
15519
|
+
return String(value);
|
|
15520
|
+
} catch {
|
|
15521
|
+
return "<unstringifiable>";
|
|
15522
|
+
}
|
|
15523
|
+
}
|
|
15524
|
+
|
|
15525
|
+
// src/shared/sqlite.ts
|
|
15526
|
+
function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
15527
|
+
const SAVEPOINT = "mc_tx_sp";
|
|
15528
|
+
|
|
15529
|
+
class NodeSqliteDatabase extends DatabaseSync {
|
|
15530
|
+
constructor(filename, options) {
|
|
15531
|
+
const translated = { ...options };
|
|
15532
|
+
if (options && "readonly" in options) {
|
|
15533
|
+
translated.readOnly = options.readonly;
|
|
15534
|
+
delete translated.readonly;
|
|
15535
|
+
}
|
|
15536
|
+
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
15537
|
+
}
|
|
15538
|
+
prepare(sql) {
|
|
15539
|
+
const stmt = super.prepare(sql);
|
|
15540
|
+
for (const method of ["run", "get", "all"]) {
|
|
15541
|
+
const original = stmt[method].bind(stmt);
|
|
15542
|
+
stmt[method] = (...args) => args.length === 1 && Array.isArray(args[0]) ? original(...args[0]) : original(...args);
|
|
15543
|
+
}
|
|
15544
|
+
return stmt;
|
|
15545
|
+
}
|
|
15546
|
+
transaction(fn) {
|
|
15547
|
+
const self2 = this;
|
|
15548
|
+
const wrapped = function(...args) {
|
|
15549
|
+
const nested = self2.isTransaction === true;
|
|
15550
|
+
self2.exec(nested ? `SAVEPOINT ${SAVEPOINT}` : "BEGIN");
|
|
15551
|
+
try {
|
|
15552
|
+
const result = fn.apply(this, args);
|
|
15553
|
+
self2.exec(nested ? `RELEASE ${SAVEPOINT}` : "COMMIT");
|
|
15554
|
+
return result;
|
|
15555
|
+
} catch (error51) {
|
|
15556
|
+
if (nested) {
|
|
15557
|
+
self2.exec(`ROLLBACK TO ${SAVEPOINT}`);
|
|
15558
|
+
self2.exec(`RELEASE ${SAVEPOINT}`);
|
|
15559
|
+
} else {
|
|
15560
|
+
self2.exec("ROLLBACK");
|
|
15561
|
+
}
|
|
15562
|
+
throw error51;
|
|
15563
|
+
}
|
|
15564
|
+
};
|
|
15565
|
+
return wrapped;
|
|
15566
|
+
}
|
|
15567
|
+
}
|
|
15568
|
+
return NodeSqliteDatabase;
|
|
15569
|
+
}
|
|
15570
|
+
var isBun, bunSpec, nodeSpec, sqliteModule, DatabaseImpl, Database;
|
|
15571
|
+
var init_sqlite = __esm(async () => {
|
|
15572
|
+
isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
15573
|
+
bunSpec = "bun:" + "sqlite";
|
|
15574
|
+
nodeSpec = "node:" + "sqlite";
|
|
15575
|
+
sqliteModule = isBun ? await import(bunSpec) : await import(nodeSpec);
|
|
15576
|
+
DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
15577
|
+
Database = DatabaseImpl;
|
|
15578
|
+
});
|
|
15579
|
+
|
|
15580
|
+
// src/shared/sqlite-helpers.ts
|
|
15581
|
+
function closeQuietly(db) {
|
|
15582
|
+
if (!db)
|
|
15583
|
+
return;
|
|
15584
|
+
try {
|
|
15585
|
+
db.close();
|
|
15586
|
+
} catch {}
|
|
15587
|
+
}
|
|
15588
|
+
|
|
15589
|
+
// src/features/magic-context/compaction-marker.ts
|
|
15590
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
15591
|
+
import { join as join3 } from "node:path";
|
|
15592
|
+
function randomBase62(length) {
|
|
15593
|
+
const chars = [];
|
|
15594
|
+
for (let i = 0;i < length; i++) {
|
|
15595
|
+
chars.push(BASE62_CHARS[Math.floor(Math.random() * BASE62_CHARS.length)]);
|
|
15596
|
+
}
|
|
15597
|
+
return chars.join("");
|
|
15598
|
+
}
|
|
15599
|
+
function generateId(prefix, timestampMs, counter = 0n) {
|
|
15600
|
+
const encoded = BigInt(timestampMs) * 0x1000n + counter;
|
|
15601
|
+
const hex3 = encoded.toString(16).padStart(14, "0");
|
|
15602
|
+
return `${prefix}_${hex3}${randomBase62(14)}`;
|
|
15603
|
+
}
|
|
15604
|
+
function generateMessageId(timestampMs, counter = 0n) {
|
|
15605
|
+
return generateId("msg", timestampMs, counter);
|
|
15606
|
+
}
|
|
15607
|
+
function generatePartId(timestampMs, counter = 0n) {
|
|
15608
|
+
return generateId("prt", timestampMs, counter);
|
|
15609
|
+
}
|
|
15610
|
+
function getOpenCodeDbPath() {
|
|
15611
|
+
return join3(getDataDir(), "opencode", "opencode.db");
|
|
15612
|
+
}
|
|
15613
|
+
function isOpenCodeSchemaCompatible(db, dbPath) {
|
|
15614
|
+
if (cachedSchemaCompatible?.path === dbPath) {
|
|
15615
|
+
return cachedSchemaCompatible.compatible;
|
|
15616
|
+
}
|
|
15617
|
+
try {
|
|
15618
|
+
const messageCols = new Set(db.prepare("PRAGMA table_info(message)").all().map((r) => r.name ?? "").filter((n) => n.length > 0));
|
|
15619
|
+
const partCols = new Set(db.prepare("PRAGMA table_info(part)").all().map((r) => r.name ?? "").filter((n) => n.length > 0));
|
|
15620
|
+
const missingMessage = REQUIRED_MESSAGE_COLUMNS.filter((c) => !messageCols.has(c));
|
|
15621
|
+
const missingPart = REQUIRED_PART_COLUMNS.filter((c) => !partCols.has(c));
|
|
15622
|
+
if (missingMessage.length > 0 || missingPart.length > 0) {
|
|
15623
|
+
log(`[magic-context] compaction-marker: OpenCode DB schema missing required columns ` + `(message: [${missingMessage.join(", ")}], part: [${missingPart.join(", ")}]). ` + `Marker injection disabled for this process. ` + `This usually means OpenCode was updated and magic-context is out of date.`);
|
|
15624
|
+
cachedSchemaCompatible = { path: dbPath, compatible: false };
|
|
15625
|
+
return false;
|
|
15626
|
+
}
|
|
15627
|
+
cachedSchemaCompatible = { path: dbPath, compatible: true };
|
|
15628
|
+
return true;
|
|
15629
|
+
} catch (error51) {
|
|
15630
|
+
log(`[magic-context] compaction-marker: schema probe failed: ${error51 instanceof Error ? error51.message : String(error51)}. ` + `Marker injection disabled until next process restart.`);
|
|
15631
|
+
cachedSchemaCompatible = { path: dbPath, compatible: false };
|
|
15632
|
+
return false;
|
|
15633
|
+
}
|
|
15634
|
+
}
|
|
15635
|
+
function getWritableOpenCodeDb() {
|
|
15636
|
+
const dbPath = getOpenCodeDbPath();
|
|
15637
|
+
if (cachedWriteDb?.path === dbPath) {
|
|
15638
|
+
return cachedWriteDb.db;
|
|
15639
|
+
}
|
|
15640
|
+
if (cachedWriteDb) {
|
|
15641
|
+
try {
|
|
15642
|
+
closeQuietly(cachedWriteDb.db);
|
|
15643
|
+
} catch {}
|
|
15644
|
+
}
|
|
15645
|
+
if (!existsSync6(dbPath)) {
|
|
15646
|
+
throw new Error(`OpenCode database not found at ${dbPath} (is OpenCode installed?)`);
|
|
15647
|
+
}
|
|
15648
|
+
const db = new Database(dbPath);
|
|
15649
|
+
db.exec("PRAGMA busy_timeout=5000");
|
|
15650
|
+
db.exec("PRAGMA journal_mode=WAL");
|
|
15651
|
+
cachedWriteDb = { path: dbPath, db };
|
|
15652
|
+
return db;
|
|
15653
|
+
}
|
|
15654
|
+
function getNonSummaryMessageSortKey(sessionId, messageId) {
|
|
15655
|
+
const db = getWritableOpenCodeDb();
|
|
15656
|
+
const row = db.prepare(`SELECT time_created, id
|
|
15657
|
+
FROM message
|
|
15658
|
+
WHERE session_id = ?
|
|
15659
|
+
AND id = ?
|
|
15660
|
+
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
15661
|
+
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')
|
|
15662
|
+
LIMIT 1`).get(sessionId, messageId);
|
|
15663
|
+
if (typeof row?.time_created !== "number" || typeof row.id !== "string") {
|
|
15664
|
+
return null;
|
|
15665
|
+
}
|
|
15666
|
+
return { id: row.id, timeCreated: row.time_created };
|
|
15667
|
+
}
|
|
15668
|
+
function findBoundaryUserMessage(sessionId, endMessageId) {
|
|
15669
|
+
const db = getWritableOpenCodeDb();
|
|
15670
|
+
const target = getNonSummaryMessageSortKey(sessionId, endMessageId);
|
|
15671
|
+
if (!target)
|
|
15672
|
+
return null;
|
|
15673
|
+
const boundary = db.prepare(`SELECT id, time_created, data
|
|
15674
|
+
FROM message
|
|
15675
|
+
WHERE session_id = ?
|
|
15676
|
+
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
15677
|
+
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')
|
|
15678
|
+
AND COALESCE(json_extract(data, '$.role'), '') = 'user'
|
|
15679
|
+
AND (time_created < ? OR (time_created = ? AND id <= ?))
|
|
15680
|
+
ORDER BY time_created DESC, id DESC
|
|
15681
|
+
LIMIT 1`).get(sessionId, target.timeCreated, target.timeCreated, target.id);
|
|
15682
|
+
if (typeof boundary?.id !== "string" || typeof boundary.time_created !== "number") {
|
|
15683
|
+
return null;
|
|
15684
|
+
}
|
|
15685
|
+
return { id: boundary.id, timeCreated: boundary.time_created };
|
|
15686
|
+
}
|
|
15687
|
+
function compareOpenCodeMessagesByCanonicalOrder(sessionId, leftMessageId, rightMessageId) {
|
|
15688
|
+
const left = getNonSummaryMessageSortKey(sessionId, leftMessageId);
|
|
15689
|
+
const right = getNonSummaryMessageSortKey(sessionId, rightMessageId);
|
|
15690
|
+
if (!left || !right)
|
|
15691
|
+
return null;
|
|
15692
|
+
if (left.timeCreated < right.timeCreated)
|
|
15693
|
+
return -1;
|
|
15694
|
+
if (left.timeCreated > right.timeCreated)
|
|
15695
|
+
return 1;
|
|
15696
|
+
if (left.id < right.id)
|
|
15697
|
+
return -1;
|
|
15698
|
+
if (left.id > right.id)
|
|
15699
|
+
return 1;
|
|
15700
|
+
return 0;
|
|
15701
|
+
}
|
|
15702
|
+
function getOpenCodeMessageById(sessionId, messageId) {
|
|
15703
|
+
const db = getWritableOpenCodeDb();
|
|
15704
|
+
const row = db.prepare(`SELECT id FROM message WHERE session_id = ? AND id = ? LIMIT 1`).get(sessionId, messageId);
|
|
15705
|
+
return row ?? null;
|
|
15706
|
+
}
|
|
15707
|
+
function injectCompactionMarker(args) {
|
|
15708
|
+
const db = getWritableOpenCodeDb();
|
|
15709
|
+
if (!isOpenCodeSchemaCompatible(db, getOpenCodeDbPath())) {
|
|
15710
|
+
return null;
|
|
15711
|
+
}
|
|
15712
|
+
const boundary = args.resolvedBoundary ?? findBoundaryUserMessage(args.sessionId, args.endMessageId);
|
|
15713
|
+
if (!boundary) {
|
|
15714
|
+
log(`[magic-context] compaction-marker: no user message found at or before endMessageId ${args.endMessageId} (ordinal ${args.endOrdinal})`);
|
|
15715
|
+
return null;
|
|
15716
|
+
}
|
|
15717
|
+
const boundaryTime = boundary.timeCreated;
|
|
15718
|
+
const summaryMsgId = generateMessageId(boundaryTime + 1, 1n);
|
|
15719
|
+
const compactionPartId = generatePartId(boundaryTime, 1n);
|
|
15720
|
+
const summaryPartId = generatePartId(boundaryTime + 1, 2n);
|
|
15721
|
+
const summaryMsgData = JSON.stringify({
|
|
15722
|
+
role: "assistant",
|
|
15723
|
+
parentID: boundary.id,
|
|
15724
|
+
summary: true,
|
|
15725
|
+
finish: "stop",
|
|
15726
|
+
mode: "compaction",
|
|
15727
|
+
agent: "compaction",
|
|
15728
|
+
path: { cwd: args.directory, root: args.directory },
|
|
15729
|
+
cost: 0,
|
|
15730
|
+
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
15731
|
+
modelID: "magic-context",
|
|
15732
|
+
providerID: "magic-context",
|
|
15733
|
+
time: { created: boundaryTime + 1 }
|
|
15734
|
+
});
|
|
15735
|
+
try {
|
|
15736
|
+
db.transaction(() => {
|
|
15737
|
+
db.prepare("INSERT INTO part (id, message_id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?, ?)").run(compactionPartId, boundary.id, args.sessionId, boundaryTime, boundaryTime, '{"type":"compaction","auto":true}');
|
|
15738
|
+
db.prepare("INSERT INTO message (id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?)").run(summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, summaryMsgData);
|
|
15739
|
+
db.prepare("INSERT INTO part (id, message_id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?, ?)").run(summaryPartId, summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, JSON.stringify({ type: "text", text: args.summaryText }));
|
|
15740
|
+
})();
|
|
15741
|
+
log(`[magic-context] compaction-marker: injected boundary at user msg ${boundary.id} (ordinal ~${args.endOrdinal}), summary msg ${summaryMsgId}`);
|
|
15742
|
+
return {
|
|
15743
|
+
boundaryMessageId: boundary.id,
|
|
15744
|
+
summaryMessageId: summaryMsgId,
|
|
15745
|
+
compactionPartId,
|
|
15746
|
+
summaryPartId
|
|
15747
|
+
};
|
|
15748
|
+
} catch (error51) {
|
|
15749
|
+
log(`[magic-context] compaction-marker: injection failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
15750
|
+
return null;
|
|
15751
|
+
}
|
|
15752
|
+
}
|
|
15753
|
+
function removeCompactionMarker(state) {
|
|
15754
|
+
try {
|
|
15755
|
+
const db = getWritableOpenCodeDb();
|
|
15756
|
+
db.transaction(() => {
|
|
15757
|
+
db.prepare("DELETE FROM part WHERE id = ?").run(state.summaryPartId);
|
|
15758
|
+
db.prepare("DELETE FROM message WHERE id = ?").run(state.summaryMessageId);
|
|
15759
|
+
db.prepare("DELETE FROM part WHERE id = ?").run(state.compactionPartId);
|
|
15760
|
+
})();
|
|
15761
|
+
return true;
|
|
15762
|
+
} catch (error51) {
|
|
15763
|
+
log(`[magic-context] compaction-marker: removal failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
15764
|
+
return false;
|
|
15765
|
+
}
|
|
15766
|
+
}
|
|
15767
|
+
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", cachedWriteDb = null, REQUIRED_MESSAGE_COLUMNS, REQUIRED_PART_COLUMNS, cachedSchemaCompatible = null;
|
|
15768
|
+
var init_compaction_marker = __esm(async () => {
|
|
15769
|
+
init_data_path();
|
|
15770
|
+
init_logger();
|
|
15771
|
+
await init_sqlite();
|
|
15772
|
+
REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
15773
|
+
REQUIRED_PART_COLUMNS = [
|
|
15774
|
+
"id",
|
|
15775
|
+
"message_id",
|
|
15776
|
+
"session_id",
|
|
15777
|
+
"time_created",
|
|
15778
|
+
"time_updated",
|
|
15779
|
+
"data"
|
|
15780
|
+
];
|
|
15781
|
+
});
|
|
15782
|
+
|
|
15449
15783
|
// src/features/magic-context/memory/project-identity.ts
|
|
15450
15784
|
import { execFileSync } from "node:child_process";
|
|
15451
15785
|
import { createHash } from "node:crypto";
|
|
@@ -15625,6 +15959,80 @@ var init_project_identity = __esm(() => {
|
|
|
15625
15959
|
};
|
|
15626
15960
|
});
|
|
15627
15961
|
|
|
15962
|
+
// src/features/magic-context/session-project-storage.ts
|
|
15963
|
+
function getUpsertSessionProjectStatement(db) {
|
|
15964
|
+
let stmt = upsertSessionProjectStatements.get(db);
|
|
15965
|
+
if (!stmt) {
|
|
15966
|
+
stmt = db.prepare(`INSERT INTO session_projects (session_id, harness, project_path, updated_at)
|
|
15967
|
+
VALUES (?, ?, ?, ?)
|
|
15968
|
+
ON CONFLICT(session_id, harness) DO UPDATE SET
|
|
15969
|
+
project_path = excluded.project_path,
|
|
15970
|
+
updated_at = excluded.updated_at
|
|
15971
|
+
WHERE session_projects.project_path <> excluded.project_path`);
|
|
15972
|
+
upsertSessionProjectStatements.set(db, stmt);
|
|
15973
|
+
}
|
|
15974
|
+
return stmt;
|
|
15975
|
+
}
|
|
15976
|
+
function getRepairSessionChunkProjectStatement(db) {
|
|
15977
|
+
let stmt = repairSessionChunkProjectStatements.get(db);
|
|
15978
|
+
if (!stmt) {
|
|
15979
|
+
stmt = db.prepare(`UPDATE compartment_chunk_embeddings
|
|
15980
|
+
SET project_path = ?
|
|
15981
|
+
WHERE session_id = ?
|
|
15982
|
+
AND harness = ?
|
|
15983
|
+
AND project_path <> ?`);
|
|
15984
|
+
repairSessionChunkProjectStatements.set(db, stmt);
|
|
15985
|
+
}
|
|
15986
|
+
return stmt;
|
|
15987
|
+
}
|
|
15988
|
+
function getRepairProjectChunkProjectStatement(db) {
|
|
15989
|
+
let stmt = repairProjectChunkProjectStatements.get(db);
|
|
15990
|
+
if (!stmt) {
|
|
15991
|
+
stmt = db.prepare(`UPDATE compartment_chunk_embeddings
|
|
15992
|
+
SET project_path = (
|
|
15993
|
+
SELECT sp.project_path
|
|
15994
|
+
FROM session_projects sp
|
|
15995
|
+
WHERE sp.session_id = compartment_chunk_embeddings.session_id
|
|
15996
|
+
AND sp.harness = compartment_chunk_embeddings.harness
|
|
15997
|
+
LIMIT 1
|
|
15998
|
+
)
|
|
15999
|
+
WHERE EXISTS (
|
|
16000
|
+
SELECT 1
|
|
16001
|
+
FROM session_projects sp
|
|
16002
|
+
WHERE sp.session_id = compartment_chunk_embeddings.session_id
|
|
16003
|
+
AND sp.harness = compartment_chunk_embeddings.harness
|
|
16004
|
+
AND sp.project_path <> compartment_chunk_embeddings.project_path
|
|
16005
|
+
AND (
|
|
16006
|
+
sp.project_path = ?
|
|
16007
|
+
OR compartment_chunk_embeddings.project_path = ?
|
|
16008
|
+
)
|
|
16009
|
+
)`);
|
|
16010
|
+
repairProjectChunkProjectStatements.set(db, stmt);
|
|
16011
|
+
}
|
|
16012
|
+
return stmt;
|
|
16013
|
+
}
|
|
16014
|
+
function recordSessionProjectIdentity(db, sessionId, projectPath) {
|
|
16015
|
+
if (!sessionId || !projectPath)
|
|
16016
|
+
return;
|
|
16017
|
+
const harness = getHarness();
|
|
16018
|
+
const now = Date.now();
|
|
16019
|
+
db.transaction(() => {
|
|
16020
|
+
getUpsertSessionProjectStatement(db).run(sessionId, harness, projectPath, now);
|
|
16021
|
+
getRepairSessionChunkProjectStatement(db).run(projectPath, sessionId, harness, projectPath);
|
|
16022
|
+
})();
|
|
16023
|
+
}
|
|
16024
|
+
function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath) {
|
|
16025
|
+
if (!projectPath)
|
|
16026
|
+
return 0;
|
|
16027
|
+
return getRepairProjectChunkProjectStatement(db).run(projectPath, projectPath).changes;
|
|
16028
|
+
}
|
|
16029
|
+
var upsertSessionProjectStatements, repairSessionChunkProjectStatements, repairProjectChunkProjectStatements;
|
|
16030
|
+
var init_session_project_storage = __esm(() => {
|
|
16031
|
+
upsertSessionProjectStatements = new WeakMap;
|
|
16032
|
+
repairSessionChunkProjectStatements = new WeakMap;
|
|
16033
|
+
repairProjectChunkProjectStatements = new WeakMap;
|
|
16034
|
+
});
|
|
16035
|
+
|
|
15628
16036
|
// src/features/magic-context/overflow-detection.ts
|
|
15629
16037
|
function extractErrorMessage(error51) {
|
|
15630
16038
|
if (!error51)
|
|
@@ -16735,78 +17143,14 @@ function removeSystemReminders(text) {
|
|
|
16735
17143
|
}
|
|
16736
17144
|
var SYSTEM_DIRECTIVE_PREFIX = "[SYSTEM DIRECTIVE: MAGIC-CONTEXT";
|
|
16737
17145
|
|
|
16738
|
-
// src/shared/sqlite.ts
|
|
16739
|
-
function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
16740
|
-
const SAVEPOINT = "mc_tx_sp";
|
|
16741
|
-
|
|
16742
|
-
class NodeSqliteDatabase extends DatabaseSync {
|
|
16743
|
-
constructor(filename, options) {
|
|
16744
|
-
const translated = { ...options };
|
|
16745
|
-
if (options && "readonly" in options) {
|
|
16746
|
-
translated.readOnly = options.readonly;
|
|
16747
|
-
delete translated.readonly;
|
|
16748
|
-
}
|
|
16749
|
-
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
16750
|
-
}
|
|
16751
|
-
prepare(sql) {
|
|
16752
|
-
const stmt = super.prepare(sql);
|
|
16753
|
-
for (const method of ["run", "get", "all"]) {
|
|
16754
|
-
const original = stmt[method].bind(stmt);
|
|
16755
|
-
stmt[method] = (...args) => args.length === 1 && Array.isArray(args[0]) ? original(...args[0]) : original(...args);
|
|
16756
|
-
}
|
|
16757
|
-
return stmt;
|
|
16758
|
-
}
|
|
16759
|
-
transaction(fn) {
|
|
16760
|
-
const self2 = this;
|
|
16761
|
-
const wrapped = function(...args) {
|
|
16762
|
-
const nested = self2.isTransaction === true;
|
|
16763
|
-
self2.exec(nested ? `SAVEPOINT ${SAVEPOINT}` : "BEGIN");
|
|
16764
|
-
try {
|
|
16765
|
-
const result = fn.apply(this, args);
|
|
16766
|
-
self2.exec(nested ? `RELEASE ${SAVEPOINT}` : "COMMIT");
|
|
16767
|
-
return result;
|
|
16768
|
-
} catch (error51) {
|
|
16769
|
-
if (nested) {
|
|
16770
|
-
self2.exec(`ROLLBACK TO ${SAVEPOINT}`);
|
|
16771
|
-
self2.exec(`RELEASE ${SAVEPOINT}`);
|
|
16772
|
-
} else {
|
|
16773
|
-
self2.exec("ROLLBACK");
|
|
16774
|
-
}
|
|
16775
|
-
throw error51;
|
|
16776
|
-
}
|
|
16777
|
-
};
|
|
16778
|
-
return wrapped;
|
|
16779
|
-
}
|
|
16780
|
-
}
|
|
16781
|
-
return NodeSqliteDatabase;
|
|
16782
|
-
}
|
|
16783
|
-
var isBun, bunSpec, nodeSpec, sqliteModule, DatabaseImpl, Database;
|
|
16784
|
-
var init_sqlite = __esm(async () => {
|
|
16785
|
-
isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
16786
|
-
bunSpec = "bun:" + "sqlite";
|
|
16787
|
-
nodeSpec = "node:" + "sqlite";
|
|
16788
|
-
sqliteModule = isBun ? await import(bunSpec) : await import(nodeSpec);
|
|
16789
|
-
DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
16790
|
-
Database = DatabaseImpl;
|
|
16791
|
-
});
|
|
16792
|
-
|
|
16793
|
-
// src/shared/sqlite-helpers.ts
|
|
16794
|
-
function closeQuietly(db) {
|
|
16795
|
-
if (!db)
|
|
16796
|
-
return;
|
|
16797
|
-
try {
|
|
16798
|
-
db.close();
|
|
16799
|
-
} catch {}
|
|
16800
|
-
}
|
|
16801
|
-
|
|
16802
17146
|
// src/hooks/magic-context/read-session-db.ts
|
|
16803
|
-
import { existsSync as
|
|
16804
|
-
import { join as
|
|
16805
|
-
function
|
|
16806
|
-
return
|
|
17147
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
17148
|
+
import { join as join4 } from "node:path";
|
|
17149
|
+
function getOpenCodeDbPath2() {
|
|
17150
|
+
return join4(getDataDir(), "opencode", "opencode.db");
|
|
16807
17151
|
}
|
|
16808
17152
|
function openCodeDbExists() {
|
|
16809
|
-
return
|
|
17153
|
+
return existsSync9(getOpenCodeDbPath2());
|
|
16810
17154
|
}
|
|
16811
17155
|
function closeCachedReadOnlyDb() {
|
|
16812
17156
|
if (!cachedReadOnlyDb) {
|
|
@@ -16821,7 +17165,7 @@ function closeCachedReadOnlyDb() {
|
|
|
16821
17165
|
}
|
|
16822
17166
|
}
|
|
16823
17167
|
function getReadOnlySessionDb() {
|
|
16824
|
-
const dbPath =
|
|
17168
|
+
const dbPath = getOpenCodeDbPath2();
|
|
16825
17169
|
if (cachedReadOnlyDb?.path === dbPath) {
|
|
16826
17170
|
return cachedReadOnlyDb.db;
|
|
16827
17171
|
}
|
|
@@ -152555,82 +152899,6 @@ var init_project_docs_hash = __esm(() => {
|
|
|
152555
152899
|
docsCache = new Map;
|
|
152556
152900
|
});
|
|
152557
152901
|
|
|
152558
|
-
// src/shared/error-message.ts
|
|
152559
|
-
function getErrorMessage(error51) {
|
|
152560
|
-
return error51 instanceof Error ? error51.message : String(error51);
|
|
152561
|
-
}
|
|
152562
|
-
function readString(value) {
|
|
152563
|
-
if (typeof value === "string" && value.length > 0)
|
|
152564
|
-
return value;
|
|
152565
|
-
if (typeof value === "number")
|
|
152566
|
-
return String(value);
|
|
152567
|
-
return;
|
|
152568
|
-
}
|
|
152569
|
-
function clip(value, max) {
|
|
152570
|
-
if (value.length <= max)
|
|
152571
|
-
return value;
|
|
152572
|
-
return `${value.slice(0, max)}…`;
|
|
152573
|
-
}
|
|
152574
|
-
function describeError(error51) {
|
|
152575
|
-
const stringForm = clip(safeString(error51), 400);
|
|
152576
|
-
if (!(error51 instanceof Error) && !(error51 && typeof error51 === "object")) {
|
|
152577
|
-
return {
|
|
152578
|
-
name: typeof error51,
|
|
152579
|
-
message: "",
|
|
152580
|
-
stringForm,
|
|
152581
|
-
brief: stringForm || "<empty>"
|
|
152582
|
-
};
|
|
152583
|
-
}
|
|
152584
|
-
const obj = error51;
|
|
152585
|
-
const nameFromField = readString(obj.name);
|
|
152586
|
-
const nameFromCtor = error51?.constructor?.name;
|
|
152587
|
-
const name2 = nameFromField ?? nameFromCtor ?? "Error";
|
|
152588
|
-
const message = readString(obj.message) ?? "";
|
|
152589
|
-
const status = readString(obj.status) ?? readString(obj.statusCode);
|
|
152590
|
-
const code = readString(obj.code);
|
|
152591
|
-
let causeName;
|
|
152592
|
-
const cause = obj.cause;
|
|
152593
|
-
if (cause && typeof cause === "object") {
|
|
152594
|
-
const causeRecord = cause;
|
|
152595
|
-
causeName = readString(causeRecord.name) ?? cause.constructor?.name;
|
|
152596
|
-
}
|
|
152597
|
-
const stack = readString(obj.stack);
|
|
152598
|
-
const stackHead = stack ? stack.split(`
|
|
152599
|
-
`).slice(0, 4).map((l) => l.trim()).filter((l) => l.length > 0).join(" | ") : undefined;
|
|
152600
|
-
const briefParts = [];
|
|
152601
|
-
if (name2)
|
|
152602
|
-
briefParts.push(name2);
|
|
152603
|
-
if (message)
|
|
152604
|
-
briefParts.push(`message="${clip(message, 200)}"`);
|
|
152605
|
-
if (status)
|
|
152606
|
-
briefParts.push(`status=${status}`);
|
|
152607
|
-
if (code)
|
|
152608
|
-
briefParts.push(`code=${code}`);
|
|
152609
|
-
if (causeName)
|
|
152610
|
-
briefParts.push(`cause=${causeName}`);
|
|
152611
|
-
if (!message && stringForm && stringForm !== name2) {
|
|
152612
|
-
briefParts.push(`str="${clip(stringForm, 200)}"`);
|
|
152613
|
-
}
|
|
152614
|
-
const brief = briefParts.join(" ") || stringForm || name2;
|
|
152615
|
-
return {
|
|
152616
|
-
name: name2,
|
|
152617
|
-
message,
|
|
152618
|
-
...status ? { status } : {},
|
|
152619
|
-
...code ? { code } : {},
|
|
152620
|
-
...causeName ? { causeName } : {},
|
|
152621
|
-
...stackHead ? { stackHead } : {},
|
|
152622
|
-
stringForm,
|
|
152623
|
-
brief
|
|
152624
|
-
};
|
|
152625
|
-
}
|
|
152626
|
-
function safeString(value) {
|
|
152627
|
-
try {
|
|
152628
|
-
return String(value);
|
|
152629
|
-
} catch {
|
|
152630
|
-
return "<unstringifiable>";
|
|
152631
|
-
}
|
|
152632
|
-
}
|
|
152633
|
-
|
|
152634
152902
|
// src/shared/stable-json.ts
|
|
152635
152903
|
function stableStringify(value, seen = new WeakSet) {
|
|
152636
152904
|
if (value === undefined)
|
|
@@ -152742,12 +153010,12 @@ var init_tool_definition_tokens = __esm(() => {
|
|
|
152742
153010
|
});
|
|
152743
153011
|
|
|
152744
153012
|
// src/features/magic-context/tool-owner-backfill.ts
|
|
152745
|
-
import { existsSync as
|
|
152746
|
-
import { join as
|
|
153013
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
153014
|
+
import { join as join5 } from "node:path";
|
|
152747
153015
|
function resolveOpencodeDbPath() {
|
|
152748
|
-
return
|
|
153016
|
+
return join5(getDataDir(), "opencode", "opencode.db");
|
|
152749
153017
|
}
|
|
152750
|
-
function
|
|
153018
|
+
function ensureBackfillStateTable2(db) {
|
|
152751
153019
|
db.exec(`
|
|
152752
153020
|
CREATE TABLE IF NOT EXISTS tool_owner_backfill_state (
|
|
152753
153021
|
session_id TEXT PRIMARY KEY,
|
|
@@ -152763,7 +153031,7 @@ function ensureBackfillStateTable(db) {
|
|
|
152763
153031
|
}
|
|
152764
153032
|
function runToolOwnerBackfill(db) {
|
|
152765
153033
|
const startedAt = performance.now();
|
|
152766
|
-
|
|
153034
|
+
ensureBackfillStateTable2(db);
|
|
152767
153035
|
const result = {
|
|
152768
153036
|
sessionsProcessed: 0,
|
|
152769
153037
|
sessionsSkippedNoOcDb: 0,
|
|
@@ -152780,7 +153048,7 @@ function runToolOwnerBackfill(db) {
|
|
|
152780
153048
|
return result;
|
|
152781
153049
|
}
|
|
152782
153050
|
const opencodeDbPath = resolveOpencodeDbPath();
|
|
152783
|
-
if (!
|
|
153051
|
+
if (!existsSync10(opencodeDbPath)) {
|
|
152784
153052
|
log(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
|
|
152785
153053
|
markAllUnbackfilledSessionsSkipped(db);
|
|
152786
153054
|
result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
|
|
@@ -152803,7 +153071,7 @@ function runToolOwnerBackfill(db) {
|
|
|
152803
153071
|
return result;
|
|
152804
153072
|
}
|
|
152805
153073
|
function isToolOwnerBackfillNeeded(db) {
|
|
152806
|
-
|
|
153074
|
+
ensureBackfillStateTable2(db);
|
|
152807
153075
|
const row = db.prepare(`SELECT 1 AS hit
|
|
152808
153076
|
FROM tags
|
|
152809
153077
|
WHERE type = 'tool' AND tool_owner_message_id IS NULL
|
|
@@ -153004,8 +153272,8 @@ var init_tool_owner_backfill = __esm(() => {
|
|
|
153004
153272
|
});
|
|
153005
153273
|
|
|
153006
153274
|
// src/features/magic-context/storage-db.ts
|
|
153007
|
-
import { chmodSync, copyFileSync, cpSync, existsSync as
|
|
153008
|
-
import { dirname as dirname4, join as
|
|
153275
|
+
import { chmodSync, copyFileSync, cpSync, existsSync as existsSync11, mkdirSync as mkdirSync4, mkdtempSync } from "node:fs";
|
|
153276
|
+
import { dirname as dirname4, join as join6 } from "node:path";
|
|
153009
153277
|
function getSchemaFenceRejection() {
|
|
153010
153278
|
return lastSchemaFenceRejection;
|
|
153011
153279
|
}
|
|
@@ -153024,7 +153292,7 @@ function restrictDatabaseFilePermissions(dbPath) {
|
|
|
153024
153292
|
return;
|
|
153025
153293
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
153026
153294
|
const file2 = `${dbPath}${suffix}`;
|
|
153027
|
-
if (!
|
|
153295
|
+
if (!existsSync11(file2))
|
|
153028
153296
|
continue;
|
|
153029
153297
|
try {
|
|
153030
153298
|
chmodSync(file2, 384);
|
|
@@ -153039,22 +153307,22 @@ function resolveDatabasePath(dbPathOverride) {
|
|
|
153039
153307
|
}
|
|
153040
153308
|
const testDataDir = process.env.MAGIC_CONTEXT_TEST_DATA_DIR;
|
|
153041
153309
|
if (testDataDir && !process.env.XDG_DATA_HOME) {
|
|
153042
|
-
const dbDir2 =
|
|
153043
|
-
return { dbDir: dbDir2, dbPath:
|
|
153310
|
+
const dbDir2 = join6(testDataDir, "cortexkit", "magic-context");
|
|
153311
|
+
return { dbDir: dbDir2, dbPath: join6(dbDir2, "context.db") };
|
|
153044
153312
|
}
|
|
153045
153313
|
if (false) {}
|
|
153046
153314
|
const dbDir = getMagicContextStorageDir();
|
|
153047
|
-
return { dbDir, dbPath:
|
|
153315
|
+
return { dbDir, dbPath: join6(dbDir, "context.db") };
|
|
153048
153316
|
}
|
|
153049
153317
|
function getDatabasePath(db) {
|
|
153050
153318
|
return pathByDatabase.get(db) ?? null;
|
|
153051
153319
|
}
|
|
153052
153320
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
153053
|
-
if (
|
|
153321
|
+
if (existsSync11(targetDbPath))
|
|
153054
153322
|
return;
|
|
153055
153323
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
153056
|
-
const legacyDbPath =
|
|
153057
|
-
if (!
|
|
153324
|
+
const legacyDbPath = join6(legacyDir, "context.db");
|
|
153325
|
+
if (!existsSync11(legacyDbPath))
|
|
153058
153326
|
return;
|
|
153059
153327
|
log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
153060
153328
|
ensureSecureStorageDir(targetDbDir);
|
|
@@ -153070,8 +153338,8 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
153070
153338
|
}
|
|
153071
153339
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
153072
153340
|
const src = `${legacyDbPath}${suffix}`;
|
|
153073
|
-
const dst =
|
|
153074
|
-
if (
|
|
153341
|
+
const dst = join6(targetDbDir, `context.db${suffix}`);
|
|
153342
|
+
if (existsSync11(src)) {
|
|
153075
153343
|
try {
|
|
153076
153344
|
copyFileSync(src, dst);
|
|
153077
153345
|
} catch (error51) {
|
|
@@ -153079,9 +153347,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
153079
153347
|
}
|
|
153080
153348
|
}
|
|
153081
153349
|
}
|
|
153082
|
-
const legacyModelsDir =
|
|
153083
|
-
const targetModelsDir =
|
|
153084
|
-
if (
|
|
153350
|
+
const legacyModelsDir = join6(legacyDir, "models");
|
|
153351
|
+
const targetModelsDir = join6(targetDbDir, "models");
|
|
153352
|
+
if (existsSync11(legacyModelsDir) && !existsSync11(targetModelsDir)) {
|
|
153085
153353
|
try {
|
|
153086
153354
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
153087
153355
|
} catch (error51) {
|
|
@@ -164181,10 +164449,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
164181
164449
|
replacer = null;
|
|
164182
164450
|
indent = EMPTY;
|
|
164183
164451
|
};
|
|
164184
|
-
var
|
|
164452
|
+
var join7 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
|
|
164185
164453
|
var join_content = (inside, value, gap) => {
|
|
164186
164454
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
164187
|
-
return
|
|
164455
|
+
return join7(comment, inside, gap);
|
|
164188
164456
|
};
|
|
164189
164457
|
var stringify_string = (holder, key, value) => {
|
|
164190
164458
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -164206,13 +164474,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
164206
164474
|
if (i !== 0) {
|
|
164207
164475
|
inside += COMMA;
|
|
164208
164476
|
}
|
|
164209
|
-
const before =
|
|
164477
|
+
const before = join7(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
164210
164478
|
inside += before || LF + deeper_gap;
|
|
164211
164479
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
164212
164480
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
164213
164481
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
164214
164482
|
}
|
|
164215
|
-
inside +=
|
|
164483
|
+
inside += join7(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
164216
164484
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
164217
164485
|
};
|
|
164218
164486
|
var object_stringify = (value, gap) => {
|
|
@@ -164233,13 +164501,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
164233
164501
|
inside += COMMA;
|
|
164234
164502
|
}
|
|
164235
164503
|
first = false;
|
|
164236
|
-
const before =
|
|
164504
|
+
const before = join7(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
164237
164505
|
inside += before || LF + deeper_gap;
|
|
164238
164506
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
164239
164507
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
164240
164508
|
};
|
|
164241
164509
|
keys.forEach(iteratee);
|
|
164242
|
-
inside +=
|
|
164510
|
+
inside += join7(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
164243
164511
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
164244
164512
|
};
|
|
164245
164513
|
function stringify(key, holder, gap) {
|
|
@@ -165239,16 +165507,16 @@ var init_compartment_prompt = () => {};
|
|
|
165239
165507
|
|
|
165240
165508
|
// src/shared/opencode-config-dir.ts
|
|
165241
165509
|
import { homedir as homedir6 } from "node:os";
|
|
165242
|
-
import { join as
|
|
165510
|
+
import { join as join11, resolve as resolve3 } from "node:path";
|
|
165243
165511
|
function getCliConfigDir() {
|
|
165244
165512
|
const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
165245
165513
|
if (envConfigDir) {
|
|
165246
165514
|
return resolve3(envConfigDir);
|
|
165247
165515
|
}
|
|
165248
165516
|
if (process.platform === "win32") {
|
|
165249
|
-
return
|
|
165517
|
+
return join11(homedir6(), ".config", "opencode");
|
|
165250
165518
|
}
|
|
165251
|
-
return
|
|
165519
|
+
return join11(process.env.XDG_CONFIG_HOME || join11(homedir6(), ".config"), "opencode");
|
|
165252
165520
|
}
|
|
165253
165521
|
function getOpenCodeConfigDir(_options) {
|
|
165254
165522
|
return getCliConfigDir();
|
|
@@ -165257,16 +165525,16 @@ function getOpenCodeConfigPaths(options) {
|
|
|
165257
165525
|
const configDir = getOpenCodeConfigDir(options);
|
|
165258
165526
|
return {
|
|
165259
165527
|
configDir,
|
|
165260
|
-
configJson:
|
|
165261
|
-
configJsonc:
|
|
165262
|
-
packageJson:
|
|
165263
|
-
omoConfig:
|
|
165528
|
+
configJson: join11(configDir, "opencode.json"),
|
|
165529
|
+
configJsonc: join11(configDir, "opencode.jsonc"),
|
|
165530
|
+
packageJson: join11(configDir, "package.json"),
|
|
165531
|
+
omoConfig: join11(configDir, "magic-context.jsonc")
|
|
165264
165532
|
};
|
|
165265
165533
|
}
|
|
165266
165534
|
var init_opencode_config_dir = () => {};
|
|
165267
165535
|
|
|
165268
165536
|
// src/shared/conflict-detector.ts
|
|
165269
|
-
import { join as
|
|
165537
|
+
import { join as join12 } from "node:path";
|
|
165270
165538
|
function detectConflicts(directory) {
|
|
165271
165539
|
const conflicts = {
|
|
165272
165540
|
compactionAuto: false,
|
|
@@ -165323,8 +165591,8 @@ function checkCompaction(directory) {
|
|
|
165323
165591
|
return { auto: true, prune: false };
|
|
165324
165592
|
}
|
|
165325
165593
|
function readProjectCompaction(directory) {
|
|
165326
|
-
const dotOcJsonc =
|
|
165327
|
-
const dotOcJson =
|
|
165594
|
+
const dotOcJsonc = join12(directory, ".opencode", "opencode.jsonc");
|
|
165595
|
+
const dotOcJson = join12(directory, ".opencode", "opencode.json");
|
|
165328
165596
|
const dotOcConfig = readJsoncFile(dotOcJsonc) ?? readJsoncFile(dotOcJson);
|
|
165329
165597
|
if (dotOcConfig?.compaction) {
|
|
165330
165598
|
const c = dotOcConfig.compaction;
|
|
@@ -165332,8 +165600,8 @@ function readProjectCompaction(directory) {
|
|
|
165332
165600
|
return { auto: c.auto === true, prune: c.prune === true, resolved: true };
|
|
165333
165601
|
}
|
|
165334
165602
|
}
|
|
165335
|
-
const rootJsonc =
|
|
165336
|
-
const rootJson =
|
|
165603
|
+
const rootJsonc = join12(directory, "opencode.jsonc");
|
|
165604
|
+
const rootJson = join12(directory, "opencode.json");
|
|
165337
165605
|
const rootConfig = readJsoncFile(rootJsonc) ?? readJsoncFile(rootJson);
|
|
165338
165606
|
if (rootConfig?.compaction) {
|
|
165339
165607
|
const c = rootConfig.compaction;
|
|
@@ -165387,10 +165655,10 @@ function collectPluginEntries(directory) {
|
|
|
165387
165655
|
}
|
|
165388
165656
|
};
|
|
165389
165657
|
for (const configPath of [
|
|
165390
|
-
|
|
165391
|
-
|
|
165392
|
-
|
|
165393
|
-
|
|
165658
|
+
join12(directory, ".opencode", "opencode.jsonc"),
|
|
165659
|
+
join12(directory, ".opencode", "opencode.json"),
|
|
165660
|
+
join12(directory, "opencode.jsonc"),
|
|
165661
|
+
join12(directory, "opencode.json")
|
|
165394
165662
|
]) {
|
|
165395
165663
|
const config2 = readJsoncFile(configPath);
|
|
165396
165664
|
pushFrom(config2?.plugin);
|
|
@@ -165431,7 +165699,7 @@ function readOmoDisabledHooks(directory) {
|
|
|
165431
165699
|
try {
|
|
165432
165700
|
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
165433
165701
|
for (const name2 of configNames) {
|
|
165434
|
-
const configPath =
|
|
165702
|
+
const configPath = join12(paths.configDir, name2);
|
|
165435
165703
|
const config2 = readJsoncFile(configPath);
|
|
165436
165704
|
if (config2?.disabled_hooks) {
|
|
165437
165705
|
for (const hook of config2.disabled_hooks) {
|
|
@@ -165441,7 +165709,7 @@ function readOmoDisabledHooks(directory) {
|
|
|
165441
165709
|
}
|
|
165442
165710
|
} catch {}
|
|
165443
165711
|
for (const name2 of configNames) {
|
|
165444
|
-
const config2 = readJsoncFile(
|
|
165712
|
+
const config2 = readJsoncFile(join12(directory, name2));
|
|
165445
165713
|
if (config2?.disabled_hooks) {
|
|
165446
165714
|
for (const hook of config2.disabled_hooks) {
|
|
165447
165715
|
disabled.add(hook);
|
|
@@ -165592,28 +165860,28 @@ __export(exports_conflict_warning_hook, {
|
|
|
165592
165860
|
sendConflictWarning: () => sendConflictWarning,
|
|
165593
165861
|
cleanupConflictWarnings: () => cleanupConflictWarnings
|
|
165594
165862
|
});
|
|
165595
|
-
import { existsSync as
|
|
165863
|
+
import { existsSync as existsSync15, readFileSync as readFileSync10 } from "node:fs";
|
|
165596
165864
|
import { homedir as homedir7, platform as platform2 } from "node:os";
|
|
165597
|
-
import { join as
|
|
165865
|
+
import { join as join13 } from "node:path";
|
|
165598
165866
|
function getDesktopStatePath() {
|
|
165599
165867
|
const os2 = platform2();
|
|
165600
165868
|
const home = homedir7();
|
|
165601
165869
|
if (os2 === "darwin") {
|
|
165602
|
-
return
|
|
165870
|
+
return join13(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
|
|
165603
165871
|
}
|
|
165604
165872
|
if (os2 === "linux") {
|
|
165605
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
165606
|
-
return
|
|
165873
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join13(home, ".config");
|
|
165874
|
+
return join13(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
|
|
165607
165875
|
}
|
|
165608
165876
|
if (os2 === "win32") {
|
|
165609
|
-
const appData = process.env.APPDATA ||
|
|
165610
|
-
return
|
|
165877
|
+
const appData = process.env.APPDATA || join13(home, "AppData", "Roaming");
|
|
165878
|
+
return join13(appData, "ai.opencode.desktop", "opencode.global.dat");
|
|
165611
165879
|
}
|
|
165612
165880
|
return null;
|
|
165613
165881
|
}
|
|
165614
165882
|
function readDesktopState(directory) {
|
|
165615
165883
|
const statePath = getDesktopStatePath();
|
|
165616
|
-
if (!statePath || !
|
|
165884
|
+
if (!statePath || !existsSync15(statePath)) {
|
|
165617
165885
|
log(`[magic-context] conflict-warning: Desktop state file not found at ${statePath}`);
|
|
165618
165886
|
return { sessionId: null, sidecarUrl: null };
|
|
165619
165887
|
}
|
|
@@ -165915,196 +166183,6 @@ var init_conflict_warning_hook = __esm(() => {
|
|
|
165915
166183
|
cachedDesktopStateByDir = new Map;
|
|
165916
166184
|
});
|
|
165917
166185
|
|
|
165918
|
-
// src/features/magic-context/compaction-marker.ts
|
|
165919
|
-
import { join as join13 } from "node:path";
|
|
165920
|
-
function randomBase62(length) {
|
|
165921
|
-
const chars = [];
|
|
165922
|
-
for (let i = 0;i < length; i++) {
|
|
165923
|
-
chars.push(BASE62_CHARS[Math.floor(Math.random() * BASE62_CHARS.length)]);
|
|
165924
|
-
}
|
|
165925
|
-
return chars.join("");
|
|
165926
|
-
}
|
|
165927
|
-
function generateId(prefix, timestampMs, counter = 0n) {
|
|
165928
|
-
const encoded = BigInt(timestampMs) * 0x1000n + counter;
|
|
165929
|
-
const hex3 = encoded.toString(16).padStart(14, "0");
|
|
165930
|
-
return `${prefix}_${hex3}${randomBase62(14)}`;
|
|
165931
|
-
}
|
|
165932
|
-
function generateMessageId(timestampMs, counter = 0n) {
|
|
165933
|
-
return generateId("msg", timestampMs, counter);
|
|
165934
|
-
}
|
|
165935
|
-
function generatePartId(timestampMs, counter = 0n) {
|
|
165936
|
-
return generateId("prt", timestampMs, counter);
|
|
165937
|
-
}
|
|
165938
|
-
function getOpenCodeDbPath2() {
|
|
165939
|
-
return join13(getDataDir(), "opencode", "opencode.db");
|
|
165940
|
-
}
|
|
165941
|
-
function isOpenCodeSchemaCompatible(db, dbPath) {
|
|
165942
|
-
if (cachedSchemaCompatible?.path === dbPath) {
|
|
165943
|
-
return cachedSchemaCompatible.compatible;
|
|
165944
|
-
}
|
|
165945
|
-
try {
|
|
165946
|
-
const messageCols = new Set(db.prepare("PRAGMA table_info(message)").all().map((r) => r.name ?? "").filter((n) => n.length > 0));
|
|
165947
|
-
const partCols = new Set(db.prepare("PRAGMA table_info(part)").all().map((r) => r.name ?? "").filter((n) => n.length > 0));
|
|
165948
|
-
const missingMessage = REQUIRED_MESSAGE_COLUMNS.filter((c) => !messageCols.has(c));
|
|
165949
|
-
const missingPart = REQUIRED_PART_COLUMNS.filter((c) => !partCols.has(c));
|
|
165950
|
-
if (missingMessage.length > 0 || missingPart.length > 0) {
|
|
165951
|
-
log(`[magic-context] compaction-marker: OpenCode DB schema missing required columns ` + `(message: [${missingMessage.join(", ")}], part: [${missingPart.join(", ")}]). ` + `Marker injection disabled for this process. ` + `This usually means OpenCode was updated and magic-context is out of date.`);
|
|
165952
|
-
cachedSchemaCompatible = { path: dbPath, compatible: false };
|
|
165953
|
-
return false;
|
|
165954
|
-
}
|
|
165955
|
-
cachedSchemaCompatible = { path: dbPath, compatible: true };
|
|
165956
|
-
return true;
|
|
165957
|
-
} catch (error51) {
|
|
165958
|
-
log(`[magic-context] compaction-marker: schema probe failed: ${error51 instanceof Error ? error51.message : String(error51)}. ` + `Marker injection disabled until next process restart.`);
|
|
165959
|
-
cachedSchemaCompatible = { path: dbPath, compatible: false };
|
|
165960
|
-
return false;
|
|
165961
|
-
}
|
|
165962
|
-
}
|
|
165963
|
-
function getWritableOpenCodeDb() {
|
|
165964
|
-
const dbPath = getOpenCodeDbPath2();
|
|
165965
|
-
if (cachedWriteDb?.path === dbPath) {
|
|
165966
|
-
return cachedWriteDb.db;
|
|
165967
|
-
}
|
|
165968
|
-
if (cachedWriteDb) {
|
|
165969
|
-
try {
|
|
165970
|
-
closeQuietly(cachedWriteDb.db);
|
|
165971
|
-
} catch {}
|
|
165972
|
-
}
|
|
165973
|
-
const db = new Database(dbPath);
|
|
165974
|
-
db.exec("PRAGMA busy_timeout=5000");
|
|
165975
|
-
db.exec("PRAGMA journal_mode=WAL");
|
|
165976
|
-
cachedWriteDb = { path: dbPath, db };
|
|
165977
|
-
return db;
|
|
165978
|
-
}
|
|
165979
|
-
function getNonSummaryMessageSortKey(sessionId, messageId) {
|
|
165980
|
-
const db = getWritableOpenCodeDb();
|
|
165981
|
-
const row = db.prepare(`SELECT time_created, id
|
|
165982
|
-
FROM message
|
|
165983
|
-
WHERE session_id = ?
|
|
165984
|
-
AND id = ?
|
|
165985
|
-
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
165986
|
-
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')
|
|
165987
|
-
LIMIT 1`).get(sessionId, messageId);
|
|
165988
|
-
if (typeof row?.time_created !== "number" || typeof row.id !== "string") {
|
|
165989
|
-
return null;
|
|
165990
|
-
}
|
|
165991
|
-
return { id: row.id, timeCreated: row.time_created };
|
|
165992
|
-
}
|
|
165993
|
-
function findBoundaryUserMessage(sessionId, endMessageId) {
|
|
165994
|
-
const db = getWritableOpenCodeDb();
|
|
165995
|
-
const target = getNonSummaryMessageSortKey(sessionId, endMessageId);
|
|
165996
|
-
if (!target)
|
|
165997
|
-
return null;
|
|
165998
|
-
const boundary = db.prepare(`SELECT id, time_created, data
|
|
165999
|
-
FROM message
|
|
166000
|
-
WHERE session_id = ?
|
|
166001
|
-
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
166002
|
-
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')
|
|
166003
|
-
AND COALESCE(json_extract(data, '$.role'), '') = 'user'
|
|
166004
|
-
AND (time_created < ? OR (time_created = ? AND id <= ?))
|
|
166005
|
-
ORDER BY time_created DESC, id DESC
|
|
166006
|
-
LIMIT 1`).get(sessionId, target.timeCreated, target.timeCreated, target.id);
|
|
166007
|
-
if (typeof boundary?.id !== "string" || typeof boundary.time_created !== "number") {
|
|
166008
|
-
return null;
|
|
166009
|
-
}
|
|
166010
|
-
return { id: boundary.id, timeCreated: boundary.time_created };
|
|
166011
|
-
}
|
|
166012
|
-
function compareOpenCodeMessagesByCanonicalOrder(sessionId, leftMessageId, rightMessageId) {
|
|
166013
|
-
const left = getNonSummaryMessageSortKey(sessionId, leftMessageId);
|
|
166014
|
-
const right = getNonSummaryMessageSortKey(sessionId, rightMessageId);
|
|
166015
|
-
if (!left || !right)
|
|
166016
|
-
return null;
|
|
166017
|
-
if (left.timeCreated < right.timeCreated)
|
|
166018
|
-
return -1;
|
|
166019
|
-
if (left.timeCreated > right.timeCreated)
|
|
166020
|
-
return 1;
|
|
166021
|
-
if (left.id < right.id)
|
|
166022
|
-
return -1;
|
|
166023
|
-
if (left.id > right.id)
|
|
166024
|
-
return 1;
|
|
166025
|
-
return 0;
|
|
166026
|
-
}
|
|
166027
|
-
function getOpenCodeMessageById(sessionId, messageId) {
|
|
166028
|
-
const db = getWritableOpenCodeDb();
|
|
166029
|
-
const row = db.prepare(`SELECT id FROM message WHERE session_id = ? AND id = ? LIMIT 1`).get(sessionId, messageId);
|
|
166030
|
-
return row ?? null;
|
|
166031
|
-
}
|
|
166032
|
-
function injectCompactionMarker(args) {
|
|
166033
|
-
const db = getWritableOpenCodeDb();
|
|
166034
|
-
if (!isOpenCodeSchemaCompatible(db, getOpenCodeDbPath2())) {
|
|
166035
|
-
return null;
|
|
166036
|
-
}
|
|
166037
|
-
const boundary = args.resolvedBoundary ?? findBoundaryUserMessage(args.sessionId, args.endMessageId);
|
|
166038
|
-
if (!boundary) {
|
|
166039
|
-
log(`[magic-context] compaction-marker: no user message found at or before endMessageId ${args.endMessageId} (ordinal ${args.endOrdinal})`);
|
|
166040
|
-
return null;
|
|
166041
|
-
}
|
|
166042
|
-
const boundaryTime = boundary.timeCreated;
|
|
166043
|
-
const summaryMsgId = generateMessageId(boundaryTime + 1, 1n);
|
|
166044
|
-
const compactionPartId = generatePartId(boundaryTime, 1n);
|
|
166045
|
-
const summaryPartId = generatePartId(boundaryTime + 1, 2n);
|
|
166046
|
-
const summaryMsgData = JSON.stringify({
|
|
166047
|
-
role: "assistant",
|
|
166048
|
-
parentID: boundary.id,
|
|
166049
|
-
summary: true,
|
|
166050
|
-
finish: "stop",
|
|
166051
|
-
mode: "compaction",
|
|
166052
|
-
agent: "compaction",
|
|
166053
|
-
path: { cwd: args.directory, root: args.directory },
|
|
166054
|
-
cost: 0,
|
|
166055
|
-
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
166056
|
-
modelID: "magic-context",
|
|
166057
|
-
providerID: "magic-context",
|
|
166058
|
-
time: { created: boundaryTime + 1 }
|
|
166059
|
-
});
|
|
166060
|
-
try {
|
|
166061
|
-
db.transaction(() => {
|
|
166062
|
-
db.prepare("INSERT INTO part (id, message_id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?, ?)").run(compactionPartId, boundary.id, args.sessionId, boundaryTime, boundaryTime, '{"type":"compaction","auto":true}');
|
|
166063
|
-
db.prepare("INSERT INTO message (id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?)").run(summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, summaryMsgData);
|
|
166064
|
-
db.prepare("INSERT INTO part (id, message_id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?, ?)").run(summaryPartId, summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, JSON.stringify({ type: "text", text: args.summaryText }));
|
|
166065
|
-
})();
|
|
166066
|
-
log(`[magic-context] compaction-marker: injected boundary at user msg ${boundary.id} (ordinal ~${args.endOrdinal}), summary msg ${summaryMsgId}`);
|
|
166067
|
-
return {
|
|
166068
|
-
boundaryMessageId: boundary.id,
|
|
166069
|
-
summaryMessageId: summaryMsgId,
|
|
166070
|
-
compactionPartId,
|
|
166071
|
-
summaryPartId
|
|
166072
|
-
};
|
|
166073
|
-
} catch (error51) {
|
|
166074
|
-
log(`[magic-context] compaction-marker: injection failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
166075
|
-
return null;
|
|
166076
|
-
}
|
|
166077
|
-
}
|
|
166078
|
-
function removeCompactionMarker(state) {
|
|
166079
|
-
try {
|
|
166080
|
-
const db = getWritableOpenCodeDb();
|
|
166081
|
-
db.transaction(() => {
|
|
166082
|
-
db.prepare("DELETE FROM part WHERE id = ?").run(state.summaryPartId);
|
|
166083
|
-
db.prepare("DELETE FROM message WHERE id = ?").run(state.summaryMessageId);
|
|
166084
|
-
db.prepare("DELETE FROM part WHERE id = ?").run(state.compactionPartId);
|
|
166085
|
-
})();
|
|
166086
|
-
return true;
|
|
166087
|
-
} catch (error51) {
|
|
166088
|
-
log(`[magic-context] compaction-marker: removal failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
166089
|
-
return false;
|
|
166090
|
-
}
|
|
166091
|
-
}
|
|
166092
|
-
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", cachedWriteDb = null, REQUIRED_MESSAGE_COLUMNS, REQUIRED_PART_COLUMNS, cachedSchemaCompatible = null;
|
|
166093
|
-
var init_compaction_marker = __esm(async () => {
|
|
166094
|
-
init_data_path();
|
|
166095
|
-
init_logger();
|
|
166096
|
-
await init_sqlite();
|
|
166097
|
-
REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
166098
|
-
REQUIRED_PART_COLUMNS = [
|
|
166099
|
-
"id",
|
|
166100
|
-
"message_id",
|
|
166101
|
-
"session_id",
|
|
166102
|
-
"time_created",
|
|
166103
|
-
"time_updated",
|
|
166104
|
-
"data"
|
|
166105
|
-
];
|
|
166106
|
-
});
|
|
166107
|
-
|
|
166108
166186
|
// src/features/magic-context/dreamer/task-config.ts
|
|
166109
166187
|
var exports_task_config = {};
|
|
166110
166188
|
__export(exports_task_config, {
|
|
@@ -168072,80 +168150,6 @@ var init_embedding_cache = __esm(() => {
|
|
|
168072
168150
|
embeddingCacheTtlMs = DEFAULT_EMBEDDING_CACHE_TTL_MS;
|
|
168073
168151
|
});
|
|
168074
168152
|
|
|
168075
|
-
// src/features/magic-context/session-project-storage.ts
|
|
168076
|
-
function getUpsertSessionProjectStatement(db) {
|
|
168077
|
-
let stmt = upsertSessionProjectStatements.get(db);
|
|
168078
|
-
if (!stmt) {
|
|
168079
|
-
stmt = db.prepare(`INSERT INTO session_projects (session_id, harness, project_path, updated_at)
|
|
168080
|
-
VALUES (?, ?, ?, ?)
|
|
168081
|
-
ON CONFLICT(session_id, harness) DO UPDATE SET
|
|
168082
|
-
project_path = excluded.project_path,
|
|
168083
|
-
updated_at = excluded.updated_at
|
|
168084
|
-
WHERE session_projects.project_path <> excluded.project_path`);
|
|
168085
|
-
upsertSessionProjectStatements.set(db, stmt);
|
|
168086
|
-
}
|
|
168087
|
-
return stmt;
|
|
168088
|
-
}
|
|
168089
|
-
function getRepairSessionChunkProjectStatement(db) {
|
|
168090
|
-
let stmt = repairSessionChunkProjectStatements.get(db);
|
|
168091
|
-
if (!stmt) {
|
|
168092
|
-
stmt = db.prepare(`UPDATE compartment_chunk_embeddings
|
|
168093
|
-
SET project_path = ?
|
|
168094
|
-
WHERE session_id = ?
|
|
168095
|
-
AND harness = ?
|
|
168096
|
-
AND project_path <> ?`);
|
|
168097
|
-
repairSessionChunkProjectStatements.set(db, stmt);
|
|
168098
|
-
}
|
|
168099
|
-
return stmt;
|
|
168100
|
-
}
|
|
168101
|
-
function getRepairProjectChunkProjectStatement(db) {
|
|
168102
|
-
let stmt = repairProjectChunkProjectStatements.get(db);
|
|
168103
|
-
if (!stmt) {
|
|
168104
|
-
stmt = db.prepare(`UPDATE compartment_chunk_embeddings
|
|
168105
|
-
SET project_path = (
|
|
168106
|
-
SELECT sp.project_path
|
|
168107
|
-
FROM session_projects sp
|
|
168108
|
-
WHERE sp.session_id = compartment_chunk_embeddings.session_id
|
|
168109
|
-
AND sp.harness = compartment_chunk_embeddings.harness
|
|
168110
|
-
LIMIT 1
|
|
168111
|
-
)
|
|
168112
|
-
WHERE EXISTS (
|
|
168113
|
-
SELECT 1
|
|
168114
|
-
FROM session_projects sp
|
|
168115
|
-
WHERE sp.session_id = compartment_chunk_embeddings.session_id
|
|
168116
|
-
AND sp.harness = compartment_chunk_embeddings.harness
|
|
168117
|
-
AND sp.project_path <> compartment_chunk_embeddings.project_path
|
|
168118
|
-
AND (
|
|
168119
|
-
sp.project_path = ?
|
|
168120
|
-
OR compartment_chunk_embeddings.project_path = ?
|
|
168121
|
-
)
|
|
168122
|
-
)`);
|
|
168123
|
-
repairProjectChunkProjectStatements.set(db, stmt);
|
|
168124
|
-
}
|
|
168125
|
-
return stmt;
|
|
168126
|
-
}
|
|
168127
|
-
function recordSessionProjectIdentity(db, sessionId, projectPath) {
|
|
168128
|
-
if (!sessionId || !projectPath)
|
|
168129
|
-
return;
|
|
168130
|
-
const harness = getHarness();
|
|
168131
|
-
const now = Date.now();
|
|
168132
|
-
db.transaction(() => {
|
|
168133
|
-
getUpsertSessionProjectStatement(db).run(sessionId, harness, projectPath, now);
|
|
168134
|
-
getRepairSessionChunkProjectStatement(db).run(projectPath, sessionId, harness, projectPath);
|
|
168135
|
-
})();
|
|
168136
|
-
}
|
|
168137
|
-
function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath) {
|
|
168138
|
-
if (!projectPath)
|
|
168139
|
-
return 0;
|
|
168140
|
-
return getRepairProjectChunkProjectStatement(db).run(projectPath, projectPath).changes;
|
|
168141
|
-
}
|
|
168142
|
-
var upsertSessionProjectStatements, repairSessionChunkProjectStatements, repairProjectChunkProjectStatements;
|
|
168143
|
-
var init_session_project_storage = __esm(() => {
|
|
168144
|
-
upsertSessionProjectStatements = new WeakMap;
|
|
168145
|
-
repairSessionChunkProjectStatements = new WeakMap;
|
|
168146
|
-
repairProjectChunkProjectStatements = new WeakMap;
|
|
168147
|
-
});
|
|
168148
|
-
|
|
168149
168153
|
// src/features/magic-context/project-embedding-registry.ts
|
|
168150
168154
|
import { createHash as createHash8, randomUUID } from "node:crypto";
|
|
168151
168155
|
function markProjectLoadUntrusted(projectIdentity) {
|
|
@@ -169782,7 +169786,7 @@ function getMemoryVerifications(db, memoryIds) {
|
|
|
169782
169786
|
var MEMORY_VERIFICATION_SENTINEL = "";
|
|
169783
169787
|
// src/features/magic-context/memory/verification-paths.ts
|
|
169784
169788
|
import { execFile } from "node:child_process";
|
|
169785
|
-
import { existsSync as
|
|
169789
|
+
import { existsSync as existsSync16, realpathSync as realpathSync2, statSync as statSync5 } from "node:fs";
|
|
169786
169790
|
import path6 from "node:path";
|
|
169787
169791
|
import { promisify } from "node:util";
|
|
169788
169792
|
async function runGit(cwd, args) {
|
|
@@ -169885,7 +169889,7 @@ function verificationFileExists(baseRoot, filePath) {
|
|
|
169885
169889
|
return false;
|
|
169886
169890
|
const root = path6.resolve(baseRoot);
|
|
169887
169891
|
const candidate = path6.resolve(root, filePath);
|
|
169888
|
-
return isWithin(root, candidate) &&
|
|
169892
|
+
return isWithin(root, candidate) && existsSync16(candidate);
|
|
169889
169893
|
}
|
|
169890
169894
|
async function normalizeVerificationFiles(args) {
|
|
169891
169895
|
const cwd = path6.resolve(args.cwd);
|
|
@@ -169918,7 +169922,7 @@ async function normalizeVerificationFiles(args) {
|
|
|
169918
169922
|
warnings.push(`Skipped verification path "${value}" because it is the repo/project root.`);
|
|
169919
169923
|
continue;
|
|
169920
169924
|
}
|
|
169921
|
-
if (
|
|
169925
|
+
if (existsSync16(candidate)) {
|
|
169922
169926
|
try {
|
|
169923
169927
|
if (statSync5(candidate).isDirectory()) {
|
|
169924
169928
|
warnings.push(`Skipped verification path "${value}" because it is a directory.`);
|
|
@@ -169949,7 +169953,7 @@ async function normalizeVerificationFiles(args) {
|
|
|
169949
169953
|
}
|
|
169950
169954
|
normalized.push(tracked);
|
|
169951
169955
|
} else {
|
|
169952
|
-
if (!
|
|
169956
|
+
if (!existsSync16(candidate)) {
|
|
169953
169957
|
warnings.push(`Skipped verification path "${value}" because it does not exist.`);
|
|
169954
169958
|
continue;
|
|
169955
169959
|
}
|
|
@@ -177293,6 +177297,9 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory) {
|
|
|
177293
177297
|
}
|
|
177294
177298
|
}
|
|
177295
177299
|
function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
|
|
177300
|
+
if (getHarness() !== "opencode") {
|
|
177301
|
+
return true;
|
|
177302
|
+
}
|
|
177296
177303
|
const targetEndMessageId = getCompartmentEndMessageIdForOrdinal(db, sessionId, lastCompartmentEnd);
|
|
177297
177304
|
if (!targetEndMessageId) {
|
|
177298
177305
|
sessionLog(sessionId, `compaction-marker: no compartment endMessageId for ordinal ${lastCompartmentEnd}; preserving existing marker`);
|
|
@@ -186349,6 +186356,29 @@ function getMagicContextBuiltinCommands() {
|
|
|
186349
186356
|
};
|
|
186350
186357
|
}
|
|
186351
186358
|
|
|
186359
|
+
// src/features/magic-context/dreamer/open-opencode-db.ts
|
|
186360
|
+
init_logger();
|
|
186361
|
+
await __promiseAll([
|
|
186362
|
+
init_sqlite(),
|
|
186363
|
+
init_compaction_marker()
|
|
186364
|
+
]);
|
|
186365
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
186366
|
+
function openOpenCodeDb() {
|
|
186367
|
+
const dbPath = getOpenCodeDbPath();
|
|
186368
|
+
if (!existsSync7(dbPath)) {
|
|
186369
|
+
log(`[dreamer] OpenCode DB not found at ${dbPath} — skipping OpenCode history scan`);
|
|
186370
|
+
return null;
|
|
186371
|
+
}
|
|
186372
|
+
try {
|
|
186373
|
+
const db = new Database(dbPath, { readonly: true });
|
|
186374
|
+
db.exec("PRAGMA busy_timeout = 5000");
|
|
186375
|
+
return db;
|
|
186376
|
+
} catch (error51) {
|
|
186377
|
+
log(`[dreamer] failed to open OpenCode DB at ${dbPath}: ${getErrorMessage(error51)}`);
|
|
186378
|
+
return null;
|
|
186379
|
+
}
|
|
186380
|
+
}
|
|
186381
|
+
|
|
186352
186382
|
// src/features/magic-context/dreamer/task-prompts.ts
|
|
186353
186383
|
var DREAMER_SYSTEM_PROMPT = `You are a background maintenance agent for the magic-context system, running during a scheduled dream window. Your task and its full instructions arrive in the message below. Never read or quote secrets from .env, credentials, or key files, and never commit — the user handles git.`;
|
|
186354
186384
|
var PROJECT_MEMORY_TAXONOMY = `## Memory taxonomy (5 categories)
|
|
@@ -186658,6 +186688,192 @@ function buildDreamTaskPrompt(task, args) {
|
|
|
186658
186688
|
// src/index.ts
|
|
186659
186689
|
init_project_identity();
|
|
186660
186690
|
|
|
186691
|
+
// src/features/magic-context/session-project-backfill.ts
|
|
186692
|
+
init_logger();
|
|
186693
|
+
init_project_identity();
|
|
186694
|
+
init_session_project_storage();
|
|
186695
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
186696
|
+
var LEASE_TTL_MS = 10 * 60 * 1000;
|
|
186697
|
+
var SESSION_QUERY_CHUNK_SIZE = 250;
|
|
186698
|
+
var YIELD_EVERY_NEW_DIRECTORIES = 10;
|
|
186699
|
+
function ensureBackfillStateTable(db) {
|
|
186700
|
+
db.exec(`
|
|
186701
|
+
CREATE TABLE IF NOT EXISTS session_project_backfill_state (
|
|
186702
|
+
harness TEXT PRIMARY KEY,
|
|
186703
|
+
status TEXT NOT NULL CHECK (status IN ('running', 'completed')),
|
|
186704
|
+
started_at INTEGER,
|
|
186705
|
+
lease_expires_at INTEGER,
|
|
186706
|
+
completed_at INTEGER
|
|
186707
|
+
);
|
|
186708
|
+
`);
|
|
186709
|
+
}
|
|
186710
|
+
function withImmediateTransaction(db, fn) {
|
|
186711
|
+
db.exec("BEGIN IMMEDIATE");
|
|
186712
|
+
try {
|
|
186713
|
+
const result = fn();
|
|
186714
|
+
db.exec("COMMIT");
|
|
186715
|
+
return result;
|
|
186716
|
+
} catch (error51) {
|
|
186717
|
+
try {
|
|
186718
|
+
db.exec("ROLLBACK");
|
|
186719
|
+
} catch {}
|
|
186720
|
+
throw error51;
|
|
186721
|
+
}
|
|
186722
|
+
}
|
|
186723
|
+
function defaultYieldFn() {
|
|
186724
|
+
return new Promise((resolve2) => setTimeout(resolve2, 0));
|
|
186725
|
+
}
|
|
186726
|
+
function acquireBackfillLease(db, harness, now) {
|
|
186727
|
+
ensureBackfillStateTable(db);
|
|
186728
|
+
return withImmediateTransaction(db, () => {
|
|
186729
|
+
const current = db.prepare(`SELECT harness, status, started_at, lease_expires_at, completed_at
|
|
186730
|
+
FROM session_project_backfill_state
|
|
186731
|
+
WHERE harness = ?`).get(harness);
|
|
186732
|
+
if (current?.status === "completed") {
|
|
186733
|
+
return "already_completed";
|
|
186734
|
+
}
|
|
186735
|
+
if (current?.status === "running" && current.lease_expires_at !== null && current.lease_expires_at > now) {
|
|
186736
|
+
return "blocked_by_lease";
|
|
186737
|
+
}
|
|
186738
|
+
db.prepare(`INSERT INTO session_project_backfill_state(
|
|
186739
|
+
harness,
|
|
186740
|
+
status,
|
|
186741
|
+
started_at,
|
|
186742
|
+
lease_expires_at,
|
|
186743
|
+
completed_at
|
|
186744
|
+
)
|
|
186745
|
+
VALUES (?, 'running', ?, ?, NULL)
|
|
186746
|
+
ON CONFLICT(harness) DO UPDATE SET
|
|
186747
|
+
status = 'running',
|
|
186748
|
+
started_at = excluded.started_at,
|
|
186749
|
+
lease_expires_at = excluded.lease_expires_at,
|
|
186750
|
+
completed_at = NULL`).run(harness, now, now + LEASE_TTL_MS);
|
|
186751
|
+
return "completed";
|
|
186752
|
+
});
|
|
186753
|
+
}
|
|
186754
|
+
function renewBackfillLease(db, harness, now) {
|
|
186755
|
+
ensureBackfillStateTable(db);
|
|
186756
|
+
db.prepare(`UPDATE session_project_backfill_state
|
|
186757
|
+
SET lease_expires_at = ?
|
|
186758
|
+
WHERE harness = ? AND status = 'running'`).run(now + LEASE_TTL_MS, harness);
|
|
186759
|
+
}
|
|
186760
|
+
function markBackfillCompleted(db, harness, now) {
|
|
186761
|
+
ensureBackfillStateTable(db);
|
|
186762
|
+
db.prepare(`INSERT INTO session_project_backfill_state(
|
|
186763
|
+
harness,
|
|
186764
|
+
status,
|
|
186765
|
+
started_at,
|
|
186766
|
+
lease_expires_at,
|
|
186767
|
+
completed_at
|
|
186768
|
+
)
|
|
186769
|
+
VALUES (?, 'completed', ?, NULL, ?)
|
|
186770
|
+
ON CONFLICT(harness) DO UPDATE SET
|
|
186771
|
+
status = 'completed',
|
|
186772
|
+
lease_expires_at = NULL,
|
|
186773
|
+
completed_at = excluded.completed_at`).run(harness, now, now);
|
|
186774
|
+
}
|
|
186775
|
+
function dedupeSessions(sessions) {
|
|
186776
|
+
const sessionsById = new Map;
|
|
186777
|
+
for (const session of sessions) {
|
|
186778
|
+
if (!session.sessionId)
|
|
186779
|
+
continue;
|
|
186780
|
+
const existing = sessionsById.get(session.sessionId);
|
|
186781
|
+
if (!existing) {
|
|
186782
|
+
sessionsById.set(session.sessionId, {
|
|
186783
|
+
sessionId: session.sessionId,
|
|
186784
|
+
directory: session.directory
|
|
186785
|
+
});
|
|
186786
|
+
continue;
|
|
186787
|
+
}
|
|
186788
|
+
if (!existing.directory && session.directory) {
|
|
186789
|
+
sessionsById.set(session.sessionId, {
|
|
186790
|
+
sessionId: session.sessionId,
|
|
186791
|
+
directory: session.directory
|
|
186792
|
+
});
|
|
186793
|
+
}
|
|
186794
|
+
}
|
|
186795
|
+
return [...sessionsById.values()];
|
|
186796
|
+
}
|
|
186797
|
+
function getMappedSessionIds(db, harness, sessions) {
|
|
186798
|
+
const mapped = new Set;
|
|
186799
|
+
for (let index = 0;index < sessions.length; index += SESSION_QUERY_CHUNK_SIZE) {
|
|
186800
|
+
const chunk = sessions.slice(index, index + SESSION_QUERY_CHUNK_SIZE);
|
|
186801
|
+
if (chunk.length === 0)
|
|
186802
|
+
continue;
|
|
186803
|
+
const placeholders = chunk.map(() => "?").join(", ");
|
|
186804
|
+
const rows = db.prepare(`SELECT session_id
|
|
186805
|
+
FROM session_projects
|
|
186806
|
+
WHERE harness = ?
|
|
186807
|
+
AND session_id IN (${placeholders})`).all(harness, ...chunk.map((session) => session.sessionId));
|
|
186808
|
+
for (const row of rows) {
|
|
186809
|
+
mapped.add(row.session_id);
|
|
186810
|
+
}
|
|
186811
|
+
}
|
|
186812
|
+
return mapped;
|
|
186813
|
+
}
|
|
186814
|
+
async function runSessionProjectBackfill(db, sessions, options = {}) {
|
|
186815
|
+
const startedAt = performance.now();
|
|
186816
|
+
const harness = getHarness();
|
|
186817
|
+
const now = options.now ?? Date.now;
|
|
186818
|
+
const resolveIdentity = options.resolveIdentity ?? resolveProjectIdentity;
|
|
186819
|
+
const yieldFn = options.yieldFn ?? defaultYieldFn;
|
|
186820
|
+
const dedupedSessions = dedupeSessions(sessions);
|
|
186821
|
+
const result = {
|
|
186822
|
+
status: "completed",
|
|
186823
|
+
totalSessions: dedupedSessions.length,
|
|
186824
|
+
alreadyMappedSessions: 0,
|
|
186825
|
+
unmappedSessions: 0,
|
|
186826
|
+
backfilledSessions: 0,
|
|
186827
|
+
skippedDeadDirectories: 0,
|
|
186828
|
+
skippedEmptyDirectories: 0,
|
|
186829
|
+
durationMs: 0
|
|
186830
|
+
};
|
|
186831
|
+
const leaseStatus = acquireBackfillLease(db, harness, now());
|
|
186832
|
+
if (leaseStatus !== "completed") {
|
|
186833
|
+
result.status = leaseStatus;
|
|
186834
|
+
result.durationMs = performance.now() - startedAt;
|
|
186835
|
+
return result;
|
|
186836
|
+
}
|
|
186837
|
+
const mappedSessionIds = getMappedSessionIds(db, harness, dedupedSessions);
|
|
186838
|
+
result.alreadyMappedSessions = mappedSessionIds.size;
|
|
186839
|
+
const existenceCache = new Map;
|
|
186840
|
+
const identityCache2 = new Map;
|
|
186841
|
+
let newDirectoryResolutions = 0;
|
|
186842
|
+
for (const session of dedupedSessions) {
|
|
186843
|
+
if (mappedSessionIds.has(session.sessionId)) {
|
|
186844
|
+
continue;
|
|
186845
|
+
}
|
|
186846
|
+
result.unmappedSessions += 1;
|
|
186847
|
+
if (!session.directory) {
|
|
186848
|
+
result.skippedEmptyDirectories += 1;
|
|
186849
|
+
continue;
|
|
186850
|
+
}
|
|
186851
|
+
const stillExists = existenceCache.get(session.directory) ?? existsSync8(session.directory);
|
|
186852
|
+
existenceCache.set(session.directory, stillExists);
|
|
186853
|
+
if (!stillExists) {
|
|
186854
|
+
result.skippedDeadDirectories += 1;
|
|
186855
|
+
continue;
|
|
186856
|
+
}
|
|
186857
|
+
let identity = identityCache2.get(session.directory);
|
|
186858
|
+
if (!identity) {
|
|
186859
|
+
identity = resolveIdentity(session.directory);
|
|
186860
|
+
identityCache2.set(session.directory, identity);
|
|
186861
|
+
newDirectoryResolutions += 1;
|
|
186862
|
+
if (newDirectoryResolutions % YIELD_EVERY_NEW_DIRECTORIES === 0) {
|
|
186863
|
+
renewBackfillLease(db, harness, now());
|
|
186864
|
+
await yieldFn();
|
|
186865
|
+
renewBackfillLease(db, harness, now());
|
|
186866
|
+
}
|
|
186867
|
+
}
|
|
186868
|
+
recordSessionProjectIdentity(db, session.sessionId, identity);
|
|
186869
|
+
result.backfilledSessions += 1;
|
|
186870
|
+
}
|
|
186871
|
+
markBackfillCompleted(db, harness, now());
|
|
186872
|
+
result.durationMs = performance.now() - startedAt;
|
|
186873
|
+
log(`[session-projects] backfilled ${result.backfilledSessions} of ${result.unmappedSessions} unmapped sessions (skipped ${result.skippedDeadDirectories} dead dirs) in ${Math.round(result.durationMs)}ms`);
|
|
186874
|
+
return result;
|
|
186875
|
+
}
|
|
186876
|
+
|
|
186661
186877
|
// src/features/magic-context/sidekick/agent.ts
|
|
186662
186878
|
init_language_directive();
|
|
186663
186879
|
|
|
@@ -187048,45 +187264,45 @@ async function runDeferredV22Backfill(db, options = {}) {
|
|
|
187048
187264
|
|
|
187049
187265
|
// src/hooks/auto-update-checker/index.ts
|
|
187050
187266
|
init_logger();
|
|
187051
|
-
import { existsSync as
|
|
187052
|
-
import { dirname as dirname7, join as
|
|
187267
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync9, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
187268
|
+
import { dirname as dirname7, join as join10 } from "node:path";
|
|
187053
187269
|
|
|
187054
187270
|
// src/hooks/auto-update-checker/cache.ts
|
|
187055
187271
|
init_logger();
|
|
187056
187272
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
187057
187273
|
import { spawn } from "node:child_process";
|
|
187058
|
-
import { existsSync as
|
|
187059
|
-
import { basename as basename2, dirname as dirname6, join as
|
|
187274
|
+
import { existsSync as existsSync13, readFileSync as readFileSync8, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
187275
|
+
import { basename as basename2, dirname as dirname6, join as join9 } from "node:path";
|
|
187060
187276
|
|
|
187061
187277
|
// src/hooks/auto-update-checker/checker.ts
|
|
187062
187278
|
init_logger();
|
|
187063
187279
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
187064
|
-
import { existsSync as
|
|
187280
|
+
import { existsSync as existsSync12, readFileSync as readFileSync7, renameSync as renameSync2, statSync as statSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
187065
187281
|
import { homedir as homedir5 } from "node:os";
|
|
187066
|
-
import { dirname as dirname5, isAbsolute as isAbsolute3, join as
|
|
187282
|
+
import { dirname as dirname5, isAbsolute as isAbsolute3, join as join8, resolve as resolve2 } from "node:path";
|
|
187067
187283
|
import { fileURLToPath } from "node:url";
|
|
187068
187284
|
|
|
187069
187285
|
// src/hooks/auto-update-checker/constants.ts
|
|
187070
187286
|
import { homedir as homedir4, platform } from "node:os";
|
|
187071
|
-
import { join as
|
|
187287
|
+
import { join as join7 } from "node:path";
|
|
187072
187288
|
var PACKAGE_NAME = "@cortexkit/opencode-magic-context";
|
|
187073
187289
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
187074
187290
|
var NPM_FETCH_TIMEOUT = 1e4;
|
|
187075
187291
|
function getOpenCodeCacheRoot() {
|
|
187076
187292
|
if (platform() === "win32") {
|
|
187077
|
-
return
|
|
187293
|
+
return join7(process.env.LOCALAPPDATA ?? homedir4(), "opencode");
|
|
187078
187294
|
}
|
|
187079
|
-
return
|
|
187295
|
+
return join7(homedir4(), ".cache", "opencode");
|
|
187080
187296
|
}
|
|
187081
187297
|
function getOpenCodeConfigRoot() {
|
|
187082
187298
|
if (platform() === "win32") {
|
|
187083
|
-
return
|
|
187299
|
+
return join7(process.env.APPDATA ?? join7(homedir4(), "AppData", "Roaming"), "opencode");
|
|
187084
187300
|
}
|
|
187085
|
-
return
|
|
187301
|
+
return join7(process.env.XDG_CONFIG_HOME ?? join7(homedir4(), ".config"), "opencode");
|
|
187086
187302
|
}
|
|
187087
|
-
var CACHE_DIR =
|
|
187088
|
-
var USER_OPENCODE_CONFIG =
|
|
187089
|
-
var USER_OPENCODE_CONFIG_JSONC =
|
|
187303
|
+
var CACHE_DIR = join7(getOpenCodeCacheRoot(), "packages");
|
|
187304
|
+
var USER_OPENCODE_CONFIG = join7(getOpenCodeConfigRoot(), "opencode.json");
|
|
187305
|
+
var USER_OPENCODE_CONFIG_JSONC = join7(getOpenCodeConfigRoot(), "opencode.jsonc");
|
|
187090
187306
|
// src/hooks/auto-update-checker/types.ts
|
|
187091
187307
|
init_zod();
|
|
187092
187308
|
var NpmPackageEnvelopeSchema = exports_external.object({
|
|
@@ -187147,8 +187363,8 @@ function extractChannel(version2) {
|
|
|
187147
187363
|
}
|
|
187148
187364
|
function getConfigPaths(directory) {
|
|
187149
187365
|
return [
|
|
187150
|
-
|
|
187151
|
-
|
|
187366
|
+
join8(directory, ".opencode", "opencode.json"),
|
|
187367
|
+
join8(directory, ".opencode", "opencode.jsonc"),
|
|
187152
187368
|
USER_OPENCODE_CONFIG,
|
|
187153
187369
|
USER_OPENCODE_CONFIG_JSONC
|
|
187154
187370
|
];
|
|
@@ -187170,8 +187386,8 @@ function findPackageJsonUp(startPath) {
|
|
|
187170
187386
|
const stat = statSync4(startPath);
|
|
187171
187387
|
let dir = stat.isDirectory() ? startPath : dirname5(startPath);
|
|
187172
187388
|
for (let i = 0;i < 10; i++) {
|
|
187173
|
-
const pkgPath =
|
|
187174
|
-
if (
|
|
187389
|
+
const pkgPath = join8(dir, "package.json");
|
|
187390
|
+
if (existsSync12(pkgPath)) {
|
|
187175
187391
|
try {
|
|
187176
187392
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync7(pkgPath, "utf-8")));
|
|
187177
187393
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
@@ -187189,7 +187405,7 @@ function findPackageJsonUp(startPath) {
|
|
|
187189
187405
|
function getLocalDevPath(directory) {
|
|
187190
187406
|
for (const configPath of getConfigPaths(directory)) {
|
|
187191
187407
|
try {
|
|
187192
|
-
if (!
|
|
187408
|
+
if (!existsSync12(configPath))
|
|
187193
187409
|
continue;
|
|
187194
187410
|
const rawConfig = parseJsonConfig(readFileSync7(configPath, "utf-8"));
|
|
187195
187411
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -187235,7 +187451,7 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
|
187235
187451
|
function findPluginEntry(directory) {
|
|
187236
187452
|
for (const configPath of getConfigPaths(directory)) {
|
|
187237
187453
|
try {
|
|
187238
|
-
if (!
|
|
187454
|
+
if (!existsSync12(configPath))
|
|
187239
187455
|
continue;
|
|
187240
187456
|
const rawConfig = parseJsonConfig(readFileSync7(configPath, "utf-8"));
|
|
187241
187457
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -187260,7 +187476,7 @@ function findPluginEntry(directory) {
|
|
|
187260
187476
|
}
|
|
187261
187477
|
var cachedPackageVersion = null;
|
|
187262
187478
|
function getSpecCachePackageJsonPath(spec) {
|
|
187263
|
-
return
|
|
187479
|
+
return join8(CACHE_DIR, spec, "node_modules", PACKAGE_NAME, "package.json");
|
|
187264
187480
|
}
|
|
187265
187481
|
function getCachedVersion(spec) {
|
|
187266
187482
|
if (!spec && cachedPackageVersion)
|
|
@@ -187269,11 +187485,11 @@ function getCachedVersion(spec) {
|
|
|
187269
187485
|
getCurrentRuntimePackageJsonPath(),
|
|
187270
187486
|
spec ? getSpecCachePackageJsonPath(spec) : null,
|
|
187271
187487
|
getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
|
|
187272
|
-
|
|
187488
|
+
join8(homedir5(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
|
|
187273
187489
|
].filter(isString);
|
|
187274
187490
|
for (const packageJsonPath of candidates) {
|
|
187275
187491
|
try {
|
|
187276
|
-
if (!
|
|
187492
|
+
if (!existsSync12(packageJsonPath))
|
|
187277
187493
|
continue;
|
|
187278
187494
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync7(packageJsonPath, "utf-8")));
|
|
187279
187495
|
if (pkg.success && pkg.data.version) {
|
|
@@ -187327,8 +187543,8 @@ function stripPackageNameFromPath(pathValue, packageName) {
|
|
|
187327
187543
|
return current;
|
|
187328
187544
|
}
|
|
187329
187545
|
function removeFromPackageLock(installDir, packageName) {
|
|
187330
|
-
const lockPath =
|
|
187331
|
-
if (!
|
|
187546
|
+
const lockPath = join9(installDir, "package-lock.json");
|
|
187547
|
+
if (!existsSync13(lockPath))
|
|
187332
187548
|
return false;
|
|
187333
187549
|
try {
|
|
187334
187550
|
const lock = import_comment_json2.parse(readFileSync8(lockPath, "utf-8"));
|
|
@@ -187354,7 +187570,7 @@ function removeFromPackageLock(installDir, packageName) {
|
|
|
187354
187570
|
}
|
|
187355
187571
|
}
|
|
187356
187572
|
function ensureDependencyVersion(packageJsonPath, packageName, version2) {
|
|
187357
|
-
if (!
|
|
187573
|
+
if (!existsSync13(packageJsonPath))
|
|
187358
187574
|
return false;
|
|
187359
187575
|
try {
|
|
187360
187576
|
const raw = import_comment_json2.parse(readFileSync8(packageJsonPath, "utf-8"));
|
|
@@ -187376,8 +187592,8 @@ function ensureDependencyVersion(packageJsonPath, packageName, version2) {
|
|
|
187376
187592
|
}
|
|
187377
187593
|
}
|
|
187378
187594
|
function removeInstalledPackage(installDir, packageName) {
|
|
187379
|
-
const packageDir =
|
|
187380
|
-
if (!
|
|
187595
|
+
const packageDir = join9(installDir, "node_modules", packageName);
|
|
187596
|
+
if (!existsSync13(packageDir))
|
|
187381
187597
|
return false;
|
|
187382
187598
|
try {
|
|
187383
187599
|
rmSync2(packageDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
@@ -187398,8 +187614,8 @@ function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackage
|
|
|
187398
187614
|
const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
|
|
187399
187615
|
if (nodeModulesDir && basename2(nodeModulesDir) === "node_modules") {
|
|
187400
187616
|
const installDir = dirname6(nodeModulesDir);
|
|
187401
|
-
const packageJsonPath =
|
|
187402
|
-
if (!
|
|
187617
|
+
const packageJsonPath = join9(installDir, "package.json");
|
|
187618
|
+
if (!existsSync13(packageJsonPath)) {
|
|
187403
187619
|
try {
|
|
187404
187620
|
writeFileSync4(packageJsonPath, `${JSON.stringify({ private: true, dependencies: {} }, null, 2)}
|
|
187405
187621
|
`);
|
|
@@ -187413,8 +187629,8 @@ function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackage
|
|
|
187413
187629
|
}
|
|
187414
187630
|
return null;
|
|
187415
187631
|
}
|
|
187416
|
-
const legacyPackageJsonPath =
|
|
187417
|
-
if (
|
|
187632
|
+
const legacyPackageJsonPath = join9(dirname6(CACHE_DIR), "package.json");
|
|
187633
|
+
if (existsSync13(legacyPackageJsonPath)) {
|
|
187418
187634
|
return { installDir: dirname6(CACHE_DIR), packageJsonPath: legacyPackageJsonPath };
|
|
187419
187635
|
}
|
|
187420
187636
|
return null;
|
|
@@ -187538,8 +187754,8 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
187538
187754
|
if (!storageDir)
|
|
187539
187755
|
return true;
|
|
187540
187756
|
try {
|
|
187541
|
-
const file2 =
|
|
187542
|
-
if (
|
|
187757
|
+
const file2 = join10(storageDir, TIMESTAMP_FILENAME);
|
|
187758
|
+
if (existsSync14(file2)) {
|
|
187543
187759
|
try {
|
|
187544
187760
|
const raw = JSON.parse(readFileSync9(file2, "utf-8"));
|
|
187545
187761
|
const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
|
|
@@ -187845,29 +188061,6 @@ function releaseLease(db, holderId, leaseKey = DREAMING_LEASE_KEY) {
|
|
|
187845
188061
|
});
|
|
187846
188062
|
}
|
|
187847
188063
|
|
|
187848
|
-
// src/features/magic-context/dreamer/open-opencode-db.ts
|
|
187849
|
-
init_logger();
|
|
187850
|
-
await __promiseAll([
|
|
187851
|
-
init_sqlite(),
|
|
187852
|
-
init_compaction_marker()
|
|
187853
|
-
]);
|
|
187854
|
-
import { existsSync as existsSync13 } from "node:fs";
|
|
187855
|
-
function openOpenCodeDb() {
|
|
187856
|
-
const dbPath = getOpenCodeDbPath2();
|
|
187857
|
-
if (!existsSync13(dbPath)) {
|
|
187858
|
-
log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
|
|
187859
|
-
return null;
|
|
187860
|
-
}
|
|
187861
|
-
try {
|
|
187862
|
-
const db = new Database(dbPath, { readonly: true });
|
|
187863
|
-
db.exec("PRAGMA busy_timeout = 5000");
|
|
187864
|
-
return db;
|
|
187865
|
-
} catch (error51) {
|
|
187866
|
-
log(`[key-files] failed to open OpenCode DB at ${dbPath}: ${getErrorMessage(error51)}`);
|
|
187867
|
-
return null;
|
|
187868
|
-
}
|
|
187869
|
-
}
|
|
187870
|
-
|
|
187871
188064
|
// src/features/magic-context/dreamer/retrospective-orphan-sweep.ts
|
|
187872
188065
|
init_logger();
|
|
187873
188066
|
var RETROSPECTIVE_CHILD_TITLE = "magic-context-dream-retrospective";
|
|
@@ -188290,7 +188483,7 @@ init_task_config();
|
|
|
188290
188483
|
|
|
188291
188484
|
// src/features/magic-context/dreamer/task-executor.ts
|
|
188292
188485
|
import { createHash as createHash10 } from "node:crypto";
|
|
188293
|
-
import { existsSync as
|
|
188486
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
188294
188487
|
|
|
188295
188488
|
// src/agents/dreamer.ts
|
|
188296
188489
|
var DREAMER_AGENT = "dreamer";
|
|
@@ -190377,7 +190570,7 @@ Output exactly JSON: {"met": false}`;
|
|
|
190377
190570
|
|
|
190378
190571
|
// src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
|
|
190379
190572
|
init_logger();
|
|
190380
|
-
import { existsSync as
|
|
190573
|
+
import { existsSync as existsSync17, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "node:fs";
|
|
190381
190574
|
import { join as join15 } from "node:path";
|
|
190382
190575
|
|
|
190383
190576
|
// src/features/magic-context/dreamer/protected-regions.ts
|
|
@@ -190481,7 +190674,7 @@ function snapshotMaintainDocsFiles(docsDir) {
|
|
|
190481
190674
|
for (const name2 of MAINTAIN_DOCS_SNAPSHOT_FILES) {
|
|
190482
190675
|
const path8 = join15(docsDir, name2);
|
|
190483
190676
|
try {
|
|
190484
|
-
if (
|
|
190677
|
+
if (existsSync17(path8)) {
|
|
190485
190678
|
snapshot.set(name2, readFileSync11(path8, "utf8"));
|
|
190486
190679
|
}
|
|
190487
190680
|
} catch {}
|
|
@@ -190513,7 +190706,7 @@ init_memory();
|
|
|
190513
190706
|
init_subagent_token_capture();
|
|
190514
190707
|
|
|
190515
190708
|
// src/features/magic-context/dreamer/map-memories-prompt.ts
|
|
190516
|
-
import { existsSync as
|
|
190709
|
+
import { existsSync as existsSync18, statSync as statSync6 } from "node:fs";
|
|
190517
190710
|
import path8 from "node:path";
|
|
190518
190711
|
var MAP_MEMORIES_SYSTEM_PROMPT = `You are a memory mapper for the magic-context system. You map project memories to the repository files that back them.
|
|
190519
190712
|
|
|
@@ -190551,7 +190744,7 @@ function extractMemoryCandidatePaths(content, repoDir) {
|
|
|
190551
190744
|
if (!abs.startsWith(`${root}/`))
|
|
190552
190745
|
continue;
|
|
190553
190746
|
try {
|
|
190554
|
-
if (
|
|
190747
|
+
if (existsSync18(abs) && statSync6(abs).isFile())
|
|
190555
190748
|
found.add(rel);
|
|
190556
190749
|
} catch {}
|
|
190557
190750
|
if (found.size >= MAX_SEED_PATHS_PER_MEMORY)
|
|
@@ -192380,8 +192573,8 @@ async function runAgenticTask(config2, ctx, helpers) {
|
|
|
192380
192573
|
const lastRunAt = getTaskScheduleState(db, projectIdentity, config2.task)?.lastRunAt ?? null;
|
|
192381
192574
|
const maintainDocsSnapshot = task === "maintain-docs" ? snapshotMaintainDocsFiles(docsDir) : undefined;
|
|
192382
192575
|
const existingDocs = task === "maintain-docs" ? {
|
|
192383
|
-
architecture:
|
|
192384
|
-
structure:
|
|
192576
|
+
architecture: existsSync19(`${docsDir}/ARCHITECTURE.md`),
|
|
192577
|
+
structure: existsSync19(`${docsDir}/STRUCTURE.md`)
|
|
192385
192578
|
} : undefined;
|
|
192386
192579
|
const userMemories = task === "curate" ? getActiveUserMemories(db).map((um) => ({ id: um.id, content: um.content })) : undefined;
|
|
192387
192580
|
let curateMemories;
|
|
@@ -204973,6 +205166,31 @@ var server = async (ctx) => {
|
|
|
204973
205166
|
log(`[v22-backfill] failed to start background runner: ${err}`);
|
|
204974
205167
|
}
|
|
204975
205168
|
}
|
|
205169
|
+
if (pluginConfig.enabled && hooks.magicContext) {
|
|
205170
|
+
setTimeout(() => {
|
|
205171
|
+
try {
|
|
205172
|
+
const db = openDatabase();
|
|
205173
|
+
if (!db || !isDatabasePersisted(db))
|
|
205174
|
+
return;
|
|
205175
|
+
const ocDb = openOpenCodeDb();
|
|
205176
|
+
if (!ocDb)
|
|
205177
|
+
return;
|
|
205178
|
+
try {
|
|
205179
|
+
const sessions = ocDb.prepare("SELECT id, COALESCE(directory, '') AS directory FROM session ORDER BY id ASC").all();
|
|
205180
|
+
runSessionProjectBackfill(db, sessions.map((session) => ({
|
|
205181
|
+
sessionId: session.id,
|
|
205182
|
+
directory: session.directory
|
|
205183
|
+
}))).catch((err) => {
|
|
205184
|
+
log(`[session-projects] background runner failed: ${err}`);
|
|
205185
|
+
});
|
|
205186
|
+
} finally {
|
|
205187
|
+
closeQuietly(ocDb);
|
|
205188
|
+
}
|
|
205189
|
+
} catch (err) {
|
|
205190
|
+
log(`[session-projects] failed to start background runner: ${err}`);
|
|
205191
|
+
}
|
|
205192
|
+
}, 0);
|
|
205193
|
+
}
|
|
204976
205194
|
const storageDir = getMagicContextStorageDir();
|
|
204977
205195
|
let rpcServer = null;
|
|
204978
205196
|
let stopDreamTimerRegistration;
|