@cortexkit/magic-context 0.16.3 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +498 -61
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -160419,18 +160419,77 @@ var init_tag_part_guards = __esm(() => {
|
|
|
160419
160419
|
init_tag_content_primitives();
|
|
160420
160420
|
});
|
|
160421
160421
|
|
|
160422
|
+
// ../plugin/src/shared/record-type-guard.ts
|
|
160423
|
+
function isRecord2(value) {
|
|
160424
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
160425
|
+
}
|
|
160426
|
+
|
|
160427
|
+
// ../plugin/src/hooks/magic-context/tool-drop-target.ts
|
|
160428
|
+
function hasMeaningfulPart(part) {
|
|
160429
|
+
if (!isRecord2(part))
|
|
160430
|
+
return false;
|
|
160431
|
+
const type = part.type;
|
|
160432
|
+
if (type === "text") {
|
|
160433
|
+
return typeof part.text === "string" && part.text.trim().length > 0;
|
|
160434
|
+
}
|
|
160435
|
+
if (typeof type !== "string")
|
|
160436
|
+
return false;
|
|
160437
|
+
if (IGNORE_PART_TYPES.has(type))
|
|
160438
|
+
return false;
|
|
160439
|
+
return true;
|
|
160440
|
+
}
|
|
160441
|
+
|
|
160442
|
+
class ToolMutationBatch {
|
|
160443
|
+
partsToRemove = new Set;
|
|
160444
|
+
affectedMessages = new Set;
|
|
160445
|
+
messages;
|
|
160446
|
+
constructor(messages) {
|
|
160447
|
+
this.messages = messages;
|
|
160448
|
+
}
|
|
160449
|
+
markForRemoval(occurrence) {
|
|
160450
|
+
this.partsToRemove.add(occurrence.part);
|
|
160451
|
+
this.affectedMessages.add(occurrence.message);
|
|
160452
|
+
}
|
|
160453
|
+
finalize() {
|
|
160454
|
+
if (this.partsToRemove.size === 0)
|
|
160455
|
+
return;
|
|
160456
|
+
for (const message of this.affectedMessages) {
|
|
160457
|
+
message.parts = message.parts.filter((p) => !this.partsToRemove.has(p));
|
|
160458
|
+
}
|
|
160459
|
+
for (let i = this.messages.length - 1;i >= 0; i -= 1) {
|
|
160460
|
+
if (!this.messages[i].parts.some(hasMeaningfulPart)) {
|
|
160461
|
+
this.messages.splice(i, 1);
|
|
160462
|
+
}
|
|
160463
|
+
}
|
|
160464
|
+
this.partsToRemove.clear();
|
|
160465
|
+
this.affectedMessages.clear();
|
|
160466
|
+
}
|
|
160467
|
+
}
|
|
160468
|
+
var IGNORE_PART_TYPES;
|
|
160469
|
+
var init_tool_drop_target = __esm(() => {
|
|
160470
|
+
IGNORE_PART_TYPES = new Set([
|
|
160471
|
+
"thinking",
|
|
160472
|
+
"reasoning",
|
|
160473
|
+
"redacted_thinking",
|
|
160474
|
+
"meta",
|
|
160475
|
+
"step-start",
|
|
160476
|
+
"step-finish"
|
|
160477
|
+
]);
|
|
160478
|
+
});
|
|
160479
|
+
|
|
160422
160480
|
// ../plugin/src/hooks/magic-context/read-session-chunk.ts
|
|
160423
160481
|
var sessionProviders;
|
|
160424
160482
|
var init_read_session_chunk = __esm(async () => {
|
|
160425
160483
|
init_read_session_formatting();
|
|
160426
160484
|
init_tag_part_guards();
|
|
160485
|
+
init_tool_drop_target();
|
|
160427
160486
|
init_read_session_formatting();
|
|
160428
160487
|
await init_read_session_db();
|
|
160429
160488
|
sessionProviders = new Map;
|
|
160430
160489
|
});
|
|
160431
160490
|
|
|
160432
160491
|
// ../plugin/src/features/magic-context/message-index.ts
|
|
160433
|
-
var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements;
|
|
160492
|
+
var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements, indexedMessageIdStatements;
|
|
160434
160493
|
var init_message_index = __esm(async () => {
|
|
160435
160494
|
init_compression_depth_storage();
|
|
160436
160495
|
await init_read_session_chunk();
|
|
@@ -160440,6 +160499,7 @@ var init_message_index = __esm(async () => {
|
|
|
160440
160499
|
deleteFtsStatements = new WeakMap;
|
|
160441
160500
|
deleteIndexStatements = new WeakMap;
|
|
160442
160501
|
countIndexedMessageStatements = new WeakMap;
|
|
160502
|
+
indexedMessageIdStatements = new WeakMap;
|
|
160443
160503
|
});
|
|
160444
160504
|
|
|
160445
160505
|
// ../plugin/src/shared/error-message.ts
|
|
@@ -160461,22 +160521,51 @@ function getCurrentVersion(db) {
|
|
|
160461
160521
|
const row = db.prepare("SELECT MAX(version) as version FROM schema_migrations").get();
|
|
160462
160522
|
return row?.version ?? 0;
|
|
160463
160523
|
}
|
|
160524
|
+
function isSiblingMigrationConflict(error48, version2) {
|
|
160525
|
+
if (!(error48 instanceof Error))
|
|
160526
|
+
return false;
|
|
160527
|
+
const code = error48.code;
|
|
160528
|
+
if (code !== "SQLITE_CONSTRAINT_PRIMARYKEY" && code !== "SQLITE_CONSTRAINT_UNIQUE") {
|
|
160529
|
+
return false;
|
|
160530
|
+
}
|
|
160531
|
+
const msg = error48.message;
|
|
160532
|
+
if (!msg.includes("schema_migrations"))
|
|
160533
|
+
return false;
|
|
160534
|
+
if (!msg.toLowerCase().includes("version"))
|
|
160535
|
+
return false;
|
|
160536
|
+
return true;
|
|
160537
|
+
}
|
|
160464
160538
|
function runMigrations(db) {
|
|
160465
160539
|
ensureMigrationsTable(db);
|
|
160466
|
-
|
|
160467
|
-
|
|
160540
|
+
let currentVersion = getCurrentVersion(db);
|
|
160541
|
+
let pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
|
|
160468
160542
|
if (pendingMigrations.length === 0) {
|
|
160469
160543
|
return;
|
|
160470
160544
|
}
|
|
160471
160545
|
log2(`[migrations] current schema version: ${currentVersion}, applying ${pendingMigrations.length} migration(s)`);
|
|
160472
|
-
|
|
160546
|
+
let migrationIndex = 0;
|
|
160547
|
+
while (migrationIndex < pendingMigrations.length) {
|
|
160548
|
+
const migration = pendingMigrations[migrationIndex];
|
|
160473
160549
|
try {
|
|
160474
160550
|
db.transaction(() => {
|
|
160475
160551
|
migration.up(db);
|
|
160476
160552
|
db.prepare("INSERT INTO schema_migrations (version, description, applied_at) VALUES (?, ?, ?)").run(migration.version, migration.description, Date.now());
|
|
160477
160553
|
})();
|
|
160478
160554
|
log2(`[migrations] applied v${migration.version}: ${migration.description}`);
|
|
160555
|
+
migrationIndex += 1;
|
|
160479
160556
|
} catch (error48) {
|
|
160557
|
+
if (isSiblingMigrationConflict(error48, migration.version)) {
|
|
160558
|
+
log2(`[migrations] v${migration.version} already applied by sibling instance — resuming with re-read version`);
|
|
160559
|
+
const reReadVersion = getCurrentVersion(db);
|
|
160560
|
+
if (reReadVersion <= currentVersion) {
|
|
160561
|
+
log2(`[migrations] FAILED v${migration.version}: sibling-conflict shape but version not advanced (${reReadVersion} <= ${currentVersion}) — failing closed`);
|
|
160562
|
+
throw new Error(`Migration v${migration.version} failed: sibling conflict reported but version did not advance. Database may need manual repair.`);
|
|
160563
|
+
}
|
|
160564
|
+
currentVersion = reReadVersion;
|
|
160565
|
+
pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
|
|
160566
|
+
migrationIndex = 0;
|
|
160567
|
+
continue;
|
|
160568
|
+
}
|
|
160480
160569
|
log2(`[migrations] FAILED v${migration.version}: ${migration.description} — ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
160481
160570
|
throw new Error(`Migration v${migration.version} failed: ${error48 instanceof Error ? error48.message : String(error48)}. Database may need manual repair.`);
|
|
160482
160571
|
}
|
|
@@ -160688,30 +160777,361 @@ var init_migrations = __esm(async () => {
|
|
|
160688
160777
|
db.exec("ALTER TABLE notes ADD COLUMN harness TEXT NOT NULL DEFAULT 'opencode'");
|
|
160689
160778
|
}
|
|
160690
160779
|
}
|
|
160780
|
+
},
|
|
160781
|
+
{
|
|
160782
|
+
version: 8,
|
|
160783
|
+
description: "Add partial indexes on tags(session_id, tag_number) for active and dropped",
|
|
160784
|
+
up: (db) => {
|
|
160785
|
+
db.exec(`
|
|
160786
|
+
CREATE INDEX IF NOT EXISTS idx_tags_active_session_tag_number
|
|
160787
|
+
ON tags(session_id, tag_number)
|
|
160788
|
+
WHERE status = 'active';
|
|
160789
|
+
|
|
160790
|
+
CREATE INDEX IF NOT EXISTS idx_tags_dropped_session_tag_number
|
|
160791
|
+
ON tags(session_id, tag_number)
|
|
160792
|
+
WHERE status = 'dropped';
|
|
160793
|
+
`);
|
|
160794
|
+
db.exec("ANALYZE tags;");
|
|
160795
|
+
}
|
|
160796
|
+
},
|
|
160797
|
+
{
|
|
160798
|
+
version: 9,
|
|
160799
|
+
description: "Persist tool_definition_measurements across plugin restarts",
|
|
160800
|
+
up: (db) => {
|
|
160801
|
+
db.exec(`
|
|
160802
|
+
CREATE TABLE IF NOT EXISTS tool_definition_measurements (
|
|
160803
|
+
provider_id TEXT NOT NULL,
|
|
160804
|
+
model_id TEXT NOT NULL,
|
|
160805
|
+
agent_name TEXT NOT NULL,
|
|
160806
|
+
tool_id TEXT NOT NULL,
|
|
160807
|
+
token_count INTEGER NOT NULL,
|
|
160808
|
+
recorded_at INTEGER NOT NULL,
|
|
160809
|
+
PRIMARY KEY (provider_id, model_id, agent_name, tool_id)
|
|
160810
|
+
);
|
|
160811
|
+
`);
|
|
160812
|
+
}
|
|
160813
|
+
},
|
|
160814
|
+
{
|
|
160815
|
+
version: 10,
|
|
160816
|
+
description: "Add tool_owner_message_id column to tags + composite identity indexes",
|
|
160817
|
+
up: (db) => {
|
|
160818
|
+
const cols = db.prepare("PRAGMA table_info(tags)").all();
|
|
160819
|
+
if (!cols.some((c) => c.name === "tool_owner_message_id")) {
|
|
160820
|
+
db.exec("ALTER TABLE tags ADD COLUMN tool_owner_message_id TEXT DEFAULT NULL");
|
|
160821
|
+
}
|
|
160822
|
+
db.exec(`
|
|
160823
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_tags_tool_composite
|
|
160824
|
+
ON tags(session_id, message_id, tool_owner_message_id)
|
|
160825
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NOT NULL;
|
|
160826
|
+
|
|
160827
|
+
CREATE INDEX IF NOT EXISTS idx_tags_tool_null_owner
|
|
160828
|
+
ON tags(session_id, message_id)
|
|
160829
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL;
|
|
160830
|
+
`);
|
|
160831
|
+
}
|
|
160691
160832
|
}
|
|
160692
160833
|
];
|
|
160693
160834
|
});
|
|
160694
160835
|
|
|
160695
|
-
// ../plugin/src/features/magic-context/
|
|
160696
|
-
|
|
160836
|
+
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
160837
|
+
function keyFor(providerID, modelID, agentName) {
|
|
160838
|
+
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
160839
|
+
return `${providerID}/${modelID}/${agent}`;
|
|
160840
|
+
}
|
|
160841
|
+
function setDatabase(db) {
|
|
160842
|
+
persistenceDb = db;
|
|
160843
|
+
}
|
|
160844
|
+
function loadToolDefinitionMeasurements(db) {
|
|
160845
|
+
let rows = [];
|
|
160846
|
+
try {
|
|
160847
|
+
rows = db.prepare("SELECT provider_id, model_id, agent_name, tool_id, token_count FROM tool_definition_measurements").all();
|
|
160848
|
+
} catch {
|
|
160849
|
+
return;
|
|
160850
|
+
}
|
|
160851
|
+
for (const row of rows) {
|
|
160852
|
+
const key = keyFor(row.provider_id, row.model_id, row.agent_name);
|
|
160853
|
+
let inner = measurements.get(key);
|
|
160854
|
+
if (!inner) {
|
|
160855
|
+
inner = new Map;
|
|
160856
|
+
measurements.set(key, inner);
|
|
160857
|
+
}
|
|
160858
|
+
inner.set(row.tool_id, row.token_count);
|
|
160859
|
+
}
|
|
160860
|
+
}
|
|
160861
|
+
var measurements, persistenceDb = null;
|
|
160862
|
+
var init_tool_definition_tokens = __esm(() => {
|
|
160863
|
+
init_read_session_formatting();
|
|
160864
|
+
measurements = new Map;
|
|
160865
|
+
});
|
|
160866
|
+
|
|
160867
|
+
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
160868
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
160697
160869
|
import { join as join15 } from "node:path";
|
|
160870
|
+
function resolveOpencodeDbPath() {
|
|
160871
|
+
return join15(getDataDir(), "opencode", "opencode.db");
|
|
160872
|
+
}
|
|
160873
|
+
function ensureBackfillStateTable(db) {
|
|
160874
|
+
db.exec(`
|
|
160875
|
+
CREATE TABLE IF NOT EXISTS tool_owner_backfill_state (
|
|
160876
|
+
session_id TEXT PRIMARY KEY,
|
|
160877
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'running', 'completed', 'skipped')),
|
|
160878
|
+
started_at INTEGER,
|
|
160879
|
+
lease_expires_at INTEGER,
|
|
160880
|
+
completed_at INTEGER,
|
|
160881
|
+
last_error TEXT
|
|
160882
|
+
);
|
|
160883
|
+
CREATE INDEX IF NOT EXISTS idx_tool_owner_backfill_state_status
|
|
160884
|
+
ON tool_owner_backfill_state(status);
|
|
160885
|
+
`);
|
|
160886
|
+
}
|
|
160887
|
+
function runToolOwnerBackfill(db) {
|
|
160888
|
+
const startedAt = performance.now();
|
|
160889
|
+
ensureBackfillStateTable(db);
|
|
160890
|
+
const result = {
|
|
160891
|
+
sessionsProcessed: 0,
|
|
160892
|
+
sessionsSkippedNoOcDb: 0,
|
|
160893
|
+
sessionsSkippedNoMatches: 0,
|
|
160894
|
+
sessionsCompleted: 0,
|
|
160895
|
+
sessionsBlockedByLease: 0,
|
|
160896
|
+
sessionsErrored: 0,
|
|
160897
|
+
rowsUpdated: 0,
|
|
160898
|
+
rowsLeftNull: 0,
|
|
160899
|
+
durationMs: 0
|
|
160900
|
+
};
|
|
160901
|
+
if (!isToolOwnerBackfillNeeded(db)) {
|
|
160902
|
+
result.durationMs = performance.now() - startedAt;
|
|
160903
|
+
return result;
|
|
160904
|
+
}
|
|
160905
|
+
const opencodeDbPath = resolveOpencodeDbPath();
|
|
160906
|
+
if (!existsSync16(opencodeDbPath)) {
|
|
160907
|
+
log2(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
|
|
160908
|
+
markAllUnbackfilledSessionsSkipped(db);
|
|
160909
|
+
result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
|
|
160910
|
+
result.durationMs = performance.now() - startedAt;
|
|
160911
|
+
return result;
|
|
160912
|
+
}
|
|
160913
|
+
db.exec(`ATTACH '${opencodeDbPath}' AS oc_backfill`);
|
|
160914
|
+
try {
|
|
160915
|
+
backfillToolOwnersInChunks(db, result);
|
|
160916
|
+
} finally {
|
|
160917
|
+
try {
|
|
160918
|
+
db.exec("DETACH DATABASE oc_backfill");
|
|
160919
|
+
} catch (error48) {
|
|
160920
|
+
log2(`[backfill] failed to detach oc_backfill database: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
160921
|
+
}
|
|
160922
|
+
}
|
|
160923
|
+
result.durationMs = performance.now() - startedAt;
|
|
160924
|
+
log2(`[backfill] sessions=${result.sessionsProcessed} completed=${result.sessionsCompleted} skipped_no_oc=${result.sessionsSkippedNoOcDb} skipped_no_matches=${result.sessionsSkippedNoMatches} blocked_by_lease=${result.sessionsBlockedByLease} errored=${result.sessionsErrored} rows_updated=${result.rowsUpdated} rows_left_null=${result.rowsLeftNull} duration_ms=${Math.round(result.durationMs)}`);
|
|
160925
|
+
return result;
|
|
160926
|
+
}
|
|
160927
|
+
function isToolOwnerBackfillNeeded(db) {
|
|
160928
|
+
ensureBackfillStateTable(db);
|
|
160929
|
+
const row = db.prepare(`SELECT 1 AS hit
|
|
160930
|
+
FROM tags
|
|
160931
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL
|
|
160932
|
+
AND NOT EXISTS (
|
|
160933
|
+
SELECT 1 FROM tool_owner_backfill_state s
|
|
160934
|
+
WHERE s.session_id = tags.session_id
|
|
160935
|
+
AND s.status IN ('completed', 'skipped')
|
|
160936
|
+
)
|
|
160937
|
+
LIMIT 1`).get();
|
|
160938
|
+
return row !== null && row !== undefined;
|
|
160939
|
+
}
|
|
160940
|
+
function markAllUnbackfilledSessionsSkipped(db) {
|
|
160941
|
+
const now = Date.now();
|
|
160942
|
+
db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, started_at, completed_at, last_error)
|
|
160943
|
+
SELECT DISTINCT session_id, 'skipped', NULL, ?, NULL
|
|
160944
|
+
FROM tags
|
|
160945
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL
|
|
160946
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
160947
|
+
status = 'skipped',
|
|
160948
|
+
completed_at = excluded.completed_at,
|
|
160949
|
+
last_error = NULL
|
|
160950
|
+
WHERE tool_owner_backfill_state.status NOT IN ('completed', 'running')`).run(now);
|
|
160951
|
+
}
|
|
160952
|
+
function countSessionsByStatus(db, status) {
|
|
160953
|
+
const row = db.prepare("SELECT COUNT(*) AS c FROM tool_owner_backfill_state WHERE status = ?").get(status);
|
|
160954
|
+
return row.c;
|
|
160955
|
+
}
|
|
160956
|
+
function acquireSessionLease(db, sessionId, now) {
|
|
160957
|
+
const expiresAt = now + LEASE_DURATION_MS;
|
|
160958
|
+
const result = db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, started_at, lease_expires_at)
|
|
160959
|
+
VALUES (?, 'running', ?, ?)
|
|
160960
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
160961
|
+
status = 'running',
|
|
160962
|
+
started_at = excluded.started_at,
|
|
160963
|
+
lease_expires_at = excluded.lease_expires_at,
|
|
160964
|
+
last_error = NULL
|
|
160965
|
+
WHERE tool_owner_backfill_state.status IN ('pending', 'skipped')
|
|
160966
|
+
OR (tool_owner_backfill_state.status = 'running'
|
|
160967
|
+
AND tool_owner_backfill_state.lease_expires_at < ?)`).run(sessionId, now, expiresAt, now);
|
|
160968
|
+
return (result.changes ?? 0) === 1;
|
|
160969
|
+
}
|
|
160970
|
+
function renewSessionLease(db, sessionId, now) {
|
|
160971
|
+
const expiresAt = now + LEASE_DURATION_MS;
|
|
160972
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
160973
|
+
SET lease_expires_at = ?
|
|
160974
|
+
WHERE session_id = ? AND status = 'running'`).run(expiresAt, sessionId);
|
|
160975
|
+
}
|
|
160976
|
+
function markSessionCompleted(db, sessionId, now) {
|
|
160977
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
160978
|
+
SET status = 'completed', completed_at = ?, lease_expires_at = NULL, last_error = NULL
|
|
160979
|
+
WHERE session_id = ?`).run(now, sessionId);
|
|
160980
|
+
}
|
|
160981
|
+
function markSessionSkipped(db, sessionId, now, reason) {
|
|
160982
|
+
db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, completed_at, last_error)
|
|
160983
|
+
VALUES (?, 'skipped', ?, ?)
|
|
160984
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
160985
|
+
status = 'skipped',
|
|
160986
|
+
completed_at = excluded.completed_at,
|
|
160987
|
+
last_error = excluded.last_error,
|
|
160988
|
+
lease_expires_at = NULL`).run(sessionId, now, reason);
|
|
160989
|
+
}
|
|
160990
|
+
function markSessionErrored(db, sessionId, error48) {
|
|
160991
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
160992
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
160993
|
+
SET last_error = ?, lease_expires_at = NULL
|
|
160994
|
+
WHERE session_id = ?`).run(message, sessionId);
|
|
160995
|
+
}
|
|
160996
|
+
function getSessionsNeedingBackfill(db) {
|
|
160997
|
+
const rows = db.prepare(`SELECT DISTINCT t.session_id
|
|
160998
|
+
FROM tags t
|
|
160999
|
+
LEFT JOIN tool_owner_backfill_state s ON s.session_id = t.session_id
|
|
161000
|
+
WHERE t.type = 'tool' AND t.tool_owner_message_id IS NULL
|
|
161001
|
+
AND (s.status IS NULL OR s.status NOT IN ('completed', 'skipped'))
|
|
161002
|
+
ORDER BY t.session_id ASC`).all();
|
|
161003
|
+
return rows.map((r) => r.session_id);
|
|
161004
|
+
}
|
|
161005
|
+
function buildSessionOwnerMap(db, sessionId) {
|
|
161006
|
+
const rows = db.prepare(`SELECT
|
|
161007
|
+
COALESCE(
|
|
161008
|
+
CASE WHEN json_extract(p.data, '$.type') = 'tool_use'
|
|
161009
|
+
THEN json_extract(p.data, '$.id')
|
|
161010
|
+
END,
|
|
161011
|
+
json_extract(p.data, '$.callID')
|
|
161012
|
+
) AS callid,
|
|
161013
|
+
m.id AS owner_id,
|
|
161014
|
+
m.time_created AS owner_t_created,
|
|
161015
|
+
p.id AS part_id,
|
|
161016
|
+
p.time_created AS part_t_created
|
|
161017
|
+
FROM oc_backfill.message m
|
|
161018
|
+
INNER JOIN oc_backfill.part p ON p.message_id = m.id
|
|
161019
|
+
WHERE m.session_id = ?
|
|
161020
|
+
AND json_extract(m.data, '$.role') = 'assistant'
|
|
161021
|
+
AND (
|
|
161022
|
+
(json_extract(p.data, '$.type') IN ('tool', 'tool-invocation')
|
|
161023
|
+
AND json_extract(p.data, '$.callID') IS NOT NULL)
|
|
161024
|
+
OR (json_extract(p.data, '$.type') = 'tool_use'
|
|
161025
|
+
AND json_extract(p.data, '$.id') IS NOT NULL)
|
|
161026
|
+
)
|
|
161027
|
+
ORDER BY
|
|
161028
|
+
m.time_created ASC,
|
|
161029
|
+
m.id ASC,
|
|
161030
|
+
p.time_created ASC,
|
|
161031
|
+
p.id ASC`).all(sessionId);
|
|
161032
|
+
const oldestByCallId = new Map;
|
|
161033
|
+
for (const r of rows) {
|
|
161034
|
+
if (typeof r.callid !== "string" || r.callid.length === 0)
|
|
161035
|
+
continue;
|
|
161036
|
+
if (!oldestByCallId.has(r.callid)) {
|
|
161037
|
+
oldestByCallId.set(r.callid, r.owner_id);
|
|
161038
|
+
}
|
|
161039
|
+
}
|
|
161040
|
+
return oldestByCallId;
|
|
161041
|
+
}
|
|
161042
|
+
function applyOwnersForSession(db, sessionId, ownersByCallId) {
|
|
161043
|
+
if (ownersByCallId.size === 0) {
|
|
161044
|
+
const leftNull = db.prepare(`SELECT COUNT(*) AS c FROM tags
|
|
161045
|
+
WHERE session_id = ? AND type = 'tool'
|
|
161046
|
+
AND tool_owner_message_id IS NULL`).get(sessionId).c;
|
|
161047
|
+
return { rowsUpdated: 0, rowsLeftNull: leftNull };
|
|
161048
|
+
}
|
|
161049
|
+
const findOrphanStmt = db.prepare(`SELECT id FROM tags
|
|
161050
|
+
WHERE session_id = ? AND message_id = ? AND type = 'tool'
|
|
161051
|
+
AND tool_owner_message_id IS NULL
|
|
161052
|
+
ORDER BY tag_number ASC
|
|
161053
|
+
LIMIT 1`);
|
|
161054
|
+
const updateRowStmt = db.prepare(`UPDATE tags
|
|
161055
|
+
SET tool_owner_message_id = ?
|
|
161056
|
+
WHERE id = ? AND tool_owner_message_id IS NULL`);
|
|
161057
|
+
let rowsUpdated = 0;
|
|
161058
|
+
db.transaction(() => {
|
|
161059
|
+
for (const [callId, ownerId] of ownersByCallId) {
|
|
161060
|
+
const orphan = findOrphanStmt.get(sessionId, callId);
|
|
161061
|
+
if (!orphan)
|
|
161062
|
+
continue;
|
|
161063
|
+
const result = updateRowStmt.run(ownerId, orphan.id);
|
|
161064
|
+
rowsUpdated += result.changes ?? 0;
|
|
161065
|
+
}
|
|
161066
|
+
})();
|
|
161067
|
+
const rowsLeftNull = db.prepare(`SELECT COUNT(*) AS c FROM tags
|
|
161068
|
+
WHERE session_id = ? AND type = 'tool'
|
|
161069
|
+
AND tool_owner_message_id IS NULL`).get(sessionId).c;
|
|
161070
|
+
return { rowsUpdated, rowsLeftNull };
|
|
161071
|
+
}
|
|
161072
|
+
function backfillToolOwnersInChunks(db, result) {
|
|
161073
|
+
const sessionIds = getSessionsNeedingBackfill(db);
|
|
161074
|
+
let lastRenewedAt = Date.now();
|
|
161075
|
+
for (const sessionId of sessionIds) {
|
|
161076
|
+
const now = Date.now();
|
|
161077
|
+
result.sessionsProcessed += 1;
|
|
161078
|
+
const acquired = acquireSessionLease(db, sessionId, now);
|
|
161079
|
+
if (!acquired) {
|
|
161080
|
+
result.sessionsBlockedByLease += 1;
|
|
161081
|
+
continue;
|
|
161082
|
+
}
|
|
161083
|
+
try {
|
|
161084
|
+
const owners = buildSessionOwnerMap(db, sessionId);
|
|
161085
|
+
const { rowsUpdated, rowsLeftNull } = applyOwnersForSession(db, sessionId, owners);
|
|
161086
|
+
result.rowsUpdated += rowsUpdated;
|
|
161087
|
+
result.rowsLeftNull += rowsLeftNull;
|
|
161088
|
+
if (owners.size === 0) {
|
|
161089
|
+
markSessionSkipped(db, sessionId, Date.now(), "no_oc_matches");
|
|
161090
|
+
result.sessionsSkippedNoMatches += 1;
|
|
161091
|
+
} else {
|
|
161092
|
+
markSessionCompleted(db, sessionId, Date.now());
|
|
161093
|
+
result.sessionsCompleted += 1;
|
|
161094
|
+
}
|
|
161095
|
+
} catch (error48) {
|
|
161096
|
+
log2(`[backfill] session=${sessionId} errored: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
161097
|
+
markSessionErrored(db, sessionId, error48);
|
|
161098
|
+
result.sessionsErrored += 1;
|
|
161099
|
+
}
|
|
161100
|
+
const sinceRenew = Date.now() - lastRenewedAt;
|
|
161101
|
+
if (sinceRenew > LEASE_RENEWAL_MS) {
|
|
161102
|
+
renewSessionLease(db, sessionId, Date.now());
|
|
161103
|
+
lastRenewedAt = Date.now();
|
|
161104
|
+
}
|
|
161105
|
+
}
|
|
161106
|
+
}
|
|
161107
|
+
var LEASE_DURATION_MS, LEASE_RENEWAL_MS;
|
|
161108
|
+
var init_tool_owner_backfill = __esm(() => {
|
|
161109
|
+
init_data_path();
|
|
161110
|
+
init_logger();
|
|
161111
|
+
LEASE_DURATION_MS = 5 * 60 * 1000;
|
|
161112
|
+
LEASE_RENEWAL_MS = 60 * 1000;
|
|
161113
|
+
});
|
|
161114
|
+
|
|
161115
|
+
// ../plugin/src/features/magic-context/storage-db.ts
|
|
161116
|
+
import { copyFileSync, cpSync, existsSync as existsSync17, mkdirSync as mkdirSync7 } from "node:fs";
|
|
161117
|
+
import { join as join16 } from "node:path";
|
|
160698
161118
|
function resolveDatabasePath() {
|
|
160699
161119
|
const dbDir = getMagicContextStorageDir();
|
|
160700
|
-
return { dbDir, dbPath:
|
|
161120
|
+
return { dbDir, dbPath: join16(dbDir, "context.db") };
|
|
160701
161121
|
}
|
|
160702
161122
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
160703
|
-
if (
|
|
161123
|
+
if (existsSync17(targetDbPath))
|
|
160704
161124
|
return;
|
|
160705
161125
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
160706
|
-
const legacyDbPath =
|
|
160707
|
-
if (!
|
|
161126
|
+
const legacyDbPath = join16(legacyDir, "context.db");
|
|
161127
|
+
if (!existsSync17(legacyDbPath))
|
|
160708
161128
|
return;
|
|
160709
161129
|
log2(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
160710
161130
|
mkdirSync7(targetDbDir, { recursive: true });
|
|
160711
161131
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
160712
161132
|
const src = `${legacyDbPath}${suffix}`;
|
|
160713
|
-
const dst =
|
|
160714
|
-
if (
|
|
161133
|
+
const dst = join16(targetDbDir, `context.db${suffix}`);
|
|
161134
|
+
if (existsSync17(src)) {
|
|
160715
161135
|
try {
|
|
160716
161136
|
copyFileSync(src, dst);
|
|
160717
161137
|
} catch (error48) {
|
|
@@ -160719,9 +161139,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
160719
161139
|
}
|
|
160720
161140
|
}
|
|
160721
161141
|
}
|
|
160722
|
-
const legacyModelsDir =
|
|
160723
|
-
const targetModelsDir =
|
|
160724
|
-
if (
|
|
161142
|
+
const legacyModelsDir = join16(legacyDir, "models");
|
|
161143
|
+
const targetModelsDir = join16(targetDbDir, "models");
|
|
161144
|
+
if (existsSync17(legacyModelsDir) && !existsSync17(targetModelsDir)) {
|
|
160725
161145
|
try {
|
|
160726
161146
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
160727
161147
|
} catch (error48) {
|
|
@@ -161007,6 +161427,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
161007
161427
|
ensureColumn(db, "tags", "tool_name", "TEXT");
|
|
161008
161428
|
ensureColumn(db, "tags", "input_byte_size", "INTEGER DEFAULT 0");
|
|
161009
161429
|
ensureColumn(db, "tags", "caveman_depth", "INTEGER DEFAULT 0");
|
|
161430
|
+
ensureColumn(db, "tags", "tool_owner_message_id", "TEXT DEFAULT NULL");
|
|
161010
161431
|
ensureColumn(db, "session_meta", "system_prompt_tokens", "INTEGER DEFAULT 0");
|
|
161011
161432
|
ensureColumn(db, "session_meta", "compaction_marker_state", "TEXT DEFAULT ''");
|
|
161012
161433
|
ensureColumn(db, "session_meta", "key_files", "TEXT DEFAULT ''");
|
|
@@ -161105,6 +161526,13 @@ function openDatabase() {
|
|
|
161105
161526
|
const db = new Database(dbPath);
|
|
161106
161527
|
initializeDatabase(db);
|
|
161107
161528
|
runMigrations(db);
|
|
161529
|
+
try {
|
|
161530
|
+
runToolOwnerBackfill(db);
|
|
161531
|
+
} catch (error48) {
|
|
161532
|
+
log2(`[magic-context] tool-owner backfill failed (continuing with lazy adoption fallback): ${getErrorMessage(error48)}`);
|
|
161533
|
+
}
|
|
161534
|
+
setDatabase(db);
|
|
161535
|
+
loadToolDefinitionMeasurements(db);
|
|
161108
161536
|
databases.set(dbPath, db);
|
|
161109
161537
|
persistenceByDatabase.set(db, true);
|
|
161110
161538
|
persistenceErrorByDatabase.delete(db);
|
|
@@ -161133,6 +161561,8 @@ var databases, persistenceByDatabase, persistenceErrorByDatabase;
|
|
|
161133
161561
|
var init_storage_db = __esm(async () => {
|
|
161134
161562
|
init_data_path();
|
|
161135
161563
|
init_logger();
|
|
161564
|
+
init_tool_definition_tokens();
|
|
161565
|
+
init_tool_owner_backfill();
|
|
161136
161566
|
await __promiseAll([
|
|
161137
161567
|
init_sqlite(),
|
|
161138
161568
|
init_migrations()
|
|
@@ -161197,7 +161627,7 @@ var init_storage_ops = __esm(() => {
|
|
|
161197
161627
|
var init_storage_source = () => {};
|
|
161198
161628
|
|
|
161199
161629
|
// ../plugin/src/features/magic-context/storage-tags.ts
|
|
161200
|
-
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements;
|
|
161630
|
+
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, getOwnerScopedToolTagNumbersStatements, getActiveTagsBySessionStatements, getMaxDroppedTagNumberStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, deleteToolTagsByOwnerStatements;
|
|
161201
161631
|
var init_storage_tags = __esm(() => {
|
|
161202
161632
|
insertTagStatements = new WeakMap;
|
|
161203
161633
|
updateTagStatusStatements = new WeakMap;
|
|
@@ -161209,6 +161639,13 @@ var init_storage_tags = __esm(() => {
|
|
|
161209
161639
|
getTagNumberByMessageIdStatements = new WeakMap;
|
|
161210
161640
|
updateTagByteSizeStatements = new WeakMap;
|
|
161211
161641
|
updateTagInputByteSizeStatements = new WeakMap;
|
|
161642
|
+
getOwnerScopedToolTagNumbersStatements = new WeakMap;
|
|
161643
|
+
getActiveTagsBySessionStatements = new WeakMap;
|
|
161644
|
+
getMaxDroppedTagNumberStatements = new WeakMap;
|
|
161645
|
+
getToolTagNumberByOwnerStatements = new WeakMap;
|
|
161646
|
+
getNullOwnerToolTagStatements = new WeakMap;
|
|
161647
|
+
adoptNullOwnerToolTagStatements = new WeakMap;
|
|
161648
|
+
deleteToolTagsByOwnerStatements = new WeakMap;
|
|
161212
161649
|
});
|
|
161213
161650
|
|
|
161214
161651
|
// ../plugin/src/features/magic-context/storage.ts
|
|
@@ -161227,20 +161664,20 @@ var init_storage = __esm(async () => {
|
|
|
161227
161664
|
});
|
|
161228
161665
|
|
|
161229
161666
|
// ../pi-plugin/src/config/index.ts
|
|
161230
|
-
import { existsSync as
|
|
161667
|
+
import { existsSync as existsSync18, readFileSync as readFileSync12 } from "node:fs";
|
|
161231
161668
|
import { homedir as homedir11 } from "node:os";
|
|
161232
|
-
import { join as
|
|
161669
|
+
import { join as join17 } from "node:path";
|
|
161233
161670
|
function getProjectConfigPaths(cwd) {
|
|
161234
|
-
const basePath =
|
|
161671
|
+
const basePath = join17(cwd, ".pi", CONFIG_FILE_NAME);
|
|
161235
161672
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
161236
161673
|
}
|
|
161237
161674
|
function getUserConfigPaths() {
|
|
161238
161675
|
const home = process.env.HOME ?? homedir11();
|
|
161239
|
-
const basePath =
|
|
161676
|
+
const basePath = join17(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
161240
161677
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
161241
161678
|
}
|
|
161242
161679
|
function resolveFirstExisting(paths) {
|
|
161243
|
-
return paths.find((path4) =>
|
|
161680
|
+
return paths.find((path4) => existsSync18(path4));
|
|
161244
161681
|
}
|
|
161245
161682
|
function loadConfigFile2(path4, scope) {
|
|
161246
161683
|
try {
|
|
@@ -161374,10 +161811,10 @@ var init_config2 = __esm(() => {
|
|
|
161374
161811
|
|
|
161375
161812
|
// src/lib/diagnostics-pi.ts
|
|
161376
161813
|
import { createHash } from "node:crypto";
|
|
161377
|
-
import { existsSync as
|
|
161814
|
+
import { existsSync as existsSync19, readFileSync as readFileSync13, statSync as statSync4 } from "node:fs";
|
|
161378
161815
|
import { createRequire as createRequire5 } from "node:module";
|
|
161379
161816
|
import { homedir as homedir12, tmpdir as tmpdir5, userInfo as userInfo3 } from "node:os";
|
|
161380
|
-
import { join as
|
|
161817
|
+
import { join as join18 } from "node:path";
|
|
161381
161818
|
function getSelfVersion3() {
|
|
161382
161819
|
const req = createRequire5(import.meta.url);
|
|
161383
161820
|
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
@@ -161392,7 +161829,7 @@ function getSelfVersion3() {
|
|
|
161392
161829
|
}
|
|
161393
161830
|
function fileSize2(path4) {
|
|
161394
161831
|
try {
|
|
161395
|
-
return
|
|
161832
|
+
return existsSync19(path4) ? statSync4(path4).size : 0;
|
|
161396
161833
|
} catch {
|
|
161397
161834
|
return 0;
|
|
161398
161835
|
}
|
|
@@ -161442,7 +161879,7 @@ function sanitizeValue2(value, key = "") {
|
|
|
161442
161879
|
return value;
|
|
161443
161880
|
}
|
|
161444
161881
|
function readJsonc3(path4) {
|
|
161445
|
-
if (!
|
|
161882
|
+
if (!existsSync19(path4))
|
|
161446
161883
|
return { value: {} };
|
|
161447
161884
|
try {
|
|
161448
161885
|
return {
|
|
@@ -161456,13 +161893,13 @@ function readJsonc3(path4) {
|
|
|
161456
161893
|
}
|
|
161457
161894
|
}
|
|
161458
161895
|
function getProjectConfigPath(cwd) {
|
|
161459
|
-
return
|
|
161896
|
+
return join18(cwd, ".pi", "magic-context.jsonc");
|
|
161460
161897
|
}
|
|
161461
161898
|
function readConfigDiagnostic(path4) {
|
|
161462
161899
|
const parsed = readJsonc3(path4);
|
|
161463
161900
|
return {
|
|
161464
161901
|
path: path4,
|
|
161465
|
-
exists:
|
|
161902
|
+
exists: existsSync19(path4),
|
|
161466
161903
|
...parsed.parseError ? { parseError: parsed.parseError } : {},
|
|
161467
161904
|
flags: sanitizeValue2(parsed.value)
|
|
161468
161905
|
};
|
|
@@ -161482,9 +161919,9 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
161482
161919
|
const projectConfigPath = getProjectConfigPath(cwd);
|
|
161483
161920
|
const loaded = loadPiConfig({ cwd });
|
|
161484
161921
|
const storageDirPath = getMagicContextStorageDir();
|
|
161485
|
-
const dbPath =
|
|
161486
|
-
const logPath =
|
|
161487
|
-
const logFileSize =
|
|
161922
|
+
const dbPath = join18(storageDirPath, "context.db");
|
|
161923
|
+
const logPath = join18(tmpdir5(), "magic-context.log");
|
|
161924
|
+
const logFileSize = existsSync19(logPath) ? statSync4(logPath).size : 0;
|
|
161488
161925
|
const otherPiExtensions = packages.filter((entry) => !hasMagicContextPackage([entry]));
|
|
161489
161926
|
return {
|
|
161490
161927
|
timestamp: new Date().toISOString(),
|
|
@@ -161497,7 +161934,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
161497
161934
|
piVersion: pi ? getPiVersion(pi.path) : null,
|
|
161498
161935
|
settings: {
|
|
161499
161936
|
path: settingsPath,
|
|
161500
|
-
exists:
|
|
161937
|
+
exists: existsSync19(settingsPath),
|
|
161501
161938
|
...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
|
|
161502
161939
|
hasMagicContextPackage: hasMagicContextPackage(packages),
|
|
161503
161940
|
packages: packages.map(sanitizeString2)
|
|
@@ -161513,7 +161950,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
161513
161950
|
loadWarnings: loaded.warnings.map(sanitizeString2),
|
|
161514
161951
|
storageDir: {
|
|
161515
161952
|
path: storageDirPath,
|
|
161516
|
-
exists:
|
|
161953
|
+
exists: existsSync19(storageDirPath),
|
|
161517
161954
|
contextDbSizeBytes: fileSize2(dbPath)
|
|
161518
161955
|
},
|
|
161519
161956
|
conflicts: {
|
|
@@ -161522,7 +161959,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
161522
161959
|
},
|
|
161523
161960
|
logFile: {
|
|
161524
161961
|
path: logPath,
|
|
161525
|
-
exists:
|
|
161962
|
+
exists: existsSync19(logPath),
|
|
161526
161963
|
sizeKb: Math.round(logFileSize / 1024)
|
|
161527
161964
|
}
|
|
161528
161965
|
};
|
|
@@ -161612,7 +162049,7 @@ var init_diagnostics_pi = __esm(() => {
|
|
|
161612
162049
|
|
|
161613
162050
|
// src/lib/logs-pi.ts
|
|
161614
162051
|
import { readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "node:fs";
|
|
161615
|
-
import { join as
|
|
162052
|
+
import { join as join19 } from "node:path";
|
|
161616
162053
|
function sanitizeLogContent2(content) {
|
|
161617
162054
|
return sanitizeString2(content);
|
|
161618
162055
|
}
|
|
@@ -161656,7 +162093,7 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
161656
162093
|
].join(`
|
|
161657
162094
|
`);
|
|
161658
162095
|
const cwd = options.cwd ?? process.cwd();
|
|
161659
|
-
const path4 =
|
|
162096
|
+
const path4 = join19(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
|
|
161660
162097
|
writeFileSync11(path4, `${bodyMarkdown}
|
|
161661
162098
|
`);
|
|
161662
162099
|
return { path: path4, bodyMarkdown };
|
|
@@ -161668,7 +162105,7 @@ var init_logs_pi = __esm(() => {
|
|
|
161668
162105
|
// src/commands/doctor-pi.ts
|
|
161669
162106
|
import { execFileSync as execFileSync3, spawnSync as spawnSync3 } from "node:child_process";
|
|
161670
162107
|
import {
|
|
161671
|
-
existsSync as
|
|
162108
|
+
existsSync as existsSync20,
|
|
161672
162109
|
mkdirSync as mkdirSync8,
|
|
161673
162110
|
readdirSync as readdirSync4,
|
|
161674
162111
|
readFileSync as readFileSync15,
|
|
@@ -161678,7 +162115,7 @@ import {
|
|
|
161678
162115
|
} from "node:fs";
|
|
161679
162116
|
import { createRequire as createRequire6 } from "node:module";
|
|
161680
162117
|
import { homedir as homedir13, tmpdir as tmpdir6 } from "node:os";
|
|
161681
|
-
import { dirname as dirname9, join as
|
|
162118
|
+
import { dirname as dirname9, join as join20 } from "node:path";
|
|
161682
162119
|
function depsFrom(options) {
|
|
161683
162120
|
return {
|
|
161684
162121
|
...DEFAULT_DEPS,
|
|
@@ -161781,10 +162218,10 @@ function hasPiPackage(packages) {
|
|
|
161781
162218
|
return packages.some((entry) => entry === PI_PACKAGE_SOURCE || entry === PACKAGE_NAME2 || entry.includes("pi-magic-context"));
|
|
161782
162219
|
}
|
|
161783
162220
|
function projectConfigPath(cwd) {
|
|
161784
|
-
return
|
|
162221
|
+
return join20(cwd, ".pi", "magic-context.jsonc");
|
|
161785
162222
|
}
|
|
161786
162223
|
function readConfigForEmbedding(path4) {
|
|
161787
|
-
if (!
|
|
162224
|
+
if (!existsSync20(path4))
|
|
161788
162225
|
return null;
|
|
161789
162226
|
try {
|
|
161790
162227
|
const rawText = readFileSync15(path4, "utf-8");
|
|
@@ -161846,19 +162283,19 @@ function countTable(db, table) {
|
|
|
161846
162283
|
}
|
|
161847
162284
|
function cacheRoots() {
|
|
161848
162285
|
const home = homedir13();
|
|
161849
|
-
const cacheHome = process.env.XDG_CACHE_HOME ||
|
|
162286
|
+
const cacheHome = process.env.XDG_CACHE_HOME || join20(home, ".cache");
|
|
161850
162287
|
return [
|
|
161851
|
-
|
|
161852
|
-
|
|
161853
|
-
|
|
161854
|
-
|
|
161855
|
-
|
|
162288
|
+
join20(home, ".pi", "cache", "extensions"),
|
|
162289
|
+
join20(home, ".pi", "cache", "packages"),
|
|
162290
|
+
join20(cacheHome, "pi", "extensions"),
|
|
162291
|
+
join20(cacheHome, "pi", "packages"),
|
|
162292
|
+
join20(getPiAgentConfigDir(), "cache", "extensions")
|
|
161856
162293
|
];
|
|
161857
162294
|
}
|
|
161858
162295
|
function findPiMagicContextCacheDirs(self, force = false) {
|
|
161859
162296
|
const found = new Map;
|
|
161860
162297
|
const visit = (path4, depth) => {
|
|
161861
|
-
if (depth < 0 || !
|
|
162298
|
+
if (depth < 0 || !existsSync20(path4))
|
|
161862
162299
|
return;
|
|
161863
162300
|
let stat;
|
|
161864
162301
|
try {
|
|
@@ -161868,8 +162305,8 @@ function findPiMagicContextCacheDirs(self, force = false) {
|
|
|
161868
162305
|
}
|
|
161869
162306
|
if (!stat.isDirectory())
|
|
161870
162307
|
return;
|
|
161871
|
-
const packageJson =
|
|
161872
|
-
if (
|
|
162308
|
+
const packageJson = join20(path4, "package.json");
|
|
162309
|
+
if (existsSync20(packageJson)) {
|
|
161873
162310
|
try {
|
|
161874
162311
|
const pkg = JSON.parse(readFileSync15(packageJson, "utf-8"));
|
|
161875
162312
|
const name2 = typeof pkg.name === "string" ? pkg.name : "";
|
|
@@ -161890,7 +162327,7 @@ function findPiMagicContextCacheDirs(self, force = false) {
|
|
|
161890
162327
|
return;
|
|
161891
162328
|
}
|
|
161892
162329
|
for (const entry of entries)
|
|
161893
|
-
visit(
|
|
162330
|
+
visit(join20(path4, entry), depth - 1);
|
|
161894
162331
|
};
|
|
161895
162332
|
for (const root of cacheRoots())
|
|
161896
162333
|
visit(root, 5);
|
|
@@ -161927,7 +162364,7 @@ async function runHealthChecks(options) {
|
|
|
161927
162364
|
}
|
|
161928
162365
|
const settingsPath = getPiUserExtensionsPath();
|
|
161929
162366
|
let packages = [];
|
|
161930
|
-
if (!
|
|
162367
|
+
if (!existsSync20(settingsPath)) {
|
|
161931
162368
|
add(results, "warn", `Pi settings not found at ${settingsPath}`);
|
|
161932
162369
|
repairPlan.addPackageEntry = true;
|
|
161933
162370
|
} else {
|
|
@@ -161951,7 +162388,7 @@ async function runHealthChecks(options) {
|
|
|
161951
162388
|
["user", userConfigPath, true],
|
|
161952
162389
|
["project", projectPath, false]
|
|
161953
162390
|
]) {
|
|
161954
|
-
if (!
|
|
162391
|
+
if (!existsSync20(path4)) {
|
|
161955
162392
|
if (required2) {
|
|
161956
162393
|
add(results, "warn", `No ${label} magic-context.jsonc found at ${path4}`);
|
|
161957
162394
|
repairPlan.writeUserConfig = true;
|
|
@@ -161984,8 +162421,8 @@ async function runHealthChecks(options) {
|
|
|
161984
162421
|
add(results, "pass", `historian.model "${historianModel}" has thinking_level "${historianThinkingLevel}" configured`);
|
|
161985
162422
|
}
|
|
161986
162423
|
const storageDir = getMagicContextStorageDir();
|
|
161987
|
-
const dbPath =
|
|
161988
|
-
const existedBeforeOpen =
|
|
162424
|
+
const dbPath = join20(storageDir, "context.db");
|
|
162425
|
+
const existedBeforeOpen = existsSync20(dbPath);
|
|
161989
162426
|
if (existedBeforeOpen)
|
|
161990
162427
|
add(results, "pass", `Shared context DB exists at ${dbPath}`);
|
|
161991
162428
|
else
|
|
@@ -162061,8 +162498,8 @@ async function runHealthChecks(options) {
|
|
|
162061
162498
|
} else {
|
|
162062
162499
|
add(results, "pass", "Pi extension cache clean (no stale cached package found)");
|
|
162063
162500
|
}
|
|
162064
|
-
const logPath =
|
|
162065
|
-
if (
|
|
162501
|
+
const logPath = join20(tmpdir6(), "magic-context.log");
|
|
162502
|
+
if (existsSync20(logPath)) {
|
|
162066
162503
|
const stat = statSync5(logPath);
|
|
162067
162504
|
const sizeKb = (stat.size / 1024).toFixed(0);
|
|
162068
162505
|
const lines = readFileSync15(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
@@ -162071,10 +162508,10 @@ async function runHealthChecks(options) {
|
|
|
162071
162508
|
} else {
|
|
162072
162509
|
add(results, "info", `No plugin log file yet at ${logPath}`);
|
|
162073
162510
|
}
|
|
162074
|
-
const historianDumpDir =
|
|
162075
|
-
if (
|
|
162511
|
+
const historianDumpDir = join20(tmpdir6(), "magic-context-historian");
|
|
162512
|
+
if (existsSync20(historianDumpDir)) {
|
|
162076
162513
|
try {
|
|
162077
|
-
const dumps = readdirSync4(historianDumpDir).filter((f) => f.endsWith(".xml")).map((f) => ({ name: f, mtime: statSync5(
|
|
162514
|
+
const dumps = readdirSync4(historianDumpDir).filter((f) => f.endsWith(".xml")).map((f) => ({ name: f, mtime: statSync5(join20(historianDumpDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
162078
162515
|
if (dumps.length > 0) {
|
|
162079
162516
|
add(results, "warn", `Historian debug dumps: ${dumps.length} file(s) in ${historianDumpDir}`);
|
|
162080
162517
|
for (const dump of dumps.slice(0, 3)) {
|
|
@@ -162117,7 +162554,7 @@ function repair(plan, prompts) {
|
|
|
162117
162554
|
}
|
|
162118
162555
|
if (plan.writeUserConfig) {
|
|
162119
162556
|
const configPath = getPiUserConfigPath();
|
|
162120
|
-
if (!
|
|
162557
|
+
if (!existsSync20(configPath)) {
|
|
162121
162558
|
try {
|
|
162122
162559
|
writeDefaultMagicContextConfig(configPath);
|
|
162123
162560
|
prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
|
|
@@ -162278,7 +162715,7 @@ var exports_doctor = {};
|
|
|
162278
162715
|
__export(exports_doctor, {
|
|
162279
162716
|
runDoctor: () => runDoctor3
|
|
162280
162717
|
});
|
|
162281
|
-
import { existsSync as
|
|
162718
|
+
import { existsSync as existsSync21, rmSync as rmSync3 } from "node:fs";
|
|
162282
162719
|
async function runDoctor3(options) {
|
|
162283
162720
|
if (options.clear)
|
|
162284
162721
|
return runClear();
|
|
@@ -162362,7 +162799,7 @@ async function runClear() {
|
|
|
162362
162799
|
const s = spinner();
|
|
162363
162800
|
s.start(`Clearing ${item.path}`);
|
|
162364
162801
|
try {
|
|
162365
|
-
if (
|
|
162802
|
+
if (existsSync21(item.path)) {
|
|
162366
162803
|
rmSync3(item.path, { recursive: true, force: true });
|
|
162367
162804
|
}
|
|
162368
162805
|
s.stop(`Cleared ${item.path}`);
|