@cortexkit/pi-magic-context 0.22.1 → 0.22.2
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 +491 -370
- package/dist/subagent-entry.js +331 -91
- package/package.json +1 -1
package/dist/subagent-entry.js
CHANGED
|
@@ -86,9 +86,6 @@ function getMagicContextStorageDir() {
|
|
|
86
86
|
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
87
87
|
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
88
88
|
}
|
|
89
|
-
function getCacheDir() {
|
|
90
|
-
return process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), ".cache");
|
|
91
|
-
}
|
|
92
89
|
var init_data_path = () => {};
|
|
93
90
|
|
|
94
91
|
// ../plugin/src/shared/logger.ts
|
|
@@ -8919,6 +8916,38 @@ var MIGRATIONS = [
|
|
|
8919
8916
|
ON tags(session_id, entry_fingerprint)
|
|
8920
8917
|
WHERE type='message' AND entry_fingerprint IS NOT NULL`);
|
|
8921
8918
|
}
|
|
8919
|
+
},
|
|
8920
|
+
{
|
|
8921
|
+
version: 28,
|
|
8922
|
+
description: "Add git commit sweep coordinator lease/cooldown table",
|
|
8923
|
+
up: (db) => {
|
|
8924
|
+
db.exec(`
|
|
8925
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
8926
|
+
project_path TEXT PRIMARY KEY,
|
|
8927
|
+
lease_holder TEXT,
|
|
8928
|
+
lease_expires_at INTEGER,
|
|
8929
|
+
last_swept_at INTEGER
|
|
8930
|
+
);
|
|
8931
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
8932
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
8933
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
8934
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
8935
|
+
`);
|
|
8936
|
+
}
|
|
8937
|
+
},
|
|
8938
|
+
{
|
|
8939
|
+
version: 29,
|
|
8940
|
+
description: "Add anchor_ordinal to notes (traceback to the conversation tail)",
|
|
8941
|
+
up: (db) => {
|
|
8942
|
+
const notesExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'").get();
|
|
8943
|
+
if (!notesExists) {
|
|
8944
|
+
return;
|
|
8945
|
+
}
|
|
8946
|
+
const columns = db.prepare("PRAGMA table_info(notes)").all();
|
|
8947
|
+
if (!columns.some((column) => column.name === "anchor_ordinal")) {
|
|
8948
|
+
db.exec("ALTER TABLE notes ADD COLUMN anchor_ordinal INTEGER");
|
|
8949
|
+
}
|
|
8950
|
+
}
|
|
8922
8951
|
}
|
|
8923
8952
|
];
|
|
8924
8953
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -141883,7 +141912,7 @@ var databases = new Map;
|
|
|
141883
141912
|
var persistenceByDatabase = new WeakMap;
|
|
141884
141913
|
var persistenceErrorByDatabase = new WeakMap;
|
|
141885
141914
|
var lastSchemaFenceRejection = null;
|
|
141886
|
-
var LATEST_SUPPORTED_VERSION =
|
|
141915
|
+
var LATEST_SUPPORTED_VERSION = 29;
|
|
141887
141916
|
function resolveDatabasePath(dbPathOverride) {
|
|
141888
141917
|
if (dbPathOverride) {
|
|
141889
141918
|
return { dbDir: dirname2(dbPathOverride), dbPath: dbPathOverride };
|
|
@@ -142203,6 +142232,17 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142203
142232
|
updated_at INTEGER NOT NULL DEFAULT 0
|
|
142204
142233
|
);
|
|
142205
142234
|
|
|
142235
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
142236
|
+
project_path TEXT PRIMARY KEY,
|
|
142237
|
+
lease_holder TEXT,
|
|
142238
|
+
lease_expires_at INTEGER,
|
|
142239
|
+
last_swept_at INTEGER
|
|
142240
|
+
);
|
|
142241
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
142242
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
142243
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
142244
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
142245
|
+
|
|
142206
142246
|
CREATE TABLE IF NOT EXISTS m0_mutation_log (
|
|
142207
142247
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
142208
142248
|
session_id TEXT NOT NULL,
|
|
@@ -157402,46 +157442,6 @@ function stripJsonComments(content) {
|
|
|
157402
157442
|
}
|
|
157403
157443
|
return result;
|
|
157404
157444
|
}
|
|
157405
|
-
function stripTrailingCommas(content) {
|
|
157406
|
-
let result = "";
|
|
157407
|
-
let inString = false;
|
|
157408
|
-
let escaped = false;
|
|
157409
|
-
for (let index = 0;index < content.length; index += 1) {
|
|
157410
|
-
const char = content[index];
|
|
157411
|
-
if (inString) {
|
|
157412
|
-
result += char;
|
|
157413
|
-
if (escaped) {
|
|
157414
|
-
escaped = false;
|
|
157415
|
-
} else if (char === "\\") {
|
|
157416
|
-
escaped = true;
|
|
157417
|
-
} else if (char === '"') {
|
|
157418
|
-
inString = false;
|
|
157419
|
-
}
|
|
157420
|
-
continue;
|
|
157421
|
-
}
|
|
157422
|
-
if (char === '"') {
|
|
157423
|
-
inString = true;
|
|
157424
|
-
result += char;
|
|
157425
|
-
continue;
|
|
157426
|
-
}
|
|
157427
|
-
if (char === ",") {
|
|
157428
|
-
let lookahead = index + 1;
|
|
157429
|
-
while (lookahead < content.length && /\s/.test(content[lookahead] ?? "")) {
|
|
157430
|
-
lookahead += 1;
|
|
157431
|
-
}
|
|
157432
|
-
const next = content[lookahead];
|
|
157433
|
-
if (next === "}" || next === "]") {
|
|
157434
|
-
continue;
|
|
157435
|
-
}
|
|
157436
|
-
}
|
|
157437
|
-
result += char;
|
|
157438
|
-
}
|
|
157439
|
-
return result;
|
|
157440
|
-
}
|
|
157441
|
-
function parseJsonc(content) {
|
|
157442
|
-
const normalized = stripTrailingCommas(stripJsonComments(content));
|
|
157443
|
-
return JSON.parse(normalized);
|
|
157444
|
-
}
|
|
157445
157445
|
|
|
157446
157446
|
// ../plugin/src/config/variable.ts
|
|
157447
157447
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
@@ -158441,7 +158441,7 @@ function getDistinctStoredModelIds(db, projectPath) {
|
|
|
158441
158441
|
}
|
|
158442
158442
|
|
|
158443
158443
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
158444
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
158444
|
+
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
158445
158445
|
init_logger();
|
|
158446
158446
|
|
|
158447
158447
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
@@ -158545,6 +158545,125 @@ function getDistinctCommitEmbeddingModelIds(db, projectPath) {
|
|
|
158545
158545
|
return new Set(rows.map((row) => typeof row.modelId === "string" ? row.modelId : null));
|
|
158546
158546
|
}
|
|
158547
158547
|
|
|
158548
|
+
// ../plugin/src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
158549
|
+
var GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
158550
|
+
var GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
158551
|
+
var GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
|
|
158552
|
+
function runImmediate(db, body) {
|
|
158553
|
+
db.exec("BEGIN IMMEDIATE");
|
|
158554
|
+
let committed = false;
|
|
158555
|
+
try {
|
|
158556
|
+
const result = body();
|
|
158557
|
+
db.exec("COMMIT");
|
|
158558
|
+
committed = true;
|
|
158559
|
+
return result;
|
|
158560
|
+
} finally {
|
|
158561
|
+
if (!committed) {
|
|
158562
|
+
try {
|
|
158563
|
+
db.exec("ROLLBACK");
|
|
158564
|
+
} catch {}
|
|
158565
|
+
}
|
|
158566
|
+
}
|
|
158567
|
+
}
|
|
158568
|
+
function rowToState(row) {
|
|
158569
|
+
return {
|
|
158570
|
+
projectPath: row.project_path,
|
|
158571
|
+
leaseHolder: row.lease_holder,
|
|
158572
|
+
leaseExpiresAt: row.lease_expires_at,
|
|
158573
|
+
lastSweptAt: row.last_swept_at
|
|
158574
|
+
};
|
|
158575
|
+
}
|
|
158576
|
+
function getGitSweepCoordinatorState(db, projectPath) {
|
|
158577
|
+
const row = db.prepare(`SELECT project_path, lease_holder, lease_expires_at, last_swept_at
|
|
158578
|
+
FROM git_sweep_coordinator
|
|
158579
|
+
WHERE project_path = ?`).get(projectPath);
|
|
158580
|
+
return row ? rowToState(row) : null;
|
|
158581
|
+
}
|
|
158582
|
+
function acquireGitSweepLease(db, projectPath, holderId, options = {}) {
|
|
158583
|
+
const cooldownMs = options.cooldownMs ?? GIT_SWEEP_COOLDOWN_MS;
|
|
158584
|
+
const leaseTtlMs = options.leaseTtlMs ?? GIT_SWEEP_LEASE_TTL_MS;
|
|
158585
|
+
return runImmediate(db, () => {
|
|
158586
|
+
const now = Date.now();
|
|
158587
|
+
const row = getGitSweepCoordinatorState(db, projectPath);
|
|
158588
|
+
if (row?.leaseHolder && row.leaseExpiresAt !== null && row.leaseExpiresAt > now) {
|
|
158589
|
+
return {
|
|
158590
|
+
acquired: false,
|
|
158591
|
+
projectPath,
|
|
158592
|
+
reason: "lease_active",
|
|
158593
|
+
leaseHolder: row.leaseHolder,
|
|
158594
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
158595
|
+
lastSweptAt: row.lastSweptAt,
|
|
158596
|
+
nextAllowedAt: null
|
|
158597
|
+
};
|
|
158598
|
+
}
|
|
158599
|
+
if (!options.ignoreCooldown && row?.lastSweptAt !== null && row?.lastSweptAt !== undefined) {
|
|
158600
|
+
const nextAllowedAt = row.lastSweptAt + cooldownMs;
|
|
158601
|
+
if (nextAllowedAt > now) {
|
|
158602
|
+
return {
|
|
158603
|
+
acquired: false,
|
|
158604
|
+
projectPath,
|
|
158605
|
+
reason: "cooldown_active",
|
|
158606
|
+
leaseHolder: row.leaseHolder,
|
|
158607
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
158608
|
+
lastSweptAt: row.lastSweptAt,
|
|
158609
|
+
nextAllowedAt
|
|
158610
|
+
};
|
|
158611
|
+
}
|
|
158612
|
+
}
|
|
158613
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
158614
|
+
db.prepare(`INSERT INTO git_sweep_coordinator (
|
|
158615
|
+
project_path,
|
|
158616
|
+
lease_holder,
|
|
158617
|
+
lease_expires_at,
|
|
158618
|
+
last_swept_at
|
|
158619
|
+
) VALUES (?, ?, ?, NULL)
|
|
158620
|
+
ON CONFLICT(project_path) DO UPDATE SET
|
|
158621
|
+
lease_holder = excluded.lease_holder,
|
|
158622
|
+
lease_expires_at = excluded.lease_expires_at`).run(projectPath, holderId, leaseExpiresAt);
|
|
158623
|
+
return {
|
|
158624
|
+
acquired: true,
|
|
158625
|
+
projectPath,
|
|
158626
|
+
holderId,
|
|
158627
|
+
acquiredAt: now,
|
|
158628
|
+
leaseExpiresAt
|
|
158629
|
+
};
|
|
158630
|
+
});
|
|
158631
|
+
}
|
|
158632
|
+
function renewGitSweepLease(db, projectPath, holderId, leaseTtlMs = GIT_SWEEP_LEASE_TTL_MS) {
|
|
158633
|
+
return runImmediate(db, () => {
|
|
158634
|
+
const now = Date.now();
|
|
158635
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
158636
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
158637
|
+
SET lease_expires_at = ?
|
|
158638
|
+
WHERE project_path = ?
|
|
158639
|
+
AND lease_holder = ?
|
|
158640
|
+
AND lease_expires_at > ?`).run(leaseExpiresAt, projectPath, holderId, now);
|
|
158641
|
+
return result.changes === 1;
|
|
158642
|
+
});
|
|
158643
|
+
}
|
|
158644
|
+
function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
|
|
158645
|
+
return runImmediate(db, () => {
|
|
158646
|
+
const now = Date.now();
|
|
158647
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
158648
|
+
SET lease_holder = NULL,
|
|
158649
|
+
lease_expires_at = NULL,
|
|
158650
|
+
last_swept_at = ?
|
|
158651
|
+
WHERE project_path = ?
|
|
158652
|
+
AND lease_holder = ?
|
|
158653
|
+
AND lease_expires_at > ?`).run(now, projectPath, holderId, now);
|
|
158654
|
+
return result.changes === 1;
|
|
158655
|
+
});
|
|
158656
|
+
}
|
|
158657
|
+
function releaseGitSweepLease(db, projectPath, holderId) {
|
|
158658
|
+
runImmediate(db, () => {
|
|
158659
|
+
db.prepare(`UPDATE git_sweep_coordinator
|
|
158660
|
+
SET lease_holder = NULL,
|
|
158661
|
+
lease_expires_at = NULL
|
|
158662
|
+
WHERE project_path = ?
|
|
158663
|
+
AND lease_holder = ?`).run(projectPath, holderId);
|
|
158664
|
+
});
|
|
158665
|
+
}
|
|
158666
|
+
|
|
158548
158667
|
// ../plugin/src/features/magic-context/memory/embedding-cache.ts
|
|
158549
158668
|
var DEFAULT_EMBEDDING_CACHE_TTL_MS = 60000;
|
|
158550
158669
|
var projectEmbeddingCache = new Map;
|
|
@@ -166040,7 +166159,8 @@ function toNote(row) {
|
|
|
166040
166159
|
updatedAt: row.updated_at,
|
|
166041
166160
|
lastCheckedAt: toNullableNumber(row.last_checked_at),
|
|
166042
166161
|
readyAt: toNullableNumber(row.ready_at),
|
|
166043
|
-
readyReason: toNullableString(row.ready_reason)
|
|
166162
|
+
readyReason: toNullableString(row.ready_reason),
|
|
166163
|
+
anchorOrdinal: toNullableNumber(row.anchor_ordinal)
|
|
166044
166164
|
};
|
|
166045
166165
|
}
|
|
166046
166166
|
function getNoteById(db, noteId) {
|
|
@@ -166092,7 +166212,7 @@ function getNotes(db, options3 = {}) {
|
|
|
166092
166212
|
}
|
|
166093
166213
|
function addNote(db, type, options3) {
|
|
166094
166214
|
const now = Date.now();
|
|
166095
|
-
const result = type === "session" ? db.prepare("INSERT INTO notes (type, status, content, session_id, created_at, updated_at, harness) VALUES ('session', 'active', ?, ?, ?, ?, ?) RETURNING *").get(options3.content, options3.sessionId, now, now, getHarness()) : db.prepare("INSERT INTO notes (type, status, content, session_id, project_path, surface_condition, created_at, updated_at, harness) VALUES ('smart', 'pending', ?, ?, ?, ?, ?, ?, ?) RETURNING *").get(options3.content, options3.sessionId ?? null, options3.projectPath, options3.surfaceCondition, now, now, getHarness());
|
|
166215
|
+
const result = type === "session" ? db.prepare("INSERT INTO notes (type, status, content, session_id, created_at, updated_at, harness, anchor_ordinal) VALUES ('session', 'active', ?, ?, ?, ?, ?, ?) RETURNING *").get(options3.content, options3.sessionId, now, now, getHarness(), options3.anchorOrdinal ?? null) : db.prepare("INSERT INTO notes (type, status, content, session_id, project_path, surface_condition, created_at, updated_at, harness, anchor_ordinal) VALUES ('smart', 'pending', ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *").get(options3.content, options3.sessionId ?? null, options3.projectPath, options3.surfaceCondition, now, now, getHarness(), options3.anchorOrdinal ?? null);
|
|
166096
166216
|
if (!isNoteRow(result)) {
|
|
166097
166217
|
throw new Error("[notes] failed to insert note");
|
|
166098
166218
|
}
|
|
@@ -166946,15 +167066,26 @@ function err3(text) {
|
|
|
166946
167066
|
isError: true
|
|
166947
167067
|
};
|
|
166948
167068
|
}
|
|
167069
|
+
function captureAnchorOrdinal(db, sessionId) {
|
|
167070
|
+
try {
|
|
167071
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
167072
|
+
return ordinal > 0 ? ordinal : null;
|
|
167073
|
+
} catch {
|
|
167074
|
+
return null;
|
|
167075
|
+
}
|
|
167076
|
+
}
|
|
167077
|
+
function anchorSuffix(note) {
|
|
167078
|
+
return note.anchorOrdinal !== null ? ` ↳ @msg ${note.anchorOrdinal}` : "";
|
|
167079
|
+
}
|
|
166949
167080
|
function formatNoteLine(note) {
|
|
166950
167081
|
if (note.type === "smart") {
|
|
166951
167082
|
const conditionLine = note.status === "ready" ? note.readyReason ?? note.surfaceCondition ?? "Condition satisfied" : note.surfaceCondition ?? "No condition recorded";
|
|
166952
167083
|
const statusSuffix2 = note.status === "active" ? "" : ` (${note.status})`;
|
|
166953
|
-
return `- **#${note.id}**${statusSuffix2}: ${note.content}
|
|
167084
|
+
return `- **#${note.id}**${statusSuffix2}: ${note.content}${anchorSuffix(note)}
|
|
166954
167085
|
*Condition*: ${conditionLine}`;
|
|
166955
167086
|
}
|
|
166956
167087
|
const statusSuffix = note.status === "active" ? "" : ` (${note.status})`;
|
|
166957
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}`;
|
|
167088
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}`;
|
|
166958
167089
|
}
|
|
166959
167090
|
var DISMISS_FOOTER = `
|
|
166960
167091
|
|
|
@@ -166976,6 +167107,7 @@ function createCtxNoteTool(deps) {
|
|
|
166976
167107
|
const content = params.content?.trim();
|
|
166977
167108
|
if (!content)
|
|
166978
167109
|
return err3("Error: 'content' is required when action is 'write'.");
|
|
167110
|
+
const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
|
|
166979
167111
|
const surfaceCondition = params.surface_condition?.trim();
|
|
166980
167112
|
if (surfaceCondition) {
|
|
166981
167113
|
if (deps.dreamerEnabled !== true) {
|
|
@@ -166988,13 +167120,18 @@ function createCtxNoteTool(deps) {
|
|
|
166988
167120
|
const note2 = addNote(deps.db, "smart", {
|
|
166989
167121
|
content,
|
|
166990
167122
|
projectPath: projectIdentity,
|
|
166991
|
-
surfaceCondition
|
|
167123
|
+
surfaceCondition,
|
|
167124
|
+
anchorOrdinal
|
|
166992
167125
|
});
|
|
166993
167126
|
return ok3(`Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
|
|
166994
167127
|
- Content: ${content}
|
|
166995
167128
|
- Condition: ${surfaceCondition}`);
|
|
166996
167129
|
}
|
|
166997
|
-
const note = addNote(deps.db, "session", {
|
|
167130
|
+
const note = addNote(deps.db, "session", {
|
|
167131
|
+
sessionId,
|
|
167132
|
+
content,
|
|
167133
|
+
anchorOrdinal
|
|
167134
|
+
});
|
|
166998
167135
|
return ok3(`Saved session note #${note.id}.`);
|
|
166999
167136
|
}
|
|
167000
167137
|
if (action2 === "dismiss") {
|
|
@@ -167057,9 +167194,13 @@ function createCtxNoteTool(deps) {
|
|
|
167057
167194
|
|
|
167058
167195
|
No notes for the current filter.`);
|
|
167059
167196
|
}
|
|
167060
|
-
|
|
167197
|
+
const body = sections.join(`
|
|
167198
|
+
|
|
167199
|
+
`);
|
|
167200
|
+
const anchorHint = body.includes("↳ @msg ") ? `
|
|
167061
167201
|
|
|
167062
|
-
|
|
167202
|
+
↳ @msg N marks the conversation tail when a note was written. To see what led to it: ctx_expand(start=N-x, end=N) (pick x for how far back to look).` : "";
|
|
167203
|
+
return ok3(`${body}${anchorHint}${DISMISS_FOOTER}`);
|
|
167063
167204
|
}
|
|
167064
167205
|
};
|
|
167065
167206
|
}
|
|
@@ -167374,6 +167515,7 @@ var insertStatements = new WeakMap;
|
|
|
167374
167515
|
var existingShasStatements = new WeakMap;
|
|
167375
167516
|
var projectCountStatements = new WeakMap;
|
|
167376
167517
|
var evictStatements = new WeakMap;
|
|
167518
|
+
var evictOverflowStatements = new WeakMap;
|
|
167377
167519
|
var latestCommitTimeStatements = new WeakMap;
|
|
167378
167520
|
function getInsertStatement(db) {
|
|
167379
167521
|
let stmt = insertStatements.get(db);
|
|
@@ -167416,17 +167558,17 @@ function getLatestCommitTimeStatement(db) {
|
|
|
167416
167558
|
}
|
|
167417
167559
|
return stmt;
|
|
167418
167560
|
}
|
|
167419
|
-
function
|
|
167420
|
-
let stmt =
|
|
167561
|
+
function getEvictOverflowStatement(db) {
|
|
167562
|
+
let stmt = evictOverflowStatements.get(db);
|
|
167421
167563
|
if (!stmt) {
|
|
167422
167564
|
stmt = db.prepare(`DELETE FROM git_commits
|
|
167423
|
-
WHERE
|
|
167424
|
-
SELECT
|
|
167565
|
+
WHERE rowid IN (
|
|
167566
|
+
SELECT rowid FROM git_commits
|
|
167425
167567
|
WHERE project_path = ?
|
|
167426
|
-
ORDER BY committed_at
|
|
167427
|
-
LIMIT ?
|
|
167568
|
+
ORDER BY committed_at DESC, sha DESC
|
|
167569
|
+
LIMIT -1 OFFSET ?
|
|
167428
167570
|
)`);
|
|
167429
|
-
|
|
167571
|
+
evictOverflowStatements.set(db, stmt);
|
|
167430
167572
|
}
|
|
167431
167573
|
return stmt;
|
|
167432
167574
|
}
|
|
@@ -167464,22 +167606,15 @@ function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
|
167464
167606
|
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
167465
167607
|
return row?.latest ?? null;
|
|
167466
167608
|
}
|
|
167467
|
-
function evictOldestCommits(db, projectPath, excess) {
|
|
167468
|
-
if (excess <= 0)
|
|
167469
|
-
return 0;
|
|
167470
|
-
const before = getCommitCount(db, projectPath);
|
|
167471
|
-
getEvictStatement(db).run(projectPath, excess);
|
|
167472
|
-
const after = getCommitCount(db, projectPath);
|
|
167473
|
-
return Math.max(0, before - after);
|
|
167474
|
-
}
|
|
167475
167609
|
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
167476
167610
|
if (maxCommits <= 0)
|
|
167477
167611
|
return 0;
|
|
167478
167612
|
const count = getCommitCount(db, projectPath);
|
|
167479
167613
|
if (count <= maxCommits)
|
|
167480
167614
|
return 0;
|
|
167481
|
-
|
|
167482
|
-
const
|
|
167615
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
167616
|
+
const after = getCommitCount(db, projectPath);
|
|
167617
|
+
const evicted = Math.max(0, count - after);
|
|
167483
167618
|
if (evicted > 0) {
|
|
167484
167619
|
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
167485
167620
|
}
|
|
@@ -167718,6 +167853,62 @@ function searchGitCommitsSync(db, projectPath, query, options3) {
|
|
|
167718
167853
|
});
|
|
167719
167854
|
return results.slice(0, options3.limit);
|
|
167720
167855
|
}
|
|
167856
|
+
// ../plugin/src/features/magic-context/literal-probes.ts
|
|
167857
|
+
var MAX_PROBES = 5;
|
|
167858
|
+
var MIN_PROBE_LENGTH = 3;
|
|
167859
|
+
var SLASH_COMMAND_RE = /\/[a-z][a-z0-9]*(?:-[a-z0-9]+)+/gi;
|
|
167860
|
+
var KEBAB_SNAKE_RE = /[a-z][a-z0-9]*(?:[-_][a-z0-9]+)+/gi;
|
|
167861
|
+
var DOTTED_RE = /[a-z0-9][a-z0-9_-]*(?:\.[a-z0-9_-]+)+/gi;
|
|
167862
|
+
var CAMEL_RE = /\b[a-zA-Z][a-z0-9]*(?:[A-Z][a-z0-9]*)+\b/g;
|
|
167863
|
+
var SHA_RE = /\b[0-9a-f]{7,40}\b/gi;
|
|
167864
|
+
var ERROR_CODE_RE = /\b(?:TS\d{4,}|ERR_[A-Z][A-Z0-9_]*)\b/g;
|
|
167865
|
+
var QUOTED_RE = /["`]([^"`]{3,80})["`]/g;
|
|
167866
|
+
function looksLikeSha(token) {
|
|
167867
|
+
return /[0-9]/.test(token) && /^[0-9a-f]{7,40}$/i.test(token);
|
|
167868
|
+
}
|
|
167869
|
+
function extractLiteralProbes(query) {
|
|
167870
|
+
const trimmed = query.trim();
|
|
167871
|
+
if (trimmed.length === 0)
|
|
167872
|
+
return [];
|
|
167873
|
+
const ordered = [];
|
|
167874
|
+
const seen = new Set;
|
|
167875
|
+
const add = (raw) => {
|
|
167876
|
+
if (!raw)
|
|
167877
|
+
return;
|
|
167878
|
+
const probe = raw.trim();
|
|
167879
|
+
if (probe.length < MIN_PROBE_LENGTH)
|
|
167880
|
+
return;
|
|
167881
|
+
const key = probe.toLowerCase();
|
|
167882
|
+
if (seen.has(key))
|
|
167883
|
+
return;
|
|
167884
|
+
seen.add(key);
|
|
167885
|
+
ordered.push(probe);
|
|
167886
|
+
};
|
|
167887
|
+
for (const m of trimmed.matchAll(QUOTED_RE))
|
|
167888
|
+
add(m[1]);
|
|
167889
|
+
for (const m of trimmed.matchAll(SLASH_COMMAND_RE))
|
|
167890
|
+
add(m[0]);
|
|
167891
|
+
for (const m of trimmed.matchAll(ERROR_CODE_RE))
|
|
167892
|
+
add(m[0]);
|
|
167893
|
+
for (const m of trimmed.matchAll(DOTTED_RE))
|
|
167894
|
+
add(m[0]);
|
|
167895
|
+
for (const m of trimmed.matchAll(KEBAB_SNAKE_RE))
|
|
167896
|
+
add(m[0]);
|
|
167897
|
+
for (const m of trimmed.matchAll(CAMEL_RE))
|
|
167898
|
+
add(m[0]);
|
|
167899
|
+
for (const m of trimmed.matchAll(SHA_RE)) {
|
|
167900
|
+
if (looksLikeSha(m[0]))
|
|
167901
|
+
add(m[0]);
|
|
167902
|
+
}
|
|
167903
|
+
return ordered.slice(0, MAX_PROBES);
|
|
167904
|
+
}
|
|
167905
|
+
function containsProbeVerbatim(text, probes) {
|
|
167906
|
+
if (probes.length === 0)
|
|
167907
|
+
return false;
|
|
167908
|
+
const haystack = text.toLowerCase();
|
|
167909
|
+
return probes.some((probe) => haystack.includes(probe.toLowerCase()));
|
|
167910
|
+
}
|
|
167911
|
+
|
|
167721
167912
|
// ../plugin/src/features/magic-context/search.ts
|
|
167722
167913
|
var DEFAULT_UNIFIED_SEARCH_LIMIT = 10;
|
|
167723
167914
|
var FTS_SEMANTIC_CANDIDATE_LIMIT = 50;
|
|
@@ -167895,36 +168086,82 @@ function linearDecayScore(rank, total) {
|
|
|
167895
168086
|
return 0;
|
|
167896
168087
|
return Math.max(0, 1 - rank / total);
|
|
167897
168088
|
}
|
|
167898
|
-
function
|
|
167899
|
-
|
|
167900
|
-
if (sanitizedQuery.length === 0) {
|
|
168089
|
+
function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
|
|
168090
|
+
if (ftsQuery.length === 0)
|
|
167901
168091
|
return [];
|
|
167902
|
-
|
|
167903
|
-
const
|
|
167904
|
-
|
|
167905
|
-
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
167906
|
-
const filtered = rows.map((row) => {
|
|
168092
|
+
const rows = getMessageSearchStatement(db).all(sessionId, ftsQuery, fetchLimit).map((row) => row);
|
|
168093
|
+
const result = [];
|
|
168094
|
+
for (const row of rows) {
|
|
167907
168095
|
const messageOrdinal = getMessageOrdinal(row.messageOrdinal);
|
|
167908
168096
|
if (messageOrdinal === null || typeof row.messageId !== "string" || typeof row.role !== "string" || typeof row.content !== "string") {
|
|
167909
|
-
|
|
168097
|
+
continue;
|
|
167910
168098
|
}
|
|
167911
168099
|
if (cutoff !== null && messageOrdinal > cutoff) {
|
|
167912
|
-
|
|
168100
|
+
continue;
|
|
167913
168101
|
}
|
|
167914
|
-
|
|
168102
|
+
result.push({
|
|
167915
168103
|
messageOrdinal,
|
|
167916
168104
|
messageId: row.messageId,
|
|
167917
168105
|
role: row.role,
|
|
167918
168106
|
content: row.content
|
|
167919
|
-
};
|
|
167920
|
-
}
|
|
167921
|
-
return
|
|
168107
|
+
});
|
|
168108
|
+
}
|
|
168109
|
+
return result;
|
|
168110
|
+
}
|
|
168111
|
+
var RRF_K = 60;
|
|
168112
|
+
var VERBATIM_PROBE_BONUS = 0.5;
|
|
168113
|
+
function searchMessages(args) {
|
|
168114
|
+
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
168115
|
+
const fetchLimit = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.limit * 3 : args.limit;
|
|
168116
|
+
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
168117
|
+
const probes = args.probes ?? [];
|
|
168118
|
+
if (probes.length === 0) {
|
|
168119
|
+
const filtered = runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff).slice(0, args.limit);
|
|
168120
|
+
return filtered.map((row, rank) => ({
|
|
168121
|
+
source: "message",
|
|
168122
|
+
content: previewText(row.content),
|
|
168123
|
+
score: linearDecayScore(rank, filtered.length),
|
|
168124
|
+
messageOrdinal: row.messageOrdinal,
|
|
168125
|
+
messageId: row.messageId,
|
|
168126
|
+
role: row.role
|
|
168127
|
+
}));
|
|
168128
|
+
}
|
|
168129
|
+
const queryLists = [];
|
|
168130
|
+
if (baseQuery.length > 0) {
|
|
168131
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff));
|
|
168132
|
+
}
|
|
168133
|
+
for (const probe of probes) {
|
|
168134
|
+
const probeQuery = sanitizeFtsQuery(probe);
|
|
168135
|
+
if (probeQuery.length === 0)
|
|
168136
|
+
continue;
|
|
168137
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, probeQuery, fetchLimit, cutoff));
|
|
168138
|
+
}
|
|
168139
|
+
const fused = new Map;
|
|
168140
|
+
for (const list of queryLists) {
|
|
168141
|
+
list.forEach((row, rank) => {
|
|
168142
|
+
const rrf = 1 / (RRF_K + rank);
|
|
168143
|
+
const existing = fused.get(row.messageId);
|
|
168144
|
+
if (existing) {
|
|
168145
|
+
existing.score += rrf;
|
|
168146
|
+
} else {
|
|
168147
|
+
fused.set(row.messageId, { row, score: rrf });
|
|
168148
|
+
}
|
|
168149
|
+
});
|
|
168150
|
+
}
|
|
168151
|
+
for (const entry of fused.values()) {
|
|
168152
|
+
if (containsProbeVerbatim(entry.row.content, probes)) {
|
|
168153
|
+
entry.score += VERBATIM_PROBE_BONUS;
|
|
168154
|
+
}
|
|
168155
|
+
}
|
|
168156
|
+
const ranked = [...fused.values()].sort((a, b) => b.score !== a.score ? b.score - a.score : a.row.messageOrdinal - b.row.messageOrdinal).slice(0, args.limit);
|
|
168157
|
+
const maxScore = ranked.length > 0 ? ranked[0].score : 1;
|
|
168158
|
+
return ranked.map((entry) => ({
|
|
167922
168159
|
source: "message",
|
|
167923
|
-
content: previewText(row.content),
|
|
167924
|
-
score:
|
|
167925
|
-
messageOrdinal: row.messageOrdinal,
|
|
167926
|
-
messageId: row.messageId,
|
|
167927
|
-
role: row.role
|
|
168160
|
+
content: previewText(entry.row.content),
|
|
168161
|
+
score: maxScore > 0 ? entry.score / maxScore : 0,
|
|
168162
|
+
messageOrdinal: entry.row.messageOrdinal,
|
|
168163
|
+
messageId: entry.row.messageId,
|
|
168164
|
+
role: entry.row.role
|
|
167928
168165
|
}));
|
|
167929
168166
|
}
|
|
167930
168167
|
function getSourceBoost(result) {
|
|
@@ -168008,12 +168245,14 @@ async function unifiedSearch(db, sessionId, projectPath, query, options3 = {}) {
|
|
|
168008
168245
|
return null;
|
|
168009
168246
|
}) : Promise.resolve(null);
|
|
168010
168247
|
await Promise.resolve();
|
|
168248
|
+
const messageProbes = options3.explicitSearch ? extractLiteralProbes(trimmedQuery) : [];
|
|
168011
168249
|
const messageResults = runMessages ? searchMessages({
|
|
168012
168250
|
db,
|
|
168013
168251
|
sessionId,
|
|
168014
168252
|
query: trimmedQuery,
|
|
168015
168253
|
limit: tierLimit,
|
|
168016
|
-
maxOrdinal: options3.maxMessageOrdinal
|
|
168254
|
+
maxOrdinal: options3.maxMessageOrdinal,
|
|
168255
|
+
probes: messageProbes
|
|
168017
168256
|
}) : [];
|
|
168018
168257
|
const queryEmbedding = await queryEmbeddingPromise;
|
|
168019
168258
|
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
@@ -168784,7 +169023,8 @@ function createCtxSearchTool(deps) {
|
|
|
168784
169023
|
maxMessageOrdinal: lastCompartmentEnd >= 0 ? lastCompartmentEnd : undefined,
|
|
168785
169024
|
gitCommitsEnabled,
|
|
168786
169025
|
sources: params.sources,
|
|
168787
|
-
visibleMemoryIds
|
|
169026
|
+
visibleMemoryIds,
|
|
169027
|
+
explicitSearch: true
|
|
168788
169028
|
});
|
|
168789
169029
|
return {
|
|
168790
169030
|
content: [{ type: "text", text: formatSearchResults(query, results) }],
|
package/package.json
CHANGED