@proxysoul/soulforge 2.16.5 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +945 -331
- package/dist/workers/intelligence.worker.js +280 -188
- package/dist/workers/io.worker.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -45146,7 +45146,17 @@ class SessionManager {
|
|
|
45146
45146
|
const updatedTabs = updatedTabsRaw.map((t) => {
|
|
45147
45147
|
let msgs;
|
|
45148
45148
|
if (t.id === tabMeta.id) {
|
|
45149
|
-
|
|
45149
|
+
if (tabIdx >= 0) {
|
|
45150
|
+
const prevRange = oldTabs[tabIdx]?.messageRange;
|
|
45151
|
+
const priorSlice = prevRange ? existingAllMessages.slice(prevRange.startLine, prevRange.endLine) : [];
|
|
45152
|
+
if (messages.length < priorSlice.length) {
|
|
45153
|
+
msgs = priorSlice;
|
|
45154
|
+
} else {
|
|
45155
|
+
msgs = messages;
|
|
45156
|
+
}
|
|
45157
|
+
} else {
|
|
45158
|
+
msgs = messages;
|
|
45159
|
+
}
|
|
45150
45160
|
} else {
|
|
45151
45161
|
const prevRange = t.messageRange;
|
|
45152
45162
|
msgs = existingAllMessages.slice(prevRange.startLine, prevRange.endLine);
|
|
@@ -45195,6 +45205,97 @@ class SessionManager {
|
|
|
45195
45205
|
await rename(coreTmp, corePath);
|
|
45196
45206
|
}
|
|
45197
45207
|
}
|
|
45208
|
+
async pruneTabsNotIn(sessionId, keepIds) {
|
|
45209
|
+
const sessionDir = join10(this.dir, sessionId);
|
|
45210
|
+
const metaPath = join10(sessionDir, "meta.json");
|
|
45211
|
+
if (!existsSync9(metaPath))
|
|
45212
|
+
return;
|
|
45213
|
+
const prev = this.saveChains.get(sessionId) ?? Promise.resolve();
|
|
45214
|
+
const next = prev.catch(() => {}).then(async () => {
|
|
45215
|
+
let meta3;
|
|
45216
|
+
try {
|
|
45217
|
+
meta3 = JSON.parse(readFileSync9(metaPath, "utf-8"));
|
|
45218
|
+
} catch {
|
|
45219
|
+
return;
|
|
45220
|
+
}
|
|
45221
|
+
const keptTabs = meta3.tabs.filter((t) => keepIds.has(t.id));
|
|
45222
|
+
if (keptTabs.length === meta3.tabs.length)
|
|
45223
|
+
return;
|
|
45224
|
+
const jsonlPath = join10(sessionDir, "messages.jsonl");
|
|
45225
|
+
const allMessages = [];
|
|
45226
|
+
if (existsSync9(jsonlPath)) {
|
|
45227
|
+
const content = readFileSync9(jsonlPath, "utf-8").trim();
|
|
45228
|
+
if (content) {
|
|
45229
|
+
for (const line of content.split(`
|
|
45230
|
+
`)) {
|
|
45231
|
+
if (!line.trim())
|
|
45232
|
+
continue;
|
|
45233
|
+
try {
|
|
45234
|
+
allMessages.push(JSON.parse(line));
|
|
45235
|
+
} catch {
|
|
45236
|
+
break;
|
|
45237
|
+
}
|
|
45238
|
+
}
|
|
45239
|
+
}
|
|
45240
|
+
}
|
|
45241
|
+
const rebuiltAll = [];
|
|
45242
|
+
const updatedTabs = keptTabs.map((t) => {
|
|
45243
|
+
const { startLine, endLine } = t.messageRange;
|
|
45244
|
+
const slice = allMessages.slice(startLine, endLine);
|
|
45245
|
+
const newStart = rebuiltAll.length;
|
|
45246
|
+
for (const m of slice)
|
|
45247
|
+
rebuiltAll.push(m);
|
|
45248
|
+
return { ...t, messageRange: { startLine: newStart, endLine: rebuiltAll.length } };
|
|
45249
|
+
});
|
|
45250
|
+
const updatedMeta = { ...meta3, tabs: updatedTabs, updatedAt: Date.now() };
|
|
45251
|
+
const corePath = join10(sessionDir, "core.json");
|
|
45252
|
+
let updatedCore = null;
|
|
45253
|
+
if (existsSync9(corePath)) {
|
|
45254
|
+
try {
|
|
45255
|
+
const coreData = JSON.parse(readFileSync9(corePath, "utf-8"));
|
|
45256
|
+
updatedCore = {};
|
|
45257
|
+
for (const id of keepIds) {
|
|
45258
|
+
if (coreData[id])
|
|
45259
|
+
updatedCore[id] = coreData[id];
|
|
45260
|
+
}
|
|
45261
|
+
} catch {
|
|
45262
|
+
updatedCore = null;
|
|
45263
|
+
}
|
|
45264
|
+
}
|
|
45265
|
+
const lines = rebuiltAll.map((m) => JSON.stringify(m)).join(`
|
|
45266
|
+
`);
|
|
45267
|
+
const suffix = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
45268
|
+
const metaTmp = `${metaPath}.${suffix}.tmp`;
|
|
45269
|
+
const jsonlTmp = `${jsonlPath}.${suffix}.tmp`;
|
|
45270
|
+
await writeFile(metaTmp, JSON.stringify(updatedMeta, null, 2), {
|
|
45271
|
+
encoding: "utf-8",
|
|
45272
|
+
mode: 384
|
|
45273
|
+
});
|
|
45274
|
+
await writeFile(jsonlTmp, lines ? `${lines}
|
|
45275
|
+
` : "", {
|
|
45276
|
+
encoding: "utf-8",
|
|
45277
|
+
mode: 384
|
|
45278
|
+
});
|
|
45279
|
+
await rename(jsonlTmp, jsonlPath);
|
|
45280
|
+
await rename(metaTmp, metaPath);
|
|
45281
|
+
if (updatedCore) {
|
|
45282
|
+
const coreTmp = `${corePath}.${suffix}.tmp`;
|
|
45283
|
+
await writeFile(coreTmp, JSON.stringify(updatedCore), {
|
|
45284
|
+
encoding: "utf-8",
|
|
45285
|
+
mode: 384
|
|
45286
|
+
});
|
|
45287
|
+
await rename(coreTmp, corePath);
|
|
45288
|
+
}
|
|
45289
|
+
});
|
|
45290
|
+
this.saveChains.set(sessionId, next);
|
|
45291
|
+
try {
|
|
45292
|
+
await next;
|
|
45293
|
+
} finally {
|
|
45294
|
+
if (this.saveChains.get(sessionId) === next) {
|
|
45295
|
+
this.saveChains.delete(sessionId);
|
|
45296
|
+
}
|
|
45297
|
+
}
|
|
45298
|
+
}
|
|
45198
45299
|
}
|
|
45199
45300
|
var init_manager = __esm(() => {
|
|
45200
45301
|
init_errors();
|
|
@@ -64339,7 +64440,7 @@ var package_default;
|
|
|
64339
64440
|
var init_package = __esm(() => {
|
|
64340
64441
|
package_default = {
|
|
64341
64442
|
name: "@proxysoul/soulforge",
|
|
64342
|
-
version: "2.
|
|
64443
|
+
version: "2.17.0",
|
|
64343
64444
|
description: "Graph-powered code intelligence \u2014 multi-agent coding with codebase-aware AI",
|
|
64344
64445
|
repository: {
|
|
64345
64446
|
type: "git",
|
|
@@ -97616,7 +97717,7 @@ Speak once, at the end. Exceptions: (a) destructive/irreversible action needs co
|
|
|
97616
97717
|
|
|
97617
97718
|
Reasoning is unchanged \u2014 think as deeply as the task needs, internally. Compression applies to OUTPUT only.
|
|
97618
97719
|
|
|
97619
|
-
Commit boundary \u2014 when a turn uses 2+ tool calls (parallel batches count), call \`set_lockin({on:false})
|
|
97720
|
+
Commit boundary \u2014 when a turn uses 2+ tool calls (parallel batches count), the LAST tool call before your final answer text MUST be \`set_lockin({on:false})\`. Sequence is strict: [last real tool] \u2192 [set_lockin({on:false})] \u2192 [final answer text]. Never write prose, then call lockin \u2014 by then the answer is already streaming and the marker arrives too late. Skip lockin entirely on zero/one-tool turns.
|
|
97620
97721
|
</tool_loop>
|
|
97621
97722
|
|
|
97622
97723
|
<answer_voice>
|
|
@@ -98494,6 +98595,19 @@ var init_hooks = __esm(() => {
|
|
|
98494
98595
|
init_tool_names();
|
|
98495
98596
|
});
|
|
98496
98597
|
|
|
98598
|
+
// src/core/utils/hash.ts
|
|
98599
|
+
function hash32(s) {
|
|
98600
|
+
let h = 2166136261;
|
|
98601
|
+
for (let i2 = 0;i2 < s.length; i2++) {
|
|
98602
|
+
h ^= s.charCodeAt(i2);
|
|
98603
|
+
h = Math.imul(h, 16777619);
|
|
98604
|
+
}
|
|
98605
|
+
return h >>> 0;
|
|
98606
|
+
}
|
|
98607
|
+
function hash32Hex(s) {
|
|
98608
|
+
return hash32(s).toString(16).padStart(8, "0");
|
|
98609
|
+
}
|
|
98610
|
+
|
|
98497
98611
|
// src/core/memory/embedder.ts
|
|
98498
98612
|
var exports_embedder = {};
|
|
98499
98613
|
__export(exports_embedder, {
|
|
@@ -98562,18 +98676,10 @@ function charNgrams(text2, n) {
|
|
|
98562
98676
|
out2.push(compact.slice(i2, i2 + n));
|
|
98563
98677
|
return out2;
|
|
98564
98678
|
}
|
|
98565
|
-
function hashToken(token) {
|
|
98566
|
-
let h = 2166136261;
|
|
98567
|
-
for (let i2 = 0;i2 < token.length; i2++) {
|
|
98568
|
-
h ^= token.charCodeAt(i2);
|
|
98569
|
-
h = Math.imul(h, 16777619);
|
|
98570
|
-
}
|
|
98571
|
-
return h >>> 0;
|
|
98572
|
-
}
|
|
98573
98679
|
function project(vec, token, weight, dim) {
|
|
98574
|
-
const h =
|
|
98680
|
+
const h = hash32(token);
|
|
98575
98681
|
const bin = h % dim;
|
|
98576
|
-
const sign = (
|
|
98682
|
+
const sign = (hash32(`s:${token}`) & 1) === 0 ? 1 : -1;
|
|
98577
98683
|
vec[bin] = (vec[bin] ?? 0) + sign * weight;
|
|
98578
98684
|
}
|
|
98579
98685
|
function embed2(text2, dim = EMBED_DIM) {
|
|
@@ -99215,6 +99321,9 @@ ${normalize(details)}`;
|
|
|
99215
99321
|
}
|
|
99216
99322
|
}
|
|
99217
99323
|
close() {
|
|
99324
|
+
try {
|
|
99325
|
+
this.db.run("PRAGMA optimize");
|
|
99326
|
+
} catch {}
|
|
99218
99327
|
this.db.close();
|
|
99219
99328
|
}
|
|
99220
99329
|
findDuplicates() {
|
|
@@ -99536,6 +99645,32 @@ ${normalize(details)}`;
|
|
|
99536
99645
|
}
|
|
99537
99646
|
} catch {}
|
|
99538
99647
|
}
|
|
99648
|
+
topCategoriesByPath(paths) {
|
|
99649
|
+
const out2 = new Map;
|
|
99650
|
+
if (paths.length === 0)
|
|
99651
|
+
return out2;
|
|
99652
|
+
const placeholders = paths.map(() => "?").join(",");
|
|
99653
|
+
const rows = this.db.query(`SELECT mf.path, m.category, m.pinned
|
|
99654
|
+
FROM memories m
|
|
99655
|
+
JOIN memory_files mf ON mf.memory_id = m.id
|
|
99656
|
+
WHERE mf.path IN (${placeholders}) AND m.hidden = 0`).all(...paths);
|
|
99657
|
+
const priority = { gotcha: 4, pref: 3, decision: 2, context: 1 };
|
|
99658
|
+
for (const r of rows) {
|
|
99659
|
+
const cur = out2.get(r.path);
|
|
99660
|
+
if (!cur) {
|
|
99661
|
+
out2.set(r.path, { category: r.category, count: 1, pinned: r.pinned });
|
|
99662
|
+
continue;
|
|
99663
|
+
}
|
|
99664
|
+
cur.count += 1;
|
|
99665
|
+
if (r.pinned > cur.pinned)
|
|
99666
|
+
cur.pinned = r.pinned;
|
|
99667
|
+
const a = cur.category ? priority[cur.category] ?? 0 : 0;
|
|
99668
|
+
const b = r.category ? priority[r.category] ?? 0 : 0;
|
|
99669
|
+
if (b > a)
|
|
99670
|
+
cur.category = r.category;
|
|
99671
|
+
}
|
|
99672
|
+
return out2;
|
|
99673
|
+
}
|
|
99539
99674
|
}
|
|
99540
99675
|
function normalize(s) {
|
|
99541
99676
|
return s.replace(/\s+/g, " ").trim().toLowerCase();
|
|
@@ -100322,16 +100457,25 @@ var init_cache = () => {};
|
|
|
100322
100457
|
|
|
100323
100458
|
// src/core/intelligence/types.ts
|
|
100324
100459
|
function detectLanguageFromPath(file2) {
|
|
100325
|
-
const
|
|
100326
|
-
|
|
100327
|
-
|
|
100328
|
-
|
|
100329
|
-
|
|
100460
|
+
const slash = file2.lastIndexOf("/");
|
|
100461
|
+
const base = (slash === -1 ? file2 : file2.slice(slash + 1)).toLowerCase();
|
|
100462
|
+
const bare = BARE_FILENAME_TO_LANGUAGE[base];
|
|
100463
|
+
if (bare)
|
|
100464
|
+
return bare;
|
|
100465
|
+
if (base.startsWith("dockerfile."))
|
|
100466
|
+
return "dockerfile";
|
|
100467
|
+
if (base.startsWith("containerfile."))
|
|
100468
|
+
return "dockerfile";
|
|
100469
|
+
if (base.startsWith("makefile."))
|
|
100470
|
+
return "makefile";
|
|
100471
|
+
if (base.startsWith("justfile."))
|
|
100472
|
+
return "just";
|
|
100473
|
+
const dot = base.lastIndexOf(".");
|
|
100474
|
+
if (dot === -1)
|
|
100330
100475
|
return "unknown";
|
|
100331
|
-
|
|
100332
|
-
return EXT_TO_LANGUAGE[file2.slice(dot).toLowerCase()] ?? "unknown";
|
|
100476
|
+
return EXT_TO_LANGUAGE[base.slice(dot)] ?? "unknown";
|
|
100333
100477
|
}
|
|
100334
|
-
var EXT_TO_LANGUAGE;
|
|
100478
|
+
var EXT_TO_LANGUAGE, BARE_FILENAME_TO_LANGUAGE;
|
|
100335
100479
|
var init_types2 = __esm(() => {
|
|
100336
100480
|
EXT_TO_LANGUAGE = {
|
|
100337
100481
|
".ts": "typescript",
|
|
@@ -100385,7 +100529,35 @@ var init_types2 = __esm(() => {
|
|
|
100385
100529
|
".toml": "toml",
|
|
100386
100530
|
".yaml": "yaml",
|
|
100387
100531
|
".yml": "yaml",
|
|
100532
|
+
".xml": "xml",
|
|
100533
|
+
".md": "markdown",
|
|
100534
|
+
".markdown": "markdown",
|
|
100535
|
+
".mdx": "mdx",
|
|
100536
|
+
".sql": "sql",
|
|
100537
|
+
".graphql": "graphql",
|
|
100538
|
+
".gql": "graphql",
|
|
100539
|
+
".proto": "proto",
|
|
100540
|
+
".env": "env",
|
|
100541
|
+
".ini": "ini",
|
|
100542
|
+
".cfg": "ini",
|
|
100543
|
+
".conf": "ini",
|
|
100544
|
+
".properties": "properties",
|
|
100388
100545
|
".dockerfile": "dockerfile",
|
|
100546
|
+
".mk": "makefile",
|
|
100547
|
+
".nix": "nix",
|
|
100548
|
+
".hcl": "hcl",
|
|
100549
|
+
".tf": "hcl",
|
|
100550
|
+
".tfvars": "hcl",
|
|
100551
|
+
".bzl": "bazel",
|
|
100552
|
+
".star": "bazel",
|
|
100553
|
+
".bazel": "bazel",
|
|
100554
|
+
".jsonnet": "jsonnet",
|
|
100555
|
+
".libsonnet": "jsonnet",
|
|
100556
|
+
".svg": "svg",
|
|
100557
|
+
".csv": "csv",
|
|
100558
|
+
".tsv": "csv",
|
|
100559
|
+
".lock": "lockfile",
|
|
100560
|
+
".lockb": "lockfile",
|
|
100389
100561
|
".vue": "vue",
|
|
100390
100562
|
".res": "rescript",
|
|
100391
100563
|
".resi": "rescript",
|
|
@@ -100393,6 +100565,39 @@ var init_types2 = __esm(() => {
|
|
|
100393
100565
|
".tla": "tlaplus",
|
|
100394
100566
|
".el": "elisp"
|
|
100395
100567
|
};
|
|
100568
|
+
BARE_FILENAME_TO_LANGUAGE = {
|
|
100569
|
+
dockerfile: "dockerfile",
|
|
100570
|
+
containerfile: "dockerfile",
|
|
100571
|
+
makefile: "makefile",
|
|
100572
|
+
gnumakefile: "makefile",
|
|
100573
|
+
justfile: "just",
|
|
100574
|
+
".justfile": "just",
|
|
100575
|
+
build: "bazel",
|
|
100576
|
+
"build.bazel": "bazel",
|
|
100577
|
+
workspace: "bazel",
|
|
100578
|
+
"workspace.bazel": "bazel",
|
|
100579
|
+
"module.bazel": "bazel",
|
|
100580
|
+
".env": "env",
|
|
100581
|
+
".gitignore": "ignore",
|
|
100582
|
+
".dockerignore": "ignore",
|
|
100583
|
+
".npmignore": "ignore",
|
|
100584
|
+
".prettierignore": "ignore",
|
|
100585
|
+
".eslintignore": "ignore",
|
|
100586
|
+
".editorconfig": "ini",
|
|
100587
|
+
"bun.lock": "lockfile",
|
|
100588
|
+
"bun.lockb": "lockfile",
|
|
100589
|
+
"package-lock.json": "lockfile",
|
|
100590
|
+
"pnpm-lock.yaml": "lockfile",
|
|
100591
|
+
"yarn.lock": "lockfile",
|
|
100592
|
+
"cargo.lock": "lockfile",
|
|
100593
|
+
"poetry.lock": "lockfile",
|
|
100594
|
+
"composer.lock": "lockfile",
|
|
100595
|
+
"gemfile.lock": "lockfile",
|
|
100596
|
+
"go.sum": "lockfile",
|
|
100597
|
+
gemfile: "ruby",
|
|
100598
|
+
rakefile: "ruby",
|
|
100599
|
+
podfile: "ruby"
|
|
100600
|
+
};
|
|
100396
100601
|
});
|
|
100397
100602
|
|
|
100398
100603
|
// src/core/intelligence/backends/lsp/protocol.ts
|
|
@@ -358647,7 +358852,17 @@ var init_forbidden = __esm(() => {
|
|
|
358647
358852
|
// src/core/intelligence/repo-map-utils.ts
|
|
358648
358853
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
358649
358854
|
import { homedir as homedir20 } from "os";
|
|
358650
|
-
import {
|
|
358855
|
+
import { join as join24, resolve as resolve12 } from "path";
|
|
358856
|
+
function isIndexablePath(file2) {
|
|
358857
|
+
return detectLanguageFromPath(file2) !== "unknown" || isBareIndexable(file2);
|
|
358858
|
+
}
|
|
358859
|
+
function isBareIndexable(file2) {
|
|
358860
|
+
const slash = file2.lastIndexOf("/");
|
|
358861
|
+
const base = (slash === -1 ? file2 : file2.slice(slash + 1)).toLowerCase();
|
|
358862
|
+
if (BARE_FILENAME_TO_LANGUAGE[base])
|
|
358863
|
+
return true;
|
|
358864
|
+
return base.startsWith("dockerfile.") || base.startsWith("containerfile.") || base.startsWith("makefile.") || base.startsWith("justfile.");
|
|
358865
|
+
}
|
|
358651
358866
|
function barrelToDir(barrelPath) {
|
|
358652
358867
|
return barrelPath.replace(BARREL_RE, "");
|
|
358653
358868
|
}
|
|
@@ -358860,8 +359075,7 @@ async function collectFilesViaGit(dir) {
|
|
|
358860
359075
|
`)) {
|
|
358861
359076
|
if (!line)
|
|
358862
359077
|
continue;
|
|
358863
|
-
|
|
358864
|
-
if (!(ext in INDEXABLE_EXTENSIONS))
|
|
359078
|
+
if (!isIndexablePath(line))
|
|
358865
359079
|
continue;
|
|
358866
359080
|
const fullPath = join24(dir, line);
|
|
358867
359081
|
if (isForbidden(fullPath))
|
|
@@ -358888,8 +359102,10 @@ async function collectFilesWalk(dir, depth, counter, out2) {
|
|
|
358888
359102
|
for (const entry of await readdir2(dir, { withFileTypes: true })) {
|
|
358889
359103
|
if (ctx.n >= WALK_FILE_CAP)
|
|
358890
359104
|
break;
|
|
358891
|
-
if (entry.name.startsWith(".") && entry.name !== ".")
|
|
358892
|
-
|
|
359105
|
+
if (entry.name.startsWith(".") && entry.name !== ".") {
|
|
359106
|
+
if (!entry.isFile() || !isIndexablePath(entry.name))
|
|
359107
|
+
continue;
|
|
359108
|
+
}
|
|
358893
359109
|
const fullPath = join24(dir, entry.name);
|
|
358894
359110
|
if (entry.isDirectory()) {
|
|
358895
359111
|
if (!IGNORED_DIRS.has(entry.name)) {
|
|
@@ -358898,8 +359114,7 @@ async function collectFilesWalk(dir, depth, counter, out2) {
|
|
|
358898
359114
|
} else if (entry.isFile()) {
|
|
358899
359115
|
if (isForbidden(fullPath))
|
|
358900
359116
|
continue;
|
|
358901
|
-
|
|
358902
|
-
if (ext in INDEXABLE_EXTENSIONS) {
|
|
359117
|
+
if (isIndexablePath(entry.name)) {
|
|
358903
359118
|
try {
|
|
358904
359119
|
const s = await stat2(fullPath);
|
|
358905
359120
|
if (s.size < MAX_FILE_SIZE) {
|
|
@@ -358919,84 +359134,35 @@ var INDEXABLE_EXTENSIONS, NON_CODE_LANGUAGES, IMPORT_TRACKABLE_LANGUAGES, BARREL
|
|
|
358919
359134
|
var init_repo_map_utils = __esm(() => {
|
|
358920
359135
|
init_file_tree();
|
|
358921
359136
|
init_forbidden();
|
|
358922
|
-
|
|
358923
|
-
|
|
358924
|
-
".tsx": "typescript",
|
|
358925
|
-
".mts": "typescript",
|
|
358926
|
-
".cts": "typescript",
|
|
358927
|
-
".js": "javascript",
|
|
358928
|
-
".jsx": "javascript",
|
|
358929
|
-
".mjs": "javascript",
|
|
358930
|
-
".cjs": "javascript",
|
|
358931
|
-
".py": "python",
|
|
358932
|
-
".go": "go",
|
|
358933
|
-
".rs": "rust",
|
|
358934
|
-
".java": "java",
|
|
358935
|
-
".c": "c",
|
|
358936
|
-
".h": "c",
|
|
358937
|
-
".cpp": "cpp",
|
|
358938
|
-
".cc": "cpp",
|
|
358939
|
-
".cxx": "cpp",
|
|
358940
|
-
".hpp": "cpp",
|
|
358941
|
-
".hh": "cpp",
|
|
358942
|
-
".hxx": "cpp",
|
|
358943
|
-
".cs": "csharp",
|
|
358944
|
-
".rb": "ruby",
|
|
358945
|
-
".php": "php",
|
|
358946
|
-
".swift": "swift",
|
|
358947
|
-
".kt": "kotlin",
|
|
358948
|
-
".kts": "kotlin",
|
|
358949
|
-
".scala": "scala",
|
|
358950
|
-
".sc": "scala",
|
|
358951
|
-
".lua": "lua",
|
|
358952
|
-
".ex": "elixir",
|
|
358953
|
-
".exs": "elixir",
|
|
358954
|
-
".dart": "dart",
|
|
358955
|
-
".zig": "zig",
|
|
358956
|
-
".sh": "bash",
|
|
358957
|
-
".bash": "bash",
|
|
358958
|
-
".zsh": "bash",
|
|
358959
|
-
".ml": "ocaml",
|
|
358960
|
-
".mli": "ocaml",
|
|
358961
|
-
".m": "objc",
|
|
358962
|
-
".el": "elisp",
|
|
358963
|
-
".res": "rescript",
|
|
358964
|
-
".resi": "rescript",
|
|
358965
|
-
".sol": "solidity",
|
|
358966
|
-
".tla": "tlaplus",
|
|
358967
|
-
".vue": "vue",
|
|
358968
|
-
".pyw": "python",
|
|
358969
|
-
".erb": "ruby",
|
|
358970
|
-
".json": "unknown",
|
|
358971
|
-
".jsonc": "unknown",
|
|
358972
|
-
".yaml": "unknown",
|
|
358973
|
-
".yml": "unknown",
|
|
358974
|
-
".toml": "unknown",
|
|
358975
|
-
".xml": "unknown",
|
|
358976
|
-
".md": "unknown",
|
|
358977
|
-
".css": "css",
|
|
358978
|
-
".scss": "css",
|
|
358979
|
-
".less": "css",
|
|
358980
|
-
".html": "html",
|
|
358981
|
-
".htm": "html",
|
|
358982
|
-
".sql": "unknown",
|
|
358983
|
-
".graphql": "unknown",
|
|
358984
|
-
".gql": "unknown",
|
|
358985
|
-
".proto": "unknown",
|
|
358986
|
-
".env": "unknown",
|
|
358987
|
-
".conf": "unknown",
|
|
358988
|
-
".ini": "unknown",
|
|
358989
|
-
".cfg": "unknown",
|
|
358990
|
-
".dockerfile": "unknown"
|
|
358991
|
-
};
|
|
359137
|
+
init_types2();
|
|
359138
|
+
INDEXABLE_EXTENSIONS = EXT_TO_LANGUAGE;
|
|
358992
359139
|
NON_CODE_LANGUAGES = new Set([
|
|
358993
359140
|
"unknown",
|
|
358994
359141
|
"css",
|
|
358995
359142
|
"html",
|
|
358996
359143
|
"json",
|
|
359144
|
+
"jsonnet",
|
|
358997
359145
|
"toml",
|
|
358998
359146
|
"yaml",
|
|
358999
|
-
"
|
|
359147
|
+
"xml",
|
|
359148
|
+
"markdown",
|
|
359149
|
+
"mdx",
|
|
359150
|
+
"sql",
|
|
359151
|
+
"graphql",
|
|
359152
|
+
"proto",
|
|
359153
|
+
"properties",
|
|
359154
|
+
"ini",
|
|
359155
|
+
"env",
|
|
359156
|
+
"dockerfile",
|
|
359157
|
+
"makefile",
|
|
359158
|
+
"nix",
|
|
359159
|
+
"hcl",
|
|
359160
|
+
"bazel",
|
|
359161
|
+
"just",
|
|
359162
|
+
"svg",
|
|
359163
|
+
"csv",
|
|
359164
|
+
"ignore",
|
|
359165
|
+
"lockfile"
|
|
359000
359166
|
]);
|
|
359001
359167
|
IMPORT_TRACKABLE_LANGUAGES = new Set([
|
|
359002
359168
|
"typescript",
|
|
@@ -359034,9 +359200,9 @@ var init_repo_map_utils = __esm(() => {
|
|
|
359034
359200
|
// src/core/intelligence/repo-map.ts
|
|
359035
359201
|
import { Database as Database2 } from "bun:sqlite";
|
|
359036
359202
|
import { execSync as execSync6 } from "child_process";
|
|
359037
|
-
import { chmodSync as chmodSync3, existsSync as existsSync22, readFileSync as readFileSync16, statSync as statSync3 } from "fs";
|
|
359203
|
+
import { chmodSync as chmodSync3, existsSync as existsSync22, readdirSync as readdirSync7, readFileSync as readFileSync16, statSync as statSync3 } from "fs";
|
|
359038
359204
|
import { stat as statAsync } from "fs/promises";
|
|
359039
|
-
import { dirname as dirname8, extname as
|
|
359205
|
+
import { dirname as dirname8, extname as extname2, join as join25, relative as relative2, resolve as resolve13 } from "path";
|
|
359040
359206
|
|
|
359041
359207
|
class RepoMap {
|
|
359042
359208
|
static testFileMatch(alias = "f") {
|
|
@@ -359133,6 +359299,7 @@ class RepoMap {
|
|
|
359133
359299
|
weight REAL NOT NULL DEFAULT 1.0,
|
|
359134
359300
|
PRIMARY KEY (source_file_id, target_file_id)
|
|
359135
359301
|
);
|
|
359302
|
+
CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target_file_id);
|
|
359136
359303
|
`);
|
|
359137
359304
|
this.db.run(`
|
|
359138
359305
|
CREATE TABLE IF NOT EXISTS refs (
|
|
@@ -359363,8 +359530,7 @@ class RepoMap {
|
|
|
359363
359530
|
const existing = existingFiles.get(relPath);
|
|
359364
359531
|
if (existing && existing.mtime_ms === file2.mtimeMs)
|
|
359365
359532
|
continue;
|
|
359366
|
-
const
|
|
359367
|
-
const language = INDEXABLE_EXTENSIONS[ext] ?? "unknown";
|
|
359533
|
+
const language = detectLanguageFromPath(file2.path);
|
|
359368
359534
|
toIndex.push({ absPath: file2.path, relPath, mtime: file2.mtimeMs, language });
|
|
359369
359535
|
}
|
|
359370
359536
|
const stale = [...existingFiles.keys()].filter((p) => !currentPaths.has(p));
|
|
@@ -359868,7 +360034,7 @@ class RepoMap {
|
|
|
359868
360034
|
const candidates = [base];
|
|
359869
360035
|
if (stripped !== relBase)
|
|
359870
360036
|
candidates.push(join25(this.cwd, relBase));
|
|
359871
|
-
const ext =
|
|
360037
|
+
const ext = extname2(stripped);
|
|
359872
360038
|
if (!ext) {
|
|
359873
360039
|
for (const tryExt of Object.keys(INDEXABLE_EXTENSIONS)) {
|
|
359874
360040
|
candidates.push(base + tryExt);
|
|
@@ -360306,15 +360472,18 @@ class RepoMap {
|
|
|
360306
360472
|
}
|
|
360307
360473
|
async computePageRank(personalization) {
|
|
360308
360474
|
const tick = () => new Promise((r) => setTimeout(r, 1));
|
|
360309
|
-
const files = this.db.query("SELECT id FROM files").all();
|
|
360475
|
+
const files = this.db.query("SELECT id, pagerank, language FROM files").all();
|
|
360310
360476
|
if (files.length === 0)
|
|
360311
360477
|
return;
|
|
360312
360478
|
const n = files.length;
|
|
360313
360479
|
const idToIdx = new Map;
|
|
360314
360480
|
const ids = [];
|
|
360481
|
+
const isCode = new Array(n);
|
|
360315
360482
|
for (const file2 of files) {
|
|
360316
|
-
|
|
360483
|
+
const idx = ids.length;
|
|
360484
|
+
idToIdx.set(file2.id, idx);
|
|
360317
360485
|
ids.push(file2.id);
|
|
360486
|
+
isCode[idx] = !NON_CODE_LANGUAGES.has(file2.language);
|
|
360318
360487
|
}
|
|
360319
360488
|
const outWeight = new Array(n).fill(0);
|
|
360320
360489
|
const adj = [];
|
|
@@ -360330,34 +360499,51 @@ class RepoMap {
|
|
|
360330
360499
|
}
|
|
360331
360500
|
}
|
|
360332
360501
|
const pv = new Float64Array(n);
|
|
360333
|
-
|
|
360502
|
+
let codeCount = 0;
|
|
360503
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360504
|
+
if (isCode[i2])
|
|
360505
|
+
codeCount++;
|
|
360506
|
+
const uniform = codeCount > 0 ? 1 / codeCount : 1 / n;
|
|
360334
360507
|
if (personalization && personalization.size > 0) {
|
|
360335
360508
|
let boostSum = 0;
|
|
360336
360509
|
for (const [fileId, boost] of personalization) {
|
|
360337
360510
|
const idx = idToIdx.get(fileId);
|
|
360338
|
-
if (idx !== undefined) {
|
|
360511
|
+
if (idx !== undefined && isCode[idx]) {
|
|
360339
360512
|
pv[idx] = boost;
|
|
360340
360513
|
boostSum += boost;
|
|
360341
360514
|
}
|
|
360342
360515
|
}
|
|
360343
360516
|
if (boostSum > 0) {
|
|
360344
360517
|
for (let i2 = 0;i2 < n; i2++) {
|
|
360345
|
-
pv[i2] = 0.7 * uniform + 0.3 * ((pv[i2] ?? 0) / boostSum);
|
|
360518
|
+
pv[i2] = isCode[i2] ? 0.7 * uniform + 0.3 * ((pv[i2] ?? 0) / boostSum) : 0;
|
|
360346
360519
|
}
|
|
360347
360520
|
} else {
|
|
360348
|
-
|
|
360521
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360522
|
+
pv[i2] = isCode[i2] ? uniform : 0;
|
|
360349
360523
|
}
|
|
360350
360524
|
} else {
|
|
360351
|
-
|
|
360525
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360526
|
+
pv[i2] = isCode[i2] ? uniform : 0;
|
|
360527
|
+
}
|
|
360528
|
+
let priorSum = 0;
|
|
360529
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360530
|
+
if (isCode[i2])
|
|
360531
|
+
priorSum += files[i2]?.pagerank || 0;
|
|
360532
|
+
let rank = new Float64Array(n);
|
|
360533
|
+
if (priorSum > 0.5 && priorSum < 1.5) {
|
|
360534
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360535
|
+
rank[i2] = isCode[i2] ? files[i2]?.pagerank ?? uniform : 0;
|
|
360536
|
+
} else {
|
|
360537
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360538
|
+
rank[i2] = isCode[i2] ? uniform : 0;
|
|
360352
360539
|
}
|
|
360353
|
-
let rank = new Float64Array(n).fill(1 / n);
|
|
360354
360540
|
let next = new Float64Array(n);
|
|
360355
360541
|
for (let iter = 0;iter < PAGERANK_ITERATIONS; iter++) {
|
|
360356
360542
|
for (let j = 0;j < n; j++)
|
|
360357
360543
|
next[j] = (1 - PAGERANK_DAMPING) * (pv[j] ?? 0);
|
|
360358
360544
|
let danglingSum = 0;
|
|
360359
360545
|
for (let i2 = 0;i2 < n; i2++) {
|
|
360360
|
-
if ((outWeight[i2] ?? 0) === 0)
|
|
360546
|
+
if (isCode[i2] && (outWeight[i2] ?? 0) === 0)
|
|
360361
360547
|
danglingSum += rank[i2] ?? 0;
|
|
360362
360548
|
}
|
|
360363
360549
|
for (let j = 0;j < n; j++) {
|
|
@@ -360367,9 +360553,14 @@ class RepoMap {
|
|
|
360367
360553
|
const contribution = PAGERANK_DAMPING * (rank[from] ?? 0) * weight / (outWeight[from] ?? 1);
|
|
360368
360554
|
next[to] = (next[to] ?? 0) + contribution;
|
|
360369
360555
|
}
|
|
360556
|
+
let delta = 0;
|
|
360557
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360558
|
+
delta += Math.abs((next[i2] ?? 0) - (rank[i2] ?? 0));
|
|
360370
360559
|
[rank, next] = [next, rank];
|
|
360371
360560
|
if (iter % 5 === 4)
|
|
360372
360561
|
await tick();
|
|
360562
|
+
if (delta < 0.000001)
|
|
360563
|
+
break;
|
|
360373
360564
|
}
|
|
360374
360565
|
const update = this.db.prepare("UPDATE files SET pagerank = ? WHERE id = ?");
|
|
360375
360566
|
const tx = this.db.transaction(() => {
|
|
@@ -360382,15 +360573,18 @@ class RepoMap {
|
|
|
360382
360573
|
} catch {}
|
|
360383
360574
|
}
|
|
360384
360575
|
computePageRankSync(personalization) {
|
|
360385
|
-
const files = this.db.query("SELECT id FROM files").all();
|
|
360576
|
+
const files = this.db.query("SELECT id, pagerank, language FROM files").all();
|
|
360386
360577
|
if (files.length === 0)
|
|
360387
360578
|
return;
|
|
360388
360579
|
const n = files.length;
|
|
360389
360580
|
const idToIdx = new Map;
|
|
360390
360581
|
const ids = [];
|
|
360582
|
+
const isCode = new Array(n);
|
|
360391
360583
|
for (const file2 of files) {
|
|
360392
|
-
|
|
360584
|
+
const idx = ids.length;
|
|
360585
|
+
idToIdx.set(file2.id, idx);
|
|
360393
360586
|
ids.push(file2.id);
|
|
360587
|
+
isCode[idx] = !NON_CODE_LANGUAGES.has(file2.language);
|
|
360394
360588
|
}
|
|
360395
360589
|
const outWeight = new Array(n).fill(0);
|
|
360396
360590
|
const adj = [];
|
|
@@ -360406,34 +360600,51 @@ class RepoMap {
|
|
|
360406
360600
|
}
|
|
360407
360601
|
}
|
|
360408
360602
|
const pv = new Float64Array(n);
|
|
360409
|
-
|
|
360603
|
+
let codeCount = 0;
|
|
360604
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360605
|
+
if (isCode[i2])
|
|
360606
|
+
codeCount++;
|
|
360607
|
+
const uniform = codeCount > 0 ? 1 / codeCount : 1 / n;
|
|
360410
360608
|
if (personalization && personalization.size > 0) {
|
|
360411
360609
|
let boostSum = 0;
|
|
360412
360610
|
for (const [fileId, boost] of personalization) {
|
|
360413
360611
|
const idx = idToIdx.get(fileId);
|
|
360414
|
-
if (idx !== undefined) {
|
|
360612
|
+
if (idx !== undefined && isCode[idx]) {
|
|
360415
360613
|
pv[idx] = boost;
|
|
360416
360614
|
boostSum += boost;
|
|
360417
360615
|
}
|
|
360418
360616
|
}
|
|
360419
360617
|
if (boostSum > 0) {
|
|
360420
360618
|
for (let i2 = 0;i2 < n; i2++) {
|
|
360421
|
-
pv[i2] = 0.7 * uniform + 0.3 * ((pv[i2] ?? 0) / boostSum);
|
|
360619
|
+
pv[i2] = isCode[i2] ? 0.7 * uniform + 0.3 * ((pv[i2] ?? 0) / boostSum) : 0;
|
|
360422
360620
|
}
|
|
360423
360621
|
} else {
|
|
360424
|
-
|
|
360622
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360623
|
+
pv[i2] = isCode[i2] ? uniform : 0;
|
|
360425
360624
|
}
|
|
360426
360625
|
} else {
|
|
360427
|
-
|
|
360626
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360627
|
+
pv[i2] = isCode[i2] ? uniform : 0;
|
|
360628
|
+
}
|
|
360629
|
+
let priorSum = 0;
|
|
360630
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360631
|
+
if (isCode[i2])
|
|
360632
|
+
priorSum += files[i2]?.pagerank || 0;
|
|
360633
|
+
let rank = new Float64Array(n);
|
|
360634
|
+
if (priorSum > 0.5 && priorSum < 1.5) {
|
|
360635
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360636
|
+
rank[i2] = isCode[i2] ? files[i2]?.pagerank ?? uniform : 0;
|
|
360637
|
+
} else {
|
|
360638
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360639
|
+
rank[i2] = isCode[i2] ? uniform : 0;
|
|
360428
360640
|
}
|
|
360429
|
-
let rank = new Float64Array(n).fill(1 / n);
|
|
360430
360641
|
let next = new Float64Array(n);
|
|
360431
360642
|
for (let iter = 0;iter < PAGERANK_ITERATIONS; iter++) {
|
|
360432
360643
|
for (let j = 0;j < n; j++)
|
|
360433
360644
|
next[j] = (1 - PAGERANK_DAMPING) * (pv[j] ?? 0);
|
|
360434
360645
|
let danglingSum = 0;
|
|
360435
360646
|
for (let i2 = 0;i2 < n; i2++) {
|
|
360436
|
-
if ((outWeight[i2] ?? 0) === 0)
|
|
360647
|
+
if (isCode[i2] && (outWeight[i2] ?? 0) === 0)
|
|
360437
360648
|
danglingSum += rank[i2] ?? 0;
|
|
360438
360649
|
}
|
|
360439
360650
|
for (let j = 0;j < n; j++) {
|
|
@@ -360443,7 +360654,12 @@ class RepoMap {
|
|
|
360443
360654
|
const contribution = PAGERANK_DAMPING * (rank[from] ?? 0) * weight / (outWeight[from] ?? 1);
|
|
360444
360655
|
next[to] = (next[to] ?? 0) + contribution;
|
|
360445
360656
|
}
|
|
360657
|
+
let delta = 0;
|
|
360658
|
+
for (let i2 = 0;i2 < n; i2++)
|
|
360659
|
+
delta += Math.abs((next[i2] ?? 0) - (rank[i2] ?? 0));
|
|
360446
360660
|
[rank, next] = [next, rank];
|
|
360661
|
+
if (delta < 0.000001)
|
|
360662
|
+
break;
|
|
360447
360663
|
}
|
|
360448
360664
|
const update = this.db.prepare("UPDATE files SET pagerank = ? WHERE id = ?");
|
|
360449
360665
|
const tx = this.db.transaction(() => {
|
|
@@ -360602,15 +360818,36 @@ class RepoMap {
|
|
|
360602
360818
|
"manage.py",
|
|
360603
360819
|
"src/main/java/Main.java",
|
|
360604
360820
|
"src/main/kotlin/Main.kt",
|
|
360821
|
+
"src/main/scala/Main.scala",
|
|
360605
360822
|
"Sources/main.swift",
|
|
360606
360823
|
"Sources/App.swift",
|
|
360607
360824
|
"src/main.c",
|
|
360608
360825
|
"src/main.cpp",
|
|
360826
|
+
"Program.cs",
|
|
360609
360827
|
"lib/main.dart",
|
|
360610
360828
|
"lib/application.ex",
|
|
360611
360829
|
"app.rb",
|
|
360612
|
-
"config.ru"
|
|
360830
|
+
"config.ru",
|
|
360831
|
+
"public/index.php",
|
|
360832
|
+
"artisan",
|
|
360833
|
+
"bin/console",
|
|
360834
|
+
"index.php",
|
|
360835
|
+
"src/main.zig",
|
|
360836
|
+
"build.zig",
|
|
360837
|
+
"app/Main.hs",
|
|
360838
|
+
"src/Main.hs",
|
|
360839
|
+
"Main.hs",
|
|
360840
|
+
"src/Main.elm"
|
|
360613
360841
|
];
|
|
360842
|
+
try {
|
|
360843
|
+
const binsDir = join25(this.cwd, "src", "bin");
|
|
360844
|
+
if (existsSync22(binsDir)) {
|
|
360845
|
+
for (const entry of readdirSync7(binsDir)) {
|
|
360846
|
+
if (entry.endsWith(".rs"))
|
|
360847
|
+
commonEntryPoints.push(`src/bin/${entry}`);
|
|
360848
|
+
}
|
|
360849
|
+
}
|
|
360850
|
+
} catch {}
|
|
360614
360851
|
for (const p of commonEntryPoints) {
|
|
360615
360852
|
if (existsSync22(join25(this.cwd, p)))
|
|
360616
360853
|
this.entryPointsCache.push(p);
|
|
@@ -360946,7 +361183,7 @@ class RepoMap {
|
|
|
360946
361183
|
if (relPath === "package.json" || relPath === "Cargo.toml" || relPath === "go.mod") {
|
|
360947
361184
|
this.entryPointsCache = null;
|
|
360948
361185
|
}
|
|
360949
|
-
const ext =
|
|
361186
|
+
const ext = extname2(absPath).toLowerCase();
|
|
360950
361187
|
const language = INDEXABLE_EXTENSIONS[ext];
|
|
360951
361188
|
if (!language)
|
|
360952
361189
|
return;
|
|
@@ -361538,10 +361775,14 @@ class RepoMap {
|
|
|
361538
361775
|
const blastRadius = this.db.query("SELECT COUNT(DISTINCT source_file_id) AS c FROM edges WHERE target_file_id = ?").get(fileRow.id)?.c ?? 0;
|
|
361539
361776
|
const symbols = this.db.query(`SELECT s.name, s.kind, s.signature, s.line
|
|
361540
361777
|
FROM symbols s
|
|
361778
|
+
LEFT JOIN (
|
|
361779
|
+
SELECT callee_symbol_id, COUNT(*) AS c FROM calls
|
|
361780
|
+
WHERE callee_symbol_id IS NOT NULL GROUP BY callee_symbol_id
|
|
361781
|
+
) cc ON cc.callee_symbol_id = s.id
|
|
361541
361782
|
WHERE s.file_id = ?
|
|
361542
361783
|
AND s.is_exported = 1
|
|
361543
361784
|
AND s.kind IN ('interface','type','class','function','enum','method')
|
|
361544
|
-
ORDER BY s.line
|
|
361785
|
+
ORDER BY COALESCE(cc.c, 0) DESC, s.line ASC
|
|
361545
361786
|
LIMIT 10`).all(fileRow.id);
|
|
361546
361787
|
return { blastRadius, symbols };
|
|
361547
361788
|
}
|
|
@@ -361704,7 +361945,7 @@ class RepoMap {
|
|
|
361704
361945
|
ORDER BY f.pagerank DESC
|
|
361705
361946
|
LIMIT ?`).all(limit);
|
|
361706
361947
|
const trackable = rows.filter((row) => {
|
|
361707
|
-
const ext =
|
|
361948
|
+
const ext = extname2(row.path).toLowerCase();
|
|
361708
361949
|
const lang = INDEXABLE_EXTENSIONS[ext];
|
|
361709
361950
|
return lang != null && IMPORT_TRACKABLE_LANGUAGES.has(lang);
|
|
361710
361951
|
});
|
|
@@ -362418,6 +362659,9 @@ class RepoMap {
|
|
|
362418
362659
|
this.onError?.(`error awaiting pending flush during close: ${e instanceof Error ? e.message : String(e)}`);
|
|
362419
362660
|
}
|
|
362420
362661
|
}
|
|
362662
|
+
try {
|
|
362663
|
+
this.db.run("PRAGMA optimize");
|
|
362664
|
+
} catch {}
|
|
362421
362665
|
this.db.close();
|
|
362422
362666
|
}
|
|
362423
362667
|
metaGet(key) {
|
|
@@ -362469,6 +362713,7 @@ var init_repo_map = __esm(() => {
|
|
|
362469
362713
|
init_clone_detection();
|
|
362470
362714
|
init_repo_map_constants();
|
|
362471
362715
|
init_repo_map_utils();
|
|
362716
|
+
init_types2();
|
|
362472
362717
|
});
|
|
362473
362718
|
|
|
362474
362719
|
// src/core/intelligence/index.ts
|
|
@@ -363142,6 +363387,34 @@ function memoryHintComposite(opts) {
|
|
|
363142
363387
|
return "";
|
|
363143
363388
|
}
|
|
363144
363389
|
}
|
|
363390
|
+
function memoryMarkersForPaths(paths) {
|
|
363391
|
+
const result = new Map;
|
|
363392
|
+
if (!_manager || paths.length === 0)
|
|
363393
|
+
return result;
|
|
363394
|
+
try {
|
|
363395
|
+
const projectDb = _manager.getDbForScope("project");
|
|
363396
|
+
const globalDb = _manager.getDbForScope("global");
|
|
363397
|
+
const project2 = projectDb.topCategoriesByPath(paths);
|
|
363398
|
+
const global2 = globalDb.topCategoriesByPath(paths);
|
|
363399
|
+
const priority = { gotcha: 4, pref: 3, decision: 2, context: 1 };
|
|
363400
|
+
for (const path of paths) {
|
|
363401
|
+
const p = project2.get(path);
|
|
363402
|
+
const g = global2.get(path);
|
|
363403
|
+
if (!p && !g)
|
|
363404
|
+
continue;
|
|
363405
|
+
const count = (p?.count ?? 0) + (g?.count ?? 0);
|
|
363406
|
+
const pinned = (p?.pinned ?? 0) + (g?.pinned ?? 0) > 0;
|
|
363407
|
+
const a = p?.category ? priority[p.category] ?? 0 : 0;
|
|
363408
|
+
const b = g?.category ? priority[g.category] ?? 0 : 0;
|
|
363409
|
+
const category = b > a ? g?.category ?? null : p?.category ?? g?.category ?? null;
|
|
363410
|
+
result.set(path, { category, count, pinned });
|
|
363411
|
+
}
|
|
363412
|
+
return result;
|
|
363413
|
+
} catch (err2) {
|
|
363414
|
+
reportHintError("paths", err2);
|
|
363415
|
+
return result;
|
|
363416
|
+
}
|
|
363417
|
+
}
|
|
363145
363418
|
var _manager = null, GLOBAL_TAB = "__global__", _tabs, _scope, SUMMARY_MAX = 60, COOLDOWN_TURNS = 10, SESSION_BUDGET = 60, SUBAGENT_BUDGET = 10, LOUD_LINES_MAX = 3;
|
|
363146
363419
|
var init_hints = __esm(() => {
|
|
363147
363420
|
init_errors();
|
|
@@ -363150,6 +363423,10 @@ var init_hints = __esm(() => {
|
|
|
363150
363423
|
});
|
|
363151
363424
|
|
|
363152
363425
|
// src/core/tools/file-events.ts
|
|
363426
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
363427
|
+
function runWithEditOrigin(origin, fn) {
|
|
363428
|
+
return _editOriginScope.run(origin, fn);
|
|
363429
|
+
}
|
|
363153
363430
|
function onFileEdited(cb) {
|
|
363154
363431
|
editListeners.add(cb);
|
|
363155
363432
|
return () => {
|
|
@@ -363169,8 +363446,9 @@ function onCacheReset(cb) {
|
|
|
363169
363446
|
};
|
|
363170
363447
|
}
|
|
363171
363448
|
function emitFileEdited(absPath, content) {
|
|
363449
|
+
const origin = _editOriginScope.getStore() ?? null;
|
|
363172
363450
|
for (const cb of editListeners)
|
|
363173
|
-
cb(absPath, content);
|
|
363451
|
+
cb(absPath, content, origin);
|
|
363174
363452
|
}
|
|
363175
363453
|
function emitFileRead(absPath) {
|
|
363176
363454
|
for (const cb of readListeners)
|
|
@@ -363180,11 +363458,12 @@ function emitCacheReset() {
|
|
|
363180
363458
|
for (const cb of cacheResetListeners)
|
|
363181
363459
|
cb();
|
|
363182
363460
|
}
|
|
363183
|
-
var editListeners, readListeners, cacheResetListeners;
|
|
363461
|
+
var editListeners, readListeners, cacheResetListeners, _editOriginScope;
|
|
363184
363462
|
var init_file_events = __esm(() => {
|
|
363185
363463
|
editListeners = new Set;
|
|
363186
363464
|
readListeners = new Set;
|
|
363187
363465
|
cacheResetListeners = new Set;
|
|
363466
|
+
_editOriginScope = new AsyncLocalStorage2;
|
|
363188
363467
|
});
|
|
363189
363468
|
|
|
363190
363469
|
// src/core/tools/edit-stack.ts
|
|
@@ -383046,7 +383325,7 @@ var init_lib2 = () => {};
|
|
|
383046
383325
|
|
|
383047
383326
|
// src/core/tools/binary-detect.ts
|
|
383048
383327
|
import { existsSync as existsSync23, statSync as statSync5 } from "fs";
|
|
383049
|
-
import { extname as
|
|
383328
|
+
import { extname as extname3, resolve as resolve26 } from "path";
|
|
383050
383329
|
function binaryHint(ext) {
|
|
383051
383330
|
if (IMAGE_EXTS.has(ext))
|
|
383052
383331
|
return " This is an image file. Describe what you need from it or ask the user to describe its contents.";
|
|
@@ -383073,7 +383352,7 @@ function checkBinaryFile(filePath) {
|
|
|
383073
383352
|
return null;
|
|
383074
383353
|
if (!isBinaryFileSync(filePath))
|
|
383075
383354
|
return null;
|
|
383076
|
-
const ext =
|
|
383355
|
+
const ext = extname3(filePath).toLowerCase();
|
|
383077
383356
|
const sizeStr = stat5.size > 1024 * 1024 ? `${(stat5.size / (1024 * 1024)).toFixed(1)}MB` : `${(stat5.size / 1024).toFixed(0)}KB`;
|
|
383078
383357
|
return `Cannot read binary file: "${filePath}" (${ext || "no extension"}, ${sizeStr}).${binaryHint(ext)}`;
|
|
383079
383358
|
} catch {
|
|
@@ -383144,7 +383423,7 @@ var init_binary_detect = __esm(() => {
|
|
|
383144
383423
|
|
|
383145
383424
|
// src/core/tools/read-file.ts
|
|
383146
383425
|
import { access as access4, stat as statAsync7 } from "fs/promises";
|
|
383147
|
-
import { extname as
|
|
383426
|
+
import { extname as extname4, resolve as resolve27 } from "path";
|
|
383148
383427
|
function toRelPath(abs) {
|
|
383149
383428
|
const cwd2 = process.cwd();
|
|
383150
383429
|
return abs.startsWith(`${cwd2}/`) ? abs.slice(cwd2.length + 1) : abs;
|
|
@@ -383265,7 +383544,7 @@ async function readOnMainThread(filePath, args2) {
|
|
|
383265
383544
|
};
|
|
383266
383545
|
}
|
|
383267
383546
|
if (await isBinaryFile(filePath)) {
|
|
383268
|
-
const ext =
|
|
383547
|
+
const ext = extname4(filePath).toLowerCase();
|
|
383269
383548
|
const sizeStr = fileStat.size > 1024 * 1024 ? `${(fileStat.size / (1024 * 1024)).toFixed(1)}MB` : `${(fileStat.size / 1024).toFixed(0)}KB`;
|
|
383270
383549
|
const hint = binaryHint(ext);
|
|
383271
383550
|
return {
|
|
@@ -383932,7 +384211,7 @@ ${fixed}`);
|
|
|
383932
384211
|
|
|
383933
384212
|
// src/core/tools/rename-symbol.ts
|
|
383934
384213
|
import { readFile as readFile17, stat as statAsync9, writeFile as writeFile12 } from "fs/promises";
|
|
383935
|
-
import { extname as
|
|
384214
|
+
import { extname as extname5, resolve as resolve30 } from "path";
|
|
383936
384215
|
async function applyEdits2(edits, tabId) {
|
|
383937
384216
|
for (const edit of edits) {
|
|
383938
384217
|
const blocked = isForbidden(edit.file);
|
|
@@ -383956,7 +384235,7 @@ function getCommentSyntax(filePath) {
|
|
|
383956
384235
|
ocamlBlock: false
|
|
383957
384236
|
};
|
|
383958
384237
|
}
|
|
383959
|
-
const ext =
|
|
384238
|
+
const ext = extname5(filePath).toLowerCase();
|
|
383960
384239
|
return {
|
|
383961
384240
|
hash: HASH_COMMENT_EXTS.has(ext),
|
|
383962
384241
|
doubleDash: DOUBLE_DASH_EXTS.has(ext),
|
|
@@ -384982,7 +385261,7 @@ import {
|
|
|
384982
385261
|
writeSync
|
|
384983
385262
|
} from "fs";
|
|
384984
385263
|
import { tmpdir as tmpdir2 } from "os";
|
|
384985
|
-
import { basename as basename5, extname as
|
|
385264
|
+
import { basename as basename5, extname as extname6, resolve as resolve31 } from "path";
|
|
384986
385265
|
import { inflateSync } from "zlib";
|
|
384987
385266
|
function _resetKittyVersionCache(override) {
|
|
384988
385267
|
_kittyVersion = override === undefined ? undefined : override;
|
|
@@ -385038,7 +385317,7 @@ function supportsKittyAnimation() {
|
|
|
385038
385317
|
return isKittyVersionAtMost(0, 37);
|
|
385039
385318
|
}
|
|
385040
385319
|
function isRenderableImage(filePath) {
|
|
385041
|
-
const ext =
|
|
385320
|
+
const ext = extname6(filePath).toLowerCase();
|
|
385042
385321
|
if (!IMAGE_EXTENSIONS2.has(ext))
|
|
385043
385322
|
return false;
|
|
385044
385323
|
try {
|
|
@@ -385471,14 +385750,14 @@ var init_tool_progress = __esm(() => {
|
|
|
385471
385750
|
import { spawn as spawn12, spawnSync as spawnSync4 } from "child_process";
|
|
385472
385751
|
import {
|
|
385473
385752
|
existsSync as existsSync25,
|
|
385474
|
-
readdirSync as
|
|
385753
|
+
readdirSync as readdirSync8,
|
|
385475
385754
|
readFileSync as readFileSync18,
|
|
385476
385755
|
statSync as statSync7,
|
|
385477
385756
|
unlinkSync as unlinkSync6,
|
|
385478
385757
|
writeFileSync as writeFileSync13
|
|
385479
385758
|
} from "fs";
|
|
385480
385759
|
import { tmpdir as tmpdir3 } from "os";
|
|
385481
|
-
import { basename as basename6, extname as
|
|
385760
|
+
import { basename as basename6, extname as extname7, resolve as resolve32 } from "path";
|
|
385482
385761
|
function safeUnlink2(path) {
|
|
385483
385762
|
try {
|
|
385484
385763
|
if (existsSync25(path))
|
|
@@ -385567,7 +385846,7 @@ function hasSips() {
|
|
|
385567
385846
|
}
|
|
385568
385847
|
async function resizeImageToTarget(data, name38, targetBytes, signal) {
|
|
385569
385848
|
const id = `soul-vision-resize-${String(Date.now())}-${String(Math.random()).slice(2, 8)}`;
|
|
385570
|
-
const ext =
|
|
385849
|
+
const ext = extname7(name38).toLowerCase() || ".jpg";
|
|
385571
385850
|
const srcPath = resolve32(tmpdir3(), `${id}${ext}`);
|
|
385572
385851
|
const dstPath = resolve32(tmpdir3(), `${id}-resized${ext}`);
|
|
385573
385852
|
try {
|
|
@@ -385773,7 +386052,7 @@ ${INSTALL_FFMPEG}` };
|
|
|
385773
386052
|
}
|
|
385774
386053
|
})();
|
|
385775
386054
|
const id = `soul-vision-direct-${String(Date.now())}-${String(Math.random()).slice(2, 8)}`;
|
|
385776
|
-
const ext =
|
|
386055
|
+
const ext = extname7(urlName).toLowerCase() || ".mp4";
|
|
385777
386056
|
const videoPath = resolve32(tmpdir3(), `${id}${ext}`);
|
|
385778
386057
|
try {
|
|
385779
386058
|
progress(toolCallId, "FETCH", `Downloading ${urlName}\u2026`);
|
|
@@ -385908,7 +386187,7 @@ async function convertLocalVideo(filePath, displayName, toolCallId, signal) {
|
|
|
385908
386187
|
return { error: `Video files require ffmpeg to convert:
|
|
385909
386188
|
${INSTALL_FFMPEG}` };
|
|
385910
386189
|
}
|
|
385911
|
-
const baseName = basename6(displayName,
|
|
386190
|
+
const baseName = basename6(displayName, extname7(displayName));
|
|
385912
386191
|
if (supportsKittyAnimation()) {
|
|
385913
386192
|
for (let attempt = 0;attempt < 2; attempt++) {
|
|
385914
386193
|
const gif = await videoToGif(filePath, toolCallId, MAX_GIF_DURATION, signal);
|
|
@@ -385927,7 +386206,7 @@ async function ensurePng(data, name38, signal) {
|
|
|
385927
386206
|
if (data.length >= 4 && data.subarray(0, 4).equals(PNG_SIGNATURE)) {
|
|
385928
386207
|
return data;
|
|
385929
386208
|
}
|
|
385930
|
-
const ext =
|
|
386209
|
+
const ext = extname7(name38).toLowerCase() || ".jpg";
|
|
385931
386210
|
return convertToPng(data, ext, signal);
|
|
385932
386211
|
}
|
|
385933
386212
|
function isGif(data) {
|
|
@@ -385966,7 +386245,7 @@ async function extractGifFrames(data, signal) {
|
|
|
385966
386245
|
return null;
|
|
385967
386246
|
const dir = tmpdir3();
|
|
385968
386247
|
const prefix = `${id}-frame-`;
|
|
385969
|
-
const frameFiles =
|
|
386248
|
+
const frameFiles = readdirSync8(dir).filter((f) => f.startsWith(prefix) && f.endsWith(".png")).sort().map((f) => resolve32(dir, f));
|
|
385970
386249
|
if (frameFiles.length === 0)
|
|
385971
386250
|
return null;
|
|
385972
386251
|
const frames = [];
|
|
@@ -385980,7 +386259,7 @@ async function extractGifFrames(data, signal) {
|
|
|
385980
386259
|
try {
|
|
385981
386260
|
const dir = tmpdir3();
|
|
385982
386261
|
const prefix = `${id}-frame-`;
|
|
385983
|
-
for (const f of
|
|
386262
|
+
for (const f of readdirSync8(dir)) {
|
|
385984
386263
|
if (f.startsWith(prefix) && f.endsWith(".png")) {
|
|
385985
386264
|
safeUnlink2(resolve32(dir, f));
|
|
385986
386265
|
}
|
|
@@ -386291,7 +386570,7 @@ var init_show_image = __esm(() => {
|
|
|
386291
386570
|
});
|
|
386292
386571
|
|
|
386293
386572
|
// src/core/skills/manager.ts
|
|
386294
|
-
import { existsSync as existsSync26, readdirSync as
|
|
386573
|
+
import { existsSync as existsSync26, readdirSync as readdirSync9, readFileSync as readFileSync19, realpathSync as realpathSync3, rmSync as rmSync3, statSync as statSync8 } from "fs";
|
|
386295
386574
|
import { homedir as homedir22 } from "os";
|
|
386296
386575
|
import { dirname as dirname14, join as join30 } from "path";
|
|
386297
386576
|
async function searchSkills(query2) {
|
|
@@ -386372,7 +386651,7 @@ function listInstalledSkills() {
|
|
|
386372
386651
|
return [...byName.values()];
|
|
386373
386652
|
}
|
|
386374
386653
|
function scanSkillDir(dir, scope, byName, seenPaths) {
|
|
386375
|
-
const entries2 =
|
|
386654
|
+
const entries2 = readdirSync9(dir, { withFileTypes: true });
|
|
386376
386655
|
for (const entry of entries2) {
|
|
386377
386656
|
if (entry.name.startsWith("."))
|
|
386378
386657
|
continue;
|
|
@@ -386687,7 +386966,7 @@ function execFileAsync(cmd, args2, opts) {
|
|
|
386687
386966
|
var init_util3 = () => {};
|
|
386688
386967
|
|
|
386689
386968
|
// src/core/tools/soul-analyze.ts
|
|
386690
|
-
import { extname as
|
|
386969
|
+
import { extname as extname8, relative as relative8 } from "path";
|
|
386691
386970
|
async function identifierFrequency(repoMap, cwd2, name38, limit) {
|
|
386692
386971
|
if (name38) {
|
|
386693
386972
|
const symbols = await repoMap.findSymbols(name38);
|
|
@@ -386750,7 +387029,7 @@ async function unusedExports(repoMap, cwd2, limit) {
|
|
|
386750
387029
|
}
|
|
386751
387030
|
}
|
|
386752
387031
|
const canTrackFileImports = (filePath) => {
|
|
386753
|
-
const ext =
|
|
387032
|
+
const ext = extname8(filePath).toLowerCase();
|
|
386754
387033
|
const lang = INDEXABLE_EXTENSIONS[ext];
|
|
386755
387034
|
return lang != null && IMPORT_TRACKABLE_LANGUAGES.has(lang);
|
|
386756
387035
|
};
|
|
@@ -391822,14 +392101,25 @@ function buildSubagentExploreTools(opts) {
|
|
|
391822
392101
|
}
|
|
391823
392102
|
function buildEmberExploreTools(opts) {
|
|
391824
392103
|
const all = buildSubagentExploreTools(opts);
|
|
391825
|
-
const {
|
|
392104
|
+
const {
|
|
392105
|
+
read,
|
|
392106
|
+
navigate,
|
|
392107
|
+
soul_grep,
|
|
392108
|
+
soul_find,
|
|
392109
|
+
soul_analyze,
|
|
392110
|
+
soul_impact,
|
|
392111
|
+
web_search,
|
|
392112
|
+
fetch_page
|
|
392113
|
+
} = all;
|
|
391826
392114
|
return {
|
|
391827
392115
|
...read ? { read } : {},
|
|
391828
392116
|
...navigate ? { navigate } : {},
|
|
391829
392117
|
...soul_grep ? { soul_grep } : {},
|
|
391830
392118
|
...soul_find ? { soul_find } : {},
|
|
391831
392119
|
...soul_analyze ? { soul_analyze } : {},
|
|
391832
|
-
...soul_impact ? { soul_impact } : {}
|
|
392120
|
+
...soul_impact ? { soul_impact } : {},
|
|
392121
|
+
...web_search ? { web_search } : {},
|
|
392122
|
+
...fetch_page ? { fetch_page } : {}
|
|
391833
392123
|
};
|
|
391834
392124
|
}
|
|
391835
392125
|
function buildSubagentCodeTools(opts) {
|
|
@@ -402308,7 +402598,11 @@ ${enrichedPrompt}`;
|
|
|
402308
402598
|
};
|
|
402309
402599
|
const parentTabId = models.tabId;
|
|
402310
402600
|
const parentSurfaced = getSurfacedHintIds(parentTabId);
|
|
402311
|
-
result = await runInSubagentScope(parentSurfaced, () =>
|
|
402601
|
+
result = await runInSubagentScope(parentSurfaced, () => runWithEditOrigin({
|
|
402602
|
+
tabId: parentTabId ?? null,
|
|
402603
|
+
agentId: task.agentId,
|
|
402604
|
+
agentLabel: task.task ? task.task.slice(0, 32) : task.agentId
|
|
402605
|
+
}, () => agent2.generate(generateArgs)), parentTabId);
|
|
402312
402606
|
} catch (genErr) {
|
|
402313
402607
|
const errWithSteps = genErr;
|
|
402314
402608
|
const recoveredSteps = errWithSteps.steps && Array.isArray(errWithSteps.steps) ? errWithSteps.steps : callbacks._steps.length > 0 ? callbacks._steps : [];
|
|
@@ -402612,6 +402906,7 @@ var init_agent_runner = __esm(() => {
|
|
|
402612
402906
|
init_config2();
|
|
402613
402907
|
init_settings();
|
|
402614
402908
|
init_model_events();
|
|
402909
|
+
init_file_events();
|
|
402615
402910
|
init_tool_timeout();
|
|
402616
402911
|
RETURN_FORMAT_INSTRUCTIONS = {
|
|
402617
402912
|
summary: "Return concise findings and reasoning. No code blocks or raw file content. " + "Focus on what you found, what it means, and what the implications are. " + "Anchor every claim with file:line so the parent can surgically read more.",
|
|
@@ -403632,7 +403927,7 @@ function lastStepHadPlanCall(messages) {
|
|
|
403632
403927
|
}
|
|
403633
403928
|
return false;
|
|
403634
403929
|
}
|
|
403635
|
-
function buildForgePrepareStep(isPlanMode, drainSteering, contextManager, tabId, codeExecution3, parentMessagesRef, proxyInstructions, cacheOpts = EPHEMERAL_CACHE) {
|
|
403930
|
+
function buildForgePrepareStep(isPlanMode, drainSteering, contextManager, tabId, codeExecution3, parentMessagesRef, proxyInstructions, cacheOpts = EPHEMERAL_CACHE, modelId) {
|
|
403636
403931
|
const previousInjects = [];
|
|
403637
403932
|
const recallInjects = [];
|
|
403638
403933
|
let lastUserTurnCount = 0;
|
|
@@ -403678,7 +403973,7 @@ ${proxyInstructions}
|
|
|
403678
403973
|
const hints = [];
|
|
403679
403974
|
let soulMapDiff = null;
|
|
403680
403975
|
if (contextManager?.hasSoulMapDiff?.()) {
|
|
403681
|
-
soulMapDiff = contextManager.buildSoulMapDiff();
|
|
403976
|
+
soulMapDiff = contextManager.buildSoulMapDiff(modelId);
|
|
403682
403977
|
}
|
|
403683
403978
|
if (contextManager) {
|
|
403684
403979
|
const userTurnCount = countUserTurns(sanitized);
|
|
@@ -403963,7 +404258,7 @@ function buildInstructions(cm, modelId) {
|
|
|
403963
404258
|
if (cached4 && cached4.key === key2)
|
|
403964
404259
|
return cached4.text;
|
|
403965
404260
|
const parts2 = [cm.buildSystemPrompt(modelId)];
|
|
403966
|
-
const snapshot = cm.buildSoulMapSnapshot(
|
|
404261
|
+
const snapshot = cm.buildSoulMapSnapshot({ modelId });
|
|
403967
404262
|
if (snapshot)
|
|
403968
404263
|
parts2.push(snapshot);
|
|
403969
404264
|
const skills = cm.buildSkillsBlock();
|
|
@@ -404197,6 +404492,21 @@ function createForgeAgent({
|
|
|
404197
404492
|
if (isAbnormalFinish(step.finishReason)) {
|
|
404198
404493
|
logBackgroundError("agent-error", `forge: ${describeAbnormalFinish(step.finishReason)}`);
|
|
404199
404494
|
}
|
|
404495
|
+
const results = step.toolResults;
|
|
404496
|
+
if (Array.isArray(results)) {
|
|
404497
|
+
for (const r of results) {
|
|
404498
|
+
const output = r.output;
|
|
404499
|
+
const value = output?.value;
|
|
404500
|
+
const success2 = value?.success;
|
|
404501
|
+
if (success2 !== false)
|
|
404502
|
+
continue;
|
|
404503
|
+
const tool4 = String(r.toolName ?? "tool");
|
|
404504
|
+
const input = r.input ?? {};
|
|
404505
|
+
const target = String(input.path ?? input.file ?? input.absPath ?? input.relPath ?? "");
|
|
404506
|
+
const reason = typeof value?.error === "string" ? value.error : typeof value?.output === "string" ? value.output.slice(0, 80) : "failed";
|
|
404507
|
+
contextManager.recordToolFailure(tool4, target, reason);
|
|
404508
|
+
}
|
|
404509
|
+
}
|
|
404200
404510
|
},
|
|
404201
404511
|
instructions: isProxyClaude ? undefined : {
|
|
404202
404512
|
role: "system",
|
|
@@ -404213,7 +404523,7 @@ function createForgeAgent({
|
|
|
404213
404523
|
...activeTools ? { activeTools } : {}
|
|
404214
404524
|
};
|
|
404215
404525
|
},
|
|
404216
|
-
prepareStep: buildForgePrepareStep(forgeMode === "plan", drainSteering, contextManager, tabId, canUseCodeExecution, parentMessagesRef, isProxyClaude ? buildInstructions(contextManager, modelId) : undefined, cacheOpts),
|
|
404526
|
+
prepareStep: buildForgePrepareStep(forgeMode === "plan", drainSteering, contextManager, tabId, canUseCodeExecution, parentMessagesRef, isProxyClaude ? buildInstructions(contextManager, modelId) : undefined, cacheOpts, modelId),
|
|
404217
404527
|
experimental_repairToolCall: repairToolCall,
|
|
404218
404528
|
providerOptions: wrappedProviderOptions,
|
|
404219
404529
|
...subagentHeaders ? { headers: subagentHeaders } : {}
|
|
@@ -417922,6 +418232,38 @@ var init_neovim = __esm(() => {
|
|
|
417922
418232
|
_onFileWrittenHandlers = new Set;
|
|
417923
418233
|
});
|
|
417924
418234
|
|
|
418235
|
+
// src/core/llm/cache-support.ts
|
|
418236
|
+
function supportsPromptCache(modelId) {
|
|
418237
|
+
const family = detectModelFamily(modelId);
|
|
418238
|
+
switch (family) {
|
|
418239
|
+
case "claude":
|
|
418240
|
+
return EXPLICIT;
|
|
418241
|
+
case "google":
|
|
418242
|
+
return IMPLICIT;
|
|
418243
|
+
case "openai":
|
|
418244
|
+
return IMPLICIT;
|
|
418245
|
+
case "deepseek":
|
|
418246
|
+
case "deepseek-reasoner":
|
|
418247
|
+
return IMPLICIT;
|
|
418248
|
+
case "xai":
|
|
418249
|
+
return IMPLICIT;
|
|
418250
|
+
case "other":
|
|
418251
|
+
return NONE2;
|
|
418252
|
+
default:
|
|
418253
|
+
return NONE2;
|
|
418254
|
+
}
|
|
418255
|
+
}
|
|
418256
|
+
function cacheTtlToMs(ttl) {
|
|
418257
|
+
return ttl === "1h" ? 60 * 60000 : 5 * 60000;
|
|
418258
|
+
}
|
|
418259
|
+
var NONE2, EXPLICIT, IMPLICIT;
|
|
418260
|
+
var init_cache_support = __esm(() => {
|
|
418261
|
+
init_provider_options();
|
|
418262
|
+
NONE2 = { enabled: false, explicit: false };
|
|
418263
|
+
EXPLICIT = { enabled: true, explicit: true };
|
|
418264
|
+
IMPLICIT = { enabled: true, explicit: false };
|
|
418265
|
+
});
|
|
418266
|
+
|
|
417925
418267
|
// src/core/prompts/families/claude.ts
|
|
417926
418268
|
var CLAUDE_PROMPT;
|
|
417927
418269
|
var init_claude = __esm(() => {
|
|
@@ -418172,12 +418514,18 @@ function invalidateDirectoryTree(cwd2) {
|
|
|
418172
418514
|
dirTreeCache.delete(key2);
|
|
418173
418515
|
}
|
|
418174
418516
|
}
|
|
418175
|
-
function buildSoulMapUserMessage(rendered, isMinimal, dirTree) {
|
|
418517
|
+
function buildSoulMapUserMessage(rendered, isMinimal, dirTree, entryPoints) {
|
|
418176
418518
|
const legend = isMinimal ? "" : LEGEND;
|
|
418177
418519
|
const treeSection = dirTree ? `
|
|
418178
418520
|
<directory_tree>
|
|
418179
418521
|
${dirTree}
|
|
418180
418522
|
</directory_tree>
|
|
418523
|
+
` : "";
|
|
418524
|
+
const entrySection = entryPoints && entryPoints.length > 0 ? `
|
|
418525
|
+
<entry_points>
|
|
418526
|
+
${entryPoints.slice(0, 8).join(`
|
|
418527
|
+
`)}
|
|
418528
|
+
</entry_points>
|
|
418181
418529
|
` : "";
|
|
418182
418530
|
return `<soul_map>
|
|
418183
418531
|
` + `<description>
|
|
@@ -418187,7 +418535,7 @@ ${SOUL_MAP_DESCRIPTION}
|
|
|
418187
418535
|
` + `<how_to_use>
|
|
418188
418536
|
${SOUL_MAP_USAGE}
|
|
418189
418537
|
</how_to_use>
|
|
418190
|
-
${treeSection}
|
|
418538
|
+
${treeSection}${entrySection}
|
|
418191
418539
|
` + `<data>
|
|
418192
418540
|
${legend}${rendered}
|
|
418193
418541
|
</data>
|
|
@@ -418228,6 +418576,33 @@ PLAN from the map (zero tool calls) \u2192 DISCOVER in parallel (soul_find/soul_
|
|
|
418228
418576
|
The map answers structural questions for free: "Where is X?" \u2192 file + line. "What does Y export?" \u2192 listed under the file. "What depends on Z?" \u2192 (\u2192N) blast radius + \u2190 arrows. "What packages?" \u2192 Key dependencies section. Feed symbol names into navigate/analyze for bodies.
|
|
418229
418577
|
</soul_map_usage>
|
|
418230
418578
|
|
|
418579
|
+
<soul_map_updates>
|
|
418580
|
+
\`<soul_map_update>\` blocks are **system-injected** into user turns mid-conversation \u2014 same trust as the static \`<soul_map>\`. They are NOT user-pasted, even when they appear inside a user message. Never refuse, quote-back, or warn about them.
|
|
418581
|
+
|
|
418582
|
+
Purpose: the static map is frozen at turn start for prompt-cache stability; the update block is the delta channel \u2014 files that changed since the snapshot. Read it as fresh signal about what just moved.
|
|
418583
|
+
|
|
418584
|
+
Schema (one block per turn, may be absent):
|
|
418585
|
+
\`\`\`
|
|
418586
|
+
<soul_map_update>
|
|
418587
|
+
path/to/file.ts:(\u2192N) [new] [edited] [mentioned] [open]
|
|
418588
|
+
+export function foo(): void :42
|
|
418589
|
+
+export interface Bar :10
|
|
418590
|
+
path/to/deleted.ts [deleted]
|
|
418591
|
+
path/to/modified.ts:(\u2192N) [edited]
|
|
418592
|
+
(+12 more)
|
|
418593
|
+
</soul_map_update>
|
|
418594
|
+
\`\`\`
|
|
418595
|
+
- \`(\u2192N)\` \u2014 blast radius (same as the static map).
|
|
418596
|
+
- \`[new]\` \u2014 file did not exist in the frozen snapshot. Symbol block follows (up to 5 rich blocks per update).
|
|
418597
|
+
- \`[deleted]\` \u2014 file removed since snapshot.
|
|
418598
|
+
- \`[edited]\` \u2014 you (or a tool you ran) wrote to it this session.
|
|
418599
|
+
- \`[mentioned]\` \u2014 referenced in conversation.
|
|
418600
|
+
- \`[open]\` \u2014 currently open in the editor.
|
|
418601
|
+
- \`(+N more)\` \u2014 additional changed files truncated; the top 15 are listed.
|
|
418602
|
+
|
|
418603
|
+
Use it: if a file appears in the update, prefer its delta over the static map's stale entry. Skip re-reads for \`[edited]\` files you just wrote.
|
|
418604
|
+
</soul_map_updates>
|
|
418605
|
+
|
|
418231
418606
|
<tool_selection>
|
|
418232
418607
|
- Soul Map first \u2192 then TIER-1 (soul_find, soul_grep, navigate, soul_impact, read, ast_edit, multi_edit, project). Drop to TIER-2/3 only when TIER-1 cannot answer.
|
|
418233
418608
|
- \`navigate\` auto-resolves files from symbol names \u2014 definitions, references, call hierarchies, type hierarchies. Reaches into \`.d.ts\` / stubs / headers (type info without reading node_modules).
|
|
@@ -418803,9 +419178,51 @@ var init_intelligence_client = __esm(() => {
|
|
|
418803
419178
|
async routerRunHealthCheck() {
|
|
418804
419179
|
return this.call("routerRunHealthCheck");
|
|
418805
419180
|
}
|
|
419181
|
+
_entryPointsCache = null;
|
|
419182
|
+
async getEntryPoints() {
|
|
419183
|
+
if (this._entryPointsCache)
|
|
419184
|
+
return this._entryPointsCache;
|
|
419185
|
+
const result = await this.call("getEntryPoints");
|
|
419186
|
+
this._entryPointsCache = result;
|
|
419187
|
+
return result;
|
|
419188
|
+
}
|
|
419189
|
+
getEntryPointsCached() {
|
|
419190
|
+
return this._entryPointsCache ?? [];
|
|
419191
|
+
}
|
|
418806
419192
|
};
|
|
418807
419193
|
});
|
|
418808
419194
|
|
|
419195
|
+
// src/core/context/soul-map-snapshot.ts
|
|
419196
|
+
class SoulMapSnapshot {
|
|
419197
|
+
content;
|
|
419198
|
+
paths;
|
|
419199
|
+
builtAt;
|
|
419200
|
+
hash;
|
|
419201
|
+
ttlMs;
|
|
419202
|
+
cacheKey;
|
|
419203
|
+
_lastAccessedAt;
|
|
419204
|
+
constructor(data, now2 = Date.now()) {
|
|
419205
|
+
this.content = data.content;
|
|
419206
|
+
this.paths = data.paths;
|
|
419207
|
+
this.ttlMs = data.ttlMs;
|
|
419208
|
+
this.builtAt = now2;
|
|
419209
|
+
this._lastAccessedAt = now2;
|
|
419210
|
+
this.hash = hash32Hex(data.content);
|
|
419211
|
+
this.cacheKey = data.cacheKey ?? this.hash;
|
|
419212
|
+
}
|
|
419213
|
+
read(now2 = Date.now()) {
|
|
419214
|
+
this._lastAccessedAt = now2;
|
|
419215
|
+
return this.content;
|
|
419216
|
+
}
|
|
419217
|
+
isIdleExpired(now2 = Date.now()) {
|
|
419218
|
+
return now2 - this._lastAccessedAt >= this.ttlMs;
|
|
419219
|
+
}
|
|
419220
|
+
get lastAccessedAt() {
|
|
419221
|
+
return this._lastAccessedAt;
|
|
419222
|
+
}
|
|
419223
|
+
}
|
|
419224
|
+
var init_soul_map_snapshot = () => {};
|
|
419225
|
+
|
|
418809
419226
|
// src/core/context/toolchain.ts
|
|
418810
419227
|
import { existsSync as existsSync30 } from "fs";
|
|
418811
419228
|
import { join as join36 } from "path";
|
|
@@ -419075,11 +419492,13 @@ import { join as join37 } from "path";
|
|
|
419075
419492
|
var DEFAULT_CONTEXT_WINDOW2 = 200000, ContextManager;
|
|
419076
419493
|
var init_manager5 = __esm(() => {
|
|
419077
419494
|
init_dist5();
|
|
419495
|
+
init_config2();
|
|
419078
419496
|
init_errors();
|
|
419079
419497
|
init_model_events();
|
|
419080
419498
|
init_repomap();
|
|
419081
419499
|
init_neovim();
|
|
419082
419500
|
init_instance2();
|
|
419501
|
+
init_cache_support();
|
|
419083
419502
|
init_provider();
|
|
419084
419503
|
init_provider_options();
|
|
419085
419504
|
init_hints();
|
|
@@ -419090,6 +419509,7 @@ var init_manager5 = __esm(() => {
|
|
|
419090
419509
|
init_file_events();
|
|
419091
419510
|
init_intelligence_client();
|
|
419092
419511
|
init_file_tree();
|
|
419512
|
+
init_soul_map_snapshot();
|
|
419093
419513
|
init_toolchain();
|
|
419094
419514
|
init_conversation_terms();
|
|
419095
419515
|
ContextManager = class ContextManager {
|
|
@@ -419120,6 +419540,7 @@ var init_manager5 = __esm(() => {
|
|
|
419120
419540
|
soulMapDiffSeq = 0;
|
|
419121
419541
|
soulMapSnapshotPaths = new Set;
|
|
419122
419542
|
soulMapDiffBlocks = new Map;
|
|
419543
|
+
soulMapSnapshot = null;
|
|
419123
419544
|
taskRouter;
|
|
419124
419545
|
semanticSummaryLimit = 500;
|
|
419125
419546
|
semanticAutoRegen = false;
|
|
@@ -419287,8 +419708,19 @@ var init_manager5 = __esm(() => {
|
|
|
419287
419708
|
unsubEdit = null;
|
|
419288
419709
|
unsubRead = null;
|
|
419289
419710
|
wireFileEventHandlers() {
|
|
419290
|
-
this.unsubEdit = onFileEdited((absPath) => {
|
|
419711
|
+
this.unsubEdit = onFileEdited((absPath, _content, origin) => {
|
|
419291
419712
|
this.recallEditEpoch++;
|
|
419713
|
+
if (origin) {
|
|
419714
|
+
const sameTab = origin.tabId && this.tabId && origin.tabId === this.tabId;
|
|
419715
|
+
const isSubagent = !!origin.agentId;
|
|
419716
|
+
if (!sameTab || isSubagent) {
|
|
419717
|
+
const rel = absPath.startsWith(`${this.cwd}/`) ? absPath.slice(this.cwd.length + 1) : absPath;
|
|
419718
|
+
this.foreignEditOrigins.set(rel, {
|
|
419719
|
+
tabId: origin.tabId ?? null,
|
|
419720
|
+
agentLabel: origin.agentLabel ?? origin.agentId ?? null
|
|
419721
|
+
});
|
|
419722
|
+
}
|
|
419723
|
+
}
|
|
419292
419724
|
this.onFileChanged(absPath);
|
|
419293
419725
|
});
|
|
419294
419726
|
this.unsubRead = onFileRead((absPath) => this.trackMentionedFile(absPath));
|
|
@@ -419502,9 +419934,11 @@ var init_manager5 = __esm(() => {
|
|
|
419502
419934
|
this.soulMapDiffBlocks.clear();
|
|
419503
419935
|
this.pendingSoulMapDiff = null;
|
|
419504
419936
|
this.lastEmittedSoulMapDiff = null;
|
|
419937
|
+
this.soulMapSnapshot = null;
|
|
419505
419938
|
this.warmRepoMapCache();
|
|
419506
419939
|
}
|
|
419507
419940
|
resetForCompaction() {
|
|
419941
|
+
this.postCompactionPending = true;
|
|
419508
419942
|
this.recallCache = null;
|
|
419509
419943
|
resetSurfacedHints(this.tabId ?? undefined);
|
|
419510
419944
|
if (this.repoMapCache)
|
|
@@ -419516,6 +419950,7 @@ var init_manager5 = __esm(() => {
|
|
|
419516
419950
|
this.soulMapDiffBlocks.clear();
|
|
419517
419951
|
this.pendingSoulMapDiff = null;
|
|
419518
419952
|
this.lastEmittedSoulMapDiff = null;
|
|
419953
|
+
this.soulMapSnapshot = null;
|
|
419519
419954
|
this.warmRepoMapCache();
|
|
419520
419955
|
}
|
|
419521
419956
|
repoMapRefreshing = false;
|
|
@@ -419536,6 +419971,7 @@ var init_manager5 = __esm(() => {
|
|
|
419536
419971
|
if (this.repoMapRefreshing)
|
|
419537
419972
|
return;
|
|
419538
419973
|
this.repoMapRefreshing = true;
|
|
419974
|
+
this.repoMap.getEntryPoints().catch(() => {});
|
|
419539
419975
|
try {
|
|
419540
419976
|
const result = await this.repoMap.render({
|
|
419541
419977
|
editorFile: this.editorFile,
|
|
@@ -419611,6 +420047,7 @@ var init_manager5 = __esm(() => {
|
|
|
419611
420047
|
return;
|
|
419612
420048
|
this.repoMapEnabled = enabled;
|
|
419613
420049
|
this.repoMapCache = null;
|
|
420050
|
+
this.soulMapSnapshot = null;
|
|
419614
420051
|
if (!enabled) {
|
|
419615
420052
|
this.repoMap.onProgress = null;
|
|
419616
420053
|
this.repoMap.onScanComplete = null;
|
|
@@ -419943,6 +420380,7 @@ ${s.signature ? `${s.signature}
|
|
|
419943
420380
|
async refreshRepoMap() {
|
|
419944
420381
|
this.repoMapReady = false;
|
|
419945
420382
|
this.repoMapCache = null;
|
|
420383
|
+
this.soulMapSnapshot = null;
|
|
419946
420384
|
this.syncRepoMapStore("scanning");
|
|
419947
420385
|
useRepoMapStore.getState().setScanError("");
|
|
419948
420386
|
await this.repoMap.scan().catch((err2) => this.handleScanError(err2));
|
|
@@ -419951,6 +420389,7 @@ ${s.signature ? `${s.signature}
|
|
|
419951
420389
|
await this.repoMap.clear();
|
|
419952
420390
|
this.repoMapReady = false;
|
|
419953
420391
|
this.repoMapCache = null;
|
|
420392
|
+
this.soulMapSnapshot = null;
|
|
419954
420393
|
const store = useRepoMapStore.getState();
|
|
419955
420394
|
store.setStats(0, 0, 0, 0);
|
|
419956
420395
|
store.setScanProgress("");
|
|
@@ -420095,29 +420534,59 @@ ${skillBlocks}
|
|
|
420095
420534
|
{ role: "assistant", content: assistantAck }
|
|
420096
420535
|
];
|
|
420097
420536
|
}
|
|
420098
|
-
buildSoulMapSnapshot(
|
|
420537
|
+
buildSoulMapSnapshot(opts = false) {
|
|
420538
|
+
const { modelId, force } = typeof opts === "boolean" ? { modelId: undefined, force: opts } : opts;
|
|
420099
420539
|
if (!this.isRepoMapReady())
|
|
420100
420540
|
return null;
|
|
420541
|
+
const cacheSupport = modelId ? supportsPromptCache(modelId) : { enabled: true, explicit: false };
|
|
420542
|
+
const ttlMs = cacheTtlToMs(loadConfig().cache?.ttl ?? "5m");
|
|
420543
|
+
const now2 = Date.now();
|
|
420544
|
+
if (!cacheSupport.enabled) {
|
|
420545
|
+
const rendered2 = this.renderSnapshotContent();
|
|
420546
|
+
if (rendered2) {
|
|
420547
|
+
this.soulMapSnapshot = new SoulMapSnapshot({ content: rendered2, paths: new Set(this.soulMapSnapshotPaths), ttlMs: 0 }, now2);
|
|
420548
|
+
this.clearDeltaState();
|
|
420549
|
+
}
|
|
420550
|
+
return rendered2;
|
|
420551
|
+
}
|
|
420552
|
+
const expired = !this.soulMapSnapshot || this.soulMapSnapshot.isIdleExpired(now2);
|
|
420553
|
+
if (!force && !expired && this.soulMapSnapshot) {
|
|
420554
|
+
return this.soulMapSnapshot.read(now2);
|
|
420555
|
+
}
|
|
420556
|
+
const rendered = this.renderSnapshotContent();
|
|
420557
|
+
if (!rendered)
|
|
420558
|
+
return null;
|
|
420559
|
+
this.soulMapSnapshot = new SoulMapSnapshot({ content: rendered, paths: new Set(this.soulMapSnapshotPaths), ttlMs }, now2);
|
|
420560
|
+
this.clearDeltaState();
|
|
420561
|
+
return rendered;
|
|
420562
|
+
}
|
|
420563
|
+
renderSnapshotContent() {
|
|
420101
420564
|
const rendered = this.renderRepoMap();
|
|
420102
420565
|
if (!rendered)
|
|
420103
420566
|
return null;
|
|
420104
420567
|
const isMinimal = this.contextWindowTokens <= 32000;
|
|
420105
420568
|
const treeLimit = this.repoMapTokenBudget ? Math.ceil(this.repoMapTokenBudget / 100) : 60;
|
|
420106
420569
|
const dirTree = buildDirectoryTree(this.cwd, treeLimit);
|
|
420107
|
-
|
|
420108
|
-
|
|
420109
|
-
|
|
420110
|
-
|
|
420111
|
-
|
|
420112
|
-
|
|
420113
|
-
|
|
420114
|
-
|
|
420570
|
+
const entryPoints = this.repoMap.getEntryPointsCached();
|
|
420571
|
+
return buildSoulMapUserMessage(rendered, isMinimal, dirTree, entryPoints);
|
|
420572
|
+
}
|
|
420573
|
+
clearDeltaState() {
|
|
420574
|
+
this.soulMapDiffChangedFiles.clear();
|
|
420575
|
+
this.soulMapDiffSeq = 0;
|
|
420576
|
+
this.soulMapDiffBlocks.clear();
|
|
420577
|
+
this.pendingSoulMapDiff = null;
|
|
420578
|
+
this.lastEmittedSoulMapDiff = null;
|
|
420579
|
+
this.soulMapNewFilesEmitted.clear();
|
|
420580
|
+
this.recentToolFailures.length = 0;
|
|
420581
|
+
this.foreignEditOrigins.clear();
|
|
420115
420582
|
}
|
|
420116
420583
|
pendingSoulMapDiff = null;
|
|
420117
420584
|
lastEmittedSoulMapDiff = null;
|
|
420118
|
-
buildSoulMapDiff() {
|
|
420585
|
+
buildSoulMapDiff(modelId) {
|
|
420119
420586
|
if (!this.isRepoMapReady())
|
|
420120
420587
|
return null;
|
|
420588
|
+
if (modelId && !supportsPromptCache(modelId).enabled)
|
|
420589
|
+
return null;
|
|
420121
420590
|
for (const path of this.soulMapDiffChangedFiles.keys()) {
|
|
420122
420591
|
if (path.startsWith("/"))
|
|
420123
420592
|
this.soulMapDiffChangedFiles.delete(path);
|
|
@@ -420125,26 +420594,55 @@ ${skillBlocks}
|
|
|
420125
420594
|
if (this.soulMapDiffChangedFiles.size === 0)
|
|
420126
420595
|
return null;
|
|
420127
420596
|
if (!this.pendingSoulMapDiff) {
|
|
420128
|
-
const changed = [...this.soulMapDiffChangedFiles.entries()].sort((a, b) =>
|
|
420597
|
+
const changed = [...this.soulMapDiffChangedFiles.entries()].sort((a, b) => {
|
|
420598
|
+
const recency = b[1] - a[1];
|
|
420599
|
+
return recency !== 0 ? recency : a[0].localeCompare(b[0]);
|
|
420600
|
+
}).map(([path]) => path);
|
|
420129
420601
|
const hasSnapshot = this.soulMapSnapshotPaths.size > 0;
|
|
420130
420602
|
const lines = ["<soul_map_update>"];
|
|
420603
|
+
const hasForeign = this.foreignEditOrigins.size > 0;
|
|
420604
|
+
const postCompaction = this.postCompactionPending;
|
|
420605
|
+
if (this.editedFiles.size > 0 && (hasForeign || postCompaction)) {
|
|
420606
|
+
const hotFiles = [...this.soulMapDiffChangedFiles.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3).map(([p]) => p.split("/").pop() ?? p);
|
|
420607
|
+
const hot = hotFiles.length > 0 ? ` (hot: ${hotFiles.join(", ")})` : "";
|
|
420608
|
+
const causes = [];
|
|
420609
|
+
if (postCompaction)
|
|
420610
|
+
causes.push("post-compaction");
|
|
420611
|
+
if (hasForeign) {
|
|
420612
|
+
const labels = new Set;
|
|
420613
|
+
for (const o of this.foreignEditOrigins.values()) {
|
|
420614
|
+
if (o.agentLabel)
|
|
420615
|
+
labels.add(`subagent ${o.agentLabel}`);
|
|
420616
|
+
else if (o.tabId && o.tabId !== this.tabId)
|
|
420617
|
+
labels.add(`tab ${o.tabId.slice(0, 8)}`);
|
|
420618
|
+
}
|
|
420619
|
+
if (labels.size > 0)
|
|
420620
|
+
causes.push([...labels].sort().join(", "));
|
|
420621
|
+
else
|
|
420622
|
+
causes.push("foreign edits");
|
|
420623
|
+
}
|
|
420624
|
+
const causeTag = causes.length > 0 ? ` \u2014 ${causes.join("; ")}` : "";
|
|
420625
|
+
lines.push(`# session: ${String(this.editedFiles.size)} files edited${hot}${causeTag}`);
|
|
420626
|
+
}
|
|
420131
420627
|
const MAX_RICH_BLOCKS = 5;
|
|
420132
420628
|
let richBlockCount = 0;
|
|
420629
|
+
const memoryMarkers = memoryMarkersForPaths(changed.slice(0, 15));
|
|
420133
420630
|
for (const file2 of changed.slice(0, 15)) {
|
|
420134
420631
|
const absPath = join37(this.cwd, file2);
|
|
420135
420632
|
const fileExists = existsSync31(absPath);
|
|
420136
420633
|
const block = this.soulMapDiffBlocks.get(file2);
|
|
420634
|
+
const provenance = this.classifyDeltaFile(absPath, file2, memoryMarkers.get(file2));
|
|
420137
420635
|
if (!fileExists) {
|
|
420138
|
-
lines.push(`- ${file2}`);
|
|
420636
|
+
lines.push(`- ${file2} [deleted]`);
|
|
420139
420637
|
} else if (hasSnapshot && !this.soulMapSnapshotPaths.has(file2)) {
|
|
420140
|
-
const tag = block ? `${file2}:${block.radiusTag} [
|
|
420638
|
+
const tag = block ? `${file2}:${block.radiusTag} [new] ${provenance}`.trimEnd() : `${file2}: [new] ${provenance}`.trimEnd();
|
|
420141
420639
|
lines.push(tag);
|
|
420142
420640
|
if (block?.symbolBlock && richBlockCount < MAX_RICH_BLOCKS) {
|
|
420143
420641
|
lines.push(block.symbolBlock);
|
|
420144
420642
|
richBlockCount++;
|
|
420145
420643
|
}
|
|
420146
420644
|
} else {
|
|
420147
|
-
const tag = block ? `${file2}:${block.radiusTag}
|
|
420645
|
+
const tag = block ? `${file2}:${block.radiusTag} ${provenance}`.trimEnd() : `${file2}: ${provenance}`.trimEnd();
|
|
420148
420646
|
lines.push(tag);
|
|
420149
420647
|
if (block?.symbolBlock && richBlockCount < MAX_RICH_BLOCKS) {
|
|
420150
420648
|
lines.push(block.symbolBlock);
|
|
@@ -420162,10 +420660,45 @@ ${skillBlocks}
|
|
|
420162
420660
|
return null;
|
|
420163
420661
|
return this.pendingSoulMapDiff;
|
|
420164
420662
|
}
|
|
420663
|
+
classifyDeltaFile(absPath, rel, memMarker) {
|
|
420664
|
+
const tags = [];
|
|
420665
|
+
if (this.editedFiles.has(absPath))
|
|
420666
|
+
tags.push("[edited]");
|
|
420667
|
+
if (this.mentionedFiles.has(absPath))
|
|
420668
|
+
tags.push("[mentioned]");
|
|
420669
|
+
if (this.editorFile === absPath)
|
|
420670
|
+
tags.push("[open]");
|
|
420671
|
+
if (this.soulMapNewFilesEmitted.has(rel) && existsSync31(absPath)) {
|
|
420672
|
+
tags.push("[modified-since-new]");
|
|
420673
|
+
}
|
|
420674
|
+
const failure = this.recentToolFailures.find((f) => f.target === absPath || f.target === rel);
|
|
420675
|
+
if (failure)
|
|
420676
|
+
tags.push(`[recent failure: ${failure.tool} \u2014 ${failure.reason}]`);
|
|
420677
|
+
if (memMarker && memMarker.count > 0) {
|
|
420678
|
+
const cat = memMarker.category ?? "memory";
|
|
420679
|
+
const pin = memMarker.pinned ? "pinned " : "";
|
|
420680
|
+
const n = memMarker.count > 1 ? ` \xD7${String(memMarker.count)}` : "";
|
|
420681
|
+
tags.push(`[${pin}${cat}${n}]`);
|
|
420682
|
+
}
|
|
420683
|
+
return tags.join(" ");
|
|
420684
|
+
}
|
|
420685
|
+
forceSnapshotRefresh() {
|
|
420686
|
+
this.soulMapSnapshot = null;
|
|
420687
|
+
}
|
|
420165
420688
|
commitSoulMapDiff() {
|
|
420166
420689
|
if (this.pendingSoulMapDiff) {
|
|
420690
|
+
const hasSnapshot = this.soulMapSnapshotPaths.size > 0;
|
|
420691
|
+
if (hasSnapshot) {
|
|
420692
|
+
for (const rel of this.soulMapDiffChangedFiles.keys()) {
|
|
420693
|
+
if (!this.soulMapSnapshotPaths.has(rel)) {
|
|
420694
|
+
this.soulMapNewFilesEmitted.add(rel);
|
|
420695
|
+
}
|
|
420696
|
+
}
|
|
420697
|
+
}
|
|
420167
420698
|
this.lastEmittedSoulMapDiff = this.pendingSoulMapDiff;
|
|
420168
420699
|
this.pendingSoulMapDiff = null;
|
|
420700
|
+
this.postCompactionPending = false;
|
|
420701
|
+
this.foreignEditOrigins.clear();
|
|
420169
420702
|
}
|
|
420170
420703
|
}
|
|
420171
420704
|
buildSkillsBlock() {
|
|
@@ -420373,6 +420906,27 @@ Project commands: ${parts2.join(" \xB7 ")}` : "";
|
|
|
420373
420906
|
return true;
|
|
420374
420907
|
}
|
|
420375
420908
|
pendingSemanticMode = null;
|
|
420909
|
+
soulMapNewFilesEmitted = new Set;
|
|
420910
|
+
recentToolFailures = [];
|
|
420911
|
+
recordToolFailure(tool4, target, reason) {
|
|
420912
|
+
const at = Date.now();
|
|
420913
|
+
const key2 = `${tool4}:${target}`;
|
|
420914
|
+
const existing = this.recentToolFailures.findIndex((f) => `${f.tool}:${f.target}` === key2);
|
|
420915
|
+
if (existing >= 0)
|
|
420916
|
+
this.recentToolFailures.splice(existing, 1);
|
|
420917
|
+
this.recentToolFailures.push({ tool: tool4, target, reason, at });
|
|
420918
|
+
if (this.recentToolFailures.length > 5)
|
|
420919
|
+
this.recentToolFailures.shift();
|
|
420920
|
+
this.pendingSoulMapDiff = null;
|
|
420921
|
+
if (target) {
|
|
420922
|
+
const rel = target.startsWith(`${this.cwd}/`) ? target.slice(this.cwd.length + 1) : target;
|
|
420923
|
+
if (!this.soulMapDiffChangedFiles.has(rel)) {
|
|
420924
|
+
this.soulMapDiffChangedFiles.set(rel, ++this.soulMapDiffSeq);
|
|
420925
|
+
}
|
|
420926
|
+
}
|
|
420927
|
+
}
|
|
420928
|
+
foreignEditOrigins = new Map;
|
|
420929
|
+
postCompactionPending = false;
|
|
420376
420930
|
};
|
|
420377
420931
|
});
|
|
420378
420932
|
|
|
@@ -492695,7 +493249,7 @@ var init_checkpoints = __esm(() => {
|
|
|
492695
493249
|
});
|
|
492696
493250
|
|
|
492697
493251
|
// src/core/commands/utils.ts
|
|
492698
|
-
import { existsSync as existsSync42, readdirSync as
|
|
493252
|
+
import { existsSync as existsSync42, readdirSync as readdirSync10, statSync as statSync10 } from "fs";
|
|
492699
493253
|
import { homedir as homedir31 } from "os";
|
|
492700
493254
|
import { join as join45 } from "path";
|
|
492701
493255
|
function sysMsg(ctx, content) {
|
|
@@ -492720,7 +493274,7 @@ function dirSize(dirPath) {
|
|
|
492720
493274
|
if (!existsSync42(dirPath))
|
|
492721
493275
|
return 0;
|
|
492722
493276
|
let total = 0;
|
|
492723
|
-
for (const entry of
|
|
493277
|
+
for (const entry of readdirSync10(dirPath)) {
|
|
492724
493278
|
const fp = join45(dirPath, entry);
|
|
492725
493279
|
try {
|
|
492726
493280
|
const s2 = statSync10(fp);
|
|
@@ -498728,13 +499282,6 @@ function getRestartSpec(options = {}) {
|
|
|
498728
499282
|
}
|
|
498729
499283
|
|
|
498730
499284
|
// src/core/sessions/emergency-save.ts
|
|
498731
|
-
function updateEmergencySnapshot(manager, meta4, tabMessages, tabCoreMessages) {
|
|
498732
|
-
const frozen = new Map;
|
|
498733
|
-
for (const [id, msgs] of tabMessages) {
|
|
498734
|
-
frozen.set(id, msgs.map((m6) => ({ ...m6 })));
|
|
498735
|
-
}
|
|
498736
|
-
_snapshot = { manager, meta: { ...meta4 }, tabMessages: frozen, tabCoreMessages };
|
|
498737
|
-
}
|
|
498738
499285
|
function flushEmergencySession() {
|
|
498739
499286
|
if (!_snapshot)
|
|
498740
499287
|
return false;
|
|
@@ -500600,13 +501147,12 @@ function hardRestart() {
|
|
|
500600
501147
|
child.unref();
|
|
500601
501148
|
process.exit(0);
|
|
500602
501149
|
}
|
|
500603
|
-
function reraiseSignal(
|
|
501150
|
+
function reraiseSignal(_signal) {
|
|
500604
501151
|
flushEmergencySession();
|
|
500605
501152
|
runCleanup();
|
|
500606
501153
|
renderer?.destroy();
|
|
500607
501154
|
printExitBanner();
|
|
500608
|
-
process.
|
|
500609
|
-
process.kill(process.pid, signal);
|
|
501155
|
+
process.exit(0);
|
|
500610
501156
|
}
|
|
500611
501157
|
function RestartSplash({ onComplete }) {
|
|
500612
501158
|
const t2 = useTheme();
|
|
@@ -501932,7 +502478,7 @@ async function handleExportAll(ctx) {
|
|
|
501932
502478
|
const tokenUsage = ctx.chat.tokenUsage;
|
|
501933
502479
|
const forgeMode = ctx.chat.forgeMode;
|
|
501934
502480
|
const repoMapReady = ctx.contextManager.isRepoMapReady();
|
|
501935
|
-
const soulMapBlock = ctx.contextManager.buildSoulMapSnapshot(
|
|
502481
|
+
const soulMapBlock = ctx.contextManager.buildSoulMapSnapshot();
|
|
501936
502482
|
const skillsMessages = ctx.contextManager.buildSkillsMessages();
|
|
501937
502483
|
const payload = {
|
|
501938
502484
|
exportedAt: new Date().toISOString(),
|
|
@@ -504085,83 +504631,6 @@ var init_useNeovim = __esm(() => {
|
|
|
504085
504631
|
});
|
|
504086
504632
|
|
|
504087
504633
|
// src/hooks/useSessionBuilder.ts
|
|
504088
|
-
function buildSessionMeta({
|
|
504089
|
-
sessionId,
|
|
504090
|
-
title,
|
|
504091
|
-
customTitle,
|
|
504092
|
-
cwd: cwd2,
|
|
504093
|
-
snapshot,
|
|
504094
|
-
currentTabMessages,
|
|
504095
|
-
currentTabCoreMessages
|
|
504096
|
-
}) {
|
|
504097
|
-
const tabMessages = new Map;
|
|
504098
|
-
const tabCoreMessages = new Map;
|
|
504099
|
-
const tabs = [];
|
|
504100
|
-
for (const tabState of snapshot.tabStates) {
|
|
504101
|
-
const isActiveTab = tabState.id === snapshot.activeTabId;
|
|
504102
|
-
const msgs = isActiveTab ? currentTabMessages : tabState.messages.filter((m6) => m6.role !== "system" || m6.showInChat);
|
|
504103
|
-
tabMessages.set(tabState.id, msgs);
|
|
504104
|
-
const cores = isActiveTab && currentTabCoreMessages ? currentTabCoreMessages : tabState.coreMessages;
|
|
504105
|
-
tabCoreMessages.set(tabState.id, cores);
|
|
504106
|
-
const cpStore = useCheckpointStore.getState();
|
|
504107
|
-
const cpState = cpStore.getCheckpoints(tabState.id);
|
|
504108
|
-
const redoStack = cpStore.getTab(tabState.id).redoStack;
|
|
504109
|
-
const seen = new Set;
|
|
504110
|
-
const checkpointTags = [];
|
|
504111
|
-
for (const cp2 of cpState) {
|
|
504112
|
-
if (cp2.gitTag && !seen.has(cp2.gitTag)) {
|
|
504113
|
-
seen.add(cp2.gitTag);
|
|
504114
|
-
checkpointTags.push({
|
|
504115
|
-
index: cp2.index,
|
|
504116
|
-
anchorMessageId: cp2.anchorMessageId,
|
|
504117
|
-
gitTag: cp2.gitTag
|
|
504118
|
-
});
|
|
504119
|
-
}
|
|
504120
|
-
}
|
|
504121
|
-
for (const entry of redoStack) {
|
|
504122
|
-
const cp2 = entry.checkpoint;
|
|
504123
|
-
if (cp2.gitTag && !seen.has(cp2.gitTag)) {
|
|
504124
|
-
seen.add(cp2.gitTag);
|
|
504125
|
-
checkpointTags.push({
|
|
504126
|
-
index: cp2.index,
|
|
504127
|
-
anchorMessageId: cp2.anchorMessageId,
|
|
504128
|
-
gitTag: cp2.gitTag
|
|
504129
|
-
});
|
|
504130
|
-
}
|
|
504131
|
-
}
|
|
504132
|
-
const uiSnapshot = useUIStore.getState();
|
|
504133
|
-
const verboseForTab = uiSnapshot.verboseByTab[tabState.id];
|
|
504134
|
-
tabs.push({
|
|
504135
|
-
id: tabState.id,
|
|
504136
|
-
label: tabState.label,
|
|
504137
|
-
activeModel: tabState.activeModel,
|
|
504138
|
-
sessionId: tabState.sessionId,
|
|
504139
|
-
planMode: tabState.planMode,
|
|
504140
|
-
planRequest: tabState.planRequest,
|
|
504141
|
-
coAuthorCommits: tabState.coAuthorCommits,
|
|
504142
|
-
forgeMode: tabState.forgeMode,
|
|
504143
|
-
tokenUsage: tabState.tokenUsage,
|
|
504144
|
-
messageRange: { startLine: 0, endLine: msgs.length },
|
|
504145
|
-
...checkpointTags.length > 0 ? { checkpointTags } : {},
|
|
504146
|
-
...verboseForTab !== undefined ? { verbose: verboseForTab } : {}
|
|
504147
|
-
});
|
|
504148
|
-
}
|
|
504149
|
-
const allMsgs = [...tabMessages.values()].flat();
|
|
504150
|
-
const startedAt = allMsgs[0]?.timestamp ?? Date.now();
|
|
504151
|
-
const activeTabState = snapshot.tabStates.find((t2) => t2.id === snapshot.activeTabId);
|
|
504152
|
-
const meta4 = {
|
|
504153
|
-
id: sessionId,
|
|
504154
|
-
title,
|
|
504155
|
-
...customTitle ? { customTitle } : {},
|
|
504156
|
-
cwd: cwd2,
|
|
504157
|
-
startedAt,
|
|
504158
|
-
updatedAt: Date.now(),
|
|
504159
|
-
activeTabId: snapshot.activeTabId,
|
|
504160
|
-
forgeMode: activeTabState?.forgeMode ?? "default",
|
|
504161
|
-
tabs
|
|
504162
|
-
};
|
|
504163
|
-
return { meta: meta4, tabMessages, tabCoreMessages };
|
|
504164
|
-
}
|
|
504165
504634
|
function buildTabMeta(args2) {
|
|
504166
504635
|
const msgs = args2.messages.filter((m6) => m6.role !== "system" || m6.showInChat);
|
|
504167
504636
|
const cpStore = useCheckpointStore.getState();
|
|
@@ -504384,13 +504853,23 @@ function useTabs() {
|
|
|
504384
504853
|
}
|
|
504385
504854
|
return states;
|
|
504386
504855
|
}, []);
|
|
504387
|
-
const restoreFromMeta = import_react37.useCallback((
|
|
504388
|
-
if (
|
|
504856
|
+
const restoreFromMeta = import_react37.useCallback((incomingMetas, activeId, tabMessages, tabCoreMessages) => {
|
|
504857
|
+
if (incomingMetas.length === 0)
|
|
504389
504858
|
return;
|
|
504390
504859
|
for (const chat of chatRegistry.current.values()) {
|
|
504391
504860
|
chat.abort();
|
|
504392
504861
|
}
|
|
504393
504862
|
chatRegistry.current.clear();
|
|
504863
|
+
const seenIds = new Set;
|
|
504864
|
+
const tabMetas = [];
|
|
504865
|
+
for (const tm of incomingMetas) {
|
|
504866
|
+
if (seenIds.has(tm.id))
|
|
504867
|
+
continue;
|
|
504868
|
+
seenIds.add(tm.id);
|
|
504869
|
+
tabMetas.push(tm);
|
|
504870
|
+
if (tabMetas.length >= MAX_TABS)
|
|
504871
|
+
break;
|
|
504872
|
+
}
|
|
504394
504873
|
const restoredTabs = tabMetas.map((tm) => ({
|
|
504395
504874
|
id: tm.id,
|
|
504396
504875
|
label: tm.label
|
|
@@ -506767,7 +507246,21 @@ function useChat({
|
|
|
506767
507246
|
visible = true,
|
|
506768
507247
|
onModelChange
|
|
506769
507248
|
}) {
|
|
506770
|
-
const [messages,
|
|
507249
|
+
const [messages, setMessagesRaw] = import_react46.useState(initialState?.messages ?? []);
|
|
507250
|
+
const messagesRef = import_react46.useRef(initialState?.messages ?? []);
|
|
507251
|
+
messagesRef.current = messages;
|
|
507252
|
+
const setMessages = import_react46.useCallback((action) => {
|
|
507253
|
+
if (typeof action === "function") {
|
|
507254
|
+
setMessagesRaw((prev) => {
|
|
507255
|
+
const next = action(prev);
|
|
507256
|
+
messagesRef.current = next;
|
|
507257
|
+
return next;
|
|
507258
|
+
});
|
|
507259
|
+
} else {
|
|
507260
|
+
messagesRef.current = action;
|
|
507261
|
+
setMessagesRaw(action);
|
|
507262
|
+
}
|
|
507263
|
+
}, []);
|
|
506771
507264
|
const [coreMessages, setCoreMessages] = import_react46.useState(initialState?.coreMessages ?? []);
|
|
506772
507265
|
const [isLoading, setIsLoading] = import_react46.useState(false);
|
|
506773
507266
|
const [loadingStartedAt, setLoadingStartedAt] = import_react46.useState(0);
|
|
@@ -506982,10 +507475,12 @@ function useChat({
|
|
|
506982
507475
|
}, [activeModelForEffect]);
|
|
506983
507476
|
const [tokenUsage, setTokenUsageRaw] = import_react46.useState(initialState?.tokenUsage ?? { ...ZERO_USAGE });
|
|
506984
507477
|
const sessionIdRef = import_react46.useRef(initialState?.sessionId ?? getAppSessionId());
|
|
506985
|
-
|
|
506986
|
-
|
|
506987
|
-
|
|
506988
|
-
|
|
507478
|
+
import_react46.useEffect(() => {
|
|
507479
|
+
if (initialState?.sessionId && initialState.sessionId !== getAppSessionId()) {
|
|
507480
|
+
setAppSessionId(initialState.sessionId);
|
|
507481
|
+
sessionIdRef.current = initialState.sessionId;
|
|
507482
|
+
}
|
|
507483
|
+
}, []);
|
|
506989
507484
|
import_react46.useEffect(() => {
|
|
506990
507485
|
const unsub = useSessionStore.subscribe((s2) => {
|
|
506991
507486
|
sessionIdRef.current = s2.appSessionId;
|
|
@@ -507603,7 +508098,7 @@ INCLUDE the plan progress above VERBATIM in ## Current State so the agent knows
|
|
|
507603
508098
|
});
|
|
507604
508099
|
}
|
|
507605
508100
|
}
|
|
507606
|
-
}, [setTokenUsage, effectiveConfig, contextManager, cwd2, tabId]);
|
|
508101
|
+
}, [setTokenUsage, effectiveConfig, contextManager, cwd2, tabId, setMessages]);
|
|
507607
508102
|
summarizeConversationRef.current = summarizeConversation;
|
|
507608
508103
|
const autoSummarizedRef = import_react46.useRef(false);
|
|
507609
508104
|
import_react46.useEffect(() => {
|
|
@@ -507915,7 +508410,7 @@ ${description}`,
|
|
|
507915
508410
|
};
|
|
507916
508411
|
setMessages((prev) => {
|
|
507917
508412
|
const allMsgs = [...prev, userMsg];
|
|
507918
|
-
queueMicrotask(() => persistThisTab(
|
|
508413
|
+
queueMicrotask(() => persistThisTab(messagesRef.current, coreMessagesRef.current));
|
|
507919
508414
|
return allMsgs;
|
|
507920
508415
|
});
|
|
507921
508416
|
const currentCoreMessages = coreMessagesRef.current;
|
|
@@ -508164,8 +508659,21 @@ ${description}`,
|
|
|
508164
508659
|
desloppify: desloppifyModelId ? resolveModel(desloppifyModelId) : undefined,
|
|
508165
508660
|
verify: verifyModelId ? resolveModel(verifyModelId) : undefined
|
|
508166
508661
|
} : undefined;
|
|
508167
|
-
|
|
508168
|
-
|
|
508662
|
+
let webSearchModel;
|
|
508663
|
+
try {
|
|
508664
|
+
webSearchModel = webSearchModelId ? resolveModel(webSearchModelId) : undefined;
|
|
508665
|
+
} catch (err2) {
|
|
508666
|
+
logBackgroundError("web-search-resolve", `webSearch model "${webSearchModelId}" failed to resolve: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
508667
|
+
webSearchModel = undefined;
|
|
508668
|
+
}
|
|
508669
|
+
webSearchModelLabelRef.current = webSearchModel ? (() => {
|
|
508670
|
+
const id = webSearchModelId;
|
|
508671
|
+
const slash = id.indexOf("/");
|
|
508672
|
+
const providerId = slash > 0 ? id.slice(0, slash) : "";
|
|
508673
|
+
const short = getShortModelLabel(id);
|
|
508674
|
+
return providerId ? `${providerId}/${short}` : short;
|
|
508675
|
+
})() : null;
|
|
508676
|
+
logBackgroundError("router:web-search", webSearchModel ? `agent mode \u2192 ${webSearchModelId}` : webSearchModelId ? `agent disabled (resolve failed) \u2192 fallback to direct scraper` : `agent disabled (no taskRouter.webSearch set) \u2192 fallback to direct scraper`);
|
|
508169
508677
|
const webSearchEnabled = effectiveConfig2.webSearch !== false;
|
|
508170
508678
|
const webSearchApproval = webSearchEnabled ? interactiveCallbacks.onWebSearchApproval : undefined;
|
|
508171
508679
|
const fetchPageApproval = interactiveCallbacks.onFetchPageApproval;
|
|
@@ -508404,11 +508912,11 @@ Proceeding without it will significantly reduce capabilities \u2014 no soul tool
|
|
|
508404
508912
|
tabLabel
|
|
508405
508913
|
});
|
|
508406
508914
|
})();
|
|
508407
|
-
result = await currentAgent.stream({
|
|
508915
|
+
result = await runWithEditOrigin({ tabId: tabId ?? null, agentId: null, agentLabel: null }, () => currentAgent.stream({
|
|
508408
508916
|
messages: newCoreMessages,
|
|
508409
508917
|
abortSignal: abortController.signal,
|
|
508410
508918
|
options: { userMessage: input }
|
|
508411
|
-
});
|
|
508919
|
+
}));
|
|
508412
508920
|
break;
|
|
508413
508921
|
} catch (err2) {
|
|
508414
508922
|
if (!isProviderOptionsError(err2) || degradeLevel === 2)
|
|
@@ -508898,10 +509406,7 @@ Proceeding without it will significantly reduce capabilities \u2014 no soul tool
|
|
|
508898
509406
|
segments: finalSegments.length > 0 ? [...finalSegments] : undefined,
|
|
508899
509407
|
...lockInCommittedAt !== undefined ? { lockInCommittedAt } : {}
|
|
508900
509408
|
};
|
|
508901
|
-
|
|
508902
|
-
persistThisTab([...prev, partialMsg], coreMessagesRef.current);
|
|
508903
|
-
return prev;
|
|
508904
|
-
});
|
|
509409
|
+
persistThisTab([...messagesRef.current, partialMsg], coreMessagesRef.current);
|
|
508905
509410
|
} catch {}
|
|
508906
509411
|
});
|
|
508907
509412
|
}
|
|
@@ -508988,7 +509493,6 @@ ${errStack}` : `Error: ${displayErr}`);
|
|
|
508988
509493
|
timestamp: Date.now(),
|
|
508989
509494
|
showInChat: true
|
|
508990
509495
|
} : null;
|
|
508991
|
-
let finalMsgsForSave = [];
|
|
508992
509496
|
setMessages((prev) => {
|
|
508993
509497
|
const allMsgs = [
|
|
508994
509498
|
...prev,
|
|
@@ -508996,7 +509500,6 @@ ${errStack}` : `Error: ${displayErr}`);
|
|
|
508996
509500
|
...errorMsgs,
|
|
508997
509501
|
...prematureStopMsg ? [prematureStopMsg] : []
|
|
508998
509502
|
];
|
|
508999
|
-
finalMsgsForSave = allMsgs;
|
|
509000
509503
|
if (assistantMsg) {
|
|
509001
509504
|
Promise.resolve().then(() => (init_bridge(), exports_bridge)).then(({ bridgeStreamEmitter: bridgeStreamEmitter2, reasoningStreamEmitter: reasoningStreamEmitter2 }) => {
|
|
509002
509505
|
reasoningStreamEmitter2.flushNow(tabId);
|
|
@@ -509040,7 +509543,7 @@ ${errStack}` : `Error: ${displayErr}`);
|
|
|
509040
509543
|
const target = effectiveConfig2.contextManagement?.pruningTarget ?? "none";
|
|
509041
509544
|
return ["main", "both"].includes(target) ? pruneOldToolResults(updated) : updated;
|
|
509042
509545
|
});
|
|
509043
|
-
persistThisTab(
|
|
509546
|
+
persistThisTab(messagesRef.current, coreMessagesRef.current);
|
|
509044
509547
|
streamSegmentsBuffer.current = [];
|
|
509045
509548
|
liveToolCallsBuffer.current = [];
|
|
509046
509549
|
lastFlushedSegments.current = [];
|
|
@@ -509650,7 +510153,8 @@ ${pContent}`;
|
|
|
509650
510153
|
setForgeMode,
|
|
509651
510154
|
onModelChange,
|
|
509652
510155
|
setCoreMessagesEager,
|
|
509653
|
-
persistThisTab
|
|
510156
|
+
persistThisTab,
|
|
510157
|
+
setMessages
|
|
509654
510158
|
]);
|
|
509655
510159
|
handleSubmitRef.current = handleSubmit;
|
|
509656
510160
|
const abort2 = import_react46.useCallback(() => {
|
|
@@ -509707,7 +510211,7 @@ ${pContent}`;
|
|
|
509707
510211
|
segmentsDirty.current = false;
|
|
509708
510212
|
toolCallsDirty.current = false;
|
|
509709
510213
|
}
|
|
509710
|
-
}, [setActivePlan, tabId]);
|
|
510214
|
+
}, [setActivePlan, tabId, setMessages]);
|
|
509711
510215
|
const snapshot = import_react46.useCallback((label) => ({
|
|
509712
510216
|
id: sessionIdRef.current,
|
|
509713
510217
|
label,
|
|
@@ -511257,20 +511761,20 @@ var init_useHover = __esm(() => {
|
|
|
511257
511761
|
});
|
|
511258
511762
|
|
|
511259
511763
|
// src/core/utils/syntax.ts
|
|
511260
|
-
import { existsSync as existsSync52, readdirSync as
|
|
511764
|
+
import { existsSync as existsSync52, readdirSync as readdirSync11 } from "fs";
|
|
511261
511765
|
import { homedir as homedir37 } from "os";
|
|
511262
511766
|
import { dirname as dirname22, join as join54, resolve as resolve40 } from "path";
|
|
511263
511767
|
function discoverParsers() {
|
|
511264
511768
|
const parsers = [];
|
|
511265
511769
|
let dirs;
|
|
511266
511770
|
try {
|
|
511267
|
-
dirs =
|
|
511771
|
+
dirs = readdirSync11(coreAssetsDir, { withFileTypes: true }).filter((d4) => d4.isDirectory()).map((d4) => d4.name);
|
|
511268
511772
|
} catch {
|
|
511269
511773
|
return parsers;
|
|
511270
511774
|
}
|
|
511271
511775
|
for (const dir of dirs) {
|
|
511272
511776
|
const langDir = resolve40(coreAssetsDir, dir);
|
|
511273
|
-
const wasmFiles =
|
|
511777
|
+
const wasmFiles = readdirSync11(langDir).filter((f3) => f3.endsWith(".wasm"));
|
|
511274
511778
|
const wasmFile = wasmFiles[0];
|
|
511275
511779
|
if (!wasmFile)
|
|
511276
511780
|
continue;
|
|
@@ -535706,10 +536210,10 @@ function getAllPackageStatus(category) {
|
|
|
535706
536210
|
}
|
|
535707
536211
|
function detectProjectLanguages(cwd2) {
|
|
535708
536212
|
const languages = [];
|
|
535709
|
-
const { readdirSync:
|
|
536213
|
+
const { readdirSync: readdirSync12 } = __require("fs");
|
|
535710
536214
|
let files;
|
|
535711
536215
|
try {
|
|
535712
|
-
files =
|
|
536216
|
+
files = readdirSync12(cwd2);
|
|
535713
536217
|
} catch {
|
|
535714
536218
|
return [];
|
|
535715
536219
|
}
|
|
@@ -539764,7 +540268,7 @@ function RouterSettings({
|
|
|
539764
540268
|
const rowBg2 = isSelected ? t2.bgPopupHighlight : t2.bgPopup;
|
|
539765
540269
|
const fbs = modelFallback?.[row.modelId] ?? [];
|
|
539766
540270
|
const fallbackLabelCol = Math.min(28, Math.max(18, Math.floor(contentW * 0.32)));
|
|
539767
|
-
const label2 = truncate4(
|
|
540271
|
+
const label2 = truncate4(row.modelId, fallbackLabelCol).padEnd(fallbackLabelCol).slice(0, fallbackLabelCol);
|
|
539768
540272
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
539769
540273
|
flexDirection: "row",
|
|
539770
540274
|
height: 1,
|
|
@@ -539790,7 +540294,7 @@ function RouterSettings({
|
|
|
539790
540294
|
bg: rowBg2,
|
|
539791
540295
|
fg: t2.brandAlt,
|
|
539792
540296
|
attributes: BOLD19,
|
|
539793
|
-
children: truncate4(`\u2192 ${fbs.
|
|
540297
|
+
children: truncate4(`\u2192 ${fbs.join(", ")}`, Math.max(8, contentW - 4 - fallbackLabelCol - 2))
|
|
539794
540298
|
}, undefined, false, undefined, this) : /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
539795
540299
|
bg: rowBg2,
|
|
539796
540300
|
fg: t2.textDim,
|
|
@@ -539850,7 +540354,7 @@ function RouterSettings({
|
|
|
539850
540354
|
bg: rowBg,
|
|
539851
540355
|
fg: t2.brandAlt,
|
|
539852
540356
|
attributes: BOLD19,
|
|
539853
|
-
children: truncate4(
|
|
540357
|
+
children: truncate4(modelId, modelCol)
|
|
539854
540358
|
}, undefined, false, undefined, this) : /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
539855
540359
|
bg: rowBg,
|
|
539856
540360
|
fg: t2.textDim,
|
|
@@ -539900,18 +540404,24 @@ var init_RouterSettings = __esm(async () => {
|
|
|
539900
540404
|
]
|
|
539901
540405
|
},
|
|
539902
540406
|
{
|
|
539903
|
-
id: "
|
|
539904
|
-
title: "
|
|
540407
|
+
id: "tools",
|
|
540408
|
+
title: "Tools",
|
|
539905
540409
|
defs: [
|
|
539906
|
-
{ kind: "slot", key: "spark", label: "Explore", icon: "read_only", hint: "Read-only agents" },
|
|
539907
|
-
{ kind: "slot", key: "ember", label: "Code", icon: "edit", hint: "Edit agents" },
|
|
539908
540410
|
{
|
|
539909
540411
|
kind: "slot",
|
|
539910
540412
|
key: "webSearch",
|
|
539911
540413
|
label: "Web Search",
|
|
539912
540414
|
icon: "web",
|
|
539913
540415
|
hint: "Web search & fetch"
|
|
539914
|
-
}
|
|
540416
|
+
}
|
|
540417
|
+
]
|
|
540418
|
+
},
|
|
540419
|
+
{
|
|
540420
|
+
id: "dispatch",
|
|
540421
|
+
title: "Dispatch",
|
|
540422
|
+
defs: [
|
|
540423
|
+
{ kind: "slot", key: "spark", label: "Explore", icon: "read_only", hint: "Read-only agents" },
|
|
540424
|
+
{ kind: "slot", key: "ember", label: "Code", icon: "edit", hint: "Edit agents" },
|
|
539915
540425
|
{
|
|
539916
540426
|
kind: "picker",
|
|
539917
540427
|
key: "maxConcurrentAgents",
|
|
@@ -542032,23 +542542,48 @@ function App({
|
|
|
542032
542542
|
setShutdownPhase(1);
|
|
542033
542543
|
schedule(async () => {
|
|
542034
542544
|
try {
|
|
542545
|
+
const sid = getAppSessionId();
|
|
542546
|
+
const liveTabs = tabMgrRef.current.tabs;
|
|
542035
542547
|
const activeChat = tabMgrRef.current.getActiveChat();
|
|
542036
|
-
const
|
|
542037
|
-
const
|
|
542038
|
-
|
|
542039
|
-
|
|
542040
|
-
|
|
542041
|
-
|
|
542042
|
-
|
|
542043
|
-
|
|
542044
|
-
|
|
542045
|
-
|
|
542046
|
-
|
|
542047
|
-
|
|
542048
|
-
|
|
542049
|
-
|
|
542050
|
-
|
|
542051
|
-
|
|
542548
|
+
const activeTabId2 = tabMgrRef.current.activeTabId;
|
|
542549
|
+
const anyContent = liveTabs.some((t3) => {
|
|
542550
|
+
const c = tabMgrRef.current.getChat(t3.id);
|
|
542551
|
+
return c?.messages.some((m6) => m6.role === "user" || m6.role === "assistant");
|
|
542552
|
+
});
|
|
542553
|
+
if (anyContent) {
|
|
542554
|
+
const liveIds = new Set(liveTabs.map((t3) => t3.id));
|
|
542555
|
+
const fallbackTitle = activeChat?.customTitle ?? SessionManager.deriveTitle(activeChat?.messages ?? []);
|
|
542556
|
+
for (const tab of liveTabs) {
|
|
542557
|
+
const chat = tabMgrRef.current.getChat(tab.id);
|
|
542558
|
+
if (!chat)
|
|
542559
|
+
continue;
|
|
542560
|
+
const filtered = chat.messages.filter((m6) => m6.role !== "system" || m6.showInChat);
|
|
542561
|
+
const { tabMeta } = buildTabMeta({
|
|
542562
|
+
tabId: tab.id,
|
|
542563
|
+
tabLabel: tab.label,
|
|
542564
|
+
activeModel: chat.activeModel,
|
|
542565
|
+
sessionId: sid,
|
|
542566
|
+
planMode: chat.planMode,
|
|
542567
|
+
planRequest: chat.planRequest,
|
|
542568
|
+
coAuthorCommits: chat.coAuthorCommits,
|
|
542569
|
+
forgeMode: chat.forgeMode,
|
|
542570
|
+
tokenUsage: chat.tokenUsage,
|
|
542571
|
+
messages: filtered,
|
|
542572
|
+
coreMessages: chat.coreMessages
|
|
542573
|
+
});
|
|
542574
|
+
await sessionManager.saveTab(sid, tabMeta, filtered, chat.coreMessages, {
|
|
542575
|
+
title: fallbackTitle,
|
|
542576
|
+
customTitle: activeChat?.customTitle ?? null,
|
|
542577
|
+
cwd: cwd2,
|
|
542578
|
+
forgeMode: activeChat?.forgeMode ?? "default",
|
|
542579
|
+
activeTabId: activeTabId2
|
|
542580
|
+
});
|
|
542581
|
+
}
|
|
542582
|
+
try {
|
|
542583
|
+
await sessionManager.pruneTabsNotIn(sid, liveIds);
|
|
542584
|
+
} catch {}
|
|
542585
|
+
setExitSessionId(sid);
|
|
542586
|
+
savedSessionIdRef.current = sid;
|
|
542052
542587
|
}
|
|
542053
542588
|
} catch (err2) {
|
|
542054
542589
|
logBackgroundError("shutdown", `session save failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
@@ -542082,10 +542617,10 @@ function App({
|
|
|
542082
542617
|
}
|
|
542083
542618
|
const data = sessionManager.loadSession(fullId);
|
|
542084
542619
|
if (data) {
|
|
542620
|
+
setAppSessionId(data.meta.id);
|
|
542085
542621
|
tabMgr.restoreFromMeta(data.meta.tabs, data.meta.activeTabId, data.tabMessages, data.tabCoreMessages);
|
|
542086
542622
|
setForgeModeHeader(data.meta.forgeMode);
|
|
542087
542623
|
setExitSessionId(data.meta.id);
|
|
542088
|
-
setAppSessionId(data.meta.id);
|
|
542089
542624
|
for (const tab of data.meta.tabs) {
|
|
542090
542625
|
if (tab.checkpointTags?.length) {
|
|
542091
542626
|
useCheckpointStore.getState().restoreTagsFromMeta(tab.id, tab.checkpointTags ?? []);
|
|
@@ -542403,23 +542938,43 @@ function App({
|
|
|
542403
542938
|
const activeChat = tabMgrRef.current?.getActiveChat();
|
|
542404
542939
|
const hasContent = activeChat?.messages.some((m6) => m6.role === "user" || m6.role === "assistant");
|
|
542405
542940
|
if (hasContent && activeChat) {
|
|
542406
|
-
|
|
542407
|
-
|
|
542408
|
-
|
|
542409
|
-
|
|
542410
|
-
|
|
542411
|
-
|
|
542412
|
-
|
|
542941
|
+
try {
|
|
542942
|
+
const sid = getAppSessionId();
|
|
542943
|
+
const liveTabs = tabMgrRef.current?.tabs ?? [];
|
|
542944
|
+
const activeTabId2 = tabMgrRef.current?.activeTabId ?? "";
|
|
542945
|
+
const liveIds = new Set(liveTabs.map((t3) => t3.id));
|
|
542946
|
+
const fallbackTitle = activeChat.customTitle ?? SessionManager.deriveTitle(activeChat.messages);
|
|
542947
|
+
for (const tab of liveTabs) {
|
|
542948
|
+
const chat = tabMgrRef.current?.getChat(tab.id);
|
|
542949
|
+
if (!chat)
|
|
542950
|
+
continue;
|
|
542951
|
+
const filtered = chat.messages.filter((m6) => m6.role !== "system" || m6.showInChat);
|
|
542952
|
+
const { tabMeta } = buildTabMeta({
|
|
542953
|
+
tabId: tab.id,
|
|
542954
|
+
tabLabel: tab.label,
|
|
542955
|
+
activeModel: chat.activeModel,
|
|
542956
|
+
sessionId: sid,
|
|
542957
|
+
planMode: chat.planMode,
|
|
542958
|
+
planRequest: chat.planRequest,
|
|
542959
|
+
coAuthorCommits: chat.coAuthorCommits,
|
|
542960
|
+
forgeMode: chat.forgeMode,
|
|
542961
|
+
tokenUsage: chat.tokenUsage,
|
|
542962
|
+
messages: filtered,
|
|
542963
|
+
coreMessages: chat.coreMessages
|
|
542964
|
+
});
|
|
542965
|
+
await sessionManager.saveTab(sid, tabMeta, filtered, chat.coreMessages, {
|
|
542966
|
+
title: fallbackTitle,
|
|
542967
|
+
customTitle: activeChat.customTitle ?? null,
|
|
542413
542968
|
cwd: cwd2,
|
|
542414
|
-
|
|
542415
|
-
|
|
542416
|
-
currentTabCoreMessages: activeChat.coreMessages
|
|
542969
|
+
forgeMode: activeChat.forgeMode,
|
|
542970
|
+
activeTabId: activeTabId2
|
|
542417
542971
|
});
|
|
542418
|
-
updateEmergencySnapshot(sessionManager, meta4, tabMessages, tabCoreMessages);
|
|
542419
|
-
await sessionManager.saveSession(meta4, tabMessages, tabCoreMessages);
|
|
542420
|
-
} catch (err2) {
|
|
542421
|
-
logBackgroundError("new-session", `session save failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
542422
542972
|
}
|
|
542973
|
+
try {
|
|
542974
|
+
await sessionManager.pruneTabsNotIn(sid, liveIds);
|
|
542975
|
+
} catch {}
|
|
542976
|
+
} catch (err2) {
|
|
542977
|
+
logBackgroundError("new-session", `session save failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
542423
542978
|
}
|
|
542424
542979
|
}
|
|
542425
542980
|
const cpStore = useCheckpointStore.getState();
|
|
@@ -542863,7 +543418,18 @@ function App({
|
|
|
542863
543418
|
}, undefined, false, undefined, this),
|
|
542864
543419
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(LlmSelector, {
|
|
542865
543420
|
visible: modalLlmSelector,
|
|
542866
|
-
activeModel:
|
|
543421
|
+
activeModel: (() => {
|
|
543422
|
+
const slot = routerSlotPicking;
|
|
543423
|
+
const fb = useUIStore.getState().fallbackForModel;
|
|
543424
|
+
if (slot) {
|
|
543425
|
+
const v5 = effectiveConfig.taskRouter?.[slot];
|
|
543426
|
+
if (typeof v5 === "string" && v5.trim())
|
|
543427
|
+
return v5;
|
|
543428
|
+
}
|
|
543429
|
+
if (fb)
|
|
543430
|
+
return fb;
|
|
543431
|
+
return activeModelForHeader;
|
|
543432
|
+
})(),
|
|
542867
543433
|
onSelect: (modelId) => {
|
|
542868
543434
|
const slot = useUIStore.getState().routerSlotPicking;
|
|
542869
543435
|
const fallbackForModel = useUIStore.getState().fallbackForModel;
|
|
@@ -542913,13 +543479,61 @@ function App({
|
|
|
542913
543479
|
visible: modalSessionPicker,
|
|
542914
543480
|
cwd: cwd2,
|
|
542915
543481
|
onClose: getCloser2("sessionPicker"),
|
|
542916
|
-
onRestore: (sessionId) => {
|
|
543482
|
+
onRestore: async (sessionId) => {
|
|
543483
|
+
try {
|
|
543484
|
+
const prevSid = getAppSessionId();
|
|
543485
|
+
if (prevSid !== sessionId) {
|
|
543486
|
+
const liveTabs = tabMgrRef.current?.tabs ?? [];
|
|
543487
|
+
const activeTabId2 = tabMgrRef.current?.activeTabId ?? "";
|
|
543488
|
+
const activeChat = tabMgrRef.current?.getActiveChat();
|
|
543489
|
+
const fallbackTitle = activeChat?.customTitle ?? SessionManager.deriveTitle(activeChat?.messages ?? []);
|
|
543490
|
+
const liveIds = new Set(liveTabs.map((t3) => t3.id));
|
|
543491
|
+
let savedAny = false;
|
|
543492
|
+
for (const tab of liveTabs) {
|
|
543493
|
+
const chat = tabMgrRef.current?.getChat(tab.id);
|
|
543494
|
+
if (!chat)
|
|
543495
|
+
continue;
|
|
543496
|
+
const filtered = chat.messages.filter((m6) => m6.role !== "system" || m6.showInChat);
|
|
543497
|
+
const hasContent = filtered.some((m6) => m6.role === "user" || m6.role === "assistant");
|
|
543498
|
+
if (!hasContent)
|
|
543499
|
+
continue;
|
|
543500
|
+
savedAny = true;
|
|
543501
|
+
const { tabMeta } = buildTabMeta({
|
|
543502
|
+
tabId: tab.id,
|
|
543503
|
+
tabLabel: tab.label,
|
|
543504
|
+
activeModel: chat.activeModel,
|
|
543505
|
+
sessionId: prevSid,
|
|
543506
|
+
planMode: chat.planMode,
|
|
543507
|
+
planRequest: chat.planRequest,
|
|
543508
|
+
coAuthorCommits: chat.coAuthorCommits,
|
|
543509
|
+
forgeMode: chat.forgeMode,
|
|
543510
|
+
tokenUsage: chat.tokenUsage,
|
|
543511
|
+
messages: filtered,
|
|
543512
|
+
coreMessages: chat.coreMessages
|
|
543513
|
+
});
|
|
543514
|
+
await sessionManager.saveTab(prevSid, tabMeta, filtered, chat.coreMessages, {
|
|
543515
|
+
title: fallbackTitle,
|
|
543516
|
+
customTitle: activeChat?.customTitle ?? null,
|
|
543517
|
+
cwd: cwd2,
|
|
543518
|
+
forgeMode: activeChat?.forgeMode ?? "default",
|
|
543519
|
+
activeTabId: activeTabId2
|
|
543520
|
+
});
|
|
543521
|
+
}
|
|
543522
|
+
if (savedAny) {
|
|
543523
|
+
try {
|
|
543524
|
+
await sessionManager.pruneTabsNotIn(prevSid, liveIds);
|
|
543525
|
+
} catch {}
|
|
543526
|
+
}
|
|
543527
|
+
}
|
|
543528
|
+
} catch (err2) {
|
|
543529
|
+
logBackgroundError("session-switch", `pre-switch save failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
543530
|
+
}
|
|
542917
543531
|
const data = sessionManager.loadSession(sessionId);
|
|
542918
543532
|
if (data) {
|
|
543533
|
+
setAppSessionId(data.meta.id);
|
|
542919
543534
|
tabMgr.restoreFromMeta(data.meta.tabs, data.meta.activeTabId, data.tabMessages, data.tabCoreMessages);
|
|
542920
543535
|
setForgeModeHeader(data.meta.forgeMode);
|
|
542921
543536
|
setExitSessionId(data.meta.id);
|
|
542922
|
-
setAppSessionId(data.meta.id);
|
|
542923
543537
|
for (const tab of data.meta.tabs) {
|
|
542924
543538
|
if (tab.checkpointTags?.length) {
|
|
542925
543539
|
useCheckpointStore.getState().restoreTagsFromMeta(tab.id, tab.checkpointTags ?? []);
|