@wolfx/pi-magic-context 0.22.1-patch.0 → 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 +574 -431
- 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,
|
|
@@ -157409,46 +157449,6 @@ function stripJsonComments(content) {
|
|
|
157409
157449
|
}
|
|
157410
157450
|
return result;
|
|
157411
157451
|
}
|
|
157412
|
-
function stripTrailingCommas(content) {
|
|
157413
|
-
let result = "";
|
|
157414
|
-
let inString = false;
|
|
157415
|
-
let escaped = false;
|
|
157416
|
-
for (let index = 0;index < content.length; index += 1) {
|
|
157417
|
-
const char = content[index];
|
|
157418
|
-
if (inString) {
|
|
157419
|
-
result += char;
|
|
157420
|
-
if (escaped) {
|
|
157421
|
-
escaped = false;
|
|
157422
|
-
} else if (char === "\\") {
|
|
157423
|
-
escaped = true;
|
|
157424
|
-
} else if (char === '"') {
|
|
157425
|
-
inString = false;
|
|
157426
|
-
}
|
|
157427
|
-
continue;
|
|
157428
|
-
}
|
|
157429
|
-
if (char === '"') {
|
|
157430
|
-
inString = true;
|
|
157431
|
-
result += char;
|
|
157432
|
-
continue;
|
|
157433
|
-
}
|
|
157434
|
-
if (char === ",") {
|
|
157435
|
-
let lookahead = index + 1;
|
|
157436
|
-
while (lookahead < content.length && /\s/.test(content[lookahead] ?? "")) {
|
|
157437
|
-
lookahead += 1;
|
|
157438
|
-
}
|
|
157439
|
-
const next = content[lookahead];
|
|
157440
|
-
if (next === "}" || next === "]") {
|
|
157441
|
-
continue;
|
|
157442
|
-
}
|
|
157443
|
-
}
|
|
157444
|
-
result += char;
|
|
157445
|
-
}
|
|
157446
|
-
return result;
|
|
157447
|
-
}
|
|
157448
|
-
function parseJsonc(content) {
|
|
157449
|
-
const normalized = stripTrailingCommas(stripJsonComments(content));
|
|
157450
|
-
return JSON.parse(normalized);
|
|
157451
|
-
}
|
|
157452
157452
|
|
|
157453
157453
|
// ../plugin/src/config/variable.ts
|
|
157454
157454
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
@@ -158448,7 +158448,7 @@ function getDistinctStoredModelIds(db, projectPath) {
|
|
|
158448
158448
|
}
|
|
158449
158449
|
|
|
158450
158450
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
158451
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
158451
|
+
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
158452
158452
|
init_logger();
|
|
158453
158453
|
|
|
158454
158454
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
@@ -158552,6 +158552,125 @@ function getDistinctCommitEmbeddingModelIds(db, projectPath) {
|
|
|
158552
158552
|
return new Set(rows.map((row) => typeof row.modelId === "string" ? row.modelId : null));
|
|
158553
158553
|
}
|
|
158554
158554
|
|
|
158555
|
+
// ../plugin/src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
158556
|
+
var GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
158557
|
+
var GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
158558
|
+
var GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
|
|
158559
|
+
function runImmediate(db, body) {
|
|
158560
|
+
db.exec("BEGIN IMMEDIATE");
|
|
158561
|
+
let committed = false;
|
|
158562
|
+
try {
|
|
158563
|
+
const result = body();
|
|
158564
|
+
db.exec("COMMIT");
|
|
158565
|
+
committed = true;
|
|
158566
|
+
return result;
|
|
158567
|
+
} finally {
|
|
158568
|
+
if (!committed) {
|
|
158569
|
+
try {
|
|
158570
|
+
db.exec("ROLLBACK");
|
|
158571
|
+
} catch {}
|
|
158572
|
+
}
|
|
158573
|
+
}
|
|
158574
|
+
}
|
|
158575
|
+
function rowToState(row) {
|
|
158576
|
+
return {
|
|
158577
|
+
projectPath: row.project_path,
|
|
158578
|
+
leaseHolder: row.lease_holder,
|
|
158579
|
+
leaseExpiresAt: row.lease_expires_at,
|
|
158580
|
+
lastSweptAt: row.last_swept_at
|
|
158581
|
+
};
|
|
158582
|
+
}
|
|
158583
|
+
function getGitSweepCoordinatorState(db, projectPath) {
|
|
158584
|
+
const row = db.prepare(`SELECT project_path, lease_holder, lease_expires_at, last_swept_at
|
|
158585
|
+
FROM git_sweep_coordinator
|
|
158586
|
+
WHERE project_path = ?`).get(projectPath);
|
|
158587
|
+
return row ? rowToState(row) : null;
|
|
158588
|
+
}
|
|
158589
|
+
function acquireGitSweepLease(db, projectPath, holderId, options = {}) {
|
|
158590
|
+
const cooldownMs = options.cooldownMs ?? GIT_SWEEP_COOLDOWN_MS;
|
|
158591
|
+
const leaseTtlMs = options.leaseTtlMs ?? GIT_SWEEP_LEASE_TTL_MS;
|
|
158592
|
+
return runImmediate(db, () => {
|
|
158593
|
+
const now = Date.now();
|
|
158594
|
+
const row = getGitSweepCoordinatorState(db, projectPath);
|
|
158595
|
+
if (row?.leaseHolder && row.leaseExpiresAt !== null && row.leaseExpiresAt > now) {
|
|
158596
|
+
return {
|
|
158597
|
+
acquired: false,
|
|
158598
|
+
projectPath,
|
|
158599
|
+
reason: "lease_active",
|
|
158600
|
+
leaseHolder: row.leaseHolder,
|
|
158601
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
158602
|
+
lastSweptAt: row.lastSweptAt,
|
|
158603
|
+
nextAllowedAt: null
|
|
158604
|
+
};
|
|
158605
|
+
}
|
|
158606
|
+
if (!options.ignoreCooldown && row?.lastSweptAt !== null && row?.lastSweptAt !== undefined) {
|
|
158607
|
+
const nextAllowedAt = row.lastSweptAt + cooldownMs;
|
|
158608
|
+
if (nextAllowedAt > now) {
|
|
158609
|
+
return {
|
|
158610
|
+
acquired: false,
|
|
158611
|
+
projectPath,
|
|
158612
|
+
reason: "cooldown_active",
|
|
158613
|
+
leaseHolder: row.leaseHolder,
|
|
158614
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
158615
|
+
lastSweptAt: row.lastSweptAt,
|
|
158616
|
+
nextAllowedAt
|
|
158617
|
+
};
|
|
158618
|
+
}
|
|
158619
|
+
}
|
|
158620
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
158621
|
+
db.prepare(`INSERT INTO git_sweep_coordinator (
|
|
158622
|
+
project_path,
|
|
158623
|
+
lease_holder,
|
|
158624
|
+
lease_expires_at,
|
|
158625
|
+
last_swept_at
|
|
158626
|
+
) VALUES (?, ?, ?, NULL)
|
|
158627
|
+
ON CONFLICT(project_path) DO UPDATE SET
|
|
158628
|
+
lease_holder = excluded.lease_holder,
|
|
158629
|
+
lease_expires_at = excluded.lease_expires_at`).run(projectPath, holderId, leaseExpiresAt);
|
|
158630
|
+
return {
|
|
158631
|
+
acquired: true,
|
|
158632
|
+
projectPath,
|
|
158633
|
+
holderId,
|
|
158634
|
+
acquiredAt: now,
|
|
158635
|
+
leaseExpiresAt
|
|
158636
|
+
};
|
|
158637
|
+
});
|
|
158638
|
+
}
|
|
158639
|
+
function renewGitSweepLease(db, projectPath, holderId, leaseTtlMs = GIT_SWEEP_LEASE_TTL_MS) {
|
|
158640
|
+
return runImmediate(db, () => {
|
|
158641
|
+
const now = Date.now();
|
|
158642
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
158643
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
158644
|
+
SET lease_expires_at = ?
|
|
158645
|
+
WHERE project_path = ?
|
|
158646
|
+
AND lease_holder = ?
|
|
158647
|
+
AND lease_expires_at > ?`).run(leaseExpiresAt, projectPath, holderId, now);
|
|
158648
|
+
return result.changes === 1;
|
|
158649
|
+
});
|
|
158650
|
+
}
|
|
158651
|
+
function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
|
|
158652
|
+
return runImmediate(db, () => {
|
|
158653
|
+
const now = Date.now();
|
|
158654
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
158655
|
+
SET lease_holder = NULL,
|
|
158656
|
+
lease_expires_at = NULL,
|
|
158657
|
+
last_swept_at = ?
|
|
158658
|
+
WHERE project_path = ?
|
|
158659
|
+
AND lease_holder = ?
|
|
158660
|
+
AND lease_expires_at > ?`).run(now, projectPath, holderId, now);
|
|
158661
|
+
return result.changes === 1;
|
|
158662
|
+
});
|
|
158663
|
+
}
|
|
158664
|
+
function releaseGitSweepLease(db, projectPath, holderId) {
|
|
158665
|
+
runImmediate(db, () => {
|
|
158666
|
+
db.prepare(`UPDATE git_sweep_coordinator
|
|
158667
|
+
SET lease_holder = NULL,
|
|
158668
|
+
lease_expires_at = NULL
|
|
158669
|
+
WHERE project_path = ?
|
|
158670
|
+
AND lease_holder = ?`).run(projectPath, holderId);
|
|
158671
|
+
});
|
|
158672
|
+
}
|
|
158673
|
+
|
|
158555
158674
|
// ../plugin/src/features/magic-context/memory/embedding-cache.ts
|
|
158556
158675
|
var DEFAULT_EMBEDDING_CACHE_TTL_MS = 60000;
|
|
158557
158676
|
var projectEmbeddingCache = new Map;
|
|
@@ -159723,14 +159842,48 @@ function readRawSessionMessagesFromDb(db, sessionId) {
|
|
|
159723
159842
|
var encoder = new TextEncoder;
|
|
159724
159843
|
var TAG_PREFIX_REGEX = /^(?:§\d+§\s*)+/;
|
|
159725
159844
|
var MALFORMED_TAG_PREFIX_REGEX = /^(?:§\d+">§(?:\d+§)?\s*)+/;
|
|
159845
|
+
var COMPLETE_TAG_PAIR_GLOBAL_REGEX = /\u00a7\d+\u00a7/g;
|
|
159846
|
+
var MALFORMED_TAG_GLOBAL_REGEX = /\u00a7\d+">(?:\u00a7(?:\d+\u00a7)?)?/g;
|
|
159847
|
+
var STRAY_SECTION_CHAR_REGEX = /\u00a7/g;
|
|
159848
|
+
function stripWellFormedLeadingTagPrefix(value) {
|
|
159849
|
+
return value.replace(/^(\u00a7\d+\u00a7\s*)+/, "");
|
|
159850
|
+
}
|
|
159851
|
+
function stripCompleteTagPairsGlobally(value) {
|
|
159852
|
+
return value.replace(COMPLETE_TAG_PAIR_GLOBAL_REGEX, "");
|
|
159853
|
+
}
|
|
159854
|
+
function stripMalformedTagNotationGlobally(value) {
|
|
159855
|
+
return value.replace(MALFORMED_TAG_GLOBAL_REGEX, "");
|
|
159856
|
+
}
|
|
159857
|
+
function stripTagSectionCharacters(value) {
|
|
159858
|
+
return value.replace(STRAY_SECTION_CHAR_REGEX, "");
|
|
159859
|
+
}
|
|
159860
|
+
function stripPersistedAssistantText(value) {
|
|
159861
|
+
let text = stripWellFormedLeadingTagPrefix(value);
|
|
159862
|
+
text = stripCompleteTagPairsGlobally(text);
|
|
159863
|
+
text = stripMalformedTagNotationGlobally(text);
|
|
159864
|
+
text = stripTagSectionCharacters(text);
|
|
159865
|
+
return text.trim();
|
|
159866
|
+
}
|
|
159726
159867
|
function byteSize(value) {
|
|
159727
159868
|
return encoder.encode(value).length;
|
|
159728
159869
|
}
|
|
159729
159870
|
function stripTagPrefix(value) {
|
|
159730
|
-
let stripped = value
|
|
159731
|
-
|
|
159871
|
+
let stripped = value;
|
|
159872
|
+
for (let pass = 0;pass < 8; pass++) {
|
|
159873
|
+
const prev = stripped;
|
|
159874
|
+
stripped = stripped.replace(MALFORMED_TAG_PREFIX_REGEX, "");
|
|
159875
|
+
stripped = stripped.replace(TAG_PREFIX_REGEX, "");
|
|
159876
|
+
if (stripped === prev)
|
|
159877
|
+
break;
|
|
159878
|
+
}
|
|
159732
159879
|
return stripped;
|
|
159733
159880
|
}
|
|
159881
|
+
function peelLeadingMcTagNotation(value) {
|
|
159882
|
+
const body = stripTagPrefix(value);
|
|
159883
|
+
if (body === value)
|
|
159884
|
+
return { tagPrefix: "", body };
|
|
159885
|
+
return { tagPrefix: value.slice(0, value.length - body.length), body };
|
|
159886
|
+
}
|
|
159734
159887
|
function prependTag(tagId, value) {
|
|
159735
159888
|
const stripped = stripTagPrefix(value);
|
|
159736
159889
|
return `§${tagId}§ ${stripped}`;
|
|
@@ -159772,7 +159925,9 @@ function hasMeaningfulPart(part) {
|
|
|
159772
159925
|
return false;
|
|
159773
159926
|
const type = part.type;
|
|
159774
159927
|
if (type === "text") {
|
|
159775
|
-
|
|
159928
|
+
if (typeof part.text !== "string")
|
|
159929
|
+
return false;
|
|
159930
|
+
return stripTagPrefix(part.text).trim().length > 0;
|
|
159776
159931
|
}
|
|
159777
159932
|
if (typeof type !== "string")
|
|
159778
159933
|
return false;
|
|
@@ -166047,7 +166202,8 @@ function toNote(row) {
|
|
|
166047
166202
|
updatedAt: row.updated_at,
|
|
166048
166203
|
lastCheckedAt: toNullableNumber(row.last_checked_at),
|
|
166049
166204
|
readyAt: toNullableNumber(row.ready_at),
|
|
166050
|
-
readyReason: toNullableString(row.ready_reason)
|
|
166205
|
+
readyReason: toNullableString(row.ready_reason),
|
|
166206
|
+
anchorOrdinal: toNullableNumber(row.anchor_ordinal)
|
|
166051
166207
|
};
|
|
166052
166208
|
}
|
|
166053
166209
|
function getNoteById(db, noteId) {
|
|
@@ -166099,7 +166255,7 @@ function getNotes(db, options3 = {}) {
|
|
|
166099
166255
|
}
|
|
166100
166256
|
function addNote(db, type, options3) {
|
|
166101
166257
|
const now = Date.now();
|
|
166102
|
-
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());
|
|
166258
|
+
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);
|
|
166103
166259
|
if (!isNoteRow(result)) {
|
|
166104
166260
|
throw new Error("[notes] failed to insert note");
|
|
166105
166261
|
}
|
|
@@ -166953,15 +167109,26 @@ function err3(text) {
|
|
|
166953
167109
|
isError: true
|
|
166954
167110
|
};
|
|
166955
167111
|
}
|
|
167112
|
+
function captureAnchorOrdinal(db, sessionId) {
|
|
167113
|
+
try {
|
|
167114
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
167115
|
+
return ordinal > 0 ? ordinal : null;
|
|
167116
|
+
} catch {
|
|
167117
|
+
return null;
|
|
167118
|
+
}
|
|
167119
|
+
}
|
|
167120
|
+
function anchorSuffix(note) {
|
|
167121
|
+
return note.anchorOrdinal !== null ? ` ↳ @msg ${note.anchorOrdinal}` : "";
|
|
167122
|
+
}
|
|
166956
167123
|
function formatNoteLine(note) {
|
|
166957
167124
|
if (note.type === "smart") {
|
|
166958
167125
|
const conditionLine = note.status === "ready" ? note.readyReason ?? note.surfaceCondition ?? "Condition satisfied" : note.surfaceCondition ?? "No condition recorded";
|
|
166959
167126
|
const statusSuffix2 = note.status === "active" ? "" : ` (${note.status})`;
|
|
166960
|
-
return `- **#${note.id}**${statusSuffix2}: ${note.content}
|
|
167127
|
+
return `- **#${note.id}**${statusSuffix2}: ${note.content}${anchorSuffix(note)}
|
|
166961
167128
|
*Condition*: ${conditionLine}`;
|
|
166962
167129
|
}
|
|
166963
167130
|
const statusSuffix = note.status === "active" ? "" : ` (${note.status})`;
|
|
166964
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}`;
|
|
167131
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}`;
|
|
166965
167132
|
}
|
|
166966
167133
|
var DISMISS_FOOTER = `
|
|
166967
167134
|
|
|
@@ -166983,6 +167150,7 @@ function createCtxNoteTool(deps) {
|
|
|
166983
167150
|
const content = params.content?.trim();
|
|
166984
167151
|
if (!content)
|
|
166985
167152
|
return err3("Error: 'content' is required when action is 'write'.");
|
|
167153
|
+
const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
|
|
166986
167154
|
const surfaceCondition = params.surface_condition?.trim();
|
|
166987
167155
|
if (surfaceCondition) {
|
|
166988
167156
|
if (deps.dreamerEnabled !== true) {
|
|
@@ -166995,13 +167163,18 @@ function createCtxNoteTool(deps) {
|
|
|
166995
167163
|
const note2 = addNote(deps.db, "smart", {
|
|
166996
167164
|
content,
|
|
166997
167165
|
projectPath: projectIdentity,
|
|
166998
|
-
surfaceCondition
|
|
167166
|
+
surfaceCondition,
|
|
167167
|
+
anchorOrdinal
|
|
166999
167168
|
});
|
|
167000
167169
|
return ok3(`Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
|
|
167001
167170
|
- Content: ${content}
|
|
167002
167171
|
- Condition: ${surfaceCondition}`);
|
|
167003
167172
|
}
|
|
167004
|
-
const note = addNote(deps.db, "session", {
|
|
167173
|
+
const note = addNote(deps.db, "session", {
|
|
167174
|
+
sessionId,
|
|
167175
|
+
content,
|
|
167176
|
+
anchorOrdinal
|
|
167177
|
+
});
|
|
167005
167178
|
return ok3(`Saved session note #${note.id}.`);
|
|
167006
167179
|
}
|
|
167007
167180
|
if (action2 === "dismiss") {
|
|
@@ -167064,9 +167237,13 @@ function createCtxNoteTool(deps) {
|
|
|
167064
167237
|
|
|
167065
167238
|
No notes for the current filter.`);
|
|
167066
167239
|
}
|
|
167067
|
-
|
|
167240
|
+
const body = sections.join(`
|
|
167068
167241
|
|
|
167069
|
-
`)
|
|
167242
|
+
`);
|
|
167243
|
+
const anchorHint = body.includes("↳ @msg ") ? `
|
|
167244
|
+
|
|
167245
|
+
↳ @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).` : "";
|
|
167246
|
+
return ok3(`${body}${anchorHint}${DISMISS_FOOTER}`);
|
|
167070
167247
|
}
|
|
167071
167248
|
};
|
|
167072
167249
|
}
|
|
@@ -167302,6 +167479,7 @@ async function readGitCommits(directory, options3 = {}) {
|
|
|
167302
167479
|
if (revision.startsWith("-")) {
|
|
167303
167480
|
throw new Error(`readGitCommits: refusing revision that looks like an option: "${revision}"`);
|
|
167304
167481
|
}
|
|
167482
|
+
const projectLabel = options3.projectIdentity ?? "<project>";
|
|
167305
167483
|
const args = [
|
|
167306
167484
|
"log",
|
|
167307
167485
|
revision,
|
|
@@ -167324,11 +167502,11 @@ async function readGitCommits(directory, options3 = {}) {
|
|
|
167324
167502
|
stdout = result.stdout;
|
|
167325
167503
|
} catch (error51) {
|
|
167326
167504
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
167327
|
-
log(`[git-commits] readGitCommits failed
|
|
167505
|
+
log(`[git-commits] readGitCommits failed for ${projectLabel}: ${message.slice(0, 500)}`);
|
|
167328
167506
|
return [];
|
|
167329
167507
|
}
|
|
167330
167508
|
if (stdout.trim().length === 0) {
|
|
167331
|
-
log(`[git-commits] readGitCommits returned empty stdout
|
|
167509
|
+
log(`[git-commits] readGitCommits returned empty stdout for ${projectLabel} (sinceMs=${options3.sinceMs ?? "none"} args=${args.slice(0, 4).join(" ")})`);
|
|
167332
167510
|
}
|
|
167333
167511
|
return parseGitLogOutput(stdout);
|
|
167334
167512
|
}
|
|
@@ -167381,6 +167559,7 @@ var insertStatements = new WeakMap;
|
|
|
167381
167559
|
var existingShasStatements = new WeakMap;
|
|
167382
167560
|
var projectCountStatements = new WeakMap;
|
|
167383
167561
|
var evictStatements = new WeakMap;
|
|
167562
|
+
var evictOverflowStatements = new WeakMap;
|
|
167384
167563
|
var latestCommitTimeStatements = new WeakMap;
|
|
167385
167564
|
function getInsertStatement(db) {
|
|
167386
167565
|
let stmt = insertStatements.get(db);
|
|
@@ -167423,17 +167602,17 @@ function getLatestCommitTimeStatement(db) {
|
|
|
167423
167602
|
}
|
|
167424
167603
|
return stmt;
|
|
167425
167604
|
}
|
|
167426
|
-
function
|
|
167427
|
-
let stmt =
|
|
167605
|
+
function getEvictOverflowStatement(db) {
|
|
167606
|
+
let stmt = evictOverflowStatements.get(db);
|
|
167428
167607
|
if (!stmt) {
|
|
167429
167608
|
stmt = db.prepare(`DELETE FROM git_commits
|
|
167430
|
-
WHERE
|
|
167431
|
-
SELECT
|
|
167609
|
+
WHERE rowid IN (
|
|
167610
|
+
SELECT rowid FROM git_commits
|
|
167432
167611
|
WHERE project_path = ?
|
|
167433
|
-
ORDER BY committed_at
|
|
167434
|
-
LIMIT ?
|
|
167612
|
+
ORDER BY committed_at DESC, sha DESC
|
|
167613
|
+
LIMIT -1 OFFSET ?
|
|
167435
167614
|
)`);
|
|
167436
|
-
|
|
167615
|
+
evictOverflowStatements.set(db, stmt);
|
|
167437
167616
|
}
|
|
167438
167617
|
return stmt;
|
|
167439
167618
|
}
|
|
@@ -167471,22 +167650,15 @@ function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
|
167471
167650
|
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
167472
167651
|
return row?.latest ?? null;
|
|
167473
167652
|
}
|
|
167474
|
-
function evictOldestCommits(db, projectPath, excess) {
|
|
167475
|
-
if (excess <= 0)
|
|
167476
|
-
return 0;
|
|
167477
|
-
const before = getCommitCount(db, projectPath);
|
|
167478
|
-
getEvictStatement(db).run(projectPath, excess);
|
|
167479
|
-
const after = getCommitCount(db, projectPath);
|
|
167480
|
-
return Math.max(0, before - after);
|
|
167481
|
-
}
|
|
167482
167653
|
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
167483
167654
|
if (maxCommits <= 0)
|
|
167484
167655
|
return 0;
|
|
167485
167656
|
const count = getCommitCount(db, projectPath);
|
|
167486
167657
|
if (count <= maxCommits)
|
|
167487
167658
|
return 0;
|
|
167488
|
-
|
|
167489
|
-
const
|
|
167659
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
167660
|
+
const after = getCommitCount(db, projectPath);
|
|
167661
|
+
const evicted = Math.max(0, count - after);
|
|
167490
167662
|
if (evicted > 0) {
|
|
167491
167663
|
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
167492
167664
|
}
|
|
@@ -167518,7 +167690,8 @@ async function indexCommitsForProject(db, projectPath, directory, options3) {
|
|
|
167518
167690
|
const sinceMs = latestIndexed !== null ? Math.max(latestIndexed - 60000, Date.now() - options3.sinceDays * MS_PER_DAY) : Date.now() - options3.sinceDays * MS_PER_DAY;
|
|
167519
167691
|
const commits = await readGitCommits(directory, {
|
|
167520
167692
|
sinceMs,
|
|
167521
|
-
maxCommits: options3.maxCommits
|
|
167693
|
+
maxCommits: options3.maxCommits,
|
|
167694
|
+
projectIdentity: projectPath
|
|
167522
167695
|
});
|
|
167523
167696
|
result.scanned = commits.length;
|
|
167524
167697
|
if (commits.length === 0) {
|
|
@@ -167725,6 +167898,62 @@ function searchGitCommitsSync(db, projectPath, query, options3) {
|
|
|
167725
167898
|
});
|
|
167726
167899
|
return results.slice(0, options3.limit);
|
|
167727
167900
|
}
|
|
167901
|
+
// ../plugin/src/features/magic-context/literal-probes.ts
|
|
167902
|
+
var MAX_PROBES = 5;
|
|
167903
|
+
var MIN_PROBE_LENGTH = 3;
|
|
167904
|
+
var SLASH_COMMAND_RE = /\/[a-z][a-z0-9]*(?:-[a-z0-9]+)+/gi;
|
|
167905
|
+
var KEBAB_SNAKE_RE = /[a-z][a-z0-9]*(?:[-_][a-z0-9]+)+/gi;
|
|
167906
|
+
var DOTTED_RE = /[a-z0-9][a-z0-9_-]*(?:\.[a-z0-9_-]+)+/gi;
|
|
167907
|
+
var CAMEL_RE = /\b[a-zA-Z][a-z0-9]*(?:[A-Z][a-z0-9]*)+\b/g;
|
|
167908
|
+
var SHA_RE = /\b[0-9a-f]{7,40}\b/gi;
|
|
167909
|
+
var ERROR_CODE_RE = /\b(?:TS\d{4,}|ERR_[A-Z][A-Z0-9_]*)\b/g;
|
|
167910
|
+
var QUOTED_RE = /["`]([^"`]{3,80})["`]/g;
|
|
167911
|
+
function looksLikeSha(token) {
|
|
167912
|
+
return /[0-9]/.test(token) && /^[0-9a-f]{7,40}$/i.test(token);
|
|
167913
|
+
}
|
|
167914
|
+
function extractLiteralProbes(query) {
|
|
167915
|
+
const trimmed = query.trim();
|
|
167916
|
+
if (trimmed.length === 0)
|
|
167917
|
+
return [];
|
|
167918
|
+
const ordered = [];
|
|
167919
|
+
const seen = new Set;
|
|
167920
|
+
const add = (raw) => {
|
|
167921
|
+
if (!raw)
|
|
167922
|
+
return;
|
|
167923
|
+
const probe = raw.trim();
|
|
167924
|
+
if (probe.length < MIN_PROBE_LENGTH)
|
|
167925
|
+
return;
|
|
167926
|
+
const key = probe.toLowerCase();
|
|
167927
|
+
if (seen.has(key))
|
|
167928
|
+
return;
|
|
167929
|
+
seen.add(key);
|
|
167930
|
+
ordered.push(probe);
|
|
167931
|
+
};
|
|
167932
|
+
for (const m of trimmed.matchAll(QUOTED_RE))
|
|
167933
|
+
add(m[1]);
|
|
167934
|
+
for (const m of trimmed.matchAll(SLASH_COMMAND_RE))
|
|
167935
|
+
add(m[0]);
|
|
167936
|
+
for (const m of trimmed.matchAll(ERROR_CODE_RE))
|
|
167937
|
+
add(m[0]);
|
|
167938
|
+
for (const m of trimmed.matchAll(DOTTED_RE))
|
|
167939
|
+
add(m[0]);
|
|
167940
|
+
for (const m of trimmed.matchAll(KEBAB_SNAKE_RE))
|
|
167941
|
+
add(m[0]);
|
|
167942
|
+
for (const m of trimmed.matchAll(CAMEL_RE))
|
|
167943
|
+
add(m[0]);
|
|
167944
|
+
for (const m of trimmed.matchAll(SHA_RE)) {
|
|
167945
|
+
if (looksLikeSha(m[0]))
|
|
167946
|
+
add(m[0]);
|
|
167947
|
+
}
|
|
167948
|
+
return ordered.slice(0, MAX_PROBES);
|
|
167949
|
+
}
|
|
167950
|
+
function containsProbeVerbatim(text, probes) {
|
|
167951
|
+
if (probes.length === 0)
|
|
167952
|
+
return false;
|
|
167953
|
+
const haystack = text.toLowerCase();
|
|
167954
|
+
return probes.some((probe) => haystack.includes(probe.toLowerCase()));
|
|
167955
|
+
}
|
|
167956
|
+
|
|
167728
167957
|
// ../plugin/src/features/magic-context/search.ts
|
|
167729
167958
|
var DEFAULT_UNIFIED_SEARCH_LIMIT = 10;
|
|
167730
167959
|
var FTS_SEMANTIC_CANDIDATE_LIMIT = 50;
|
|
@@ -167902,36 +168131,82 @@ function linearDecayScore(rank, total) {
|
|
|
167902
168131
|
return 0;
|
|
167903
168132
|
return Math.max(0, 1 - rank / total);
|
|
167904
168133
|
}
|
|
167905
|
-
function
|
|
167906
|
-
|
|
167907
|
-
if (sanitizedQuery.length === 0) {
|
|
168134
|
+
function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
|
|
168135
|
+
if (ftsQuery.length === 0)
|
|
167908
168136
|
return [];
|
|
167909
|
-
|
|
167910
|
-
const
|
|
167911
|
-
|
|
167912
|
-
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
167913
|
-
const filtered = rows.map((row) => {
|
|
168137
|
+
const rows = getMessageSearchStatement(db).all(sessionId, ftsQuery, fetchLimit).map((row) => row);
|
|
168138
|
+
const result = [];
|
|
168139
|
+
for (const row of rows) {
|
|
167914
168140
|
const messageOrdinal = getMessageOrdinal(row.messageOrdinal);
|
|
167915
168141
|
if (messageOrdinal === null || typeof row.messageId !== "string" || typeof row.role !== "string" || typeof row.content !== "string") {
|
|
167916
|
-
|
|
168142
|
+
continue;
|
|
167917
168143
|
}
|
|
167918
168144
|
if (cutoff !== null && messageOrdinal > cutoff) {
|
|
167919
|
-
|
|
168145
|
+
continue;
|
|
167920
168146
|
}
|
|
167921
|
-
|
|
168147
|
+
result.push({
|
|
167922
168148
|
messageOrdinal,
|
|
167923
168149
|
messageId: row.messageId,
|
|
167924
168150
|
role: row.role,
|
|
167925
168151
|
content: row.content
|
|
167926
|
-
};
|
|
167927
|
-
}
|
|
167928
|
-
return
|
|
168152
|
+
});
|
|
168153
|
+
}
|
|
168154
|
+
return result;
|
|
168155
|
+
}
|
|
168156
|
+
var RRF_K = 60;
|
|
168157
|
+
var VERBATIM_PROBE_BONUS = 0.5;
|
|
168158
|
+
function searchMessages(args) {
|
|
168159
|
+
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
168160
|
+
const fetchLimit = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.limit * 3 : args.limit;
|
|
168161
|
+
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
168162
|
+
const probes = args.probes ?? [];
|
|
168163
|
+
if (probes.length === 0) {
|
|
168164
|
+
const filtered = runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff).slice(0, args.limit);
|
|
168165
|
+
return filtered.map((row, rank) => ({
|
|
168166
|
+
source: "message",
|
|
168167
|
+
content: previewText(row.content),
|
|
168168
|
+
score: linearDecayScore(rank, filtered.length),
|
|
168169
|
+
messageOrdinal: row.messageOrdinal,
|
|
168170
|
+
messageId: row.messageId,
|
|
168171
|
+
role: row.role
|
|
168172
|
+
}));
|
|
168173
|
+
}
|
|
168174
|
+
const queryLists = [];
|
|
168175
|
+
if (baseQuery.length > 0) {
|
|
168176
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff));
|
|
168177
|
+
}
|
|
168178
|
+
for (const probe of probes) {
|
|
168179
|
+
const probeQuery = sanitizeFtsQuery(probe);
|
|
168180
|
+
if (probeQuery.length === 0)
|
|
168181
|
+
continue;
|
|
168182
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, probeQuery, fetchLimit, cutoff));
|
|
168183
|
+
}
|
|
168184
|
+
const fused = new Map;
|
|
168185
|
+
for (const list of queryLists) {
|
|
168186
|
+
list.forEach((row, rank) => {
|
|
168187
|
+
const rrf = 1 / (RRF_K + rank);
|
|
168188
|
+
const existing = fused.get(row.messageId);
|
|
168189
|
+
if (existing) {
|
|
168190
|
+
existing.score += rrf;
|
|
168191
|
+
} else {
|
|
168192
|
+
fused.set(row.messageId, { row, score: rrf });
|
|
168193
|
+
}
|
|
168194
|
+
});
|
|
168195
|
+
}
|
|
168196
|
+
for (const entry of fused.values()) {
|
|
168197
|
+
if (containsProbeVerbatim(entry.row.content, probes)) {
|
|
168198
|
+
entry.score += VERBATIM_PROBE_BONUS;
|
|
168199
|
+
}
|
|
168200
|
+
}
|
|
168201
|
+
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);
|
|
168202
|
+
const maxScore = ranked.length > 0 ? ranked[0].score : 1;
|
|
168203
|
+
return ranked.map((entry) => ({
|
|
167929
168204
|
source: "message",
|
|
167930
|
-
content: previewText(row.content),
|
|
167931
|
-
score:
|
|
167932
|
-
messageOrdinal: row.messageOrdinal,
|
|
167933
|
-
messageId: row.messageId,
|
|
167934
|
-
role: row.role
|
|
168205
|
+
content: previewText(entry.row.content),
|
|
168206
|
+
score: maxScore > 0 ? entry.score / maxScore : 0,
|
|
168207
|
+
messageOrdinal: entry.row.messageOrdinal,
|
|
168208
|
+
messageId: entry.row.messageId,
|
|
168209
|
+
role: entry.row.role
|
|
167935
168210
|
}));
|
|
167936
168211
|
}
|
|
167937
168212
|
function getSourceBoost(result) {
|
|
@@ -168015,12 +168290,14 @@ async function unifiedSearch(db, sessionId, projectPath, query, options3 = {}) {
|
|
|
168015
168290
|
return null;
|
|
168016
168291
|
}) : Promise.resolve(null);
|
|
168017
168292
|
await Promise.resolve();
|
|
168293
|
+
const messageProbes = options3.explicitSearch ? extractLiteralProbes(trimmedQuery) : [];
|
|
168018
168294
|
const messageResults = runMessages ? searchMessages({
|
|
168019
168295
|
db,
|
|
168020
168296
|
sessionId,
|
|
168021
168297
|
query: trimmedQuery,
|
|
168022
168298
|
limit: tierLimit,
|
|
168023
|
-
maxOrdinal: options3.maxMessageOrdinal
|
|
168299
|
+
maxOrdinal: options3.maxMessageOrdinal,
|
|
168300
|
+
probes: messageProbes
|
|
168024
168301
|
}) : [];
|
|
168025
168302
|
const queryEmbedding = await queryEmbeddingPromise;
|
|
168026
168303
|
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
@@ -168791,7 +169068,8 @@ function createCtxSearchTool(deps) {
|
|
|
168791
169068
|
maxMessageOrdinal: lastCompartmentEnd >= 0 ? lastCompartmentEnd : undefined,
|
|
168792
169069
|
gitCommitsEnabled,
|
|
168793
169070
|
sources: params.sources,
|
|
168794
|
-
visibleMemoryIds
|
|
169071
|
+
visibleMemoryIds,
|
|
169072
|
+
explicitSearch: true
|
|
168795
169073
|
});
|
|
168796
169074
|
return {
|
|
168797
169075
|
content: [{ type: "text", text: formatSearchResults(query, results) }],
|