@cortexkit/opencode-magic-context 0.30.5 → 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/dreamer/task-scheduler.d.ts +2 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts +20 -0
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/index.d.ts +1 -1
- package/dist/features/magic-context/git-commits/index.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/indexer.d.ts +6 -0
- package/dist/features/magic-context/git-commits/indexer.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts +17 -0
- package/dist/features/magic-context/git-commits/sweep-coordinator.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/command-handler.d.ts.map +1 -1
- 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 +809 -540
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- 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, {
|
|
@@ -167985,6 +168063,20 @@ function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
|
|
|
167985
168063
|
return result.changes === 1;
|
|
167986
168064
|
});
|
|
167987
168065
|
}
|
|
168066
|
+
function parkGitSweepNonIndexable(db, projectPath, holderId, reprobeMs = GIT_SWEEP_NON_INDEXABLE_REPROBE_MS) {
|
|
168067
|
+
return runImmediate2(db, () => {
|
|
168068
|
+
const now = Date.now();
|
|
168069
|
+
const sweptAt = now + reprobeMs - GIT_SWEEP_COOLDOWN_MS;
|
|
168070
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
168071
|
+
SET lease_holder = NULL,
|
|
168072
|
+
lease_expires_at = NULL,
|
|
168073
|
+
last_swept_at = ?
|
|
168074
|
+
WHERE project_path = ?
|
|
168075
|
+
AND lease_holder = ?
|
|
168076
|
+
AND lease_expires_at > ?`).run(sweptAt, projectPath, holderId, now);
|
|
168077
|
+
return result.changes === 1;
|
|
168078
|
+
});
|
|
168079
|
+
}
|
|
167988
168080
|
function releaseGitSweepLease(db, projectPath, holderId) {
|
|
167989
168081
|
runImmediate2(db, () => {
|
|
167990
168082
|
db.prepare(`UPDATE git_sweep_coordinator
|
|
@@ -167994,10 +168086,11 @@ function releaseGitSweepLease(db, projectPath, holderId) {
|
|
|
167994
168086
|
AND lease_holder = ?`).run(projectPath, holderId);
|
|
167995
168087
|
});
|
|
167996
168088
|
}
|
|
167997
|
-
var GIT_SWEEP_COOLDOWN_MS, GIT_SWEEP_LEASE_TTL_MS, GIT_SWEEP_LEASE_RENEWAL_MS;
|
|
168089
|
+
var GIT_SWEEP_COOLDOWN_MS, GIT_SWEEP_LEASE_TTL_MS, GIT_SWEEP_NON_INDEXABLE_REPROBE_MS, GIT_SWEEP_LEASE_RENEWAL_MS;
|
|
167998
168090
|
var init_sweep_coordinator = __esm(() => {
|
|
167999
168091
|
GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
168000
168092
|
GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
168093
|
+
GIT_SWEEP_NON_INDEXABLE_REPROBE_MS = 24 * 60 * 60 * 1000;
|
|
168001
168094
|
GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
|
|
168002
168095
|
});
|
|
168003
168096
|
|
|
@@ -168057,80 +168150,6 @@ var init_embedding_cache = __esm(() => {
|
|
|
168057
168150
|
embeddingCacheTtlMs = DEFAULT_EMBEDDING_CACHE_TTL_MS;
|
|
168058
168151
|
});
|
|
168059
168152
|
|
|
168060
|
-
// src/features/magic-context/session-project-storage.ts
|
|
168061
|
-
function getUpsertSessionProjectStatement(db) {
|
|
168062
|
-
let stmt = upsertSessionProjectStatements.get(db);
|
|
168063
|
-
if (!stmt) {
|
|
168064
|
-
stmt = db.prepare(`INSERT INTO session_projects (session_id, harness, project_path, updated_at)
|
|
168065
|
-
VALUES (?, ?, ?, ?)
|
|
168066
|
-
ON CONFLICT(session_id, harness) DO UPDATE SET
|
|
168067
|
-
project_path = excluded.project_path,
|
|
168068
|
-
updated_at = excluded.updated_at
|
|
168069
|
-
WHERE session_projects.project_path <> excluded.project_path`);
|
|
168070
|
-
upsertSessionProjectStatements.set(db, stmt);
|
|
168071
|
-
}
|
|
168072
|
-
return stmt;
|
|
168073
|
-
}
|
|
168074
|
-
function getRepairSessionChunkProjectStatement(db) {
|
|
168075
|
-
let stmt = repairSessionChunkProjectStatements.get(db);
|
|
168076
|
-
if (!stmt) {
|
|
168077
|
-
stmt = db.prepare(`UPDATE compartment_chunk_embeddings
|
|
168078
|
-
SET project_path = ?
|
|
168079
|
-
WHERE session_id = ?
|
|
168080
|
-
AND harness = ?
|
|
168081
|
-
AND project_path <> ?`);
|
|
168082
|
-
repairSessionChunkProjectStatements.set(db, stmt);
|
|
168083
|
-
}
|
|
168084
|
-
return stmt;
|
|
168085
|
-
}
|
|
168086
|
-
function getRepairProjectChunkProjectStatement(db) {
|
|
168087
|
-
let stmt = repairProjectChunkProjectStatements.get(db);
|
|
168088
|
-
if (!stmt) {
|
|
168089
|
-
stmt = db.prepare(`UPDATE compartment_chunk_embeddings
|
|
168090
|
-
SET project_path = (
|
|
168091
|
-
SELECT sp.project_path
|
|
168092
|
-
FROM session_projects sp
|
|
168093
|
-
WHERE sp.session_id = compartment_chunk_embeddings.session_id
|
|
168094
|
-
AND sp.harness = compartment_chunk_embeddings.harness
|
|
168095
|
-
LIMIT 1
|
|
168096
|
-
)
|
|
168097
|
-
WHERE EXISTS (
|
|
168098
|
-
SELECT 1
|
|
168099
|
-
FROM session_projects sp
|
|
168100
|
-
WHERE sp.session_id = compartment_chunk_embeddings.session_id
|
|
168101
|
-
AND sp.harness = compartment_chunk_embeddings.harness
|
|
168102
|
-
AND sp.project_path <> compartment_chunk_embeddings.project_path
|
|
168103
|
-
AND (
|
|
168104
|
-
sp.project_path = ?
|
|
168105
|
-
OR compartment_chunk_embeddings.project_path = ?
|
|
168106
|
-
)
|
|
168107
|
-
)`);
|
|
168108
|
-
repairProjectChunkProjectStatements.set(db, stmt);
|
|
168109
|
-
}
|
|
168110
|
-
return stmt;
|
|
168111
|
-
}
|
|
168112
|
-
function recordSessionProjectIdentity(db, sessionId, projectPath) {
|
|
168113
|
-
if (!sessionId || !projectPath)
|
|
168114
|
-
return;
|
|
168115
|
-
const harness = getHarness();
|
|
168116
|
-
const now = Date.now();
|
|
168117
|
-
db.transaction(() => {
|
|
168118
|
-
getUpsertSessionProjectStatement(db).run(sessionId, harness, projectPath, now);
|
|
168119
|
-
getRepairSessionChunkProjectStatement(db).run(projectPath, sessionId, harness, projectPath);
|
|
168120
|
-
})();
|
|
168121
|
-
}
|
|
168122
|
-
function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath) {
|
|
168123
|
-
if (!projectPath)
|
|
168124
|
-
return 0;
|
|
168125
|
-
return getRepairProjectChunkProjectStatement(db).run(projectPath, projectPath).changes;
|
|
168126
|
-
}
|
|
168127
|
-
var upsertSessionProjectStatements, repairSessionChunkProjectStatements, repairProjectChunkProjectStatements;
|
|
168128
|
-
var init_session_project_storage = __esm(() => {
|
|
168129
|
-
upsertSessionProjectStatements = new WeakMap;
|
|
168130
|
-
repairSessionChunkProjectStatements = new WeakMap;
|
|
168131
|
-
repairProjectChunkProjectStatements = new WeakMap;
|
|
168132
|
-
});
|
|
168133
|
-
|
|
168134
168153
|
// src/features/magic-context/project-embedding-registry.ts
|
|
168135
168154
|
import { createHash as createHash8, randomUUID } from "node:crypto";
|
|
168136
168155
|
function markProjectLoadUntrusted(projectIdentity) {
|
|
@@ -169767,7 +169786,7 @@ function getMemoryVerifications(db, memoryIds) {
|
|
|
169767
169786
|
var MEMORY_VERIFICATION_SENTINEL = "";
|
|
169768
169787
|
// src/features/magic-context/memory/verification-paths.ts
|
|
169769
169788
|
import { execFile } from "node:child_process";
|
|
169770
|
-
import { existsSync as
|
|
169789
|
+
import { existsSync as existsSync16, realpathSync as realpathSync2, statSync as statSync5 } from "node:fs";
|
|
169771
169790
|
import path6 from "node:path";
|
|
169772
169791
|
import { promisify } from "node:util";
|
|
169773
169792
|
async function runGit(cwd, args) {
|
|
@@ -169870,7 +169889,7 @@ function verificationFileExists(baseRoot, filePath) {
|
|
|
169870
169889
|
return false;
|
|
169871
169890
|
const root = path6.resolve(baseRoot);
|
|
169872
169891
|
const candidate = path6.resolve(root, filePath);
|
|
169873
|
-
return isWithin(root, candidate) &&
|
|
169892
|
+
return isWithin(root, candidate) && existsSync16(candidate);
|
|
169874
169893
|
}
|
|
169875
169894
|
async function normalizeVerificationFiles(args) {
|
|
169876
169895
|
const cwd = path6.resolve(args.cwd);
|
|
@@ -169903,7 +169922,7 @@ async function normalizeVerificationFiles(args) {
|
|
|
169903
169922
|
warnings.push(`Skipped verification path "${value}" because it is the repo/project root.`);
|
|
169904
169923
|
continue;
|
|
169905
169924
|
}
|
|
169906
|
-
if (
|
|
169925
|
+
if (existsSync16(candidate)) {
|
|
169907
169926
|
try {
|
|
169908
169927
|
if (statSync5(candidate).isDirectory()) {
|
|
169909
169928
|
warnings.push(`Skipped verification path "${value}" because it is a directory.`);
|
|
@@ -169934,7 +169953,7 @@ async function normalizeVerificationFiles(args) {
|
|
|
169934
169953
|
}
|
|
169935
169954
|
normalized.push(tracked);
|
|
169936
169955
|
} else {
|
|
169937
|
-
if (!
|
|
169956
|
+
if (!existsSync16(candidate)) {
|
|
169938
169957
|
warnings.push(`Skipped verification path "${value}" because it does not exist.`);
|
|
169939
169958
|
continue;
|
|
169940
169959
|
}
|
|
@@ -177278,6 +177297,9 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory) {
|
|
|
177278
177297
|
}
|
|
177279
177298
|
}
|
|
177280
177299
|
function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
|
|
177300
|
+
if (getHarness() !== "opencode") {
|
|
177301
|
+
return true;
|
|
177302
|
+
}
|
|
177281
177303
|
const targetEndMessageId = getCompartmentEndMessageIdForOrdinal(db, sessionId, lastCompartmentEnd);
|
|
177282
177304
|
if (!targetEndMessageId) {
|
|
177283
177305
|
sessionLog(sessionId, `compaction-marker: no compartment endMessageId for ordinal ${lastCompartmentEnd}; preserving existing marker`);
|
|
@@ -186334,6 +186356,29 @@ function getMagicContextBuiltinCommands() {
|
|
|
186334
186356
|
};
|
|
186335
186357
|
}
|
|
186336
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
|
+
|
|
186337
186382
|
// src/features/magic-context/dreamer/task-prompts.ts
|
|
186338
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.`;
|
|
186339
186384
|
var PROJECT_MEMORY_TAXONOMY = `## Memory taxonomy (5 categories)
|
|
@@ -186643,6 +186688,192 @@ function buildDreamTaskPrompt(task, args) {
|
|
|
186643
186688
|
// src/index.ts
|
|
186644
186689
|
init_project_identity();
|
|
186645
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
|
+
|
|
186646
186877
|
// src/features/magic-context/sidekick/agent.ts
|
|
186647
186878
|
init_language_directive();
|
|
186648
186879
|
|
|
@@ -187033,45 +187264,45 @@ async function runDeferredV22Backfill(db, options = {}) {
|
|
|
187033
187264
|
|
|
187034
187265
|
// src/hooks/auto-update-checker/index.ts
|
|
187035
187266
|
init_logger();
|
|
187036
|
-
import { existsSync as
|
|
187037
|
-
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";
|
|
187038
187269
|
|
|
187039
187270
|
// src/hooks/auto-update-checker/cache.ts
|
|
187040
187271
|
init_logger();
|
|
187041
187272
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
187042
187273
|
import { spawn } from "node:child_process";
|
|
187043
|
-
import { existsSync as
|
|
187044
|
-
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";
|
|
187045
187276
|
|
|
187046
187277
|
// src/hooks/auto-update-checker/checker.ts
|
|
187047
187278
|
init_logger();
|
|
187048
187279
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
187049
|
-
import { existsSync as
|
|
187280
|
+
import { existsSync as existsSync12, readFileSync as readFileSync7, renameSync as renameSync2, statSync as statSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
187050
187281
|
import { homedir as homedir5 } from "node:os";
|
|
187051
|
-
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";
|
|
187052
187283
|
import { fileURLToPath } from "node:url";
|
|
187053
187284
|
|
|
187054
187285
|
// src/hooks/auto-update-checker/constants.ts
|
|
187055
187286
|
import { homedir as homedir4, platform } from "node:os";
|
|
187056
|
-
import { join as
|
|
187287
|
+
import { join as join7 } from "node:path";
|
|
187057
187288
|
var PACKAGE_NAME = "@cortexkit/opencode-magic-context";
|
|
187058
187289
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
187059
187290
|
var NPM_FETCH_TIMEOUT = 1e4;
|
|
187060
187291
|
function getOpenCodeCacheRoot() {
|
|
187061
187292
|
if (platform() === "win32") {
|
|
187062
|
-
return
|
|
187293
|
+
return join7(process.env.LOCALAPPDATA ?? homedir4(), "opencode");
|
|
187063
187294
|
}
|
|
187064
|
-
return
|
|
187295
|
+
return join7(homedir4(), ".cache", "opencode");
|
|
187065
187296
|
}
|
|
187066
187297
|
function getOpenCodeConfigRoot() {
|
|
187067
187298
|
if (platform() === "win32") {
|
|
187068
|
-
return
|
|
187299
|
+
return join7(process.env.APPDATA ?? join7(homedir4(), "AppData", "Roaming"), "opencode");
|
|
187069
187300
|
}
|
|
187070
|
-
return
|
|
187301
|
+
return join7(process.env.XDG_CONFIG_HOME ?? join7(homedir4(), ".config"), "opencode");
|
|
187071
187302
|
}
|
|
187072
|
-
var CACHE_DIR =
|
|
187073
|
-
var USER_OPENCODE_CONFIG =
|
|
187074
|
-
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");
|
|
187075
187306
|
// src/hooks/auto-update-checker/types.ts
|
|
187076
187307
|
init_zod();
|
|
187077
187308
|
var NpmPackageEnvelopeSchema = exports_external.object({
|
|
@@ -187132,8 +187363,8 @@ function extractChannel(version2) {
|
|
|
187132
187363
|
}
|
|
187133
187364
|
function getConfigPaths(directory) {
|
|
187134
187365
|
return [
|
|
187135
|
-
|
|
187136
|
-
|
|
187366
|
+
join8(directory, ".opencode", "opencode.json"),
|
|
187367
|
+
join8(directory, ".opencode", "opencode.jsonc"),
|
|
187137
187368
|
USER_OPENCODE_CONFIG,
|
|
187138
187369
|
USER_OPENCODE_CONFIG_JSONC
|
|
187139
187370
|
];
|
|
@@ -187155,8 +187386,8 @@ function findPackageJsonUp(startPath) {
|
|
|
187155
187386
|
const stat = statSync4(startPath);
|
|
187156
187387
|
let dir = stat.isDirectory() ? startPath : dirname5(startPath);
|
|
187157
187388
|
for (let i = 0;i < 10; i++) {
|
|
187158
|
-
const pkgPath =
|
|
187159
|
-
if (
|
|
187389
|
+
const pkgPath = join8(dir, "package.json");
|
|
187390
|
+
if (existsSync12(pkgPath)) {
|
|
187160
187391
|
try {
|
|
187161
187392
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync7(pkgPath, "utf-8")));
|
|
187162
187393
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
@@ -187174,7 +187405,7 @@ function findPackageJsonUp(startPath) {
|
|
|
187174
187405
|
function getLocalDevPath(directory) {
|
|
187175
187406
|
for (const configPath of getConfigPaths(directory)) {
|
|
187176
187407
|
try {
|
|
187177
|
-
if (!
|
|
187408
|
+
if (!existsSync12(configPath))
|
|
187178
187409
|
continue;
|
|
187179
187410
|
const rawConfig = parseJsonConfig(readFileSync7(configPath, "utf-8"));
|
|
187180
187411
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -187220,7 +187451,7 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
|
187220
187451
|
function findPluginEntry(directory) {
|
|
187221
187452
|
for (const configPath of getConfigPaths(directory)) {
|
|
187222
187453
|
try {
|
|
187223
|
-
if (!
|
|
187454
|
+
if (!existsSync12(configPath))
|
|
187224
187455
|
continue;
|
|
187225
187456
|
const rawConfig = parseJsonConfig(readFileSync7(configPath, "utf-8"));
|
|
187226
187457
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -187245,7 +187476,7 @@ function findPluginEntry(directory) {
|
|
|
187245
187476
|
}
|
|
187246
187477
|
var cachedPackageVersion = null;
|
|
187247
187478
|
function getSpecCachePackageJsonPath(spec) {
|
|
187248
|
-
return
|
|
187479
|
+
return join8(CACHE_DIR, spec, "node_modules", PACKAGE_NAME, "package.json");
|
|
187249
187480
|
}
|
|
187250
187481
|
function getCachedVersion(spec) {
|
|
187251
187482
|
if (!spec && cachedPackageVersion)
|
|
@@ -187254,11 +187485,11 @@ function getCachedVersion(spec) {
|
|
|
187254
187485
|
getCurrentRuntimePackageJsonPath(),
|
|
187255
187486
|
spec ? getSpecCachePackageJsonPath(spec) : null,
|
|
187256
187487
|
getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
|
|
187257
|
-
|
|
187488
|
+
join8(homedir5(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
|
|
187258
187489
|
].filter(isString);
|
|
187259
187490
|
for (const packageJsonPath of candidates) {
|
|
187260
187491
|
try {
|
|
187261
|
-
if (!
|
|
187492
|
+
if (!existsSync12(packageJsonPath))
|
|
187262
187493
|
continue;
|
|
187263
187494
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync7(packageJsonPath, "utf-8")));
|
|
187264
187495
|
if (pkg.success && pkg.data.version) {
|
|
@@ -187312,8 +187543,8 @@ function stripPackageNameFromPath(pathValue, packageName) {
|
|
|
187312
187543
|
return current;
|
|
187313
187544
|
}
|
|
187314
187545
|
function removeFromPackageLock(installDir, packageName) {
|
|
187315
|
-
const lockPath =
|
|
187316
|
-
if (!
|
|
187546
|
+
const lockPath = join9(installDir, "package-lock.json");
|
|
187547
|
+
if (!existsSync13(lockPath))
|
|
187317
187548
|
return false;
|
|
187318
187549
|
try {
|
|
187319
187550
|
const lock = import_comment_json2.parse(readFileSync8(lockPath, "utf-8"));
|
|
@@ -187339,7 +187570,7 @@ function removeFromPackageLock(installDir, packageName) {
|
|
|
187339
187570
|
}
|
|
187340
187571
|
}
|
|
187341
187572
|
function ensureDependencyVersion(packageJsonPath, packageName, version2) {
|
|
187342
|
-
if (!
|
|
187573
|
+
if (!existsSync13(packageJsonPath))
|
|
187343
187574
|
return false;
|
|
187344
187575
|
try {
|
|
187345
187576
|
const raw = import_comment_json2.parse(readFileSync8(packageJsonPath, "utf-8"));
|
|
@@ -187361,8 +187592,8 @@ function ensureDependencyVersion(packageJsonPath, packageName, version2) {
|
|
|
187361
187592
|
}
|
|
187362
187593
|
}
|
|
187363
187594
|
function removeInstalledPackage(installDir, packageName) {
|
|
187364
|
-
const packageDir =
|
|
187365
|
-
if (!
|
|
187595
|
+
const packageDir = join9(installDir, "node_modules", packageName);
|
|
187596
|
+
if (!existsSync13(packageDir))
|
|
187366
187597
|
return false;
|
|
187367
187598
|
try {
|
|
187368
187599
|
rmSync2(packageDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
@@ -187383,8 +187614,8 @@ function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackage
|
|
|
187383
187614
|
const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
|
|
187384
187615
|
if (nodeModulesDir && basename2(nodeModulesDir) === "node_modules") {
|
|
187385
187616
|
const installDir = dirname6(nodeModulesDir);
|
|
187386
|
-
const packageJsonPath =
|
|
187387
|
-
if (!
|
|
187617
|
+
const packageJsonPath = join9(installDir, "package.json");
|
|
187618
|
+
if (!existsSync13(packageJsonPath)) {
|
|
187388
187619
|
try {
|
|
187389
187620
|
writeFileSync4(packageJsonPath, `${JSON.stringify({ private: true, dependencies: {} }, null, 2)}
|
|
187390
187621
|
`);
|
|
@@ -187398,8 +187629,8 @@ function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackage
|
|
|
187398
187629
|
}
|
|
187399
187630
|
return null;
|
|
187400
187631
|
}
|
|
187401
|
-
const legacyPackageJsonPath =
|
|
187402
|
-
if (
|
|
187632
|
+
const legacyPackageJsonPath = join9(dirname6(CACHE_DIR), "package.json");
|
|
187633
|
+
if (existsSync13(legacyPackageJsonPath)) {
|
|
187403
187634
|
return { installDir: dirname6(CACHE_DIR), packageJsonPath: legacyPackageJsonPath };
|
|
187404
187635
|
}
|
|
187405
187636
|
return null;
|
|
@@ -187523,8 +187754,8 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
187523
187754
|
if (!storageDir)
|
|
187524
187755
|
return true;
|
|
187525
187756
|
try {
|
|
187526
|
-
const file2 =
|
|
187527
|
-
if (
|
|
187757
|
+
const file2 = join10(storageDir, TIMESTAMP_FILENAME);
|
|
187758
|
+
if (existsSync14(file2)) {
|
|
187528
187759
|
try {
|
|
187529
187760
|
const raw = JSON.parse(readFileSync9(file2, "utf-8"));
|
|
187530
187761
|
const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
|
|
@@ -187830,29 +188061,6 @@ function releaseLease(db, holderId, leaseKey = DREAMING_LEASE_KEY) {
|
|
|
187830
188061
|
});
|
|
187831
188062
|
}
|
|
187832
188063
|
|
|
187833
|
-
// src/features/magic-context/dreamer/open-opencode-db.ts
|
|
187834
|
-
init_logger();
|
|
187835
|
-
await __promiseAll([
|
|
187836
|
-
init_sqlite(),
|
|
187837
|
-
init_compaction_marker()
|
|
187838
|
-
]);
|
|
187839
|
-
import { existsSync as existsSync13 } from "node:fs";
|
|
187840
|
-
function openOpenCodeDb() {
|
|
187841
|
-
const dbPath = getOpenCodeDbPath2();
|
|
187842
|
-
if (!existsSync13(dbPath)) {
|
|
187843
|
-
log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
|
|
187844
|
-
return null;
|
|
187845
|
-
}
|
|
187846
|
-
try {
|
|
187847
|
-
const db = new Database(dbPath, { readonly: true });
|
|
187848
|
-
db.exec("PRAGMA busy_timeout = 5000");
|
|
187849
|
-
return db;
|
|
187850
|
-
} catch (error51) {
|
|
187851
|
-
log(`[key-files] failed to open OpenCode DB at ${dbPath}: ${getErrorMessage(error51)}`);
|
|
187852
|
-
return null;
|
|
187853
|
-
}
|
|
187854
|
-
}
|
|
187855
|
-
|
|
187856
188064
|
// src/features/magic-context/dreamer/retrospective-orphan-sweep.ts
|
|
187857
188065
|
init_logger();
|
|
187858
188066
|
var RETROSPECTIVE_CHILD_TITLE = "magic-context-dream-retrospective";
|
|
@@ -188275,7 +188483,7 @@ init_task_config();
|
|
|
188275
188483
|
|
|
188276
188484
|
// src/features/magic-context/dreamer/task-executor.ts
|
|
188277
188485
|
import { createHash as createHash10 } from "node:crypto";
|
|
188278
|
-
import { existsSync as
|
|
188486
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
188279
188487
|
|
|
188280
188488
|
// src/agents/dreamer.ts
|
|
188281
188489
|
var DREAMER_AGENT = "dreamer";
|
|
@@ -190362,7 +190570,7 @@ Output exactly JSON: {"met": false}`;
|
|
|
190362
190570
|
|
|
190363
190571
|
// src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
|
|
190364
190572
|
init_logger();
|
|
190365
|
-
import { existsSync as
|
|
190573
|
+
import { existsSync as existsSync17, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "node:fs";
|
|
190366
190574
|
import { join as join15 } from "node:path";
|
|
190367
190575
|
|
|
190368
190576
|
// src/features/magic-context/dreamer/protected-regions.ts
|
|
@@ -190466,7 +190674,7 @@ function snapshotMaintainDocsFiles(docsDir) {
|
|
|
190466
190674
|
for (const name2 of MAINTAIN_DOCS_SNAPSHOT_FILES) {
|
|
190467
190675
|
const path8 = join15(docsDir, name2);
|
|
190468
190676
|
try {
|
|
190469
|
-
if (
|
|
190677
|
+
if (existsSync17(path8)) {
|
|
190470
190678
|
snapshot.set(name2, readFileSync11(path8, "utf8"));
|
|
190471
190679
|
}
|
|
190472
190680
|
} catch {}
|
|
@@ -190498,7 +190706,7 @@ init_memory();
|
|
|
190498
190706
|
init_subagent_token_capture();
|
|
190499
190707
|
|
|
190500
190708
|
// src/features/magic-context/dreamer/map-memories-prompt.ts
|
|
190501
|
-
import { existsSync as
|
|
190709
|
+
import { existsSync as existsSync18, statSync as statSync6 } from "node:fs";
|
|
190502
190710
|
import path8 from "node:path";
|
|
190503
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.
|
|
190504
190712
|
|
|
@@ -190536,7 +190744,7 @@ function extractMemoryCandidatePaths(content, repoDir) {
|
|
|
190536
190744
|
if (!abs.startsWith(`${root}/`))
|
|
190537
190745
|
continue;
|
|
190538
190746
|
try {
|
|
190539
|
-
if (
|
|
190747
|
+
if (existsSync18(abs) && statSync6(abs).isFile())
|
|
190540
190748
|
found.add(rel);
|
|
190541
190749
|
} catch {}
|
|
190542
190750
|
if (found.size >= MAX_SEED_PATHS_PER_MEMORY)
|
|
@@ -192365,8 +192573,8 @@ async function runAgenticTask(config2, ctx, helpers) {
|
|
|
192365
192573
|
const lastRunAt = getTaskScheduleState(db, projectIdentity, config2.task)?.lastRunAt ?? null;
|
|
192366
192574
|
const maintainDocsSnapshot = task === "maintain-docs" ? snapshotMaintainDocsFiles(docsDir) : undefined;
|
|
192367
192575
|
const existingDocs = task === "maintain-docs" ? {
|
|
192368
|
-
architecture:
|
|
192369
|
-
structure:
|
|
192576
|
+
architecture: existsSync19(`${docsDir}/ARCHITECTURE.md`),
|
|
192577
|
+
structure: existsSync19(`${docsDir}/STRUCTURE.md`)
|
|
192370
192578
|
} : undefined;
|
|
192371
192579
|
const userMemories = task === "curate" ? getActiveUserMemories(db).map((um) => ({ id: um.id, content: um.content })) : undefined;
|
|
192372
192580
|
let curateMemories;
|
|
@@ -192632,11 +192840,21 @@ function recordTransientFailure(db, projectIdentity, due, finishedAt, error51) {
|
|
|
192632
192840
|
});
|
|
192633
192841
|
}
|
|
192634
192842
|
}
|
|
192843
|
+
var LEASE_WAIT_POLL_MS = 2000;
|
|
192844
|
+
var MANUAL_RUN_LEASE_WAIT_MS = 60000;
|
|
192635
192845
|
async function runDomainGroup(deps, group, cb) {
|
|
192636
192846
|
const { db, projectIdentity, executor } = deps;
|
|
192637
192847
|
const leaseKey = leaseKeyFor(group[0].config.task, projectIdentity);
|
|
192638
192848
|
const holderId = crypto.randomUUID();
|
|
192639
|
-
|
|
192849
|
+
let acquired = acquireLease(db, holderId, leaseKey);
|
|
192850
|
+
if (!acquired && cb?.leaseWaitMs) {
|
|
192851
|
+
const deadline = Date.now() + cb.leaseWaitMs;
|
|
192852
|
+
while (!acquired && Date.now() < deadline) {
|
|
192853
|
+
await new Promise((resolve4) => setTimeout(resolve4, LEASE_WAIT_POLL_MS));
|
|
192854
|
+
acquired = acquireLease(db, holderId, leaseKey);
|
|
192855
|
+
}
|
|
192856
|
+
}
|
|
192857
|
+
if (!acquired) {
|
|
192640
192858
|
log(`[dreamer] domain lease busy (${leaseKey}) — deferring ${group.length} task(s)`);
|
|
192641
192859
|
for (const due of group)
|
|
192642
192860
|
cb?.onBusy?.(due.config.task);
|
|
@@ -192731,6 +192949,7 @@ async function runManualDream(deps) {
|
|
|
192731
192949
|
}
|
|
192732
192950
|
await Promise.all([...groups.values()].map((group) => runDomainGroup({ ...deps, executor: deps.executor }, group, {
|
|
192733
192951
|
forceGate,
|
|
192952
|
+
leaseWaitMs: MANUAL_RUN_LEASE_WAIT_MS,
|
|
192734
192953
|
onRan: (t) => result.ran.push(t),
|
|
192735
192954
|
onFailed: (t) => result.failed.push(t),
|
|
192736
192955
|
onBusy: (t) => result.deferredBusy.push(t)
|
|
@@ -192779,7 +192998,15 @@ var GIT_TIMEOUT_MS3 = 1e4;
|
|
|
192779
192998
|
var DEFAULT_MAX_COMMITS = 5000;
|
|
192780
192999
|
var RECORD_SEPARATOR = "\x1E";
|
|
192781
193000
|
var FIELD_SEPARATOR = "\x1F";
|
|
192782
|
-
|
|
193001
|
+
function classifyGitLogFailure(message) {
|
|
193002
|
+
if (message.includes("not a git repository"))
|
|
193003
|
+
return "not_a_repo";
|
|
193004
|
+
if (message.includes("unknown revision or path not in the working tree") || message.includes("does not have any commits yet") || message.includes("bad revision")) {
|
|
193005
|
+
return "no_head";
|
|
193006
|
+
}
|
|
193007
|
+
return "transient";
|
|
193008
|
+
}
|
|
193009
|
+
async function readGitCommitsResult(directory, options = {}) {
|
|
192783
193010
|
const revision = options.branch ?? "HEAD";
|
|
192784
193011
|
if (revision.startsWith("-")) {
|
|
192785
193012
|
throw new Error(`readGitCommits: refusing revision that looks like an option: "${revision}"`);
|
|
@@ -192807,13 +193034,18 @@ async function readGitCommits(directory, options = {}) {
|
|
|
192807
193034
|
stdout = result.stdout;
|
|
192808
193035
|
} catch (error51) {
|
|
192809
193036
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
192810
|
-
|
|
192811
|
-
|
|
193037
|
+
const failure = classifyGitLogFailure(message);
|
|
193038
|
+
if (failure === "transient") {
|
|
193039
|
+
log(`[git-commits] readGitCommits failed for ${projectLabel}: ${message.slice(0, 500)}`);
|
|
193040
|
+
} else {
|
|
193041
|
+
log(`[git-commits] ${projectLabel} is not indexable (${failure})`);
|
|
193042
|
+
}
|
|
193043
|
+
return { commits: [], failure };
|
|
192812
193044
|
}
|
|
192813
193045
|
if (stdout.trim().length === 0) {
|
|
192814
193046
|
log(`[git-commits] readGitCommits returned empty stdout for ${projectLabel} (sinceMs=${options.sinceMs ?? "none"} args=${args.slice(0, 4).join(" ")})`);
|
|
192815
193047
|
}
|
|
192816
|
-
return parseGitLogOutput(stdout);
|
|
193048
|
+
return { commits: parseGitLogOutput(stdout), failure: null };
|
|
192817
193049
|
}
|
|
192818
193050
|
function parseGitLogOutput(stdout) {
|
|
192819
193051
|
const commits = [];
|
|
@@ -192872,7 +193104,8 @@ async function indexCommitsForProject(db, projectPath, directory, options) {
|
|
|
192872
193104
|
inserted: 0,
|
|
192873
193105
|
updated: 0,
|
|
192874
193106
|
evicted: 0,
|
|
192875
|
-
embedded: 0
|
|
193107
|
+
embedded: 0,
|
|
193108
|
+
nonIndexable: false
|
|
192876
193109
|
};
|
|
192877
193110
|
if (indexInProgress.has(projectPath)) {
|
|
192878
193111
|
log(`[git-commits] index already in progress for ${projectPath}, skipping`);
|
|
@@ -192882,12 +193115,17 @@ async function indexCommitsForProject(db, projectPath, directory, options) {
|
|
|
192882
193115
|
try {
|
|
192883
193116
|
const latestIndexed = getLatestIndexedCommitTimeMs(db, projectPath);
|
|
192884
193117
|
const sinceMs = latestIndexed !== null ? Math.max(latestIndexed - 60000, Date.now() - options.sinceDays * MS_PER_DAY) : Date.now() - options.sinceDays * MS_PER_DAY;
|
|
192885
|
-
const
|
|
193118
|
+
const read = await readGitCommitsResult(directory, {
|
|
192886
193119
|
sinceMs,
|
|
192887
193120
|
maxCommits: options.maxCommits,
|
|
192888
193121
|
projectIdentity: projectPath
|
|
192889
193122
|
});
|
|
193123
|
+
const commits = read.commits;
|
|
192890
193124
|
result.scanned = commits.length;
|
|
193125
|
+
if (read.failure === "not_a_repo" || read.failure === "no_head") {
|
|
193126
|
+
result.nonIndexable = true;
|
|
193127
|
+
return result;
|
|
193128
|
+
}
|
|
192891
193129
|
if (commits.length === 0) {
|
|
192892
193130
|
result.evicted = enforceProjectCap(db, projectPath, options.maxCommits);
|
|
192893
193131
|
log(`[git-commits] no new commits for ${projectPath} (sinceMs=${sinceMs} latestIndexed=${latestIndexed ?? "none"} evicted=${result.evicted})`);
|
|
@@ -193320,6 +193558,12 @@ async function sweepGitCommits(args) {
|
|
|
193320
193558
|
sinceDays: gitCommitIndexing.since_days,
|
|
193321
193559
|
maxCommits: gitCommitIndexing.max_commits
|
|
193322
193560
|
});
|
|
193561
|
+
if (result.nonIndexable) {
|
|
193562
|
+
if (!parkGitSweepNonIndexable(db, projectIdentity, holderId)) {
|
|
193563
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
193564
|
+
}
|
|
193565
|
+
return;
|
|
193566
|
+
}
|
|
193323
193567
|
let drainedEmbeddings = 0;
|
|
193324
193568
|
if (result.embedded > 0) {
|
|
193325
193569
|
drainedEmbeddings = await embedUnembeddedCommits(db, projectIdentity);
|
|
@@ -194631,7 +194875,7 @@ function summarizeManualDream(s) {
|
|
|
194631
194875
|
if (s.skippedNoWork.length > 0)
|
|
194632
194876
|
lines.push(`Skipped (no work): ${s.skippedNoWork.join(", ")}`);
|
|
194633
194877
|
if (s.deferredBusy.length > 0)
|
|
194634
|
-
lines.push(`Busy
|
|
194878
|
+
lines.push(`Busy: ${s.deferredBusy.join(", ")} — another dream task holds this domain's lease; retry in a minute`);
|
|
194635
194879
|
if (s.ran.length === 0 && s.failed.length === 0 && s.skippedNoWork.length === 0 && s.deferredBusy.length === 0) {
|
|
194636
194880
|
lines.push("No enabled dream tasks to run.");
|
|
194637
194881
|
}
|
|
@@ -204922,6 +205166,31 @@ var server = async (ctx) => {
|
|
|
204922
205166
|
log(`[v22-backfill] failed to start background runner: ${err}`);
|
|
204923
205167
|
}
|
|
204924
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
|
+
}
|
|
204925
205194
|
const storageDir = getMagicContextStorageDir();
|
|
204926
205195
|
let rpcServer = null;
|
|
204927
205196
|
let stopDreamTimerRegistration;
|