@cortexkit/pi-magic-context 0.22.1 → 0.22.3
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 +546 -399
- package/dist/subagent-entry.js +375 -97
- 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;
|
|
@@ -159716,14 +159835,48 @@ function readRawSessionMessagesFromDb(db, sessionId) {
|
|
|
159716
159835
|
var encoder = new TextEncoder;
|
|
159717
159836
|
var TAG_PREFIX_REGEX = /^(?:§\d+§\s*)+/;
|
|
159718
159837
|
var MALFORMED_TAG_PREFIX_REGEX = /^(?:§\d+">§(?:\d+§)?\s*)+/;
|
|
159838
|
+
var COMPLETE_TAG_PAIR_GLOBAL_REGEX = /\u00a7\d+\u00a7/g;
|
|
159839
|
+
var MALFORMED_TAG_GLOBAL_REGEX = /\u00a7\d+">(?:\u00a7(?:\d+\u00a7)?)?/g;
|
|
159840
|
+
var STRAY_SECTION_CHAR_REGEX = /\u00a7/g;
|
|
159841
|
+
function stripWellFormedLeadingTagPrefix(value) {
|
|
159842
|
+
return value.replace(/^(\u00a7\d+\u00a7\s*)+/, "");
|
|
159843
|
+
}
|
|
159844
|
+
function stripCompleteTagPairsGlobally(value) {
|
|
159845
|
+
return value.replace(COMPLETE_TAG_PAIR_GLOBAL_REGEX, "");
|
|
159846
|
+
}
|
|
159847
|
+
function stripMalformedTagNotationGlobally(value) {
|
|
159848
|
+
return value.replace(MALFORMED_TAG_GLOBAL_REGEX, "");
|
|
159849
|
+
}
|
|
159850
|
+
function stripTagSectionCharacters(value) {
|
|
159851
|
+
return value.replace(STRAY_SECTION_CHAR_REGEX, "");
|
|
159852
|
+
}
|
|
159853
|
+
function stripPersistedAssistantText(value) {
|
|
159854
|
+
let text = stripWellFormedLeadingTagPrefix(value);
|
|
159855
|
+
text = stripCompleteTagPairsGlobally(text);
|
|
159856
|
+
text = stripMalformedTagNotationGlobally(text);
|
|
159857
|
+
text = stripTagSectionCharacters(text);
|
|
159858
|
+
return text.trim();
|
|
159859
|
+
}
|
|
159719
159860
|
function byteSize(value) {
|
|
159720
159861
|
return encoder.encode(value).length;
|
|
159721
159862
|
}
|
|
159722
159863
|
function stripTagPrefix(value) {
|
|
159723
|
-
let stripped = value
|
|
159724
|
-
|
|
159864
|
+
let stripped = value;
|
|
159865
|
+
for (let pass = 0;pass < 8; pass++) {
|
|
159866
|
+
const prev = stripped;
|
|
159867
|
+
stripped = stripped.replace(MALFORMED_TAG_PREFIX_REGEX, "");
|
|
159868
|
+
stripped = stripped.replace(TAG_PREFIX_REGEX, "");
|
|
159869
|
+
if (stripped === prev)
|
|
159870
|
+
break;
|
|
159871
|
+
}
|
|
159725
159872
|
return stripped;
|
|
159726
159873
|
}
|
|
159874
|
+
function peelLeadingMcTagNotation(value) {
|
|
159875
|
+
const body = stripTagPrefix(value);
|
|
159876
|
+
if (body === value)
|
|
159877
|
+
return { tagPrefix: "", body };
|
|
159878
|
+
return { tagPrefix: value.slice(0, value.length - body.length), body };
|
|
159879
|
+
}
|
|
159727
159880
|
function prependTag(tagId, value) {
|
|
159728
159881
|
const stripped = stripTagPrefix(value);
|
|
159729
159882
|
return `§${tagId}§ ${stripped}`;
|
|
@@ -159765,7 +159918,9 @@ function hasMeaningfulPart(part) {
|
|
|
159765
159918
|
return false;
|
|
159766
159919
|
const type = part.type;
|
|
159767
159920
|
if (type === "text") {
|
|
159768
|
-
|
|
159921
|
+
if (typeof part.text !== "string")
|
|
159922
|
+
return false;
|
|
159923
|
+
return stripTagPrefix(part.text).trim().length > 0;
|
|
159769
159924
|
}
|
|
159770
159925
|
if (typeof type !== "string")
|
|
159771
159926
|
return false;
|
|
@@ -166040,7 +166195,8 @@ function toNote(row) {
|
|
|
166040
166195
|
updatedAt: row.updated_at,
|
|
166041
166196
|
lastCheckedAt: toNullableNumber(row.last_checked_at),
|
|
166042
166197
|
readyAt: toNullableNumber(row.ready_at),
|
|
166043
|
-
readyReason: toNullableString(row.ready_reason)
|
|
166198
|
+
readyReason: toNullableString(row.ready_reason),
|
|
166199
|
+
anchorOrdinal: toNullableNumber(row.anchor_ordinal)
|
|
166044
166200
|
};
|
|
166045
166201
|
}
|
|
166046
166202
|
function getNoteById(db, noteId) {
|
|
@@ -166092,7 +166248,7 @@ function getNotes(db, options3 = {}) {
|
|
|
166092
166248
|
}
|
|
166093
166249
|
function addNote(db, type, options3) {
|
|
166094
166250
|
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());
|
|
166251
|
+
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
166252
|
if (!isNoteRow(result)) {
|
|
166097
166253
|
throw new Error("[notes] failed to insert note");
|
|
166098
166254
|
}
|
|
@@ -166946,15 +167102,26 @@ function err3(text) {
|
|
|
166946
167102
|
isError: true
|
|
166947
167103
|
};
|
|
166948
167104
|
}
|
|
167105
|
+
function captureAnchorOrdinal(db, sessionId) {
|
|
167106
|
+
try {
|
|
167107
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
167108
|
+
return ordinal > 0 ? ordinal : null;
|
|
167109
|
+
} catch {
|
|
167110
|
+
return null;
|
|
167111
|
+
}
|
|
167112
|
+
}
|
|
167113
|
+
function anchorSuffix(note) {
|
|
167114
|
+
return note.anchorOrdinal !== null ? ` ↳ @msg ${note.anchorOrdinal}` : "";
|
|
167115
|
+
}
|
|
166949
167116
|
function formatNoteLine(note) {
|
|
166950
167117
|
if (note.type === "smart") {
|
|
166951
167118
|
const conditionLine = note.status === "ready" ? note.readyReason ?? note.surfaceCondition ?? "Condition satisfied" : note.surfaceCondition ?? "No condition recorded";
|
|
166952
167119
|
const statusSuffix2 = note.status === "active" ? "" : ` (${note.status})`;
|
|
166953
|
-
return `- **#${note.id}**${statusSuffix2}: ${note.content}
|
|
167120
|
+
return `- **#${note.id}**${statusSuffix2}: ${note.content}${anchorSuffix(note)}
|
|
166954
167121
|
*Condition*: ${conditionLine}`;
|
|
166955
167122
|
}
|
|
166956
167123
|
const statusSuffix = note.status === "active" ? "" : ` (${note.status})`;
|
|
166957
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}`;
|
|
167124
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}`;
|
|
166958
167125
|
}
|
|
166959
167126
|
var DISMISS_FOOTER = `
|
|
166960
167127
|
|
|
@@ -166976,6 +167143,7 @@ function createCtxNoteTool(deps) {
|
|
|
166976
167143
|
const content = params.content?.trim();
|
|
166977
167144
|
if (!content)
|
|
166978
167145
|
return err3("Error: 'content' is required when action is 'write'.");
|
|
167146
|
+
const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
|
|
166979
167147
|
const surfaceCondition = params.surface_condition?.trim();
|
|
166980
167148
|
if (surfaceCondition) {
|
|
166981
167149
|
if (deps.dreamerEnabled !== true) {
|
|
@@ -166988,13 +167156,18 @@ function createCtxNoteTool(deps) {
|
|
|
166988
167156
|
const note2 = addNote(deps.db, "smart", {
|
|
166989
167157
|
content,
|
|
166990
167158
|
projectPath: projectIdentity,
|
|
166991
|
-
surfaceCondition
|
|
167159
|
+
surfaceCondition,
|
|
167160
|
+
anchorOrdinal
|
|
166992
167161
|
});
|
|
166993
167162
|
return ok3(`Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
|
|
166994
167163
|
- Content: ${content}
|
|
166995
167164
|
- Condition: ${surfaceCondition}`);
|
|
166996
167165
|
}
|
|
166997
|
-
const note = addNote(deps.db, "session", {
|
|
167166
|
+
const note = addNote(deps.db, "session", {
|
|
167167
|
+
sessionId,
|
|
167168
|
+
content,
|
|
167169
|
+
anchorOrdinal
|
|
167170
|
+
});
|
|
166998
167171
|
return ok3(`Saved session note #${note.id}.`);
|
|
166999
167172
|
}
|
|
167000
167173
|
if (action2 === "dismiss") {
|
|
@@ -167057,9 +167230,13 @@ function createCtxNoteTool(deps) {
|
|
|
167057
167230
|
|
|
167058
167231
|
No notes for the current filter.`);
|
|
167059
167232
|
}
|
|
167060
|
-
|
|
167233
|
+
const body = sections.join(`
|
|
167061
167234
|
|
|
167062
|
-
`)
|
|
167235
|
+
`);
|
|
167236
|
+
const anchorHint = body.includes("↳ @msg ") ? `
|
|
167237
|
+
|
|
167238
|
+
↳ @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).` : "";
|
|
167239
|
+
return ok3(`${body}${anchorHint}${DISMISS_FOOTER}`);
|
|
167063
167240
|
}
|
|
167064
167241
|
};
|
|
167065
167242
|
}
|
|
@@ -167295,6 +167472,7 @@ async function readGitCommits(directory, options3 = {}) {
|
|
|
167295
167472
|
if (revision.startsWith("-")) {
|
|
167296
167473
|
throw new Error(`readGitCommits: refusing revision that looks like an option: "${revision}"`);
|
|
167297
167474
|
}
|
|
167475
|
+
const projectLabel = options3.projectIdentity ?? "<project>";
|
|
167298
167476
|
const args = [
|
|
167299
167477
|
"log",
|
|
167300
167478
|
revision,
|
|
@@ -167317,11 +167495,11 @@ async function readGitCommits(directory, options3 = {}) {
|
|
|
167317
167495
|
stdout = result.stdout;
|
|
167318
167496
|
} catch (error51) {
|
|
167319
167497
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
167320
|
-
log(`[git-commits] readGitCommits failed
|
|
167498
|
+
log(`[git-commits] readGitCommits failed for ${projectLabel}: ${message.slice(0, 500)}`);
|
|
167321
167499
|
return [];
|
|
167322
167500
|
}
|
|
167323
167501
|
if (stdout.trim().length === 0) {
|
|
167324
|
-
log(`[git-commits] readGitCommits returned empty stdout
|
|
167502
|
+
log(`[git-commits] readGitCommits returned empty stdout for ${projectLabel} (sinceMs=${options3.sinceMs ?? "none"} args=${args.slice(0, 4).join(" ")})`);
|
|
167325
167503
|
}
|
|
167326
167504
|
return parseGitLogOutput(stdout);
|
|
167327
167505
|
}
|
|
@@ -167374,6 +167552,7 @@ var insertStatements = new WeakMap;
|
|
|
167374
167552
|
var existingShasStatements = new WeakMap;
|
|
167375
167553
|
var projectCountStatements = new WeakMap;
|
|
167376
167554
|
var evictStatements = new WeakMap;
|
|
167555
|
+
var evictOverflowStatements = new WeakMap;
|
|
167377
167556
|
var latestCommitTimeStatements = new WeakMap;
|
|
167378
167557
|
function getInsertStatement(db) {
|
|
167379
167558
|
let stmt = insertStatements.get(db);
|
|
@@ -167416,17 +167595,17 @@ function getLatestCommitTimeStatement(db) {
|
|
|
167416
167595
|
}
|
|
167417
167596
|
return stmt;
|
|
167418
167597
|
}
|
|
167419
|
-
function
|
|
167420
|
-
let stmt =
|
|
167598
|
+
function getEvictOverflowStatement(db) {
|
|
167599
|
+
let stmt = evictOverflowStatements.get(db);
|
|
167421
167600
|
if (!stmt) {
|
|
167422
167601
|
stmt = db.prepare(`DELETE FROM git_commits
|
|
167423
|
-
WHERE
|
|
167424
|
-
SELECT
|
|
167602
|
+
WHERE rowid IN (
|
|
167603
|
+
SELECT rowid FROM git_commits
|
|
167425
167604
|
WHERE project_path = ?
|
|
167426
|
-
ORDER BY committed_at
|
|
167427
|
-
LIMIT ?
|
|
167605
|
+
ORDER BY committed_at DESC, sha DESC
|
|
167606
|
+
LIMIT -1 OFFSET ?
|
|
167428
167607
|
)`);
|
|
167429
|
-
|
|
167608
|
+
evictOverflowStatements.set(db, stmt);
|
|
167430
167609
|
}
|
|
167431
167610
|
return stmt;
|
|
167432
167611
|
}
|
|
@@ -167464,22 +167643,15 @@ function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
|
167464
167643
|
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
167465
167644
|
return row?.latest ?? null;
|
|
167466
167645
|
}
|
|
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
167646
|
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
167476
167647
|
if (maxCommits <= 0)
|
|
167477
167648
|
return 0;
|
|
167478
167649
|
const count = getCommitCount(db, projectPath);
|
|
167479
167650
|
if (count <= maxCommits)
|
|
167480
167651
|
return 0;
|
|
167481
|
-
|
|
167482
|
-
const
|
|
167652
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
167653
|
+
const after = getCommitCount(db, projectPath);
|
|
167654
|
+
const evicted = Math.max(0, count - after);
|
|
167483
167655
|
if (evicted > 0) {
|
|
167484
167656
|
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
167485
167657
|
}
|
|
@@ -167511,7 +167683,8 @@ async function indexCommitsForProject(db, projectPath, directory, options3) {
|
|
|
167511
167683
|
const sinceMs = latestIndexed !== null ? Math.max(latestIndexed - 60000, Date.now() - options3.sinceDays * MS_PER_DAY) : Date.now() - options3.sinceDays * MS_PER_DAY;
|
|
167512
167684
|
const commits = await readGitCommits(directory, {
|
|
167513
167685
|
sinceMs,
|
|
167514
|
-
maxCommits: options3.maxCommits
|
|
167686
|
+
maxCommits: options3.maxCommits,
|
|
167687
|
+
projectIdentity: projectPath
|
|
167515
167688
|
});
|
|
167516
167689
|
result.scanned = commits.length;
|
|
167517
167690
|
if (commits.length === 0) {
|
|
@@ -167718,6 +167891,62 @@ function searchGitCommitsSync(db, projectPath, query, options3) {
|
|
|
167718
167891
|
});
|
|
167719
167892
|
return results.slice(0, options3.limit);
|
|
167720
167893
|
}
|
|
167894
|
+
// ../plugin/src/features/magic-context/literal-probes.ts
|
|
167895
|
+
var MAX_PROBES = 5;
|
|
167896
|
+
var MIN_PROBE_LENGTH = 3;
|
|
167897
|
+
var SLASH_COMMAND_RE = /\/[a-z][a-z0-9]*(?:-[a-z0-9]+)+/gi;
|
|
167898
|
+
var KEBAB_SNAKE_RE = /[a-z][a-z0-9]*(?:[-_][a-z0-9]+)+/gi;
|
|
167899
|
+
var DOTTED_RE = /[a-z0-9][a-z0-9_-]*(?:\.[a-z0-9_-]+)+/gi;
|
|
167900
|
+
var CAMEL_RE = /\b[a-zA-Z][a-z0-9]*(?:[A-Z][a-z0-9]*)+\b/g;
|
|
167901
|
+
var SHA_RE = /\b[0-9a-f]{7,40}\b/gi;
|
|
167902
|
+
var ERROR_CODE_RE = /\b(?:TS\d{4,}|ERR_[A-Z][A-Z0-9_]*)\b/g;
|
|
167903
|
+
var QUOTED_RE = /["`]([^"`]{3,80})["`]/g;
|
|
167904
|
+
function looksLikeSha(token) {
|
|
167905
|
+
return /[0-9]/.test(token) && /^[0-9a-f]{7,40}$/i.test(token);
|
|
167906
|
+
}
|
|
167907
|
+
function extractLiteralProbes(query) {
|
|
167908
|
+
const trimmed = query.trim();
|
|
167909
|
+
if (trimmed.length === 0)
|
|
167910
|
+
return [];
|
|
167911
|
+
const ordered = [];
|
|
167912
|
+
const seen = new Set;
|
|
167913
|
+
const add = (raw) => {
|
|
167914
|
+
if (!raw)
|
|
167915
|
+
return;
|
|
167916
|
+
const probe = raw.trim();
|
|
167917
|
+
if (probe.length < MIN_PROBE_LENGTH)
|
|
167918
|
+
return;
|
|
167919
|
+
const key = probe.toLowerCase();
|
|
167920
|
+
if (seen.has(key))
|
|
167921
|
+
return;
|
|
167922
|
+
seen.add(key);
|
|
167923
|
+
ordered.push(probe);
|
|
167924
|
+
};
|
|
167925
|
+
for (const m of trimmed.matchAll(QUOTED_RE))
|
|
167926
|
+
add(m[1]);
|
|
167927
|
+
for (const m of trimmed.matchAll(SLASH_COMMAND_RE))
|
|
167928
|
+
add(m[0]);
|
|
167929
|
+
for (const m of trimmed.matchAll(ERROR_CODE_RE))
|
|
167930
|
+
add(m[0]);
|
|
167931
|
+
for (const m of trimmed.matchAll(DOTTED_RE))
|
|
167932
|
+
add(m[0]);
|
|
167933
|
+
for (const m of trimmed.matchAll(KEBAB_SNAKE_RE))
|
|
167934
|
+
add(m[0]);
|
|
167935
|
+
for (const m of trimmed.matchAll(CAMEL_RE))
|
|
167936
|
+
add(m[0]);
|
|
167937
|
+
for (const m of trimmed.matchAll(SHA_RE)) {
|
|
167938
|
+
if (looksLikeSha(m[0]))
|
|
167939
|
+
add(m[0]);
|
|
167940
|
+
}
|
|
167941
|
+
return ordered.slice(0, MAX_PROBES);
|
|
167942
|
+
}
|
|
167943
|
+
function containsProbeVerbatim(text, probes) {
|
|
167944
|
+
if (probes.length === 0)
|
|
167945
|
+
return false;
|
|
167946
|
+
const haystack = text.toLowerCase();
|
|
167947
|
+
return probes.some((probe) => haystack.includes(probe.toLowerCase()));
|
|
167948
|
+
}
|
|
167949
|
+
|
|
167721
167950
|
// ../plugin/src/features/magic-context/search.ts
|
|
167722
167951
|
var DEFAULT_UNIFIED_SEARCH_LIMIT = 10;
|
|
167723
167952
|
var FTS_SEMANTIC_CANDIDATE_LIMIT = 50;
|
|
@@ -167895,36 +168124,82 @@ function linearDecayScore(rank, total) {
|
|
|
167895
168124
|
return 0;
|
|
167896
168125
|
return Math.max(0, 1 - rank / total);
|
|
167897
168126
|
}
|
|
167898
|
-
function
|
|
167899
|
-
|
|
167900
|
-
if (sanitizedQuery.length === 0) {
|
|
168127
|
+
function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
|
|
168128
|
+
if (ftsQuery.length === 0)
|
|
167901
168129
|
return [];
|
|
167902
|
-
|
|
167903
|
-
const
|
|
167904
|
-
|
|
167905
|
-
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
167906
|
-
const filtered = rows.map((row) => {
|
|
168130
|
+
const rows = getMessageSearchStatement(db).all(sessionId, ftsQuery, fetchLimit).map((row) => row);
|
|
168131
|
+
const result = [];
|
|
168132
|
+
for (const row of rows) {
|
|
167907
168133
|
const messageOrdinal = getMessageOrdinal(row.messageOrdinal);
|
|
167908
168134
|
if (messageOrdinal === null || typeof row.messageId !== "string" || typeof row.role !== "string" || typeof row.content !== "string") {
|
|
167909
|
-
|
|
168135
|
+
continue;
|
|
167910
168136
|
}
|
|
167911
168137
|
if (cutoff !== null && messageOrdinal > cutoff) {
|
|
167912
|
-
|
|
168138
|
+
continue;
|
|
167913
168139
|
}
|
|
167914
|
-
|
|
168140
|
+
result.push({
|
|
167915
168141
|
messageOrdinal,
|
|
167916
168142
|
messageId: row.messageId,
|
|
167917
168143
|
role: row.role,
|
|
167918
168144
|
content: row.content
|
|
167919
|
-
};
|
|
167920
|
-
}
|
|
167921
|
-
return
|
|
168145
|
+
});
|
|
168146
|
+
}
|
|
168147
|
+
return result;
|
|
168148
|
+
}
|
|
168149
|
+
var RRF_K = 60;
|
|
168150
|
+
var VERBATIM_PROBE_BONUS = 0.5;
|
|
168151
|
+
function searchMessages(args) {
|
|
168152
|
+
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
168153
|
+
const fetchLimit = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.limit * 3 : args.limit;
|
|
168154
|
+
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
168155
|
+
const probes = args.probes ?? [];
|
|
168156
|
+
if (probes.length === 0) {
|
|
168157
|
+
const filtered = runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff).slice(0, args.limit);
|
|
168158
|
+
return filtered.map((row, rank) => ({
|
|
168159
|
+
source: "message",
|
|
168160
|
+
content: previewText(row.content),
|
|
168161
|
+
score: linearDecayScore(rank, filtered.length),
|
|
168162
|
+
messageOrdinal: row.messageOrdinal,
|
|
168163
|
+
messageId: row.messageId,
|
|
168164
|
+
role: row.role
|
|
168165
|
+
}));
|
|
168166
|
+
}
|
|
168167
|
+
const queryLists = [];
|
|
168168
|
+
if (baseQuery.length > 0) {
|
|
168169
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff));
|
|
168170
|
+
}
|
|
168171
|
+
for (const probe of probes) {
|
|
168172
|
+
const probeQuery = sanitizeFtsQuery(probe);
|
|
168173
|
+
if (probeQuery.length === 0)
|
|
168174
|
+
continue;
|
|
168175
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, probeQuery, fetchLimit, cutoff));
|
|
168176
|
+
}
|
|
168177
|
+
const fused = new Map;
|
|
168178
|
+
for (const list of queryLists) {
|
|
168179
|
+
list.forEach((row, rank) => {
|
|
168180
|
+
const rrf = 1 / (RRF_K + rank);
|
|
168181
|
+
const existing = fused.get(row.messageId);
|
|
168182
|
+
if (existing) {
|
|
168183
|
+
existing.score += rrf;
|
|
168184
|
+
} else {
|
|
168185
|
+
fused.set(row.messageId, { row, score: rrf });
|
|
168186
|
+
}
|
|
168187
|
+
});
|
|
168188
|
+
}
|
|
168189
|
+
for (const entry of fused.values()) {
|
|
168190
|
+
if (containsProbeVerbatim(entry.row.content, probes)) {
|
|
168191
|
+
entry.score += VERBATIM_PROBE_BONUS;
|
|
168192
|
+
}
|
|
168193
|
+
}
|
|
168194
|
+
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);
|
|
168195
|
+
const maxScore = ranked.length > 0 ? ranked[0].score : 1;
|
|
168196
|
+
return ranked.map((entry) => ({
|
|
167922
168197
|
source: "message",
|
|
167923
|
-
content: previewText(row.content),
|
|
167924
|
-
score:
|
|
167925
|
-
messageOrdinal: row.messageOrdinal,
|
|
167926
|
-
messageId: row.messageId,
|
|
167927
|
-
role: row.role
|
|
168198
|
+
content: previewText(entry.row.content),
|
|
168199
|
+
score: maxScore > 0 ? entry.score / maxScore : 0,
|
|
168200
|
+
messageOrdinal: entry.row.messageOrdinal,
|
|
168201
|
+
messageId: entry.row.messageId,
|
|
168202
|
+
role: entry.row.role
|
|
167928
168203
|
}));
|
|
167929
168204
|
}
|
|
167930
168205
|
function getSourceBoost(result) {
|
|
@@ -168008,12 +168283,14 @@ async function unifiedSearch(db, sessionId, projectPath, query, options3 = {}) {
|
|
|
168008
168283
|
return null;
|
|
168009
168284
|
}) : Promise.resolve(null);
|
|
168010
168285
|
await Promise.resolve();
|
|
168286
|
+
const messageProbes = options3.explicitSearch ? extractLiteralProbes(trimmedQuery) : [];
|
|
168011
168287
|
const messageResults = runMessages ? searchMessages({
|
|
168012
168288
|
db,
|
|
168013
168289
|
sessionId,
|
|
168014
168290
|
query: trimmedQuery,
|
|
168015
168291
|
limit: tierLimit,
|
|
168016
|
-
maxOrdinal: options3.maxMessageOrdinal
|
|
168292
|
+
maxOrdinal: options3.maxMessageOrdinal,
|
|
168293
|
+
probes: messageProbes
|
|
168017
168294
|
}) : [];
|
|
168018
168295
|
const queryEmbedding = await queryEmbeddingPromise;
|
|
168019
168296
|
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
@@ -168784,7 +169061,8 @@ function createCtxSearchTool(deps) {
|
|
|
168784
169061
|
maxMessageOrdinal: lastCompartmentEnd >= 0 ? lastCompartmentEnd : undefined,
|
|
168785
169062
|
gitCommitsEnabled,
|
|
168786
169063
|
sources: params.sources,
|
|
168787
|
-
visibleMemoryIds
|
|
169064
|
+
visibleMemoryIds,
|
|
169065
|
+
explicitSearch: true
|
|
168788
169066
|
});
|
|
168789
169067
|
return {
|
|
168790
169068
|
content: [{ type: "text", text: formatSearchResults(query, results) }],
|