@cortexkit/opencode-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/config/agent-disable.d.ts +0 -9
- package/dist/config/agent-disable.d.ts.map +1 -1
- package/dist/config/schema/agent-overrides.d.ts +0 -3
- package/dist/config/schema/agent-overrides.d.ts.map +1 -1
- package/dist/features/builtin-commands/types.d.ts +0 -2
- package/dist/features/builtin-commands/types.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/scheduler.d.ts +0 -4
- package/dist/features/magic-context/dreamer/scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts +8 -0
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/index.d.ts +1 -0
- package/dist/features/magic-context/git-commits/index.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/indexer.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts +48 -0
- package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts.map +1 -0
- package/dist/features/magic-context/key-files/storage-key-files.d.ts +0 -5
- package/dist/features/magic-context/key-files/storage-key-files.d.ts.map +1 -1
- package/dist/features/magic-context/literal-probes.d.ts +24 -0
- package/dist/features/magic-context/literal-probes.d.ts.map +1 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +7 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts +8 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +14 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/derive-budgets.d.ts +3 -3
- package/dist/hooks/magic-context/event-handler.d.ts +7 -0
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +7 -0
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +1 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/live-session-state.d.ts +12 -0
- package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +7 -2
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +9 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +23 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
- package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -1
- package/dist/hooks/magic-context/text-complete.d.ts +23 -0
- package/dist/hooks/magic-context/text-complete.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +9 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +561 -190
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts +54 -27
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +3 -1
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/models-dev-cache.test.ts +192 -360
- package/src/shared/models-dev-cache.ts +162 -193
- package/src/shared/rpc-types.ts +3 -1
- package/src/tui/index.tsx +17 -8
- package/src/tui/slots/sidebar-content.tsx +20 -10
package/dist/index.js
CHANGED
|
@@ -15213,9 +15213,6 @@ function getMagicContextStorageDir() {
|
|
|
15213
15213
|
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
15214
15214
|
return path2.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
15215
15215
|
}
|
|
15216
|
-
function getCacheDir() {
|
|
15217
|
-
return process.env.XDG_CACHE_HOME ?? path2.join(os.homedir(), ".cache");
|
|
15218
|
-
}
|
|
15219
15216
|
var init_data_path = () => {};
|
|
15220
15217
|
|
|
15221
15218
|
// src/shared/logger.ts
|
|
@@ -149161,14 +149158,45 @@ function readRawSessionMessageByIdFromDb(db, sessionId, messageId) {
|
|
|
149161
149158
|
}
|
|
149162
149159
|
|
|
149163
149160
|
// src/hooks/magic-context/tag-content-primitives.ts
|
|
149161
|
+
function stripWellFormedLeadingTagPrefix(value) {
|
|
149162
|
+
return value.replace(/^(\u00a7\d+\u00a7\s*)+/, "");
|
|
149163
|
+
}
|
|
149164
|
+
function stripCompleteTagPairsGlobally(value) {
|
|
149165
|
+
return value.replace(COMPLETE_TAG_PAIR_GLOBAL_REGEX, "");
|
|
149166
|
+
}
|
|
149167
|
+
function stripMalformedTagNotationGlobally(value) {
|
|
149168
|
+
return value.replace(MALFORMED_TAG_GLOBAL_REGEX, "");
|
|
149169
|
+
}
|
|
149170
|
+
function stripTagSectionCharacters(value) {
|
|
149171
|
+
return value.replace(STRAY_SECTION_CHAR_REGEX, "");
|
|
149172
|
+
}
|
|
149173
|
+
function stripPersistedAssistantText(value) {
|
|
149174
|
+
let text = stripWellFormedLeadingTagPrefix(value);
|
|
149175
|
+
text = stripCompleteTagPairsGlobally(text);
|
|
149176
|
+
text = stripMalformedTagNotationGlobally(text);
|
|
149177
|
+
text = stripTagSectionCharacters(text);
|
|
149178
|
+
return text.trim();
|
|
149179
|
+
}
|
|
149164
149180
|
function byteSize(value) {
|
|
149165
149181
|
return encoder.encode(value).length;
|
|
149166
149182
|
}
|
|
149167
149183
|
function stripTagPrefix(value) {
|
|
149168
|
-
let stripped = value
|
|
149169
|
-
|
|
149184
|
+
let stripped = value;
|
|
149185
|
+
for (let pass = 0;pass < 8; pass++) {
|
|
149186
|
+
const prev = stripped;
|
|
149187
|
+
stripped = stripped.replace(MALFORMED_TAG_PREFIX_REGEX, "");
|
|
149188
|
+
stripped = stripped.replace(TAG_PREFIX_REGEX, "");
|
|
149189
|
+
if (stripped === prev)
|
|
149190
|
+
break;
|
|
149191
|
+
}
|
|
149170
149192
|
return stripped;
|
|
149171
149193
|
}
|
|
149194
|
+
function peelLeadingMcTagNotation(value) {
|
|
149195
|
+
const body = stripTagPrefix(value);
|
|
149196
|
+
if (body === value)
|
|
149197
|
+
return { tagPrefix: "", body };
|
|
149198
|
+
return { tagPrefix: value.slice(0, value.length - body.length), body };
|
|
149199
|
+
}
|
|
149172
149200
|
function prependTag(tagId, value) {
|
|
149173
149201
|
const stripped = stripTagPrefix(value);
|
|
149174
149202
|
return `§${tagId}§ ${stripped}`;
|
|
@@ -149179,11 +149207,14 @@ function isThinkingPart(part) {
|
|
|
149179
149207
|
const candidate = part;
|
|
149180
149208
|
return candidate.type === "thinking" || candidate.type === "reasoning";
|
|
149181
149209
|
}
|
|
149182
|
-
var encoder, TAG_PREFIX_REGEX, MALFORMED_TAG_PREFIX_REGEX;
|
|
149210
|
+
var encoder, TAG_PREFIX_REGEX, MALFORMED_TAG_PREFIX_REGEX, COMPLETE_TAG_PAIR_GLOBAL_REGEX, MALFORMED_TAG_GLOBAL_REGEX, STRAY_SECTION_CHAR_REGEX;
|
|
149183
149211
|
var init_tag_content_primitives = __esm(() => {
|
|
149184
149212
|
encoder = new TextEncoder;
|
|
149185
149213
|
TAG_PREFIX_REGEX = /^(?:§\d+§\s*)+/;
|
|
149186
149214
|
MALFORMED_TAG_PREFIX_REGEX = /^(?:§\d+">§(?:\d+§)?\s*)+/;
|
|
149215
|
+
COMPLETE_TAG_PAIR_GLOBAL_REGEX = /\u00a7\d+\u00a7/g;
|
|
149216
|
+
MALFORMED_TAG_GLOBAL_REGEX = /\u00a7\d+">(?:\u00a7(?:\d+\u00a7)?)?/g;
|
|
149217
|
+
STRAY_SECTION_CHAR_REGEX = /\u00a7/g;
|
|
149187
149218
|
});
|
|
149188
149219
|
|
|
149189
149220
|
// src/hooks/magic-context/tag-part-guards.ts
|
|
@@ -149311,7 +149342,9 @@ function hasMeaningfulPart(part) {
|
|
|
149311
149342
|
return false;
|
|
149312
149343
|
const type = part.type;
|
|
149313
149344
|
if (type === "text") {
|
|
149314
|
-
|
|
149345
|
+
if (typeof part.text !== "string")
|
|
149346
|
+
return false;
|
|
149347
|
+
return stripTagPrefix(part.text).trim().length > 0;
|
|
149315
149348
|
}
|
|
149316
149349
|
if (typeof type !== "string")
|
|
149317
149350
|
return false;
|
|
@@ -149427,6 +149460,7 @@ function createToolDropTarget(compositeKey, thinkingParts, index, batch) {
|
|
|
149427
149460
|
}
|
|
149428
149461
|
var DROP_PREFIX = "[dropped", IGNORE_PART_TYPES, TRUNCATION_SENTINEL = "...[truncated]";
|
|
149429
149462
|
var init_tool_drop_target = __esm(() => {
|
|
149463
|
+
init_tag_content_primitives();
|
|
149430
149464
|
IGNORE_PART_TYPES = new Set([
|
|
149431
149465
|
"thinking",
|
|
149432
149466
|
"reasoning",
|
|
@@ -150727,6 +150761,17 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
150727
150761
|
updated_at INTEGER NOT NULL DEFAULT 0
|
|
150728
150762
|
);
|
|
150729
150763
|
|
|
150764
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
150765
|
+
project_path TEXT PRIMARY KEY,
|
|
150766
|
+
lease_holder TEXT,
|
|
150767
|
+
lease_expires_at INTEGER,
|
|
150768
|
+
last_swept_at INTEGER
|
|
150769
|
+
);
|
|
150770
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
150771
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
150772
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
150773
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
150774
|
+
|
|
150730
150775
|
CREATE TABLE IF NOT EXISTS m0_mutation_log (
|
|
150731
150776
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
150732
150777
|
session_id TEXT NOT NULL,
|
|
@@ -151256,7 +151301,7 @@ function getDatabasePersistenceError(db) {
|
|
|
151256
151301
|
return null;
|
|
151257
151302
|
return persistenceErrorByDatabase.get(db) ?? null;
|
|
151258
151303
|
}
|
|
151259
|
-
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION =
|
|
151304
|
+
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION = 29, sqlitePragmaConfig;
|
|
151260
151305
|
var init_storage_db = __esm(async () => {
|
|
151261
151306
|
init_data_path();
|
|
151262
151307
|
init_logger();
|
|
@@ -152047,6 +152092,38 @@ var init_migrations = __esm(async () => {
|
|
|
152047
152092
|
ON tags(session_id, entry_fingerprint)
|
|
152048
152093
|
WHERE type='message' AND entry_fingerprint IS NOT NULL`);
|
|
152049
152094
|
}
|
|
152095
|
+
},
|
|
152096
|
+
{
|
|
152097
|
+
version: 28,
|
|
152098
|
+
description: "Add git commit sweep coordinator lease/cooldown table",
|
|
152099
|
+
up: (db) => {
|
|
152100
|
+
db.exec(`
|
|
152101
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
152102
|
+
project_path TEXT PRIMARY KEY,
|
|
152103
|
+
lease_holder TEXT,
|
|
152104
|
+
lease_expires_at INTEGER,
|
|
152105
|
+
last_swept_at INTEGER
|
|
152106
|
+
);
|
|
152107
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
152108
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
152109
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
152110
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
152111
|
+
`);
|
|
152112
|
+
}
|
|
152113
|
+
},
|
|
152114
|
+
{
|
|
152115
|
+
version: 29,
|
|
152116
|
+
description: "Add anchor_ordinal to notes (traceback to the conversation tail)",
|
|
152117
|
+
up: (db) => {
|
|
152118
|
+
const notesExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'").get();
|
|
152119
|
+
if (!notesExists) {
|
|
152120
|
+
return;
|
|
152121
|
+
}
|
|
152122
|
+
const columns = db.prepare("PRAGMA table_info(notes)").all();
|
|
152123
|
+
if (!columns.some((column) => column.name === "anchor_ordinal")) {
|
|
152124
|
+
db.exec("ALTER TABLE notes ADD COLUMN anchor_ordinal INTEGER");
|
|
152125
|
+
}
|
|
152126
|
+
}
|
|
152050
152127
|
}
|
|
152051
152128
|
];
|
|
152052
152129
|
LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -153004,7 +153081,8 @@ function toNote(row) {
|
|
|
153004
153081
|
updatedAt: row.updated_at,
|
|
153005
153082
|
lastCheckedAt: toNullableNumber(row.last_checked_at),
|
|
153006
153083
|
readyAt: toNullableNumber(row.ready_at),
|
|
153007
|
-
readyReason: toNullableString(row.ready_reason)
|
|
153084
|
+
readyReason: toNullableString(row.ready_reason),
|
|
153085
|
+
anchorOrdinal: toNullableNumber(row.anchor_ordinal)
|
|
153008
153086
|
};
|
|
153009
153087
|
}
|
|
153010
153088
|
function getNoteById(db, noteId) {
|
|
@@ -153056,7 +153134,7 @@ function getNotes(db, options = {}) {
|
|
|
153056
153134
|
}
|
|
153057
153135
|
function addNote(db, type, options) {
|
|
153058
153136
|
const now = Date.now();
|
|
153059
|
-
const result = type === "session" ? db.prepare("INSERT INTO notes (type, status, content, session_id, created_at, updated_at, harness) VALUES ('session', 'active', ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.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(options.content, options.sessionId ?? null, options.projectPath, options.surfaceCondition, now, now, getHarness());
|
|
153137
|
+
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(options.content, options.sessionId, now, now, getHarness(), options.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(options.content, options.sessionId ?? null, options.projectPath, options.surfaceCondition, now, now, getHarness(), options.anchorOrdinal ?? null);
|
|
153060
153138
|
if (!isNoteRow(result)) {
|
|
153061
153139
|
throw new Error("[notes] failed to insert note");
|
|
153062
153140
|
}
|
|
@@ -164319,8 +164397,130 @@ var init_storage_git_commit_embeddings = __esm(() => {
|
|
|
164319
164397
|
distinctModelIdStatements = new WeakMap;
|
|
164320
164398
|
});
|
|
164321
164399
|
|
|
164400
|
+
// src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
164401
|
+
function runImmediate2(db, body) {
|
|
164402
|
+
db.exec("BEGIN IMMEDIATE");
|
|
164403
|
+
let committed = false;
|
|
164404
|
+
try {
|
|
164405
|
+
const result = body();
|
|
164406
|
+
db.exec("COMMIT");
|
|
164407
|
+
committed = true;
|
|
164408
|
+
return result;
|
|
164409
|
+
} finally {
|
|
164410
|
+
if (!committed) {
|
|
164411
|
+
try {
|
|
164412
|
+
db.exec("ROLLBACK");
|
|
164413
|
+
} catch {}
|
|
164414
|
+
}
|
|
164415
|
+
}
|
|
164416
|
+
}
|
|
164417
|
+
function rowToState(row) {
|
|
164418
|
+
return {
|
|
164419
|
+
projectPath: row.project_path,
|
|
164420
|
+
leaseHolder: row.lease_holder,
|
|
164421
|
+
leaseExpiresAt: row.lease_expires_at,
|
|
164422
|
+
lastSweptAt: row.last_swept_at
|
|
164423
|
+
};
|
|
164424
|
+
}
|
|
164425
|
+
function getGitSweepCoordinatorState(db, projectPath) {
|
|
164426
|
+
const row = db.prepare(`SELECT project_path, lease_holder, lease_expires_at, last_swept_at
|
|
164427
|
+
FROM git_sweep_coordinator
|
|
164428
|
+
WHERE project_path = ?`).get(projectPath);
|
|
164429
|
+
return row ? rowToState(row) : null;
|
|
164430
|
+
}
|
|
164431
|
+
function acquireGitSweepLease(db, projectPath, holderId, options = {}) {
|
|
164432
|
+
const cooldownMs = options.cooldownMs ?? GIT_SWEEP_COOLDOWN_MS;
|
|
164433
|
+
const leaseTtlMs = options.leaseTtlMs ?? GIT_SWEEP_LEASE_TTL_MS;
|
|
164434
|
+
return runImmediate2(db, () => {
|
|
164435
|
+
const now = Date.now();
|
|
164436
|
+
const row = getGitSweepCoordinatorState(db, projectPath);
|
|
164437
|
+
if (row?.leaseHolder && row.leaseExpiresAt !== null && row.leaseExpiresAt > now) {
|
|
164438
|
+
return {
|
|
164439
|
+
acquired: false,
|
|
164440
|
+
projectPath,
|
|
164441
|
+
reason: "lease_active",
|
|
164442
|
+
leaseHolder: row.leaseHolder,
|
|
164443
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
164444
|
+
lastSweptAt: row.lastSweptAt,
|
|
164445
|
+
nextAllowedAt: null
|
|
164446
|
+
};
|
|
164447
|
+
}
|
|
164448
|
+
if (!options.ignoreCooldown && row?.lastSweptAt !== null && row?.lastSweptAt !== undefined) {
|
|
164449
|
+
const nextAllowedAt = row.lastSweptAt + cooldownMs;
|
|
164450
|
+
if (nextAllowedAt > now) {
|
|
164451
|
+
return {
|
|
164452
|
+
acquired: false,
|
|
164453
|
+
projectPath,
|
|
164454
|
+
reason: "cooldown_active",
|
|
164455
|
+
leaseHolder: row.leaseHolder,
|
|
164456
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
164457
|
+
lastSweptAt: row.lastSweptAt,
|
|
164458
|
+
nextAllowedAt
|
|
164459
|
+
};
|
|
164460
|
+
}
|
|
164461
|
+
}
|
|
164462
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
164463
|
+
db.prepare(`INSERT INTO git_sweep_coordinator (
|
|
164464
|
+
project_path,
|
|
164465
|
+
lease_holder,
|
|
164466
|
+
lease_expires_at,
|
|
164467
|
+
last_swept_at
|
|
164468
|
+
) VALUES (?, ?, ?, NULL)
|
|
164469
|
+
ON CONFLICT(project_path) DO UPDATE SET
|
|
164470
|
+
lease_holder = excluded.lease_holder,
|
|
164471
|
+
lease_expires_at = excluded.lease_expires_at`).run(projectPath, holderId, leaseExpiresAt);
|
|
164472
|
+
return {
|
|
164473
|
+
acquired: true,
|
|
164474
|
+
projectPath,
|
|
164475
|
+
holderId,
|
|
164476
|
+
acquiredAt: now,
|
|
164477
|
+
leaseExpiresAt
|
|
164478
|
+
};
|
|
164479
|
+
});
|
|
164480
|
+
}
|
|
164481
|
+
function renewGitSweepLease(db, projectPath, holderId, leaseTtlMs = GIT_SWEEP_LEASE_TTL_MS) {
|
|
164482
|
+
return runImmediate2(db, () => {
|
|
164483
|
+
const now = Date.now();
|
|
164484
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
164485
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
164486
|
+
SET lease_expires_at = ?
|
|
164487
|
+
WHERE project_path = ?
|
|
164488
|
+
AND lease_holder = ?
|
|
164489
|
+
AND lease_expires_at > ?`).run(leaseExpiresAt, projectPath, holderId, now);
|
|
164490
|
+
return result.changes === 1;
|
|
164491
|
+
});
|
|
164492
|
+
}
|
|
164493
|
+
function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
|
|
164494
|
+
return runImmediate2(db, () => {
|
|
164495
|
+
const now = Date.now();
|
|
164496
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
164497
|
+
SET lease_holder = NULL,
|
|
164498
|
+
lease_expires_at = NULL,
|
|
164499
|
+
last_swept_at = ?
|
|
164500
|
+
WHERE project_path = ?
|
|
164501
|
+
AND lease_holder = ?
|
|
164502
|
+
AND lease_expires_at > ?`).run(now, projectPath, holderId, now);
|
|
164503
|
+
return result.changes === 1;
|
|
164504
|
+
});
|
|
164505
|
+
}
|
|
164506
|
+
function releaseGitSweepLease(db, projectPath, holderId) {
|
|
164507
|
+
runImmediate2(db, () => {
|
|
164508
|
+
db.prepare(`UPDATE git_sweep_coordinator
|
|
164509
|
+
SET lease_holder = NULL,
|
|
164510
|
+
lease_expires_at = NULL
|
|
164511
|
+
WHERE project_path = ?
|
|
164512
|
+
AND lease_holder = ?`).run(projectPath, holderId);
|
|
164513
|
+
});
|
|
164514
|
+
}
|
|
164515
|
+
var GIT_SWEEP_COOLDOWN_MS, GIT_SWEEP_LEASE_TTL_MS, GIT_SWEEP_LEASE_RENEWAL_MS;
|
|
164516
|
+
var init_sweep_coordinator = __esm(() => {
|
|
164517
|
+
GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
164518
|
+
GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
164519
|
+
GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
|
|
164520
|
+
});
|
|
164521
|
+
|
|
164322
164522
|
// src/features/magic-context/project-embedding-registry.ts
|
|
164323
|
-
import { createHash as createHash7 } from "node:crypto";
|
|
164523
|
+
import { createHash as createHash7, randomUUID } from "node:crypto";
|
|
164324
164524
|
function resolveEmbeddingConfig(config2) {
|
|
164325
164525
|
if (!config2 || config2.provider === "local") {
|
|
164326
164526
|
return {
|
|
@@ -164584,6 +164784,7 @@ var init_project_embedding_registry = __esm(() => {
|
|
|
164584
164784
|
init_magic_context();
|
|
164585
164785
|
init_logger();
|
|
164586
164786
|
init_storage_git_commit_embeddings();
|
|
164787
|
+
init_sweep_coordinator();
|
|
164587
164788
|
init_embedding_cache();
|
|
164588
164789
|
init_embedding_identity();
|
|
164589
164790
|
init_embedding_local();
|
|
@@ -164682,32 +164883,48 @@ var init_storage_memory_fts = __esm(() => {
|
|
|
164682
164883
|
});
|
|
164683
164884
|
|
|
164684
164885
|
// src/shared/models-dev-cache.ts
|
|
164685
|
-
import {
|
|
164686
|
-
import { existsSync as existsSync14, readFileSync as readFileSync12 } from "node:fs";
|
|
164687
|
-
import { homedir as homedir9, platform as platform3 } from "node:os";
|
|
164886
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync12, renameSync as renameSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
164688
164887
|
import { join as join18 } from "node:path";
|
|
164689
|
-
function
|
|
164690
|
-
return
|
|
164691
|
-
}
|
|
164692
|
-
function
|
|
164693
|
-
|
|
164694
|
-
|
|
164695
|
-
|
|
164696
|
-
|
|
164697
|
-
|
|
164698
|
-
|
|
164699
|
-
|
|
164700
|
-
|
|
164701
|
-
|
|
164702
|
-
|
|
164703
|
-
|
|
164704
|
-
|
|
164705
|
-
|
|
164706
|
-
|
|
164707
|
-
|
|
164708
|
-
|
|
164709
|
-
|
|
164710
|
-
|
|
164888
|
+
function isSaneLimit(limit) {
|
|
164889
|
+
return typeof limit === "number" && limit >= MIN_SANE_LIMIT && limit <= MAX_SANE_LIMIT;
|
|
164890
|
+
}
|
|
164891
|
+
function persistFilePath() {
|
|
164892
|
+
return join18(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
|
|
164893
|
+
}
|
|
164894
|
+
function loadPersistedApiCacheOnce() {
|
|
164895
|
+
if (persistSeedLoaded || apiCache !== null)
|
|
164896
|
+
return;
|
|
164897
|
+
persistSeedLoaded = true;
|
|
164898
|
+
try {
|
|
164899
|
+
const raw = readFileSync12(persistFilePath(), "utf-8");
|
|
164900
|
+
const obj = JSON.parse(raw);
|
|
164901
|
+
const map2 = new Map;
|
|
164902
|
+
for (const [key, limit] of Object.entries(obj)) {
|
|
164903
|
+
if (isSaneLimit(limit))
|
|
164904
|
+
map2.set(key, { limit });
|
|
164905
|
+
}
|
|
164906
|
+
if (map2.size > 0) {
|
|
164907
|
+
apiCache = map2;
|
|
164908
|
+
sessionLog("global", `models-dev-cache: seeded ${map2.size} entries from persisted cache (cold start)`);
|
|
164909
|
+
}
|
|
164910
|
+
} catch {}
|
|
164911
|
+
}
|
|
164912
|
+
function persistApiCache() {
|
|
164913
|
+
if (!apiCache)
|
|
164914
|
+
return;
|
|
164915
|
+
const obj = {};
|
|
164916
|
+
for (const [key, value] of apiCache) {
|
|
164917
|
+
if (isSaneLimit(value.limit))
|
|
164918
|
+
obj[key] = value.limit;
|
|
164919
|
+
}
|
|
164920
|
+
try {
|
|
164921
|
+
const dir = getMagicContextStorageDir();
|
|
164922
|
+
mkdirSync5(dir, { recursive: true });
|
|
164923
|
+
const target = persistFilePath();
|
|
164924
|
+
const tmp = `${target}.${process.pid}.tmp`;
|
|
164925
|
+
writeFileSync4(tmp, JSON.stringify(obj), { encoding: "utf-8", mode: 384 });
|
|
164926
|
+
renameSync3(tmp, target);
|
|
164927
|
+
} catch {}
|
|
164711
164928
|
}
|
|
164712
164929
|
function resolveLimit(limit) {
|
|
164713
164930
|
if (!limit)
|
|
@@ -164720,7 +164937,7 @@ function resolveLimit(limit) {
|
|
|
164720
164937
|
}
|
|
164721
164938
|
function setCachedModelMetadata(cache, key, model) {
|
|
164722
164939
|
const limit = resolveLimit(model?.limit);
|
|
164723
|
-
if (limit
|
|
164940
|
+
if (!isSaneLimit(limit)) {
|
|
164724
164941
|
return;
|
|
164725
164942
|
}
|
|
164726
164943
|
const value = { limit };
|
|
@@ -164732,54 +164949,26 @@ function setCachedModelMetadata(cache, key, model) {
|
|
|
164732
164949
|
}
|
|
164733
164950
|
}
|
|
164734
164951
|
}
|
|
164735
|
-
function
|
|
164736
|
-
const
|
|
164737
|
-
const
|
|
164738
|
-
let
|
|
164739
|
-
|
|
164740
|
-
if (
|
|
164741
|
-
|
|
164742
|
-
|
|
164743
|
-
|
|
164744
|
-
for (const [providerId, provider2] of Object.entries(data)) {
|
|
164745
|
-
if (!provider2?.models || typeof provider2.models !== "object")
|
|
164746
|
-
continue;
|
|
164747
|
-
for (const [modelId, model] of Object.entries(provider2.models)) {
|
|
164748
|
-
setCachedModelMetadata(metadata, `${providerId}/${modelId}`, model);
|
|
164749
|
-
}
|
|
164750
|
-
}
|
|
164751
|
-
}
|
|
164752
|
-
} catch (error51) {
|
|
164753
|
-
sessionLog("global", `models-dev-cache: failed to read models.json at ${modelsJsonPath}:`, error51 instanceof Error ? error51.message : String(error51));
|
|
164754
|
-
}
|
|
164755
|
-
try {
|
|
164756
|
-
const configPath = getOpencodeConfigPath();
|
|
164757
|
-
if (configPath && existsSync14(configPath)) {
|
|
164758
|
-
const config2 = parseJsonc(readFileSync12(configPath, "utf-8"));
|
|
164759
|
-
if (config2.provider && typeof config2.provider === "object") {
|
|
164760
|
-
for (const [providerId, provider2] of Object.entries(config2.provider)) {
|
|
164761
|
-
if (!provider2?.models || typeof provider2.models !== "object")
|
|
164762
|
-
continue;
|
|
164763
|
-
for (const [modelId, model] of Object.entries(provider2.models)) {
|
|
164764
|
-
setCachedModelMetadata(metadata, `${providerId}/${modelId}`, model);
|
|
164765
|
-
}
|
|
164766
|
-
}
|
|
164767
|
-
}
|
|
164952
|
+
async function refreshModelLimitsFromApi(client, options) {
|
|
164953
|
+
const attempts = Math.max(1, (options?.retries ?? 0) + 1);
|
|
164954
|
+
const delayMs = options?.retryDelayMs ?? 1000;
|
|
164955
|
+
for (let attempt = 1;attempt <= attempts; attempt++) {
|
|
164956
|
+
const ok = await refreshModelLimitsOnce(client);
|
|
164957
|
+
if (ok)
|
|
164958
|
+
return;
|
|
164959
|
+
if (attempt < attempts) {
|
|
164960
|
+
await new Promise((resolve6) => setTimeout(resolve6, delayMs));
|
|
164768
164961
|
}
|
|
164769
|
-
} catch (error51) {
|
|
164770
|
-
sessionLog("global", "models-dev-cache: failed to read opencode config for custom models:", error51 instanceof Error ? error51.message : String(error51));
|
|
164771
164962
|
}
|
|
164772
|
-
sessionLog("global", `models-dev-cache: file-layer loaded ${metadata.size} model metadata entries (modelsJsonPath=${modelsJsonPath}, found=${fileFound})`);
|
|
164773
|
-
return metadata;
|
|
164774
164963
|
}
|
|
164775
|
-
async function
|
|
164964
|
+
async function refreshModelLimitsOnce(client) {
|
|
164776
164965
|
try {
|
|
164777
164966
|
const result = await client.config.providers();
|
|
164778
164967
|
const data = result.data;
|
|
164779
164968
|
const providers = data?.providers;
|
|
164780
|
-
if (!Array.isArray(providers)) {
|
|
164781
|
-
sessionLog("global", "models-dev-cache: API refresh returned no providers payload");
|
|
164782
|
-
return;
|
|
164969
|
+
if (!Array.isArray(providers) || providers.length === 0) {
|
|
164970
|
+
sessionLog("global", "models-dev-cache: API refresh returned no providers payload (will retry if attempts remain)");
|
|
164971
|
+
return false;
|
|
164783
164972
|
}
|
|
164784
164973
|
const map2 = new Map;
|
|
164785
164974
|
for (const entry of providers) {
|
|
@@ -164793,27 +164982,22 @@ async function refreshModelLimitsFromApi(client) {
|
|
|
164793
164982
|
const previousSize = apiCache?.size ?? null;
|
|
164794
164983
|
apiCache = map2;
|
|
164795
164984
|
apiLoadedAt = Date.now();
|
|
164985
|
+
persistApiCache();
|
|
164796
164986
|
if (previousSize === null) {
|
|
164797
164987
|
sessionLog("global", `models-dev-cache: API layer loaded ${map2.size} model metadata entries`);
|
|
164798
164988
|
} else if (previousSize !== map2.size) {
|
|
164799
164989
|
sessionLog("global", `models-dev-cache: API layer loaded ${map2.size} model metadata entries (was ${previousSize})`);
|
|
164800
164990
|
}
|
|
164991
|
+
return true;
|
|
164801
164992
|
} catch (error51) {
|
|
164802
164993
|
sessionLog("global", "models-dev-cache: API refresh failed:", error51 instanceof Error ? error51.message : String(error51));
|
|
164994
|
+
return false;
|
|
164803
164995
|
}
|
|
164804
164996
|
}
|
|
164805
|
-
function
|
|
164806
|
-
|
|
164807
|
-
if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
|
|
164808
|
-
fileLastAttempt = now;
|
|
164809
|
-
fileCache = loadModelsDevMetadataFromFile();
|
|
164810
|
-
}
|
|
164997
|
+
function getSdkContextLimit(providerID, modelID) {
|
|
164998
|
+
loadPersistedApiCacheOnce();
|
|
164811
164999
|
const fromApi = lookupLimitWithTagFallback(apiCache, providerID, modelID);
|
|
164812
|
-
|
|
164813
|
-
if (typeof fromApi === "number" && typeof fromFile === "number") {
|
|
164814
|
-
return Math.max(fromApi, fromFile);
|
|
164815
|
-
}
|
|
164816
|
-
return fromApi ?? fromFile;
|
|
165000
|
+
return isSaneLimit(fromApi) ? fromApi : undefined;
|
|
164817
165001
|
}
|
|
164818
165002
|
function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
164819
165003
|
if (!cache)
|
|
@@ -164830,12 +165014,10 @@ function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
|
164830
165014
|
}
|
|
164831
165015
|
return;
|
|
164832
165016
|
}
|
|
164833
|
-
var
|
|
165017
|
+
var MIN_SANE_LIMIT = 20000, MAX_SANE_LIMIT = 3000000, apiCache = null, apiLoadedAt = 0, persistSeedLoaded = false;
|
|
164834
165018
|
var init_models_dev_cache = __esm(() => {
|
|
164835
165019
|
init_data_path();
|
|
164836
|
-
init_jsonc_parser();
|
|
164837
165020
|
init_logger();
|
|
164838
|
-
RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
164839
165021
|
});
|
|
164840
165022
|
|
|
164841
165023
|
// src/shared/rpc-notifications.ts
|
|
@@ -165561,7 +165743,7 @@ var init_compartment_runner_validation = __esm(async () => {
|
|
|
165561
165743
|
});
|
|
165562
165744
|
|
|
165563
165745
|
// src/hooks/magic-context/compartment-runner-historian.ts
|
|
165564
|
-
import { mkdirSync as
|
|
165746
|
+
import { mkdirSync as mkdirSync6, unlinkSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
165565
165747
|
import { join as join21 } from "node:path";
|
|
165566
165748
|
function historianResponseDumpDir(directory) {
|
|
165567
165749
|
return getProjectMagicContextHistorianDir(directory);
|
|
@@ -165864,11 +166046,11 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
165864
166046
|
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
165865
166047
|
try {
|
|
165866
166048
|
const dumpDir = historianResponseDumpDir(directory);
|
|
165867
|
-
|
|
166049
|
+
mkdirSync6(dumpDir, { recursive: true });
|
|
165868
166050
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
165869
166051
|
const safeLabel = sanitizeDumpName(label);
|
|
165870
166052
|
const dumpPath = join21(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
165871
|
-
|
|
166053
|
+
writeFileSync5(dumpPath, text, "utf8");
|
|
165872
166054
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
165873
166055
|
label,
|
|
165874
166056
|
dumpPath
|
|
@@ -165990,7 +166172,7 @@ function insertCompartmentEvents(db, sessionId, events, compartmentIds) {
|
|
|
165990
166172
|
var init_compartment_events = () => {};
|
|
165991
166173
|
|
|
165992
166174
|
// src/hooks/magic-context/historian-state-file.ts
|
|
165993
|
-
import { mkdirSync as
|
|
166175
|
+
import { mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
165994
166176
|
function cleanupHistorianStateFile(path6) {
|
|
165995
166177
|
if (!path6)
|
|
165996
166178
|
return;
|
|
@@ -166545,9 +166727,7 @@ function injectTemporalMarkers(messages) {
|
|
|
166545
166727
|
if (prefix && Array.isArray(msg.parts)) {
|
|
166546
166728
|
const target = findFirstVisibleTextPart(msg.parts);
|
|
166547
166729
|
if (target && typeof target.text === "string") {
|
|
166548
|
-
const
|
|
166549
|
-
const tagPrefix = tagMatch ? tagMatch[0] : "";
|
|
166550
|
-
const body = target.text.slice(tagPrefix.length);
|
|
166730
|
+
const { tagPrefix, body } = peelLeadingMcTagNotation(target.text);
|
|
166551
166731
|
if (!TEMPORAL_MARKER_PATTERN.test(body)) {
|
|
166552
166732
|
target.text = tagPrefix + prefix + body;
|
|
166553
166733
|
injected++;
|
|
@@ -166562,6 +166742,7 @@ function injectTemporalMarkers(messages) {
|
|
|
166562
166742
|
}
|
|
166563
166743
|
var TEMPORAL_AWARENESS_THRESHOLD_SECONDS = 300, SECONDS_PER_MINUTE = 60, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, TEMPORAL_MARKER_PATTERN;
|
|
166564
166744
|
var init_temporal_awareness = __esm(() => {
|
|
166745
|
+
init_tag_content_primitives();
|
|
166565
166746
|
SECONDS_PER_HOUR = 60 * 60;
|
|
166566
166747
|
SECONDS_PER_DAY = 24 * 60 * 60;
|
|
166567
166748
|
SECONDS_PER_WEEK = 7 * 24 * 60 * 60;
|
|
@@ -170826,7 +171007,7 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
170826
171007
|
const [providerID, ...rest] = historianModelOverride.split("/");
|
|
170827
171008
|
const modelID = rest.join("/");
|
|
170828
171009
|
if (providerID && modelID) {
|
|
170829
|
-
const limit =
|
|
171010
|
+
const limit = getSdkContextLimit(providerID, modelID);
|
|
170830
171011
|
if (typeof limit === "number" && limit > 0)
|
|
170831
171012
|
return limit;
|
|
170832
171013
|
}
|
|
@@ -170845,7 +171026,7 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
170845
171026
|
const modelID = rest.join("/");
|
|
170846
171027
|
if (!providerID || !modelID)
|
|
170847
171028
|
continue;
|
|
170848
|
-
const limit =
|
|
171029
|
+
const limit = getSdkContextLimit(providerID, modelID);
|
|
170849
171030
|
if (typeof limit !== "number" || limit <= 0)
|
|
170850
171031
|
continue;
|
|
170851
171032
|
if (minLimit === undefined || limit < minLimit)
|
|
@@ -171212,6 +171393,7 @@ __export(exports_recomp_orchestrator, {
|
|
|
171212
171393
|
setRecompNote: () => setRecompNote,
|
|
171213
171394
|
runManagedUpgrade: () => runManagedUpgrade,
|
|
171214
171395
|
runManagedRecomp: () => runManagedRecomp,
|
|
171396
|
+
isRecompSkip: () => isRecompSkip,
|
|
171215
171397
|
isRecompFailure: () => isRecompFailure,
|
|
171216
171398
|
isRecompComplete: () => isRecompComplete,
|
|
171217
171399
|
extractRecompReason: () => extractRecompReason,
|
|
@@ -171224,6 +171406,9 @@ function resolveLiveModelKey(liveSessionState, sessionId) {
|
|
|
171224
171406
|
function isRecompFailure(message) {
|
|
171225
171407
|
return /—\s*(Failed|Skipped)/.test(message);
|
|
171226
171408
|
}
|
|
171409
|
+
function isRecompSkip(message) {
|
|
171410
|
+
return /—\s*Skipped|already mutating compartment state|already running/i.test(message);
|
|
171411
|
+
}
|
|
171227
171412
|
function isRecompComplete(message) {
|
|
171228
171413
|
return /—\s*Complete/.test(message);
|
|
171229
171414
|
}
|
|
@@ -171239,9 +171424,10 @@ function contextualizeUpgradeReason(reason) {
|
|
|
171239
171424
|
}
|
|
171240
171425
|
return rewritten;
|
|
171241
171426
|
}
|
|
171242
|
-
function setRecompStarting(liveSessionState, sessionId, note) {
|
|
171427
|
+
function setRecompStarting(liveSessionState, sessionId, note, kind = "recomp") {
|
|
171243
171428
|
liveSessionState.recompProgressBySession.set(sessionId, {
|
|
171244
171429
|
sessionId,
|
|
171430
|
+
kind,
|
|
171245
171431
|
phase: "recomp",
|
|
171246
171432
|
processedMessages: 0,
|
|
171247
171433
|
totalMessages: 0,
|
|
@@ -171266,6 +171452,7 @@ function setRecompTerminal(liveSessionState, sessionId, phase, message) {
|
|
|
171266
171452
|
const existing = liveSessionState.recompProgressBySession.get(sessionId);
|
|
171267
171453
|
liveSessionState.recompProgressBySession.set(sessionId, {
|
|
171268
171454
|
sessionId,
|
|
171455
|
+
kind: existing?.kind ?? "recomp",
|
|
171269
171456
|
phase,
|
|
171270
171457
|
processedMessages: existing?.processedMessages ?? 0,
|
|
171271
171458
|
totalMessages: existing?.totalMessages ?? 0,
|
|
@@ -171275,10 +171462,10 @@ function setRecompTerminal(liveSessionState, sessionId, phase, message) {
|
|
|
171275
171462
|
updatedAt: Date.now(),
|
|
171276
171463
|
message
|
|
171277
171464
|
});
|
|
171278
|
-
if (phase === "done") {
|
|
171465
|
+
if (phase === "done" || phase === "skipped") {
|
|
171279
171466
|
const t = setTimeout(() => {
|
|
171280
171467
|
const cur = liveSessionState.recompProgressBySession.get(sessionId);
|
|
171281
|
-
if (cur?.phase ===
|
|
171468
|
+
if (cur?.phase === phase)
|
|
171282
171469
|
liveSessionState.recompProgressBySession.delete(sessionId);
|
|
171283
171470
|
}, RECOMP_DONE_GRACE_MS);
|
|
171284
171471
|
t.unref?.();
|
|
@@ -171307,7 +171494,11 @@ function buildRecompDeps(ctx, sessionId) {
|
|
|
171307
171494
|
ctx.liveSessionState.deferredHistoryRefreshSessions.add(sid);
|
|
171308
171495
|
},
|
|
171309
171496
|
onRecompProgress: (p) => {
|
|
171310
|
-
ctx.liveSessionState.recompProgressBySession.
|
|
171497
|
+
const prevKind = ctx.liveSessionState.recompProgressBySession.get(sessionId)?.kind ?? "recomp";
|
|
171498
|
+
ctx.liveSessionState.recompProgressBySession.set(sessionId, {
|
|
171499
|
+
...p,
|
|
171500
|
+
kind: p.kind ?? prevKind
|
|
171501
|
+
});
|
|
171311
171502
|
}
|
|
171312
171503
|
};
|
|
171313
171504
|
}
|
|
@@ -171326,10 +171517,11 @@ async function resolveSessionDirectory(ctx, sessionId) {
|
|
|
171326
171517
|
return ctx.directory;
|
|
171327
171518
|
}
|
|
171328
171519
|
async function runManagedRecomp(ctx, sessionId, options) {
|
|
171329
|
-
setRecompStarting(ctx.liveSessionState, sessionId, "Starting recomp…");
|
|
171520
|
+
setRecompStarting(ctx.liveSessionState, sessionId, "Starting recomp…", "recomp");
|
|
171330
171521
|
try {
|
|
171331
171522
|
const message = await executeContextRecomp(buildRecompDeps(ctx, sessionId), options);
|
|
171332
|
-
|
|
171523
|
+
const terminalPhase = isRecompSkip(message) ? "skipped" : isRecompFailure(message) ? "failed" : "done";
|
|
171524
|
+
setRecompTerminal(ctx.liveSessionState, sessionId, terminalPhase, extractRecompReason(message));
|
|
171333
171525
|
return message;
|
|
171334
171526
|
} catch (error51) {
|
|
171335
171527
|
setRecompTerminal(ctx.liveSessionState, sessionId, "failed", `Recomp crashed: ${String(error51)}`);
|
|
@@ -171339,7 +171531,7 @@ Recomp crashed: ${String(error51)}`;
|
|
|
171339
171531
|
}
|
|
171340
171532
|
}
|
|
171341
171533
|
async function runManagedUpgrade(ctx, sessionId) {
|
|
171342
|
-
setRecompStarting(ctx.liveSessionState, sessionId, "Starting upgrade…");
|
|
171534
|
+
setRecompStarting(ctx.liveSessionState, sessionId, "Starting upgrade…", "upgrade");
|
|
171343
171535
|
try {
|
|
171344
171536
|
const compartments = getCompartments(ctx.db, sessionId);
|
|
171345
171537
|
const legacyCount = compartments.filter((c) => c.legacy === 1 || !c.p1 || c.p1.trim() === "").length;
|
|
@@ -171397,6 +171589,7 @@ async function runUpgradeMemoryMigration(ctx, sessionId, migrationDirectory) {
|
|
|
171397
171589
|
const prev = ctx.liveSessionState.recompProgressBySession.get(sessionId);
|
|
171398
171590
|
ctx.liveSessionState.recompProgressBySession.set(sessionId, {
|
|
171399
171591
|
sessionId,
|
|
171592
|
+
kind: prev?.kind ?? "upgrade",
|
|
171400
171593
|
phase: "migration",
|
|
171401
171594
|
processedMessages: prev?.processedMessages ?? 0,
|
|
171402
171595
|
totalMessages: prev?.totalMessages ?? 0,
|
|
@@ -171493,7 +171686,7 @@ var exports_tui_config = {};
|
|
|
171493
171686
|
__export(exports_tui_config, {
|
|
171494
171687
|
ensureTuiPluginEntry: () => ensureTuiPluginEntry
|
|
171495
171688
|
});
|
|
171496
|
-
import { existsSync as
|
|
171689
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync16, writeFileSync as writeFileSync9 } from "node:fs";
|
|
171497
171690
|
import { dirname as dirname9, join as join25 } from "node:path";
|
|
171498
171691
|
function isMagicContextEntry(entry) {
|
|
171499
171692
|
if (!entry)
|
|
@@ -171510,9 +171703,9 @@ function resolveTuiConfigPath() {
|
|
|
171510
171703
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
171511
171704
|
const jsoncPath = join25(configDir, "tui.jsonc");
|
|
171512
171705
|
const jsonPath = join25(configDir, "tui.json");
|
|
171513
|
-
if (
|
|
171706
|
+
if (existsSync15(jsoncPath))
|
|
171514
171707
|
return jsoncPath;
|
|
171515
|
-
if (
|
|
171708
|
+
if (existsSync15(jsonPath))
|
|
171516
171709
|
return jsonPath;
|
|
171517
171710
|
return jsonPath;
|
|
171518
171711
|
}
|
|
@@ -171520,7 +171713,7 @@ function ensureTuiPluginEntry() {
|
|
|
171520
171713
|
try {
|
|
171521
171714
|
const configPath = resolveTuiConfigPath();
|
|
171522
171715
|
let config2 = {};
|
|
171523
|
-
if (
|
|
171716
|
+
if (existsSync15(configPath)) {
|
|
171524
171717
|
const raw = readFileSync16(configPath, "utf-8");
|
|
171525
171718
|
config2 = import_comment_json4.parse(raw) ?? {};
|
|
171526
171719
|
}
|
|
@@ -171540,8 +171733,8 @@ function ensureTuiPluginEntry() {
|
|
|
171540
171733
|
plugins.push(PLUGIN_ENTRY);
|
|
171541
171734
|
}
|
|
171542
171735
|
config2.plugin = plugins;
|
|
171543
|
-
|
|
171544
|
-
|
|
171736
|
+
mkdirSync10(dirname9(configPath), { recursive: true });
|
|
171737
|
+
writeFileSync9(configPath, `${import_comment_json4.stringify(config2, null, 2)}
|
|
171545
171738
|
`);
|
|
171546
171739
|
log(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
171547
171740
|
return true;
|
|
@@ -173466,7 +173659,8 @@ function createLiveSessionState() {
|
|
|
173466
173659
|
pendingMaterializationSessions: new Set,
|
|
173467
173660
|
deferredMaterializationSessions: new Set,
|
|
173468
173661
|
sessionDirectoryBySession: new Map,
|
|
173469
|
-
recompProgressBySession: new Map
|
|
173662
|
+
recompProgressBySession: new Map,
|
|
173663
|
+
internalChildSessions: new Set
|
|
173470
173664
|
};
|
|
173471
173665
|
}
|
|
173472
173666
|
|
|
@@ -175083,7 +175277,7 @@ async function processDreamQueue(args) {
|
|
|
175083
175277
|
return null;
|
|
175084
175278
|
}
|
|
175085
175279
|
const projectDirectory = args.sessionDirectoryOverride ?? resolveDreamSessionDirectory(entry.projectIdentity);
|
|
175086
|
-
log(`[dreamer] dequeued project ${entry.projectIdentity}
|
|
175280
|
+
log(`[dreamer] dequeued project ${entry.projectIdentity}, starting dream run`);
|
|
175087
175281
|
let result;
|
|
175088
175282
|
try {
|
|
175089
175283
|
result = await runDream({
|
|
@@ -175207,6 +175401,7 @@ async function readGitCommits(directory, options = {}) {
|
|
|
175207
175401
|
if (revision.startsWith("-")) {
|
|
175208
175402
|
throw new Error(`readGitCommits: refusing revision that looks like an option: "${revision}"`);
|
|
175209
175403
|
}
|
|
175404
|
+
const projectLabel = options.projectIdentity ?? "<project>";
|
|
175210
175405
|
const args = [
|
|
175211
175406
|
"log",
|
|
175212
175407
|
revision,
|
|
@@ -175229,11 +175424,11 @@ async function readGitCommits(directory, options = {}) {
|
|
|
175229
175424
|
stdout = result.stdout;
|
|
175230
175425
|
} catch (error51) {
|
|
175231
175426
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
175232
|
-
log(`[git-commits] readGitCommits failed
|
|
175427
|
+
log(`[git-commits] readGitCommits failed for ${projectLabel}: ${message.slice(0, 500)}`);
|
|
175233
175428
|
return [];
|
|
175234
175429
|
}
|
|
175235
175430
|
if (stdout.trim().length === 0) {
|
|
175236
|
-
log(`[git-commits] readGitCommits returned empty stdout
|
|
175431
|
+
log(`[git-commits] readGitCommits returned empty stdout for ${projectLabel} (sinceMs=${options.sinceMs ?? "none"} args=${args.slice(0, 4).join(" ")})`);
|
|
175237
175432
|
}
|
|
175238
175433
|
return parseGitLogOutput(stdout);
|
|
175239
175434
|
}
|
|
@@ -175288,6 +175483,7 @@ var insertStatements = new WeakMap;
|
|
|
175288
175483
|
var existingShasStatements = new WeakMap;
|
|
175289
175484
|
var projectCountStatements = new WeakMap;
|
|
175290
175485
|
var evictStatements = new WeakMap;
|
|
175486
|
+
var evictOverflowStatements = new WeakMap;
|
|
175291
175487
|
var latestCommitTimeStatements = new WeakMap;
|
|
175292
175488
|
function getInsertStatement(db) {
|
|
175293
175489
|
let stmt = insertStatements.get(db);
|
|
@@ -175330,17 +175526,17 @@ function getLatestCommitTimeStatement(db) {
|
|
|
175330
175526
|
}
|
|
175331
175527
|
return stmt;
|
|
175332
175528
|
}
|
|
175333
|
-
function
|
|
175334
|
-
let stmt =
|
|
175529
|
+
function getEvictOverflowStatement(db) {
|
|
175530
|
+
let stmt = evictOverflowStatements.get(db);
|
|
175335
175531
|
if (!stmt) {
|
|
175336
175532
|
stmt = db.prepare(`DELETE FROM git_commits
|
|
175337
|
-
WHERE
|
|
175338
|
-
SELECT
|
|
175533
|
+
WHERE rowid IN (
|
|
175534
|
+
SELECT rowid FROM git_commits
|
|
175339
175535
|
WHERE project_path = ?
|
|
175340
|
-
ORDER BY committed_at
|
|
175341
|
-
LIMIT ?
|
|
175536
|
+
ORDER BY committed_at DESC, sha DESC
|
|
175537
|
+
LIMIT -1 OFFSET ?
|
|
175342
175538
|
)`);
|
|
175343
|
-
|
|
175539
|
+
evictOverflowStatements.set(db, stmt);
|
|
175344
175540
|
}
|
|
175345
175541
|
return stmt;
|
|
175346
175542
|
}
|
|
@@ -175378,22 +175574,15 @@ function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
|
175378
175574
|
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
175379
175575
|
return row?.latest ?? null;
|
|
175380
175576
|
}
|
|
175381
|
-
function evictOldestCommits(db, projectPath, excess) {
|
|
175382
|
-
if (excess <= 0)
|
|
175383
|
-
return 0;
|
|
175384
|
-
const before = getCommitCount(db, projectPath);
|
|
175385
|
-
getEvictStatement(db).run(projectPath, excess);
|
|
175386
|
-
const after = getCommitCount(db, projectPath);
|
|
175387
|
-
return Math.max(0, before - after);
|
|
175388
|
-
}
|
|
175389
175577
|
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
175390
175578
|
if (maxCommits <= 0)
|
|
175391
175579
|
return 0;
|
|
175392
175580
|
const count = getCommitCount(db, projectPath);
|
|
175393
175581
|
if (count <= maxCommits)
|
|
175394
175582
|
return 0;
|
|
175395
|
-
|
|
175396
|
-
const
|
|
175583
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
175584
|
+
const after = getCommitCount(db, projectPath);
|
|
175585
|
+
const evicted = Math.max(0, count - after);
|
|
175397
175586
|
if (evicted > 0) {
|
|
175398
175587
|
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
175399
175588
|
}
|
|
@@ -175425,7 +175614,8 @@ async function indexCommitsForProject(db, projectPath, directory, options) {
|
|
|
175425
175614
|
const sinceMs = latestIndexed !== null ? Math.max(latestIndexed - 60000, Date.now() - options.sinceDays * MS_PER_DAY) : Date.now() - options.sinceDays * MS_PER_DAY;
|
|
175426
175615
|
const commits = await readGitCommits(directory, {
|
|
175427
175616
|
sinceMs,
|
|
175428
|
-
maxCommits: options.maxCommits
|
|
175617
|
+
maxCommits: options.maxCommits,
|
|
175618
|
+
projectIdentity: projectPath
|
|
175429
175619
|
});
|
|
175430
175620
|
result.scanned = commits.length;
|
|
175431
175621
|
if (commits.length === 0) {
|
|
@@ -175637,6 +175827,7 @@ function searchGitCommitsSync(db, projectPath, query, options) {
|
|
|
175637
175827
|
|
|
175638
175828
|
// src/features/magic-context/git-commits/index.ts
|
|
175639
175829
|
init_storage_git_commit_embeddings();
|
|
175830
|
+
init_sweep_coordinator();
|
|
175640
175831
|
|
|
175641
175832
|
// src/plugin/dream-timer.ts
|
|
175642
175833
|
init_embedding();
|
|
@@ -175669,7 +175860,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
175669
175860
|
const isNewRegistration = !registeredProjects.has(args.directory);
|
|
175670
175861
|
registeredProjects.set(args.directory, args);
|
|
175671
175862
|
if (isNewRegistration) {
|
|
175672
|
-
log(`[dreamer] registered project ${args.
|
|
175863
|
+
log(`[dreamer] registered project ${args.projectIdentity} (dreaming=${dreamingEnabled} embeddings=${embeddingSweepEnabled} commits=${commitIndexingEnabled}; total=${registeredProjects.size})`);
|
|
175673
175864
|
}
|
|
175674
175865
|
if (!activeTimer) {
|
|
175675
175866
|
log(`[dreamer] started independent schedule timer (every ${DREAM_TIMER_INTERVAL_MS / 60000}m)`);
|
|
@@ -175684,7 +175875,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
175684
175875
|
}
|
|
175685
175876
|
return () => {
|
|
175686
175877
|
registeredProjects.delete(args.directory);
|
|
175687
|
-
log(`[dreamer] unregistered project ${args.
|
|
175878
|
+
log(`[dreamer] unregistered project ${args.projectIdentity} (remaining=${registeredProjects.size})`);
|
|
175688
175879
|
if (registeredProjects.size === 0 && activeTimer) {
|
|
175689
175880
|
clearInterval(activeTimer);
|
|
175690
175881
|
activeTimer = null;
|
|
@@ -175732,7 +175923,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
175732
175923
|
return;
|
|
175733
175924
|
}
|
|
175734
175925
|
try {
|
|
175735
|
-
log(`[dreamer] timer tick (${origin}) ${reg.
|
|
175926
|
+
log(`[dreamer] timer tick (${origin}) ${reg.projectIdentity} — checking schedule window "${reg.dreamerConfig.schedule}"`);
|
|
175736
175927
|
checkScheduleAndEnqueue(db, reg.dreamerConfig.schedule, reg.projectIdentity);
|
|
175737
175928
|
await processDreamQueue({
|
|
175738
175929
|
db,
|
|
@@ -175747,13 +175938,34 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
175747
175938
|
fallbackModels: resolveFallbackChain(DREAMER_AGENT, reg.dreamerConfig.fallback_models)
|
|
175748
175939
|
});
|
|
175749
175940
|
} catch (error51) {
|
|
175750
|
-
log(`[dreamer] timer-triggered queue processing failed for ${reg.
|
|
175941
|
+
log(`[dreamer] timer-triggered queue processing failed for ${reg.projectIdentity}:`, error51);
|
|
175751
175942
|
}
|
|
175752
175943
|
}
|
|
175944
|
+
function startGitSweepLeaseRenewal(db, projectIdentity, holderId) {
|
|
175945
|
+
const timer = setInterval(() => {
|
|
175946
|
+
try {
|
|
175947
|
+
if (!renewGitSweepLease(db, projectIdentity, holderId)) {
|
|
175948
|
+
log(`[git-commits] sweep lease renewal failed for ${projectIdentity}`);
|
|
175949
|
+
}
|
|
175950
|
+
} catch (error51) {
|
|
175951
|
+
log(`[git-commits] sweep lease renewal errored for ${projectIdentity}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
175952
|
+
}
|
|
175953
|
+
}, GIT_SWEEP_LEASE_RENEWAL_MS);
|
|
175954
|
+
timer.unref?.();
|
|
175955
|
+
return () => clearInterval(timer);
|
|
175956
|
+
}
|
|
175753
175957
|
async function sweepGitCommits(args) {
|
|
175754
175958
|
const { directory, projectIdentity, db, gitCommitIndexing } = args;
|
|
175959
|
+
const holderId = crypto.randomUUID();
|
|
175960
|
+
const lease2 = acquireGitSweepLease(db, projectIdentity, holderId);
|
|
175961
|
+
if (!lease2.acquired) {
|
|
175962
|
+
const reason = lease2.reason === "cooldown_active" ? `cooldown active until ${lease2.nextAllowedAt}` : `lease held by ${lease2.leaseHolder ?? "another holder"} until ${lease2.leaseExpiresAt ?? "unknown"}`;
|
|
175963
|
+
log(`[git-commits] sweep skipped for ${projectIdentity}: ${reason}`);
|
|
175964
|
+
return;
|
|
175965
|
+
}
|
|
175755
175966
|
const startedAt = Date.now();
|
|
175756
|
-
|
|
175967
|
+
const stopRenewal = startGitSweepLeaseRenewal(db, projectIdentity, holderId);
|
|
175968
|
+
log(`[git-commits] sweep starting for ${projectIdentity} (sinceDays=${gitCommitIndexing.since_days} maxCommits=${gitCommitIndexing.max_commits})`);
|
|
175757
175969
|
try {
|
|
175758
175970
|
const result = await indexCommitsForProject(db, projectIdentity, directory, {
|
|
175759
175971
|
sinceDays: gitCommitIndexing.since_days,
|
|
@@ -175763,11 +175975,19 @@ async function sweepGitCommits(args) {
|
|
|
175763
175975
|
if (result.embedded > 0) {
|
|
175764
175976
|
drainedEmbeddings = await embedUnembeddedCommits(db, projectIdentity);
|
|
175765
175977
|
}
|
|
175978
|
+
const cooldownMarked = markGitSweepSuccessAndRelease(db, projectIdentity, holderId);
|
|
175979
|
+
if (!cooldownMarked) {
|
|
175980
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
175981
|
+
log(`[git-commits] sweep finished for ${projectIdentity}, but lease was no longer active; cooldown not advanced`);
|
|
175982
|
+
}
|
|
175766
175983
|
const elapsedMs = Date.now() - startedAt;
|
|
175767
175984
|
log(`[git-commits] sweep finished for ${projectIdentity} in ${elapsedMs}ms: scanned=${result.scanned} inserted=${result.inserted} updated=${result.updated} evicted=${result.evicted} embedded=${result.embedded} drained=${drainedEmbeddings}`);
|
|
175768
175985
|
} catch (error51) {
|
|
175986
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
175769
175987
|
const elapsedMs = Date.now() - startedAt;
|
|
175770
|
-
log(`[git-commits] sweep failed for ${
|
|
175988
|
+
log(`[git-commits] sweep failed for ${projectIdentity} after ${elapsedMs}ms: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
175989
|
+
} finally {
|
|
175990
|
+
stopRenewal();
|
|
175771
175991
|
}
|
|
175772
175992
|
}
|
|
175773
175993
|
|
|
@@ -175908,7 +176128,7 @@ init_models_dev_cache();
|
|
|
175908
176128
|
var DEFAULT_CONTEXT_LIMIT = 128000;
|
|
175909
176129
|
var MAX_EXECUTE_THRESHOLD = 80;
|
|
175910
176130
|
function resolveContextLimit(providerID, modelID, ctx) {
|
|
175911
|
-
const fromModelsDev = providerID && modelID ?
|
|
176131
|
+
const fromModelsDev = providerID && modelID ? getSdkContextLimit(providerID, modelID) : undefined;
|
|
175912
176132
|
const baseline = fromModelsDev ?? DEFAULT_CONTEXT_LIMIT;
|
|
175913
176133
|
if (ctx?.db && ctx.sessionID) {
|
|
175914
176134
|
try {
|
|
@@ -175921,7 +176141,7 @@ function resolveContextLimit(providerID, modelID, ctx) {
|
|
|
175921
176141
|
return baseline;
|
|
175922
176142
|
}
|
|
175923
176143
|
function resolveTrustedContextLimit(providerID, modelID, ctx) {
|
|
175924
|
-
const fromModelsDev = providerID && modelID ?
|
|
176144
|
+
const fromModelsDev = providerID && modelID ? getSdkContextLimit(providerID, modelID) : undefined;
|
|
175925
176145
|
let detected;
|
|
175926
176146
|
if (ctx?.db && ctx.sessionID) {
|
|
175927
176147
|
try {
|
|
@@ -177279,7 +177499,8 @@ function getSessionCreatedInfo(properties) {
|
|
|
177279
177499
|
id: info.id,
|
|
177280
177500
|
parentID: info.parentID,
|
|
177281
177501
|
providerID: typeof info.providerID === "string" ? info.providerID : undefined,
|
|
177282
|
-
modelID: typeof info.modelID === "string" ? info.modelID : undefined
|
|
177502
|
+
modelID: typeof info.modelID === "string" ? info.modelID : undefined,
|
|
177503
|
+
title: typeof info.title === "string" ? info.title : undefined
|
|
177283
177504
|
};
|
|
177284
177505
|
}
|
|
177285
177506
|
function getMessageUpdatedAssistantInfo(properties) {
|
|
@@ -179346,6 +179567,64 @@ init_embedding();
|
|
|
179346
179567
|
|
|
179347
179568
|
// src/features/magic-context/search.ts
|
|
179348
179569
|
init_logger();
|
|
179570
|
+
|
|
179571
|
+
// src/features/magic-context/literal-probes.ts
|
|
179572
|
+
var MAX_PROBES = 5;
|
|
179573
|
+
var MIN_PROBE_LENGTH = 3;
|
|
179574
|
+
var SLASH_COMMAND_RE = /\/[a-z][a-z0-9]*(?:-[a-z0-9]+)+/gi;
|
|
179575
|
+
var KEBAB_SNAKE_RE = /[a-z][a-z0-9]*(?:[-_][a-z0-9]+)+/gi;
|
|
179576
|
+
var DOTTED_RE = /[a-z0-9][a-z0-9_-]*(?:\.[a-z0-9_-]+)+/gi;
|
|
179577
|
+
var CAMEL_RE = /\b[a-zA-Z][a-z0-9]*(?:[A-Z][a-z0-9]*)+\b/g;
|
|
179578
|
+
var SHA_RE = /\b[0-9a-f]{7,40}\b/gi;
|
|
179579
|
+
var ERROR_CODE_RE = /\b(?:TS\d{4,}|ERR_[A-Z][A-Z0-9_]*)\b/g;
|
|
179580
|
+
var QUOTED_RE = /["`]([^"`]{3,80})["`]/g;
|
|
179581
|
+
function looksLikeSha(token) {
|
|
179582
|
+
return /[0-9]/.test(token) && /^[0-9a-f]{7,40}$/i.test(token);
|
|
179583
|
+
}
|
|
179584
|
+
function extractLiteralProbes(query) {
|
|
179585
|
+
const trimmed = query.trim();
|
|
179586
|
+
if (trimmed.length === 0)
|
|
179587
|
+
return [];
|
|
179588
|
+
const ordered = [];
|
|
179589
|
+
const seen = new Set;
|
|
179590
|
+
const add = (raw) => {
|
|
179591
|
+
if (!raw)
|
|
179592
|
+
return;
|
|
179593
|
+
const probe = raw.trim();
|
|
179594
|
+
if (probe.length < MIN_PROBE_LENGTH)
|
|
179595
|
+
return;
|
|
179596
|
+
const key = probe.toLowerCase();
|
|
179597
|
+
if (seen.has(key))
|
|
179598
|
+
return;
|
|
179599
|
+
seen.add(key);
|
|
179600
|
+
ordered.push(probe);
|
|
179601
|
+
};
|
|
179602
|
+
for (const m of trimmed.matchAll(QUOTED_RE))
|
|
179603
|
+
add(m[1]);
|
|
179604
|
+
for (const m of trimmed.matchAll(SLASH_COMMAND_RE))
|
|
179605
|
+
add(m[0]);
|
|
179606
|
+
for (const m of trimmed.matchAll(ERROR_CODE_RE))
|
|
179607
|
+
add(m[0]);
|
|
179608
|
+
for (const m of trimmed.matchAll(DOTTED_RE))
|
|
179609
|
+
add(m[0]);
|
|
179610
|
+
for (const m of trimmed.matchAll(KEBAB_SNAKE_RE))
|
|
179611
|
+
add(m[0]);
|
|
179612
|
+
for (const m of trimmed.matchAll(CAMEL_RE))
|
|
179613
|
+
add(m[0]);
|
|
179614
|
+
for (const m of trimmed.matchAll(SHA_RE)) {
|
|
179615
|
+
if (looksLikeSha(m[0]))
|
|
179616
|
+
add(m[0]);
|
|
179617
|
+
}
|
|
179618
|
+
return ordered.slice(0, MAX_PROBES);
|
|
179619
|
+
}
|
|
179620
|
+
function containsProbeVerbatim(text, probes) {
|
|
179621
|
+
if (probes.length === 0)
|
|
179622
|
+
return false;
|
|
179623
|
+
const haystack = text.toLowerCase();
|
|
179624
|
+
return probes.some((probe) => haystack.includes(probe.toLowerCase()));
|
|
179625
|
+
}
|
|
179626
|
+
|
|
179627
|
+
// src/features/magic-context/search.ts
|
|
179349
179628
|
init_memory();
|
|
179350
179629
|
init_embedding();
|
|
179351
179630
|
init_storage_memory_fts();
|
|
@@ -179525,36 +179804,82 @@ function linearDecayScore(rank, total) {
|
|
|
179525
179804
|
return 0;
|
|
179526
179805
|
return Math.max(0, 1 - rank / total);
|
|
179527
179806
|
}
|
|
179528
|
-
function
|
|
179529
|
-
|
|
179530
|
-
if (sanitizedQuery.length === 0) {
|
|
179807
|
+
function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
|
|
179808
|
+
if (ftsQuery.length === 0)
|
|
179531
179809
|
return [];
|
|
179532
|
-
|
|
179533
|
-
const
|
|
179534
|
-
|
|
179535
|
-
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
179536
|
-
const filtered = rows.map((row) => {
|
|
179810
|
+
const rows = getMessageSearchStatement(db).all(sessionId, ftsQuery, fetchLimit).map((row) => row);
|
|
179811
|
+
const result = [];
|
|
179812
|
+
for (const row of rows) {
|
|
179537
179813
|
const messageOrdinal = getMessageOrdinal(row.messageOrdinal);
|
|
179538
179814
|
if (messageOrdinal === null || typeof row.messageId !== "string" || typeof row.role !== "string" || typeof row.content !== "string") {
|
|
179539
|
-
|
|
179815
|
+
continue;
|
|
179540
179816
|
}
|
|
179541
179817
|
if (cutoff !== null && messageOrdinal > cutoff) {
|
|
179542
|
-
|
|
179818
|
+
continue;
|
|
179543
179819
|
}
|
|
179544
|
-
|
|
179820
|
+
result.push({
|
|
179545
179821
|
messageOrdinal,
|
|
179546
179822
|
messageId: row.messageId,
|
|
179547
179823
|
role: row.role,
|
|
179548
179824
|
content: row.content
|
|
179549
|
-
};
|
|
179550
|
-
}
|
|
179551
|
-
return
|
|
179825
|
+
});
|
|
179826
|
+
}
|
|
179827
|
+
return result;
|
|
179828
|
+
}
|
|
179829
|
+
var RRF_K = 60;
|
|
179830
|
+
var VERBATIM_PROBE_BONUS = 0.5;
|
|
179831
|
+
function searchMessages(args) {
|
|
179832
|
+
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
179833
|
+
const fetchLimit = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.limit * 3 : args.limit;
|
|
179834
|
+
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
179835
|
+
const probes = args.probes ?? [];
|
|
179836
|
+
if (probes.length === 0) {
|
|
179837
|
+
const filtered = runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff).slice(0, args.limit);
|
|
179838
|
+
return filtered.map((row, rank) => ({
|
|
179839
|
+
source: "message",
|
|
179840
|
+
content: previewText(row.content),
|
|
179841
|
+
score: linearDecayScore(rank, filtered.length),
|
|
179842
|
+
messageOrdinal: row.messageOrdinal,
|
|
179843
|
+
messageId: row.messageId,
|
|
179844
|
+
role: row.role
|
|
179845
|
+
}));
|
|
179846
|
+
}
|
|
179847
|
+
const queryLists = [];
|
|
179848
|
+
if (baseQuery.length > 0) {
|
|
179849
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff));
|
|
179850
|
+
}
|
|
179851
|
+
for (const probe of probes) {
|
|
179852
|
+
const probeQuery = sanitizeFtsQuery(probe);
|
|
179853
|
+
if (probeQuery.length === 0)
|
|
179854
|
+
continue;
|
|
179855
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, probeQuery, fetchLimit, cutoff));
|
|
179856
|
+
}
|
|
179857
|
+
const fused = new Map;
|
|
179858
|
+
for (const list of queryLists) {
|
|
179859
|
+
list.forEach((row, rank) => {
|
|
179860
|
+
const rrf = 1 / (RRF_K + rank);
|
|
179861
|
+
const existing = fused.get(row.messageId);
|
|
179862
|
+
if (existing) {
|
|
179863
|
+
existing.score += rrf;
|
|
179864
|
+
} else {
|
|
179865
|
+
fused.set(row.messageId, { row, score: rrf });
|
|
179866
|
+
}
|
|
179867
|
+
});
|
|
179868
|
+
}
|
|
179869
|
+
for (const entry of fused.values()) {
|
|
179870
|
+
if (containsProbeVerbatim(entry.row.content, probes)) {
|
|
179871
|
+
entry.score += VERBATIM_PROBE_BONUS;
|
|
179872
|
+
}
|
|
179873
|
+
}
|
|
179874
|
+
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);
|
|
179875
|
+
const maxScore = ranked.length > 0 ? ranked[0].score : 1;
|
|
179876
|
+
return ranked.map((entry) => ({
|
|
179552
179877
|
source: "message",
|
|
179553
|
-
content: previewText(row.content),
|
|
179554
|
-
score:
|
|
179555
|
-
messageOrdinal: row.messageOrdinal,
|
|
179556
|
-
messageId: row.messageId,
|
|
179557
|
-
role: row.role
|
|
179878
|
+
content: previewText(entry.row.content),
|
|
179879
|
+
score: maxScore > 0 ? entry.score / maxScore : 0,
|
|
179880
|
+
messageOrdinal: entry.row.messageOrdinal,
|
|
179881
|
+
messageId: entry.row.messageId,
|
|
179882
|
+
role: entry.row.role
|
|
179558
179883
|
}));
|
|
179559
179884
|
}
|
|
179560
179885
|
function getSourceBoost(result) {
|
|
@@ -179638,12 +179963,14 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
179638
179963
|
return null;
|
|
179639
179964
|
}) : Promise.resolve(null);
|
|
179640
179965
|
await Promise.resolve();
|
|
179966
|
+
const messageProbes = options.explicitSearch ? extractLiteralProbes(trimmedQuery) : [];
|
|
179641
179967
|
const messageResults = runMessages ? searchMessages({
|
|
179642
179968
|
db,
|
|
179643
179969
|
sessionId,
|
|
179644
179970
|
query: trimmedQuery,
|
|
179645
179971
|
limit: tierLimit,
|
|
179646
|
-
maxOrdinal: options.maxMessageOrdinal
|
|
179972
|
+
maxOrdinal: options.maxMessageOrdinal,
|
|
179973
|
+
probes: messageProbes
|
|
179647
179974
|
}) : [];
|
|
179648
179975
|
const queryEmbedding = await queryEmbeddingPromise;
|
|
179649
179976
|
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
@@ -180226,7 +180553,7 @@ function isVisibleNoteReadPart(part) {
|
|
|
180226
180553
|
}
|
|
180227
180554
|
|
|
180228
180555
|
// src/hooks/magic-context/todo-view.ts
|
|
180229
|
-
import { createHash as
|
|
180556
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
180230
180557
|
var TERMINAL_STATUSES = new Set(["completed", "cancelled"]);
|
|
180231
180558
|
var TITLE_DONE_STATUSES = new Set(["completed"]);
|
|
180232
180559
|
var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
|
|
@@ -180271,7 +180598,7 @@ function buildSyntheticTodoPart(stateJson) {
|
|
|
180271
180598
|
};
|
|
180272
180599
|
}
|
|
180273
180600
|
function computeSyntheticCallId(stateJson) {
|
|
180274
|
-
const hash2 =
|
|
180601
|
+
const hash2 = createHash9("sha256").update(stateJson).digest("hex").slice(0, 16);
|
|
180275
180602
|
return `${SYNTHETIC_CALL_ID_PREFIX}${hash2}`;
|
|
180276
180603
|
}
|
|
180277
180604
|
function parseTodoState(stateJson) {
|
|
@@ -180837,6 +181164,10 @@ function createTransform(deps) {
|
|
|
180837
181164
|
return;
|
|
180838
181165
|
}
|
|
180839
181166
|
logTransformTiming(sessionId, "getOrCreateSessionMeta", tMeta);
|
|
181167
|
+
if (deps.internalChildSessions?.has(sessionId)) {
|
|
181168
|
+
sessionLog(sessionId, "transform skipped (internal magic-context child session)");
|
|
181169
|
+
return;
|
|
181170
|
+
}
|
|
180840
181171
|
const reducedMode = sessionMeta.isSubagent;
|
|
180841
181172
|
const fullFeatureMode = !reducedMode;
|
|
180842
181173
|
let sessionDirectory = deps.directory ?? "";
|
|
@@ -181432,6 +181763,7 @@ function truncateHistorianEmergencyError(error51) {
|
|
|
181432
181763
|
|
|
181433
181764
|
// src/hooks/magic-context/event-handler.ts
|
|
181434
181765
|
var CONTEXT_USAGE_TTL_MS = 60 * 60 * 1000;
|
|
181766
|
+
var INTERNAL_CHILD_TITLE_PREFIX = "magic-context-";
|
|
181435
181767
|
function formatTokens(value) {
|
|
181436
181768
|
return value.toLocaleString();
|
|
181437
181769
|
}
|
|
@@ -181496,6 +181828,10 @@ function createEventHandler2(deps) {
|
|
|
181496
181828
|
if (!info) {
|
|
181497
181829
|
return;
|
|
181498
181830
|
}
|
|
181831
|
+
if (deps.internalChildSessions && info.parentID.length > 0 && typeof info.title === "string" && info.title.startsWith(INTERNAL_CHILD_TITLE_PREFIX)) {
|
|
181832
|
+
deps.internalChildSessions.add(info.id);
|
|
181833
|
+
sessionLog(info.id, `marked internal magic-context child (title="${info.title}") — exempt from transform + injection`);
|
|
181834
|
+
}
|
|
181499
181835
|
try {
|
|
181500
181836
|
const modelKey = resolveModelKey(info.providerID, info.modelID);
|
|
181501
181837
|
updateSessionMeta(deps.db, info.id, {
|
|
@@ -181912,11 +182248,10 @@ await __promiseAll([
|
|
|
181912
182248
|
]);
|
|
181913
182249
|
|
|
181914
182250
|
// src/hooks/magic-context/text-complete.ts
|
|
181915
|
-
|
|
181916
|
-
var SECTION_CHAR_REGEX = /\u00a7/g;
|
|
182251
|
+
init_tag_content_primitives();
|
|
181917
182252
|
function createTextCompleteHandler() {
|
|
181918
182253
|
return async (_input, output) => {
|
|
181919
|
-
output.text = output.text
|
|
182254
|
+
output.text = stripPersistedAssistantText(output.text);
|
|
181920
182255
|
};
|
|
181921
182256
|
}
|
|
181922
182257
|
|
|
@@ -182138,7 +182473,7 @@ function createToolExecuteAfterHook(args) {
|
|
|
182138
182473
|
init_send_session_notification();
|
|
182139
182474
|
|
|
182140
182475
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
182141
|
-
import { createHash as
|
|
182476
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
182142
182477
|
|
|
182143
182478
|
// src/agents/magic-context-prompt.ts
|
|
182144
182479
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
@@ -182260,6 +182595,9 @@ function clearSystemPromptHashSession(sessionId, handleMaps) {
|
|
|
182260
182595
|
function isInternalOpenCodeAgent(systemPromptContent) {
|
|
182261
182596
|
return systemPromptContent.includes("You are a title generator. You output ONLY a thread title.") || systemPromptContent.includes("Summarize what was done in this conversation. Write like a pull request description.") || systemPromptContent.includes("You are an anchored context summarization assistant for coding sessions.");
|
|
182262
182597
|
}
|
|
182598
|
+
function isMagicContextInternalAgent(systemPromptContent) {
|
|
182599
|
+
return systemPromptContent.includes("You are Historian — the hippocampus of a long-running coding agent.") || systemPromptContent.includes("You are a memory maintenance agent for the magic-context system.") || systemPromptContent.includes("You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.") || systemPromptContent.includes("You are a file importance evaluator. Given read statistics about files");
|
|
182600
|
+
}
|
|
182263
182601
|
function createSystemPromptHashHandler(deps) {
|
|
182264
182602
|
const stickyDateBySession = new Map;
|
|
182265
182603
|
const handler = async (input, output) => {
|
|
@@ -182272,6 +182610,10 @@ function createSystemPromptHashHandler(deps) {
|
|
|
182272
182610
|
sessionLog(sessionId, "system-prompt-hash skipped (OpenCode internal agent: title/summary/compaction)");
|
|
182273
182611
|
return;
|
|
182274
182612
|
}
|
|
182613
|
+
if (deps.internalChildSessions?.has(sessionId) || isMagicContextInternalAgent(fullPromptForDetection)) {
|
|
182614
|
+
sessionLog(sessionId, "system-prompt-hash skipped (Magic Context internal child: historian/dreamer/sidekick/migration)");
|
|
182615
|
+
return;
|
|
182616
|
+
}
|
|
182275
182617
|
const injectionEnabled = deps.injectionEnabled !== false;
|
|
182276
182618
|
const skipSignatures = deps.injectionSkipSignatures ?? [];
|
|
182277
182619
|
if (!injectionEnabled) {
|
|
@@ -182322,7 +182664,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
182322
182664
|
`);
|
|
182323
182665
|
if (systemContent.length === 0)
|
|
182324
182666
|
return;
|
|
182325
|
-
const currentHash =
|
|
182667
|
+
const currentHash = createHash10("md5").update(systemContent).digest("hex");
|
|
182326
182668
|
if (!sessionMetaEarly) {
|
|
182327
182669
|
return;
|
|
182328
182670
|
}
|
|
@@ -182530,6 +182872,7 @@ function createMagicContextHook(deps) {
|
|
|
182530
182872
|
const liveModelBySession = deps.liveSessionState?.liveModelBySession ?? new Map;
|
|
182531
182873
|
const agentBySession = deps.liveSessionState?.agentBySession ?? new Map;
|
|
182532
182874
|
const sessionDirectoryBySession = deps.liveSessionState?.sessionDirectoryBySession ?? new Map;
|
|
182875
|
+
const internalChildSessions = deps.liveSessionState?.internalChildSessions ?? new Set;
|
|
182533
182876
|
const recompProgressBySession = deps.liveSessionState?.recompProgressBySession ?? new Map;
|
|
182534
182877
|
const recentReduceBySession = new Map;
|
|
182535
182878
|
const toolUsageSinceUserTurn = new Map;
|
|
@@ -182561,7 +182904,8 @@ function createMagicContextHook(deps) {
|
|
|
182561
182904
|
pendingMaterializationSessions,
|
|
182562
182905
|
deferredMaterializationSessions,
|
|
182563
182906
|
sessionDirectoryBySession,
|
|
182564
|
-
recompProgressBySession
|
|
182907
|
+
recompProgressBySession,
|
|
182908
|
+
internalChildSessions
|
|
182565
182909
|
},
|
|
182566
182910
|
directory: deps.directory,
|
|
182567
182911
|
historianChunkTokens: getHistorianChunkTokens(),
|
|
@@ -182606,6 +182950,7 @@ function createMagicContextHook(deps) {
|
|
|
182606
182950
|
deferredMaterializationSessions,
|
|
182607
182951
|
lastHeuristicsTurnId,
|
|
182608
182952
|
commitSeenLastPass,
|
|
182953
|
+
internalChildSessions,
|
|
182609
182954
|
client: deps.client,
|
|
182610
182955
|
directory: deps.directory,
|
|
182611
182956
|
memoryConfig: deps.config.memory ? {
|
|
@@ -182657,6 +183002,7 @@ function createMagicContextHook(deps) {
|
|
|
182657
183002
|
tagger: deps.tagger,
|
|
182658
183003
|
db,
|
|
182659
183004
|
client: deps.client,
|
|
183005
|
+
internalChildSessions,
|
|
182660
183006
|
getNotificationParams: (sessionId) => getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession),
|
|
182661
183007
|
nudgePlacements,
|
|
182662
183008
|
onSessionCacheInvalidated: (sessionId) => {
|
|
@@ -182674,6 +183020,7 @@ function createMagicContextHook(deps) {
|
|
|
182674
183020
|
recompProgressBySession.delete(sessionId);
|
|
182675
183021
|
recentReduceBySession.delete(sessionId);
|
|
182676
183022
|
toolUsageSinceUserTurn.delete(sessionId);
|
|
183023
|
+
internalChildSessions.delete(sessionId);
|
|
182677
183024
|
}
|
|
182678
183025
|
});
|
|
182679
183026
|
const runDreamQueueInBackground = () => {
|
|
@@ -182784,6 +183131,7 @@ function createMagicContextHook(deps) {
|
|
|
182784
183131
|
injectionSkipSignatures: deps.config.system_prompt_injection?.skip_signatures ?? [
|
|
182785
183132
|
"<!-- magic-context: skip -->"
|
|
182786
183133
|
],
|
|
183134
|
+
internalChildSessions,
|
|
182787
183135
|
experimentalUserMemories: deps.config.dreamer?.user_memories?.enabled,
|
|
182788
183136
|
experimentalPinKeyFiles: deps.config.dreamer?.pin_key_files?.enabled ?? false,
|
|
182789
183137
|
experimentalPinKeyFilesTokenBudget: deps.config.dreamer?.pin_key_files?.token_budget,
|
|
@@ -183551,6 +183899,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
|
|
|
183551
183899
|
if (!p)
|
|
183552
183900
|
return null;
|
|
183553
183901
|
return {
|
|
183902
|
+
kind: p.kind ?? "recomp",
|
|
183554
183903
|
phase: p.phase,
|
|
183555
183904
|
processedMessages: p.processedMessages,
|
|
183556
183905
|
totalMessages: p.totalMessages,
|
|
@@ -183570,6 +183919,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
|
|
|
183570
183919
|
return {
|
|
183571
183920
|
...empty,
|
|
183572
183921
|
recompProgress: {
|
|
183922
|
+
kind: p.kind ?? "recomp",
|
|
183573
183923
|
phase: p.phase,
|
|
183574
183924
|
processedMessages: p.processedMessages,
|
|
183575
183925
|
totalMessages: p.totalMessages,
|
|
@@ -184286,16 +184636,30 @@ Example: \`ctx_note(action="write", content="Implement X because Y", surface_con
|
|
|
184286
184636
|
|
|
184287
184637
|
Historian reads these notes, deduplicates them, and rewrites the remaining useful notes over time.`;
|
|
184288
184638
|
// src/tools/ctx-note/tools.ts
|
|
184289
|
-
await
|
|
184639
|
+
await __promiseAll([
|
|
184640
|
+
init_message_index(),
|
|
184641
|
+
init_storage()
|
|
184642
|
+
]);
|
|
184290
184643
|
import { tool as tool3 } from "@opencode-ai/plugin";
|
|
184644
|
+
function captureAnchorOrdinal(db, sessionId) {
|
|
184645
|
+
try {
|
|
184646
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
184647
|
+
return ordinal > 0 ? ordinal : null;
|
|
184648
|
+
} catch {
|
|
184649
|
+
return null;
|
|
184650
|
+
}
|
|
184651
|
+
}
|
|
184652
|
+
function anchorSuffix(note) {
|
|
184653
|
+
return note.anchorOrdinal !== null ? ` ↳ @msg ${note.anchorOrdinal}` : "";
|
|
184654
|
+
}
|
|
184291
184655
|
function formatNoteLine(note) {
|
|
184292
184656
|
const statusSuffix = note.status === "active" ? "" : ` (${note.status})`;
|
|
184293
184657
|
if (note.type === "session") {
|
|
184294
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}`;
|
|
184658
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}`;
|
|
184295
184659
|
}
|
|
184296
184660
|
const conditionText = note.status === "ready" ? note.readyReason ?? note.surfaceCondition ?? "Condition satisfied" : note.surfaceCondition ?? "No condition recorded";
|
|
184297
184661
|
const conditionLabel = note.status === "ready" ? "Condition met" : "Condition";
|
|
184298
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}
|
|
184662
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}
|
|
184299
184663
|
${conditionLabel}: ${conditionText}`;
|
|
184300
184664
|
}
|
|
184301
184665
|
var DISMISS_FOOTER = `
|
|
@@ -184373,6 +184737,7 @@ function createCtxNoteTool(deps) {
|
|
|
184373
184737
|
if (!content) {
|
|
184374
184738
|
return "Error: 'content' is required when action is 'write'.";
|
|
184375
184739
|
}
|
|
184740
|
+
const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
|
|
184376
184741
|
if (args.surface_condition?.trim()) {
|
|
184377
184742
|
if (!deps.dreamerEnabled) {
|
|
184378
184743
|
return "Error: Smart notes require dreamer to be enabled. Enable dreamer in magic-context.jsonc to use surface_condition.";
|
|
@@ -184384,13 +184749,14 @@ function createCtxNoteTool(deps) {
|
|
|
184384
184749
|
content,
|
|
184385
184750
|
projectPath: projectIdentity,
|
|
184386
184751
|
sessionId,
|
|
184387
|
-
surfaceCondition: args.surface_condition.trim()
|
|
184752
|
+
surfaceCondition: args.surface_condition.trim(),
|
|
184753
|
+
anchorOrdinal
|
|
184388
184754
|
});
|
|
184389
184755
|
return `Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
|
|
184390
184756
|
- Content: ${content}
|
|
184391
184757
|
- Condition: ${args.surface_condition.trim()}`;
|
|
184392
184758
|
}
|
|
184393
|
-
const note = addNote(deps.db, "session", { sessionId, content });
|
|
184759
|
+
const note = addNote(deps.db, "session", { sessionId, content, anchorOrdinal });
|
|
184394
184760
|
return `Saved session note #${note.id}. Historian will rewrite or deduplicate notes as needed.`;
|
|
184395
184761
|
}
|
|
184396
184762
|
if (action === "dismiss") {
|
|
@@ -184453,9 +184819,13 @@ ${parts.join(`
|
|
|
184453
184819
|
|
|
184454
184820
|
No session notes or smart notes.`;
|
|
184455
184821
|
}
|
|
184456
|
-
|
|
184822
|
+
const body = sections.join(`
|
|
184457
184823
|
|
|
184458
|
-
`)
|
|
184824
|
+
`);
|
|
184825
|
+
const anchorHint = body.includes("↳ @msg ") ? `
|
|
184826
|
+
|
|
184827
|
+
↳ @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).` : "";
|
|
184828
|
+
return body + anchorHint + DISMISS_FOOTER;
|
|
184459
184829
|
}
|
|
184460
184830
|
});
|
|
184461
184831
|
}
|
|
@@ -184746,7 +185116,8 @@ function createCtxSearchTool(deps) {
|
|
|
184746
185116
|
maxMessageOrdinal: lastCompartmentEnd >= 0 ? lastCompartmentEnd : undefined,
|
|
184747
185117
|
gitCommitsEnabled,
|
|
184748
185118
|
sources: normalizeSources(args.sources),
|
|
184749
|
-
visibleMemoryIds
|
|
185119
|
+
visibleMemoryIds,
|
|
185120
|
+
explicitSearch: true
|
|
184750
185121
|
});
|
|
184751
185122
|
return formatSearchResults(query, results);
|
|
184752
185123
|
}
|
|
@@ -184847,22 +185218,22 @@ init_models_dev_cache();
|
|
|
184847
185218
|
init_logger();
|
|
184848
185219
|
import { randomBytes } from "node:crypto";
|
|
184849
185220
|
import {
|
|
184850
|
-
mkdirSync as
|
|
185221
|
+
mkdirSync as mkdirSync9,
|
|
184851
185222
|
readdirSync,
|
|
184852
185223
|
readFileSync as readFileSync15,
|
|
184853
|
-
renameSync as
|
|
185224
|
+
renameSync as renameSync4,
|
|
184854
185225
|
unlinkSync as unlinkSync3,
|
|
184855
|
-
writeFileSync as
|
|
185226
|
+
writeFileSync as writeFileSync8
|
|
184856
185227
|
} from "node:fs";
|
|
184857
185228
|
import { createServer } from "node:http";
|
|
184858
185229
|
import { dirname as dirname8 } from "node:path";
|
|
184859
185230
|
|
|
184860
185231
|
// src/shared/rpc-utils.ts
|
|
184861
|
-
import { createHash as
|
|
185232
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
184862
185233
|
import { join as join24 } from "node:path";
|
|
184863
185234
|
function projectHash(directory) {
|
|
184864
185235
|
const normalized = directory.replace(/\/+$/, "");
|
|
184865
|
-
return
|
|
185236
|
+
return createHash11("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
184866
185237
|
}
|
|
184867
185238
|
function rpcPortDir(storageDir, directory) {
|
|
184868
185239
|
return join24(storageDir, "rpc", projectHash(directory));
|
|
@@ -184945,15 +185316,15 @@ class MagicContextRpcServer {
|
|
|
184945
185316
|
try {
|
|
184946
185317
|
this.warnIfOtherLiveInstance();
|
|
184947
185318
|
const dir = dirname8(this.portFilePath);
|
|
184948
|
-
|
|
185319
|
+
mkdirSync9(dir, { recursive: true, mode: 448 });
|
|
184949
185320
|
const tmpPath = `${this.portFilePath}.tmp`;
|
|
184950
|
-
|
|
185321
|
+
writeFileSync8(tmpPath, JSON.stringify({
|
|
184951
185322
|
port: this.port,
|
|
184952
185323
|
pid: process.pid,
|
|
184953
185324
|
started_at: this.startedAt,
|
|
184954
185325
|
token: this.token
|
|
184955
185326
|
}), { encoding: "utf-8", mode: 384 });
|
|
184956
|
-
|
|
185327
|
+
renameSync4(tmpPath, this.portFilePath);
|
|
184957
185328
|
log(`[rpc] server listening on 127.0.0.1:${this.port}`);
|
|
184958
185329
|
} catch (err) {
|
|
184959
185330
|
log(`[rpc] failed to write port file: ${err}`);
|
|
@@ -185153,7 +185524,7 @@ var plugin = async (ctx) => {
|
|
|
185153
185524
|
rpcServer.start().catch((err) => {
|
|
185154
185525
|
log(`[magic-context] RPC server failed to start: ${err}`);
|
|
185155
185526
|
});
|
|
185156
|
-
refreshModelLimitsFromApi(ctx.client);
|
|
185527
|
+
refreshModelLimitsFromApi(ctx.client, { retries: 3, retryDelayMs: 1000 });
|
|
185157
185528
|
}
|
|
185158
185529
|
{
|
|
185159
185530
|
const fence = getSchemaFenceRejection();
|