reasonix 0.40.0 → 0.41.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/README.md +21 -13
- package/README.zh-CN.md +19 -13
- package/dashboard/app.css +8 -4
- package/dashboard/dist/app.js +279 -224
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/acp-64VQZLDJ.js +708 -0
- package/dist/cli/acp-64VQZLDJ.js.map +1 -0
- package/dist/cli/chat-ZAGX52RV.js +46 -0
- package/dist/cli/{chunk-UCMTWZKU.js → chunk-2CXPDAWX.js} +2 -2
- package/dist/cli/{chunk-CLAN6PVH.js → chunk-4H3ZRJ2U.js} +19 -7
- package/dist/cli/chunk-4H3ZRJ2U.js.map +1 -0
- package/dist/cli/{chunk-A5LSGEEK.js → chunk-4W2CICFQ.js} +21 -10
- package/dist/cli/{chunk-A5LSGEEK.js.map → chunk-4W2CICFQ.js.map} +1 -1
- package/dist/cli/{chunk-CZSJILQP.js → chunk-65Q5HQ26.js} +39 -1
- package/dist/cli/chunk-65Q5HQ26.js.map +1 -0
- package/dist/cli/{chunk-XHQIK7B6.js → chunk-7SPOFTMT.js} +2 -2
- package/dist/cli/{chunk-5GKJLNP2.js → chunk-7VFNPMKG.js} +2 -2
- package/dist/cli/{chunk-UVRXTSK3.js → chunk-A3LL4XDV.js} +8 -2
- package/dist/cli/chunk-A3LL4XDV.js.map +1 -0
- package/dist/cli/{chunk-VLNRQMCI.js → chunk-A7VHMMDE.js} +2 -2
- package/dist/cli/{chunk-R4YTW7PR.js → chunk-ARF3N2SY.js} +56 -12
- package/dist/cli/chunk-ARF3N2SY.js.map +1 -0
- package/dist/cli/{chunk-AVB3WZWU.js → chunk-AT6GGIBV.js} +10 -10
- package/dist/cli/{chunk-RFX7TYVV.js → chunk-BOFL3T45.js} +14 -1
- package/dist/cli/chunk-BOFL3T45.js.map +1 -0
- package/dist/cli/{chunk-SZH34P45.js → chunk-BYZGO3BX.js} +43 -17
- package/dist/cli/chunk-BYZGO3BX.js.map +1 -0
- package/dist/cli/{chunk-7DLHHBGN.js → chunk-CD4SCQL4.js} +6 -4
- package/dist/cli/chunk-CD4SCQL4.js.map +1 -0
- package/dist/cli/{chunk-HCC42PEI.js → chunk-CFY2XLY6.js} +6 -2
- package/dist/cli/chunk-CFY2XLY6.js.map +1 -0
- package/dist/cli/{chunk-26UDIXLD.js → chunk-F2AV2QDK.js} +493 -460
- package/dist/cli/chunk-F2AV2QDK.js.map +1 -0
- package/dist/cli/{chunk-KMWKGPFZ.js → chunk-H4OLWRSX.js} +10 -1
- package/dist/cli/chunk-H4OLWRSX.js.map +1 -0
- package/dist/cli/{chunk-4YV2GBYG.js → chunk-IEA6JOIP.js} +291 -98
- package/dist/cli/chunk-IEA6JOIP.js.map +1 -0
- package/dist/cli/{chunk-WKOMCPXP.js → chunk-KZYLMMU5.js} +21 -13
- package/dist/cli/chunk-KZYLMMU5.js.map +1 -0
- package/dist/cli/{chunk-JWCTX5S4.js → chunk-L7W3HJZQ.js} +2 -2
- package/dist/cli/{chunk-MRLXEMZ7.js → chunk-LN27AKV3.js} +1 -1
- package/dist/cli/chunk-LN27AKV3.js.map +1 -0
- package/dist/cli/{chunk-IYF36OCJ.js → chunk-LTXADNCO.js} +2 -2
- package/dist/cli/{chunk-H7PHYVPM.js → chunk-MHGPBJ2T.js} +44 -8
- package/dist/cli/chunk-MHGPBJ2T.js.map +1 -0
- package/dist/cli/{chunk-ULBW7DYL.js → chunk-RAUPWSYA.js} +2 -2
- package/dist/cli/chunk-SXLJBFIV.js +245 -0
- package/dist/cli/chunk-SXLJBFIV.js.map +1 -0
- package/dist/cli/{chunk-4X3NY5ZM.js → chunk-UV7XJUJH.js} +2 -2
- package/dist/cli/{chunk-XJLZ4HKU.js → chunk-VFG4GIT3.js} +2 -2
- package/dist/cli/{chunk-FFNOMR32.js → chunk-WE3YZULK.js} +2 -2
- package/dist/cli/chunk-Y5XNV3NX.js +25 -0
- package/dist/cli/chunk-Y5XNV3NX.js.map +1 -0
- package/dist/cli/{chunk-XST7BSZJ.js → chunk-YJFKFTAL.js} +7 -1
- package/dist/cli/chunk-YJFKFTAL.js.map +1 -0
- package/dist/cli/{code-YQGVLIT2.js → code-X3M6ENTQ.js} +38 -35
- package/dist/cli/{code-YQGVLIT2.js.map → code-X3M6ENTQ.js.map} +1 -1
- package/dist/cli/{commands-FQZOBLLZ.js → commands-QY7MSQG7.js} +4 -4
- package/dist/cli/{commit-ZS24SHPG.js → commit-BRCQ3OQO.js} +3 -3
- package/dist/cli/{desktop-6OLENOOO.js → desktop-ZTMHQR2Y.js} +247 -28
- package/dist/cli/desktop-ZTMHQR2Y.js.map +1 -0
- package/dist/cli/{diff-2VUKNGEI.js → diff-YASCB7PU.js} +7 -7
- package/dist/cli/{doctor-JO2WNN6C.js → doctor-XCN5ETVP.js} +9 -9
- package/dist/cli/{events-APSVNROZ.js → events-2AJTXR7I.js} +3 -3
- package/dist/cli/index.js +69 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-DCKOE5RF.js → mcp-YMWBLRR7.js} +2 -2
- package/dist/cli/{mcp-browse-D6GBP5RQ.js → mcp-browse-XLDUE6SB.js} +7 -3
- package/dist/cli/mcp-browse-XLDUE6SB.js.map +1 -0
- package/dist/cli/{mcp-inspect-KFGFPJ3E.js → mcp-inspect-H4D2HSJP.js} +5 -7
- package/dist/cli/{mcp-inspect-KFGFPJ3E.js.map → mcp-inspect-H4D2HSJP.js.map} +1 -1
- package/dist/cli/{prompt-PKCCLLAD.js → prompt-RSIHN62V.js} +4 -3
- package/dist/cli/{prune-sessions-LV33R47N.js → prune-sessions-4N3BVST2.js} +2 -2
- package/dist/cli/{replay-WFCYX7XF.js → replay-3GTWM75X.js} +8 -8
- package/dist/cli/{run-IUJYEPMT.js → run-BLZPTRDX.js} +19 -21
- package/dist/cli/{run-IUJYEPMT.js.map → run-BLZPTRDX.js.map} +1 -1
- package/dist/cli/{server-CN4QPPVJ.js → server-DRFPXXSH.js} +16 -12
- package/dist/cli/{server-CN4QPPVJ.js.map → server-DRFPXXSH.js.map} +1 -1
- package/dist/cli/{sessions-F5GPGTJN.js → sessions-BOWFPTXT.js} +13 -13
- package/dist/cli/{setup-WWMDBPSB.js → setup-FQL2JJC2.js} +5 -5
- package/dist/cli/version-XQXYSJ5L.js +30 -0
- package/dist/index.d.ts +148 -103
- package/dist/index.js +468 -134
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/cli/chat-G7CUW4ZI.js +0 -45
- package/dist/cli/chunk-26UDIXLD.js.map +0 -1
- package/dist/cli/chunk-4YV2GBYG.js.map +0 -1
- package/dist/cli/chunk-7DLHHBGN.js.map +0 -1
- package/dist/cli/chunk-CLAN6PVH.js.map +0 -1
- package/dist/cli/chunk-CPTZ5OHX.js +0 -18
- package/dist/cli/chunk-CPTZ5OHX.js.map +0 -1
- package/dist/cli/chunk-CZSJILQP.js.map +0 -1
- package/dist/cli/chunk-H7PHYVPM.js.map +0 -1
- package/dist/cli/chunk-HCC42PEI.js.map +0 -1
- package/dist/cli/chunk-KMWKGPFZ.js.map +0 -1
- package/dist/cli/chunk-MRLXEMZ7.js.map +0 -1
- package/dist/cli/chunk-R4YTW7PR.js.map +0 -1
- package/dist/cli/chunk-RFX7TYVV.js.map +0 -1
- package/dist/cli/chunk-SZH34P45.js.map +0 -1
- package/dist/cli/chunk-UVRXTSK3.js.map +0 -1
- package/dist/cli/chunk-WKOMCPXP.js.map +0 -1
- package/dist/cli/chunk-XST7BSZJ.js.map +0 -1
- package/dist/cli/desktop-6OLENOOO.js.map +0 -1
- package/dist/cli/mcp-browse-D6GBP5RQ.js.map +0 -1
- package/dist/cli/version-KQUPV6T5.js +0 -30
- /package/dist/cli/{chat-G7CUW4ZI.js.map → chat-ZAGX52RV.js.map} +0 -0
- /package/dist/cli/{chunk-UCMTWZKU.js.map → chunk-2CXPDAWX.js.map} +0 -0
- /package/dist/cli/{chunk-XHQIK7B6.js.map → chunk-7SPOFTMT.js.map} +0 -0
- /package/dist/cli/{chunk-5GKJLNP2.js.map → chunk-7VFNPMKG.js.map} +0 -0
- /package/dist/cli/{chunk-VLNRQMCI.js.map → chunk-A7VHMMDE.js.map} +0 -0
- /package/dist/cli/{chunk-AVB3WZWU.js.map → chunk-AT6GGIBV.js.map} +0 -0
- /package/dist/cli/{chunk-JWCTX5S4.js.map → chunk-L7W3HJZQ.js.map} +0 -0
- /package/dist/cli/{chunk-IYF36OCJ.js.map → chunk-LTXADNCO.js.map} +0 -0
- /package/dist/cli/{chunk-ULBW7DYL.js.map → chunk-RAUPWSYA.js.map} +0 -0
- /package/dist/cli/{chunk-4X3NY5ZM.js.map → chunk-UV7XJUJH.js.map} +0 -0
- /package/dist/cli/{chunk-XJLZ4HKU.js.map → chunk-VFG4GIT3.js.map} +0 -0
- /package/dist/cli/{chunk-FFNOMR32.js.map → chunk-WE3YZULK.js.map} +0 -0
- /package/dist/cli/{commands-FQZOBLLZ.js.map → commands-QY7MSQG7.js.map} +0 -0
- /package/dist/cli/{commit-ZS24SHPG.js.map → commit-BRCQ3OQO.js.map} +0 -0
- /package/dist/cli/{diff-2VUKNGEI.js.map → diff-YASCB7PU.js.map} +0 -0
- /package/dist/cli/{doctor-JO2WNN6C.js.map → doctor-XCN5ETVP.js.map} +0 -0
- /package/dist/cli/{events-APSVNROZ.js.map → events-2AJTXR7I.js.map} +0 -0
- /package/dist/cli/{mcp-DCKOE5RF.js.map → mcp-YMWBLRR7.js.map} +0 -0
- /package/dist/cli/{prompt-PKCCLLAD.js.map → prompt-RSIHN62V.js.map} +0 -0
- /package/dist/cli/{prune-sessions-LV33R47N.js.map → prune-sessions-4N3BVST2.js.map} +0 -0
- /package/dist/cli/{replay-WFCYX7XF.js.map → replay-3GTWM75X.js.map} +0 -0
- /package/dist/cli/{sessions-F5GPGTJN.js.map → sessions-BOWFPTXT.js.map} +0 -0
- /package/dist/cli/{setup-WWMDBPSB.js.map → setup-FQL2JJC2.js.map} +0 -0
- /package/dist/cli/{version-KQUPV6T5.js.map → version-XQXYSJ5L.js.map} +0 -0
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
buildCodeToolset
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-AT6GGIBV.js";
|
|
5
|
+
import "./chunk-RAUPWSYA.js";
|
|
6
|
+
import {
|
|
7
|
+
createMcpRuntime
|
|
8
|
+
} from "./chunk-SXLJBFIV.js";
|
|
6
9
|
import {
|
|
7
10
|
Eventizer,
|
|
8
11
|
autoResolveVerdict
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-A7VHMMDE.js";
|
|
13
|
+
import "./chunk-LTXADNCO.js";
|
|
14
|
+
import "./chunk-BOFL3T45.js";
|
|
11
15
|
import {
|
|
12
16
|
CacheFirstLoop,
|
|
13
17
|
ImmutablePrefix,
|
|
@@ -15,31 +19,39 @@ import {
|
|
|
15
19
|
listFilesWithStatsAsync,
|
|
16
20
|
parseAtQuery,
|
|
17
21
|
rankPickerCandidates
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import
|
|
22
|
+
} from "./chunk-IEA6JOIP.js";
|
|
23
|
+
import "./chunk-VFG4GIT3.js";
|
|
24
|
+
import "./chunk-7SPOFTMT.js";
|
|
25
|
+
import {
|
|
26
|
+
parseMcpSpec
|
|
27
|
+
} from "./chunk-CFY2XLY6.js";
|
|
22
28
|
import {
|
|
29
|
+
MemoryStore,
|
|
23
30
|
codeSystemPrompt
|
|
24
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-ARF3N2SY.js";
|
|
25
32
|
import {
|
|
26
33
|
canonicalPresetName,
|
|
27
34
|
resolvePreset
|
|
28
35
|
} from "./chunk-E46ECXJD.js";
|
|
29
|
-
import "./chunk-DAEAAVDF.js";
|
|
30
36
|
import {
|
|
31
|
-
|
|
32
|
-
} from "./chunk-
|
|
37
|
+
countTokens
|
|
38
|
+
} from "./chunk-DAEAAVDF.js";
|
|
39
|
+
import {
|
|
40
|
+
DeepSeekClient,
|
|
41
|
+
pickPrimaryBalance
|
|
42
|
+
} from "./chunk-H4OLWRSX.js";
|
|
33
43
|
import {
|
|
34
44
|
loadDotenv
|
|
35
45
|
} from "./chunk-3Q3C4W66.js";
|
|
36
46
|
import {
|
|
37
47
|
pauseGate
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
import
|
|
48
|
+
} from "./chunk-BYZGO3BX.js";
|
|
49
|
+
import {
|
|
50
|
+
SkillStore
|
|
51
|
+
} from "./chunk-CD4SCQL4.js";
|
|
40
52
|
import "./chunk-FM57FNPJ.js";
|
|
41
|
-
import "./chunk-
|
|
42
|
-
import "./chunk-
|
|
53
|
+
import "./chunk-4H3ZRJ2U.js";
|
|
54
|
+
import "./chunk-WE3YZULK.js";
|
|
43
55
|
import "./chunk-5X7LZJDE.js";
|
|
44
56
|
import {
|
|
45
57
|
deleteSession,
|
|
@@ -48,8 +60,8 @@ import {
|
|
|
48
60
|
loadSessionMeta,
|
|
49
61
|
patchSessionMeta,
|
|
50
62
|
timestampSuffix
|
|
51
|
-
} from "./chunk-
|
|
52
|
-
import "./chunk-
|
|
63
|
+
} from "./chunk-YJFKFTAL.js";
|
|
64
|
+
import "./chunk-MHGPBJ2T.js";
|
|
53
65
|
import {
|
|
54
66
|
isPlausibleKey,
|
|
55
67
|
loadApiKey,
|
|
@@ -61,14 +73,16 @@ import {
|
|
|
61
73
|
loadRecentWorkspaces,
|
|
62
74
|
loadWorkspaceDir,
|
|
63
75
|
pushRecentWorkspace,
|
|
76
|
+
readConfig,
|
|
64
77
|
saveApiKey,
|
|
65
78
|
saveBaseUrl,
|
|
66
79
|
saveEditMode,
|
|
67
80
|
saveEditor,
|
|
68
81
|
savePreset,
|
|
69
82
|
saveReasoningEffort,
|
|
70
|
-
saveWorkspaceDir
|
|
71
|
-
|
|
83
|
+
saveWorkspaceDir,
|
|
84
|
+
writeConfig
|
|
85
|
+
} from "./chunk-65Q5HQ26.js";
|
|
72
86
|
import "./chunk-ZTLZO42A.js";
|
|
73
87
|
import "./chunk-ORM6PK57.js";
|
|
74
88
|
import {
|
|
@@ -158,8 +172,9 @@ function emitSettings(tab) {
|
|
|
158
172
|
async function emitBalance(tab) {
|
|
159
173
|
if (!tab.runtime) return;
|
|
160
174
|
const bal = await tab.runtime.loop.client.getBalance().catch(() => null);
|
|
161
|
-
if (!bal
|
|
162
|
-
const primary = bal.balance_infos
|
|
175
|
+
if (!bal) return;
|
|
176
|
+
const primary = pickPrimaryBalance(bal.balance_infos);
|
|
177
|
+
if (!primary) return;
|
|
163
178
|
emit(
|
|
164
179
|
{
|
|
165
180
|
type: "$balance",
|
|
@@ -175,13 +190,95 @@ function emitSessions(tab) {
|
|
|
175
190
|
const items = listSessionsForWorkspace(tab.rootDir).map((s) => ({
|
|
176
191
|
name: s.name,
|
|
177
192
|
messageCount: s.messageCount,
|
|
178
|
-
mtime: s.mtime.toISOString()
|
|
193
|
+
mtime: s.mtime.toISOString(),
|
|
194
|
+
summary: s.meta.summary
|
|
179
195
|
}));
|
|
180
196
|
emit({ type: "$sessions", items }, tab.id);
|
|
181
197
|
} catch (err) {
|
|
182
198
|
emit({ type: "$error", message: `session_list failed: ${err.message}` }, tab.id);
|
|
183
199
|
}
|
|
184
200
|
}
|
|
201
|
+
function summarizeMcpSpec(raw) {
|
|
202
|
+
try {
|
|
203
|
+
const parsed = parseMcpSpec(raw);
|
|
204
|
+
if (parsed.transport === "stdio") {
|
|
205
|
+
const argv = [parsed.command, ...parsed.args].join(" ");
|
|
206
|
+
return {
|
|
207
|
+
raw,
|
|
208
|
+
name: parsed.name,
|
|
209
|
+
transport: "stdio",
|
|
210
|
+
summary: `stdio \xB7 ${argv}`,
|
|
211
|
+
status: "configured"
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
raw,
|
|
216
|
+
name: parsed.name,
|
|
217
|
+
transport: parsed.transport,
|
|
218
|
+
summary: `${parsed.transport} \xB7 ${parsed.url}`,
|
|
219
|
+
status: "configured"
|
|
220
|
+
};
|
|
221
|
+
} catch (err) {
|
|
222
|
+
return {
|
|
223
|
+
raw,
|
|
224
|
+
name: null,
|
|
225
|
+
transport: "stdio",
|
|
226
|
+
summary: raw,
|
|
227
|
+
parseError: err.message,
|
|
228
|
+
status: "failed",
|
|
229
|
+
statusReason: err.message
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function emitMcpSpecs(tab) {
|
|
234
|
+
const cfg = readConfig();
|
|
235
|
+
const specs = (cfg.mcp ?? []).map((raw) => {
|
|
236
|
+
const base = summarizeMcpSpec(raw);
|
|
237
|
+
const live = tab.mcpStatuses.get(raw);
|
|
238
|
+
if (!live) return base;
|
|
239
|
+
return { ...base, status: live.kind, statusReason: live.reason, toolCount: live.toolCount };
|
|
240
|
+
});
|
|
241
|
+
const bridged = specs.length > 0 && specs.every((s) => s.status === "connected");
|
|
242
|
+
emit({ type: "$mcp_specs", specs, bridged }, tab.id);
|
|
243
|
+
}
|
|
244
|
+
function emitMemory(tab) {
|
|
245
|
+
try {
|
|
246
|
+
const store = new MemoryStore({ projectRoot: tab.rootDir });
|
|
247
|
+
const entries = store.list().map((e) => ({
|
|
248
|
+
name: e.name,
|
|
249
|
+
scope: e.scope,
|
|
250
|
+
description: e.description
|
|
251
|
+
}));
|
|
252
|
+
emit({ type: "$memory", entries }, tab.id);
|
|
253
|
+
} catch (err) {
|
|
254
|
+
emit({ type: "$error", message: `memory_get failed: ${err.message}` }, tab.id);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function emitCtxBreakdown(tab) {
|
|
258
|
+
if (!tab.runtime) return;
|
|
259
|
+
try {
|
|
260
|
+
const sys = countTokens(tab.runtime.loop.prefix.system);
|
|
261
|
+
const tools = countTokens(JSON.stringify(tab.runtime.loop.prefix.toolSpecs));
|
|
262
|
+
emit({ type: "$ctx_breakdown", reservedTokens: sys + tools }, tab.id);
|
|
263
|
+
} catch {
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function emitSkills(tab) {
|
|
267
|
+
try {
|
|
268
|
+
const store = new SkillStore({ projectRoot: tab.rootDir });
|
|
269
|
+
const items = store.list().map((s) => ({
|
|
270
|
+
name: s.name,
|
|
271
|
+
description: s.description,
|
|
272
|
+
scope: s.scope,
|
|
273
|
+
path: s.path,
|
|
274
|
+
runAs: s.runAs,
|
|
275
|
+
model: s.model
|
|
276
|
+
}));
|
|
277
|
+
emit({ type: "$skills", items }, tab.id);
|
|
278
|
+
} catch (err) {
|
|
279
|
+
emit({ type: "$error", message: `skills_get failed: ${err.message}` }, tab.id);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
185
282
|
var tabCounter = 0;
|
|
186
283
|
function nextTabId() {
|
|
187
284
|
tabCounter++;
|
|
@@ -198,15 +295,16 @@ function mintSessionFor(rootDir) {
|
|
|
198
295
|
function buildRuntimeFor(tab) {
|
|
199
296
|
const client = new DeepSeekClient({ baseUrl: loadBaseUrl() });
|
|
200
297
|
const prefix = new ImmutablePrefix({ system: tab.system, toolSpecs: tab.toolset.tools.specs() });
|
|
298
|
+
const reasoningEffort = loadReasoningEffort();
|
|
201
299
|
const loop = new CacheFirstLoop({
|
|
202
300
|
client,
|
|
203
301
|
prefix,
|
|
204
302
|
tools: tab.toolset.tools,
|
|
205
303
|
model: tab.currentModel,
|
|
206
304
|
budgetUsd: tab.budgetUsd,
|
|
207
|
-
session: tab.currentSession
|
|
305
|
+
session: tab.currentSession,
|
|
306
|
+
reasoningEffort
|
|
208
307
|
});
|
|
209
|
-
const reasoningEffort = loadReasoningEffort();
|
|
210
308
|
const eventizer = new Eventizer();
|
|
211
309
|
const ctx = { model: tab.currentModel, prefixHash: prefix.fingerprint, reasoningEffort };
|
|
212
310
|
return { loop, eventizer, ctx };
|
|
@@ -321,22 +419,73 @@ async function desktopCommand(opts) {
|
|
|
321
419
|
recentMentions: [],
|
|
322
420
|
pendingGateIds: /* @__PURE__ */ new Set(),
|
|
323
421
|
completedStepIds: /* @__PURE__ */ new Set(),
|
|
324
|
-
planTotalSteps: 0
|
|
422
|
+
planTotalSteps: 0,
|
|
423
|
+
mcpRuntime: null,
|
|
424
|
+
mcpStatuses: /* @__PURE__ */ new Map()
|
|
325
425
|
};
|
|
326
426
|
tab.currentSession = mintSessionFor(dir);
|
|
327
427
|
if (loadApiKey()) {
|
|
328
428
|
process.env.DEEPSEEK_API_KEY = loadApiKey();
|
|
329
429
|
tab.runtime = buildRuntimeFor(tab);
|
|
430
|
+
void bridgeTabMcp(tab);
|
|
330
431
|
}
|
|
331
432
|
tabs.set(tab.id, tab);
|
|
332
433
|
return tab;
|
|
333
434
|
}
|
|
435
|
+
function bridgeTabMcp(tab) {
|
|
436
|
+
if (!tab.runtime) return Promise.resolve();
|
|
437
|
+
if (tab.mcpRuntime) {
|
|
438
|
+
return tab.mcpRuntime.reloadFromConfig(tab.runtime.loop).then(() => emitMcpSpecs(tab)).catch((err) => {
|
|
439
|
+
emit({ type: "$error", message: `mcp reload failed: ${err.message}` }, tab.id);
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
const requested = (readConfig().mcp ?? []).length;
|
|
443
|
+
if (requested === 0) return Promise.resolve();
|
|
444
|
+
const runtime = createMcpRuntime({
|
|
445
|
+
getTools: () => tab.toolset.tools,
|
|
446
|
+
getMcpPrefix: () => void 0,
|
|
447
|
+
getRequestedCount: () => requested,
|
|
448
|
+
progressSink: { current: null }
|
|
449
|
+
});
|
|
450
|
+
tab.mcpRuntime = runtime;
|
|
451
|
+
runtime.setLifecycleSink((notice) => {
|
|
452
|
+
if (notice.kind === "slow") return;
|
|
453
|
+
const cfg = readConfig().mcp ?? [];
|
|
454
|
+
const target = cfg.find((raw) => {
|
|
455
|
+
try {
|
|
456
|
+
return parseMcpSpec(raw).name === notice.name;
|
|
457
|
+
} catch {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
if (!target) return;
|
|
462
|
+
if (notice.kind === "handshake") {
|
|
463
|
+
tab.mcpStatuses.set(target, { kind: "handshake" });
|
|
464
|
+
} else if (notice.kind === "connected") {
|
|
465
|
+
tab.mcpStatuses.set(target, { kind: "connected", toolCount: notice.tools });
|
|
466
|
+
} else if (notice.kind === "failed") {
|
|
467
|
+
tab.mcpStatuses.set(target, { kind: "failed", reason: notice.reason });
|
|
468
|
+
} else if (notice.kind === "disabled") {
|
|
469
|
+
tab.mcpStatuses.set(target, { kind: "disabled" });
|
|
470
|
+
}
|
|
471
|
+
emitMcpSpecs(tab);
|
|
472
|
+
});
|
|
473
|
+
return runtime.reloadFromConfig(tab.runtime.loop).then(() => void 0).catch((err) => {
|
|
474
|
+
emit({ type: "$error", message: `mcp bridge failed: ${err.message}` }, tab.id);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
334
477
|
async function closeTab(tab) {
|
|
335
478
|
tab.aborter?.abort();
|
|
336
479
|
try {
|
|
337
480
|
await tab.toolset.jobs.shutdown();
|
|
338
481
|
} catch {
|
|
339
482
|
}
|
|
483
|
+
if (tab.mcpRuntime) {
|
|
484
|
+
try {
|
|
485
|
+
await tab.mcpRuntime.closeAll();
|
|
486
|
+
} catch {
|
|
487
|
+
}
|
|
488
|
+
}
|
|
340
489
|
tabs.delete(tab.id);
|
|
341
490
|
emit({ type: "$tab_closed" }, tab.id);
|
|
342
491
|
}
|
|
@@ -344,6 +493,18 @@ async function desktopCommand(opts) {
|
|
|
344
493
|
if (!tab.runtime) return;
|
|
345
494
|
const rt = tab.runtime;
|
|
346
495
|
tab.aborter = new AbortController();
|
|
496
|
+
if (tab.currentSession) {
|
|
497
|
+
const existing = loadSessionMeta(tab.currentSession).summary;
|
|
498
|
+
if (!existing || !existing.trim()) {
|
|
499
|
+
const summary = text.replace(/\s+/g, " ").trim().slice(0, 60);
|
|
500
|
+
if (summary) {
|
|
501
|
+
try {
|
|
502
|
+
patchSessionMeta(tab.currentSession, { summary });
|
|
503
|
+
} catch {
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
347
508
|
await tabContext.run(tab.id, async () => {
|
|
348
509
|
try {
|
|
349
510
|
for await (const ev of rt.loop.step(text)) {
|
|
@@ -398,6 +559,7 @@ async function desktopCommand(opts) {
|
|
|
398
559
|
if (tab.runtime) tab.runtime = buildRuntimeFor(tab);
|
|
399
560
|
emitSessions(tab);
|
|
400
561
|
emitSettings(tab);
|
|
562
|
+
emitSkills(tab);
|
|
401
563
|
}
|
|
402
564
|
function forgetGate(id) {
|
|
403
565
|
for (const t of tabs.values()) {
|
|
@@ -532,6 +694,10 @@ async function desktopCommand(opts) {
|
|
|
532
694
|
else emit({ type: "$needs_setup", reason: "no_api_key" }, first.id);
|
|
533
695
|
emitSessions(first);
|
|
534
696
|
emitSettings(first);
|
|
697
|
+
emitMcpSpecs(first);
|
|
698
|
+
emitSkills(first);
|
|
699
|
+
emitMemory(first);
|
|
700
|
+
emitCtxBreakdown(first);
|
|
535
701
|
void emitBalance(first);
|
|
536
702
|
const rl = createInterface({ input: stdin });
|
|
537
703
|
rl.on("line", (line) => {
|
|
@@ -553,6 +719,10 @@ async function desktopCommand(opts) {
|
|
|
553
719
|
else emit({ type: "$needs_setup", reason: "no_api_key" }, tab2.id);
|
|
554
720
|
emitSessions(tab2);
|
|
555
721
|
emitSettings(tab2);
|
|
722
|
+
emitMcpSpecs(tab2);
|
|
723
|
+
emitSkills(tab2);
|
|
724
|
+
emitMemory(tab2);
|
|
725
|
+
emitCtxBreakdown(tab2);
|
|
556
726
|
void emitBalance(tab2);
|
|
557
727
|
} catch (err) {
|
|
558
728
|
emit({ type: "$error", message: `tab_open failed: ${err.message}` });
|
|
@@ -632,6 +802,56 @@ async function desktopCommand(opts) {
|
|
|
632
802
|
void closeTab(tab);
|
|
633
803
|
return;
|
|
634
804
|
}
|
|
805
|
+
if (msg.cmd === "mcp_specs_get") {
|
|
806
|
+
emitMcpSpecs(tab);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
if (msg.cmd === "mcp_specs_add") {
|
|
810
|
+
const spec = msg.spec.trim();
|
|
811
|
+
if (!spec) {
|
|
812
|
+
emit({ type: "$error", message: "mcp_specs_add: spec is empty" }, tab.id);
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
try {
|
|
816
|
+
parseMcpSpec(spec);
|
|
817
|
+
} catch (err) {
|
|
818
|
+
emit({ type: "$error", message: `mcp_specs_add: ${err.message}` }, tab.id);
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
try {
|
|
822
|
+
const cfg = readConfig();
|
|
823
|
+
const list = cfg.mcp ?? [];
|
|
824
|
+
if (!list.includes(spec)) {
|
|
825
|
+
cfg.mcp = [...list, spec];
|
|
826
|
+
writeConfig(cfg);
|
|
827
|
+
}
|
|
828
|
+
emitMcpSpecs(tab);
|
|
829
|
+
void bridgeTabMcp(tab);
|
|
830
|
+
} catch (err) {
|
|
831
|
+
emit({ type: "$error", message: `mcp_specs_add: ${err.message}` }, tab.id);
|
|
832
|
+
}
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
if (msg.cmd === "mcp_specs_remove") {
|
|
836
|
+
try {
|
|
837
|
+
const cfg = readConfig();
|
|
838
|
+
const list = cfg.mcp ?? [];
|
|
839
|
+
if (list.includes(msg.spec)) {
|
|
840
|
+
cfg.mcp = list.filter((s) => s !== msg.spec);
|
|
841
|
+
writeConfig(cfg);
|
|
842
|
+
}
|
|
843
|
+
tab.mcpStatuses.delete(msg.spec);
|
|
844
|
+
emitMcpSpecs(tab);
|
|
845
|
+
void bridgeTabMcp(tab);
|
|
846
|
+
} catch (err) {
|
|
847
|
+
emit({ type: "$error", message: `mcp_specs_remove: ${err.message}` }, tab.id);
|
|
848
|
+
}
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
if (msg.cmd === "skills_get") {
|
|
852
|
+
emitSkills(tab);
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
635
855
|
if (msg.cmd === "session_list") {
|
|
636
856
|
emitSessions(tab);
|
|
637
857
|
return;
|
|
@@ -701,7 +921,6 @@ async function desktopCommand(opts) {
|
|
|
701
921
|
const resolved = resolvePreset(tab.currentPreset);
|
|
702
922
|
tab.currentModel = resolved.model;
|
|
703
923
|
savePreset(tab.currentPreset);
|
|
704
|
-
saveReasoningEffort(resolved.reasoningEffort);
|
|
705
924
|
tab.system = codeSystemPrompt(tab.rootDir, {
|
|
706
925
|
hasSemanticSearch: tab.toolset.semantic.enabled,
|
|
707
926
|
modelId: tab.currentModel
|
|
@@ -804,4 +1023,4 @@ async function desktopCommand(opts) {
|
|
|
804
1023
|
export {
|
|
805
1024
|
desktopCommand
|
|
806
1025
|
};
|
|
807
|
-
//# sourceMappingURL=desktop-
|
|
1026
|
+
//# sourceMappingURL=desktop-ZTMHQR2Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/desktop.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { existsSync, statSync, writeSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { stdin } from \"node:process\";\nimport { createInterface } from \"node:readline\";\nimport {\n type FileWithStats,\n listDirectory,\n listFilesWithStatsAsync,\n parseAtQuery,\n rankPickerCandidates,\n} from \"../../at-mentions.js\";\nimport { pickPrimaryBalance } from \"../../client.js\";\nimport { codeSystemPrompt } from \"../../code/prompt.js\";\nimport { buildCodeToolset } from \"../../code/setup.js\";\nimport {\n type EditMode,\n isPlausibleKey,\n loadApiKey,\n loadBaseUrl,\n loadEditMode,\n loadEditor,\n loadPreset,\n loadReasoningEffort,\n loadRecentWorkspaces,\n loadWorkspaceDir,\n pushRecentWorkspace,\n readConfig,\n saveApiKey,\n saveBaseUrl,\n saveEditMode,\n saveEditor,\n savePreset,\n saveReasoningEffort,\n saveWorkspaceDir,\n writeConfig,\n} from \"../../config.js\";\nimport { Eventizer } from \"../../core/eventize.js\";\nimport type { Event as KernelEvent } from \"../../core/events.js\";\nimport {\n type CheckpointVerdict,\n type ChoiceVerdict,\n type ConfirmationChoice,\n type PlanVerdict,\n type RevisionVerdict,\n pauseGate,\n} from \"../../core/pause-gate.js\";\nimport { autoResolveVerdict } from \"../../core/pause-policy.js\";\nimport { loadDotenv } from \"../../env.js\";\nimport { CacheFirstLoop, DeepSeekClient, ImmutablePrefix } from \"../../index.js\";\nimport { parseMcpSpec } from \"../../mcp/spec.js\";\nimport {\n deleteSession,\n listSessionsForWorkspace,\n loadSessionMessages,\n loadSessionMeta,\n patchSessionMeta,\n timestampSuffix,\n} from \"../../memory/session.js\";\nimport { MemoryStore } from \"../../memory/user.js\";\nimport { SkillStore } from \"../../skills.js\";\nimport { countTokens } from \"../../tokenizer.js\";\nimport type { ChoiceOption } from \"../../tools/choice.js\";\nimport type { ChatMessage } from \"../../types.js\";\nimport { VERSION } from \"../../version.js\";\nimport { canonicalPresetName, resolvePreset } from \"../ui/presets.js\";\nimport { type McpRuntime, createMcpRuntime } from \"./mcp-runtime.js\";\n\nexport interface DesktopOptions {\n model: string;\n budgetUsd?: number;\n /** Root directory the agent's filesystem tools operate inside. Defaults to cwd. */\n dir?: string;\n}\n\ntype InMessage = { tabId?: string } & (\n | { cmd: \"user_input\"; text: string }\n | { cmd: \"abort\" }\n | { cmd: \"confirm_response\"; id: number; response: ConfirmationChoice }\n | { cmd: \"choice_response\"; id: number; response: ChoiceVerdict }\n | { cmd: \"plan_response\"; id: number; response: PlanVerdict }\n | { cmd: \"checkpoint_response\"; id: number; response: CheckpointVerdict }\n | { cmd: \"revision_response\"; id: number; response: RevisionVerdict }\n | { cmd: \"session_list\" }\n | { cmd: \"session_delete\"; name: string }\n | { cmd: \"session_load\"; name: string }\n | { cmd: \"new_chat\" }\n | { cmd: \"setup_save_key\"; key: string }\n | { cmd: \"settings_get\" }\n | {\n cmd: \"settings_save\";\n reasoningEffort?: \"high\" | \"max\";\n editMode?: EditMode;\n budgetUsd?: number | null;\n baseUrl?: string;\n workspaceDir?: string;\n preset?: \"auto\" | \"flash\" | \"pro\";\n editor?: string;\n }\n | { cmd: \"mention_query\"; query: string; nonce: number }\n | { cmd: \"mention_preview\"; path: string; nonce: number }\n | { cmd: \"mention_picked\"; path: string }\n | { cmd: \"tab_open\"; workspaceDir?: string }\n | { cmd: \"tab_close\" }\n | { cmd: \"mcp_specs_get\" }\n | { cmd: \"mcp_specs_add\"; spec: string }\n | { cmd: \"mcp_specs_remove\"; spec: string }\n | { cmd: \"skills_get\" }\n);\n\ninterface NeedsSetupEvent {\n type: \"$needs_setup\";\n reason: \"no_api_key\";\n}\n\ninterface SettingsEvent {\n type: \"$settings\";\n reasoningEffort: \"high\" | \"max\";\n editMode: EditMode;\n budgetUsd: number | null;\n baseUrl?: string;\n apiKeyPrefix?: string;\n workspaceDir: string;\n recentWorkspaces: string[];\n model: string;\n preset: \"auto\" | \"flash\" | \"pro\";\n editor?: string;\n version: string;\n}\n\ninterface BalanceEvent {\n type: \"$balance\";\n currency: string;\n total: number;\n isAvailable: boolean;\n}\n\ninterface PlanRequiredEvent {\n type: \"$plan_required\";\n id: number;\n plan: string;\n steps?: unknown[];\n summary?: string;\n}\n\ninterface SessionsEvent {\n type: \"$sessions\";\n items: { name: string; messageCount: number; mtime: string }[];\n}\n\ninterface MentionResultsEvent {\n type: \"$mention_results\";\n nonce: number;\n query: string;\n results: string[];\n}\n\ninterface MentionPreviewEvent {\n type: \"$mention_preview\";\n nonce: number;\n path: string;\n head: string;\n totalLines: number;\n}\n\ninterface TabOpenedEvent {\n type: \"$tab_opened\";\n workspaceDir: string;\n}\n\ninterface TabClosedEvent {\n type: \"$tab_closed\";\n}\n\ntype LoadedSegment =\n | { kind: \"text\"; text: string }\n | { kind: \"reasoning\"; text: string }\n | {\n kind: \"tool\";\n callId: string;\n name: string;\n args: string;\n result?: string;\n ok?: boolean;\n };\n\ntype LoadedMessage =\n | { kind: \"user\"; text: string }\n | {\n kind: \"assistant\";\n turn: number;\n segments: LoadedSegment[];\n pending: false;\n };\n\ninterface SessionLoadedEvent {\n type: \"$session_loaded\";\n name: string;\n messages: LoadedMessage[];\n carryover: {\n totalCostUsd: number;\n cacheHitTokens: number;\n cacheMissTokens: number;\n };\n}\n\ninterface ConfirmRequiredEvent {\n type: \"$confirm_required\";\n id: number;\n kind: \"run_command\" | \"run_background\";\n command: string;\n}\n\ninterface ChoiceRequiredEvent {\n type: \"$choice_required\";\n id: number;\n question: string;\n options: ChoiceOption[];\n allowCustom: boolean;\n}\n\ninterface PlanStepLite {\n id: string;\n title: string;\n action: string;\n risk?: \"low\" | \"med\" | \"high\";\n}\n\ninterface CheckpointRequiredEvent {\n type: \"$checkpoint_required\";\n id: number;\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n completed: number;\n total: number;\n}\n\ninterface RevisionRequiredEvent {\n type: \"$revision_required\";\n id: number;\n reason: string;\n remainingSteps: PlanStepLite[];\n summary?: string;\n}\n\ninterface StepCompletedEvent {\n type: \"$step_completed\";\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n}\n\ninterface PlanClearedEvent {\n type: \"$plan_cleared\";\n}\n\ntype McpSpecStatus = \"configured\" | \"handshake\" | \"connected\" | \"failed\" | \"disabled\";\n\ninterface McpSpecInfo {\n raw: string;\n name: string | null;\n transport: \"stdio\" | \"sse\" | \"streamable-http\";\n summary: string;\n parseError?: string;\n status: McpSpecStatus;\n statusReason?: string;\n toolCount?: number;\n}\n\ninterface McpSpecsEvent {\n type: \"$mcp_specs\";\n specs: McpSpecInfo[];\n bridged: boolean;\n}\n\ninterface CtxBreakdownEvent {\n type: \"$ctx_breakdown\";\n reservedTokens: number;\n}\n\ninterface MemoryEntryInfo {\n name: string;\n scope: \"project\" | \"global\";\n description: string;\n}\n\ninterface MemoryEvent {\n type: \"$memory\";\n entries: MemoryEntryInfo[];\n}\n\ninterface SkillInfo {\n name: string;\n description: string;\n scope: \"project\" | \"global\" | \"builtin\";\n path: string;\n runAs: \"inline\" | \"subagent\";\n model?: string;\n}\n\ninterface SkillsEvent {\n type: \"$skills\";\n items: SkillInfo[];\n}\n\n/** Direct fd write — bypasses Node's stream layer (and its piped-output\n * block buffering) so every JSON line reaches Rust the moment it's\n * produced, not whenever the next 8 KB flushes. */\ntype EmittableEvent =\n | KernelEvent\n | { type: \"$ready\" }\n | { type: \"$error\"; message: string }\n | { type: \"$turn_complete\" }\n | ConfirmRequiredEvent\n | ChoiceRequiredEvent\n | PlanRequiredEvent\n | CheckpointRequiredEvent\n | RevisionRequiredEvent\n | StepCompletedEvent\n | PlanClearedEvent\n | SessionsEvent\n | SessionLoadedEvent\n | NeedsSetupEvent\n | SettingsEvent\n | BalanceEvent\n | MentionResultsEvent\n | MentionPreviewEvent\n | TabOpenedEvent\n | TabClosedEvent\n | McpSpecsEvent\n | SkillsEvent\n | CtxBreakdownEvent\n | MemoryEvent;\n\nfunction emit(ev: EmittableEvent, tabId?: string): void {\n const payload = tabId ? { ...ev, tabId } : ev;\n writeSync(1, Buffer.from(`${JSON.stringify(payload)}\\n`, \"utf8\"));\n}\n\nfunction buildLoadedMessages(records: ChatMessage[]): LoadedMessage[] {\n const out: LoadedMessage[] = [];\n let turn = 0;\n let pendingAssistantIdx = -1;\n for (const rec of records) {\n if (rec.role === \"system\") continue;\n if (rec.role === \"user\") {\n out.push({ kind: \"user\", text: rec.content ?? \"\" });\n pendingAssistantIdx = -1;\n continue;\n }\n if (rec.role === \"assistant\") {\n turn++;\n const segments: LoadedSegment[] = [];\n if (rec.reasoning_content) segments.push({ kind: \"reasoning\", text: rec.reasoning_content });\n if (rec.content) segments.push({ kind: \"text\", text: rec.content });\n if (rec.tool_calls) {\n for (let i = 0; i < rec.tool_calls.length; i++) {\n const tc = rec.tool_calls[i];\n if (!tc) continue;\n segments.push({\n kind: \"tool\",\n callId: tc.id ?? `tc-r-${turn}-${i}`,\n name: tc.function?.name ?? \"\",\n args: tc.function?.arguments ?? \"\",\n });\n }\n }\n out.push({ kind: \"assistant\", turn, segments, pending: false });\n pendingAssistantIdx = out.length - 1;\n continue;\n }\n if (rec.role === \"tool\") {\n if (pendingAssistantIdx < 0) continue;\n const host = out[pendingAssistantIdx];\n if (host?.kind !== \"assistant\") continue;\n const callId = rec.tool_call_id;\n if (!callId) continue;\n const seg = host.segments.find((s) => s.kind === \"tool\" && s.callId === callId);\n if (seg && seg.kind === \"tool\") {\n seg.result = rec.content ?? \"\";\n seg.ok = !/error|failed/i.test(seg.result.slice(0, 200));\n }\n }\n }\n return out;\n}\n\nfunction emitSettings(tab: Tab): void {\n const apiKey = loadApiKey();\n const recent = loadRecentWorkspaces().filter((p) => p !== tab.rootDir);\n emit(\n {\n type: \"$settings\",\n reasoningEffort: loadReasoningEffort(),\n editMode: loadEditMode(),\n budgetUsd: tab.runtime?.loop.budgetUsd ?? null,\n baseUrl: loadBaseUrl(),\n apiKeyPrefix: apiKey ? `${apiKey.slice(0, 6)}…${apiKey.slice(-3)}` : undefined,\n workspaceDir: tab.rootDir,\n recentWorkspaces: recent,\n model: tab.currentModel,\n preset: tab.currentPreset,\n editor: loadEditor(),\n version: VERSION,\n },\n tab.id,\n );\n}\n\nasync function emitBalance(tab: Tab): Promise<void> {\n if (!tab.runtime) return;\n const bal = await tab.runtime.loop.client.getBalance().catch(() => null);\n if (!bal) return;\n const primary = pickPrimaryBalance(bal.balance_infos);\n if (!primary) return;\n emit(\n {\n type: \"$balance\",\n currency: primary.currency,\n total: Number(primary.total_balance),\n isAvailable: bal.is_available,\n },\n tab.id,\n );\n}\n\nfunction emitSessions(tab: Tab): void {\n try {\n const items = listSessionsForWorkspace(tab.rootDir).map((s) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: s.mtime.toISOString(),\n summary: s.meta.summary,\n }));\n emit({ type: \"$sessions\", items }, tab.id);\n } catch (err) {\n emit({ type: \"$error\", message: `session_list failed: ${(err as Error).message}` }, tab.id);\n }\n}\n\nfunction summarizeMcpSpec(raw: string): McpSpecInfo {\n try {\n const parsed = parseMcpSpec(raw);\n if (parsed.transport === \"stdio\") {\n const argv = [parsed.command, ...parsed.args].join(\" \");\n return {\n raw,\n name: parsed.name,\n transport: \"stdio\",\n summary: `stdio · ${argv}`,\n status: \"configured\",\n };\n }\n return {\n raw,\n name: parsed.name,\n transport: parsed.transport,\n summary: `${parsed.transport} · ${parsed.url}`,\n status: \"configured\",\n };\n } catch (err) {\n return {\n raw,\n name: null,\n transport: \"stdio\",\n summary: raw,\n parseError: (err as Error).message,\n status: \"failed\",\n statusReason: (err as Error).message,\n };\n }\n}\n\nfunction emitMcpSpecs(tab: Tab): void {\n const cfg = readConfig();\n const specs = (cfg.mcp ?? []).map((raw) => {\n const base = summarizeMcpSpec(raw);\n const live = tab.mcpStatuses.get(raw);\n if (!live) return base;\n return { ...base, status: live.kind, statusReason: live.reason, toolCount: live.toolCount };\n });\n const bridged = specs.length > 0 && specs.every((s) => s.status === \"connected\");\n emit({ type: \"$mcp_specs\", specs, bridged }, tab.id);\n}\n\nfunction emitMemory(tab: Tab): void {\n try {\n const store = new MemoryStore({ projectRoot: tab.rootDir });\n const entries: MemoryEntryInfo[] = store.list().map((e) => ({\n name: e.name,\n scope: e.scope,\n description: e.description,\n }));\n emit({ type: \"$memory\", entries }, tab.id);\n } catch (err) {\n emit({ type: \"$error\", message: `memory_get failed: ${(err as Error).message}` }, tab.id);\n }\n}\n\n// reserved = system prompt + tool specs, constant for the tab's lifetime once\n// the loop is built. The growing log portion is already covered by the\n// per-turn cache hit/miss numbers in `model.final`.\nfunction emitCtxBreakdown(tab: Tab): void {\n if (!tab.runtime) return;\n try {\n const sys = countTokens(tab.runtime.loop.prefix.system);\n const tools = countTokens(JSON.stringify(tab.runtime.loop.prefix.toolSpecs));\n emit({ type: \"$ctx_breakdown\", reservedTokens: sys + tools }, tab.id);\n } catch {\n // tokenizer warmup can throw on first call before the data file loads\n }\n}\n\nfunction emitSkills(tab: Tab): void {\n try {\n const store = new SkillStore({ projectRoot: tab.rootDir });\n const items = store.list().map((s) => ({\n name: s.name,\n description: s.description,\n scope: s.scope,\n path: s.path,\n runAs: s.runAs,\n model: s.model,\n }));\n emit({ type: \"$skills\", items }, tab.id);\n } catch (err) {\n emit({ type: \"$error\", message: `skills_get failed: ${(err as Error).message}` }, tab.id);\n }\n}\n\ninterface RuntimeState {\n loop: CacheFirstLoop;\n eventizer: Eventizer;\n ctx: { model: string; prefixHash: string; reasoningEffort: \"high\" | \"max\" };\n}\n\ntype SymbolEntry = { name: string; path: string; line: number; kind: string };\n\ninterface Tab {\n readonly id: string;\n rootDir: string;\n currentSession: string;\n currentPreset: \"auto\" | \"flash\" | \"pro\";\n currentModel: string;\n budgetUsd: number | undefined;\n toolset: Awaited<ReturnType<typeof buildCodeToolset>>;\n system: string;\n runtime: RuntimeState | null;\n aborter: AbortController | null;\n fileIndex: FileWithStats[] | null;\n fileIndexBuilding: Promise<FileWithStats[]> | null;\n symbolIndex: SymbolEntry[] | null;\n symbolBuilding: Promise<SymbolEntry[]> | null;\n recentMentions: string[];\n /** Pause-gate ids waiting on this tab — abort uses these to free stranded plan_checkpoint / plan_revision / shell-confirm callers. */\n pendingGateIds: Set<number>;\n /** Step ids already marked complete in the in-flight plan — also tells UI when a plan is \"active\". */\n completedStepIds: Set<string>;\n /** Total steps in the in-flight plan (0 = no active plan / steps not provided). */\n planTotalSteps: number;\n mcpRuntime: McpRuntime | null;\n mcpStatuses: Map<string, { kind: McpSpecStatus; reason?: string; toolCount?: number }>;\n}\n\nlet tabCounter = 0;\nfunction nextTabId(): string {\n tabCounter++;\n return `t${tabCounter}`;\n}\n\nfunction mintSessionFor(rootDir: string): string {\n const name = `desktop-${timestampSuffix()}-${tabCounter}`;\n try {\n patchSessionMeta(name, { workspace: rootDir });\n } catch {\n // session meta is for filtering only — failure shouldn't block chat\n }\n return name;\n}\n\nfunction buildRuntimeFor(tab: Tab): RuntimeState {\n const client = new DeepSeekClient({ baseUrl: loadBaseUrl() });\n const prefix = new ImmutablePrefix({ system: tab.system, toolSpecs: tab.toolset.tools.specs() });\n const reasoningEffort = loadReasoningEffort();\n const loop = new CacheFirstLoop({\n client,\n prefix,\n tools: tab.toolset.tools,\n model: tab.currentModel,\n budgetUsd: tab.budgetUsd,\n session: tab.currentSession,\n reasoningEffort,\n });\n const eventizer = new Eventizer();\n const ctx = { model: tab.currentModel, prefixHash: prefix.fingerprint, reasoningEffort };\n return { loop, eventizer, ctx };\n}\n\nconst TS_EXPORT_RE =\n /^export\\s+(?:default\\s+)?(?:async\\s+)?(function|class|const|let|var|interface|type|enum)\\s+\\*?\\s*(\\w+)/;\n\nasync function getFileIndexFor(tab: Tab): Promise<FileWithStats[]> {\n if (tab.fileIndex) return tab.fileIndex;\n if (tab.fileIndexBuilding) return tab.fileIndexBuilding;\n tab.fileIndexBuilding = listFilesWithStatsAsync(tab.rootDir, { maxResults: 5000 })\n .then((res) => {\n tab.fileIndex = res;\n tab.fileIndexBuilding = null;\n return res;\n })\n .catch((err) => {\n tab.fileIndexBuilding = null;\n throw err;\n });\n return tab.fileIndexBuilding;\n}\n\nasync function getSymbolIndexFor(tab: Tab): Promise<SymbolEntry[]> {\n if (tab.symbolIndex) return tab.symbolIndex;\n if (tab.symbolBuilding) return tab.symbolBuilding;\n tab.symbolBuilding = (async () => {\n const files = await getFileIndexFor(tab);\n const sourceExts = /\\.(?:ts|tsx|js|jsx|mts|cts)$/;\n const candidates = files.filter((f) => sourceExts.test(f.path)).slice(0, 1500);\n const out: SymbolEntry[] = [];\n const PARALLEL = 16;\n for (let i = 0; i < candidates.length; i += PARALLEL) {\n const batch = candidates.slice(i, i + PARALLEL);\n await Promise.all(\n batch.map(async (entry) => {\n const abs = isAbsolute(entry.path) ? entry.path : join(tab.rootDir, entry.path);\n try {\n const text = await readFile(abs, \"utf8\");\n const lines = text.split(/\\r?\\n/);\n for (let li = 0; li < lines.length; li++) {\n const line = lines[li]!;\n if (!line.startsWith(\"export \")) continue;\n const m = TS_EXPORT_RE.exec(line);\n if (m) out.push({ kind: m[1]!, name: m[2]!, path: entry.path, line: li + 1 });\n }\n } catch {\n // unreadable / binary — skip\n }\n }),\n );\n }\n tab.symbolIndex = out;\n tab.symbolBuilding = null;\n return out;\n })().catch((err) => {\n tab.symbolBuilding = null;\n throw err;\n });\n return tab.symbolBuilding;\n}\n\nfunction rankSymbols(syms: readonly SymbolEntry[], q: string, limit: number): string[] {\n const needle = q.toLowerCase();\n const scored: { entry: SymbolEntry; score: number }[] = [];\n for (const s of syms) {\n const lower = s.name.toLowerCase();\n let score: number;\n if (lower === needle) score = 0;\n else if (lower.startsWith(needle)) score = 100;\n else if (lower.includes(needle)) score = 500 + lower.indexOf(needle);\n else continue;\n scored.push({ entry: s, score });\n }\n scored.sort((a, b) => a.score - b.score || a.entry.name.localeCompare(b.entry.name));\n return scored.slice(0, limit).map((s) => `${s.entry.path}:${s.entry.line}`);\n}\n\nfunction pushMentionRecent(tab: Tab, path: string): void {\n const MAX = 20;\n const idx = tab.recentMentions.indexOf(path);\n if (idx >= 0) tab.recentMentions.splice(idx, 1);\n tab.recentMentions.unshift(path);\n if (tab.recentMentions.length > MAX) tab.recentMentions.length = MAX;\n}\n\nexport async function desktopCommand(opts: DesktopOptions): Promise<void> {\n loadDotenv();\n\n const tabs = new Map<string, Tab>();\n const tabContext = new AsyncLocalStorage<string>();\n\n function activeRunningTab(): Tab | undefined {\n const id = tabContext.getStore();\n return id ? tabs.get(id) : undefined;\n }\n\n async function createTab(initialDir?: string): Promise<Tab> {\n const dir = resolve(initialDir ?? opts.dir ?? loadWorkspaceDir() ?? process.cwd());\n pushRecentWorkspace(dir);\n const preset = canonicalPresetName(loadPreset());\n const resolved = resolvePreset(preset);\n const model = opts.model || resolved.model;\n const toolset = await buildCodeToolset({ rootDir: dir });\n const system = codeSystemPrompt(dir, {\n hasSemanticSearch: toolset.semantic.enabled,\n modelId: model,\n });\n const tab: Tab = {\n id: nextTabId(),\n rootDir: dir,\n currentSession: \"\",\n currentPreset: preset,\n currentModel: model,\n budgetUsd: opts.budgetUsd,\n toolset,\n system,\n runtime: null,\n aborter: null,\n fileIndex: null,\n fileIndexBuilding: null,\n symbolIndex: null,\n symbolBuilding: null,\n recentMentions: [],\n pendingGateIds: new Set<number>(),\n completedStepIds: new Set<string>(),\n planTotalSteps: 0,\n mcpRuntime: null,\n mcpStatuses: new Map(),\n };\n tab.currentSession = mintSessionFor(dir);\n if (loadApiKey()) {\n process.env.DEEPSEEK_API_KEY = loadApiKey();\n tab.runtime = buildRuntimeFor(tab);\n void bridgeTabMcp(tab);\n }\n tabs.set(tab.id, tab);\n return tab;\n }\n\n function bridgeTabMcp(tab: Tab): Promise<void> {\n if (!tab.runtime) return Promise.resolve();\n if (tab.mcpRuntime) {\n // Already constructed — reload so new/removed specs settle without restart.\n return tab.mcpRuntime\n .reloadFromConfig(tab.runtime.loop)\n .then(() => emitMcpSpecs(tab))\n .catch((err) => {\n emit({ type: \"$error\", message: `mcp reload failed: ${(err as Error).message}` }, tab.id);\n });\n }\n const requested = (readConfig().mcp ?? []).length;\n if (requested === 0) return Promise.resolve();\n const runtime = createMcpRuntime({\n getTools: () => tab.toolset.tools,\n getMcpPrefix: () => undefined,\n getRequestedCount: () => requested,\n progressSink: { current: null },\n });\n tab.mcpRuntime = runtime;\n runtime.setLifecycleSink((notice) => {\n if (notice.kind === \"slow\") return; // not surfaced in the desktop panel\n const cfg = readConfig().mcp ?? [];\n const target = cfg.find((raw) => {\n try {\n return parseMcpSpec(raw).name === notice.name;\n } catch {\n return false;\n }\n });\n if (!target) return;\n if (notice.kind === \"handshake\") {\n tab.mcpStatuses.set(target, { kind: \"handshake\" });\n } else if (notice.kind === \"connected\") {\n tab.mcpStatuses.set(target, { kind: \"connected\", toolCount: notice.tools });\n } else if (notice.kind === \"failed\") {\n tab.mcpStatuses.set(target, { kind: \"failed\", reason: notice.reason });\n } else if (notice.kind === \"disabled\") {\n tab.mcpStatuses.set(target, { kind: \"disabled\" });\n }\n emitMcpSpecs(tab);\n });\n return runtime\n .reloadFromConfig(tab.runtime.loop)\n .then(() => undefined)\n .catch((err) => {\n emit({ type: \"$error\", message: `mcp bridge failed: ${(err as Error).message}` }, tab.id);\n });\n }\n\n async function closeTab(tab: Tab): Promise<void> {\n tab.aborter?.abort();\n try {\n await tab.toolset.jobs.shutdown();\n } catch {\n // shutdown errors aren't actionable here\n }\n if (tab.mcpRuntime) {\n try {\n await tab.mcpRuntime.closeAll();\n } catch {\n // MCP shutdown errors aren't actionable here either\n }\n }\n tabs.delete(tab.id);\n emit({ type: \"$tab_closed\" }, tab.id);\n }\n\n async function runTurn(tab: Tab, text: string): Promise<void> {\n if (!tab.runtime) return;\n const rt = tab.runtime;\n tab.aborter = new AbortController();\n if (tab.currentSession) {\n const existing = loadSessionMeta(tab.currentSession).summary;\n if (!existing || !existing.trim()) {\n const summary = text.replace(/\\s+/g, \" \").trim().slice(0, 60);\n if (summary) {\n try {\n patchSessionMeta(tab.currentSession, { summary });\n } catch {\n // meta is for display only — failure shouldn't block the turn\n }\n }\n }\n }\n await tabContext.run(tab.id, async () => {\n try {\n for await (const ev of rt.loop.step(text)) {\n for (const kev of rt.eventizer.consume(ev, rt.ctx)) emit(kev, tab.id);\n if (tab.aborter?.signal.aborted) break;\n }\n } catch (err) {\n emit({ type: \"$error\", message: (err as Error).message }, tab.id);\n } finally {\n tab.aborter = null;\n emit({ type: \"$turn_complete\" }, tab.id);\n if (tab.planTotalSteps > 0 && tab.completedStepIds.size >= tab.planTotalSteps) {\n tab.completedStepIds.clear();\n tab.planTotalSteps = 0;\n emit({ type: \"$plan_cleared\" }, tab.id);\n }\n emitSessions(tab);\n void emitBalance(tab);\n }\n });\n }\n\n async function switchWorkspace(tab: Tab, nextDir: string): Promise<void> {\n const target = resolve(nextDir);\n if (target === tab.rootDir) {\n emitSettings(tab);\n return;\n }\n if (!existsSync(target) || !statSync(target).isDirectory()) {\n emit({ type: \"$error\", message: `Workspace not found: ${target}` }, tab.id);\n emitSettings(tab);\n return;\n }\n tab.aborter?.abort();\n try {\n await tab.toolset.jobs.shutdown();\n } catch {\n // shutdown errors aren't actionable here\n }\n tab.rootDir = target;\n saveWorkspaceDir(target);\n pushRecentWorkspace(target);\n tab.fileIndex = null;\n tab.fileIndexBuilding = null;\n tab.symbolIndex = null;\n tab.symbolBuilding = null;\n tab.recentMentions.length = 0;\n tab.currentSession = mintSessionFor(target);\n tab.toolset = await buildCodeToolset({ rootDir: target });\n tab.system = codeSystemPrompt(target, {\n hasSemanticSearch: tab.toolset.semantic.enabled,\n modelId: tab.currentModel,\n });\n if (tab.runtime) tab.runtime = buildRuntimeFor(tab);\n emitSessions(tab);\n emitSettings(tab);\n emitSkills(tab);\n }\n\n function forgetGate(id: number): Tab | undefined {\n for (const t of tabs.values()) {\n if (t.pendingGateIds.delete(id)) return t;\n }\n return undefined;\n }\n\n function cancelPendingGates(tab: Tab): void {\n const hadActivePlan = tab.planTotalSteps > 0 || tab.completedStepIds.size > 0;\n const ids = [...tab.pendingGateIds];\n tab.pendingGateIds.clear();\n for (const id of ids) pauseGate.cancel(id);\n if (hadActivePlan) {\n tab.completedStepIds.clear();\n tab.planTotalSteps = 0;\n emit({ type: \"$plan_cleared\" }, tab.id);\n }\n }\n\n const first = await createTab();\n process.once(\"exit\", () => {\n for (const t of tabs.values()) void t.toolset.jobs.shutdown();\n });\n\n pauseGate.on((req) => {\n const tab = activeRunningTab();\n const tabId = tab?.id;\n if (tab) tab.pendingGateIds.add(req.id);\n // Shared auto-resolve policy (e.g. plan_checkpoint in auto/yolo) — must\n // still run BEFORE we emit any UI event, otherwise the surface flickers\n // a card that we'd immediately tear down.\n const auto = autoResolveVerdict(req, loadEditMode());\n if (auto !== null) {\n // plan_checkpoint specifically needs the step-completed signal to flow\n // through so the rail progress ticks. Emit it before resolving.\n if (req.kind === \"plan_checkpoint\") {\n const payload = req.payload as {\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n };\n if (tab) tab.completedStepIds.add(payload.stepId);\n emit(\n {\n type: \"$step_completed\",\n stepId: payload.stepId,\n title: payload.title,\n result: payload.result,\n notes: payload.notes,\n },\n tabId,\n );\n }\n if (tab) tab.pendingGateIds.delete(req.id);\n pauseGate.resolve(req.id, auto);\n return;\n }\n if (req.kind === \"run_command\" || req.kind === \"run_background\") {\n const payload = req.payload as { command?: string };\n emit(\n { type: \"$confirm_required\", id: req.id, kind: req.kind, command: payload.command ?? \"\" },\n tabId,\n );\n return;\n }\n if (req.kind === \"choice\") {\n const payload = req.payload as {\n question: string;\n options: ChoiceOption[];\n allowCustom: boolean;\n };\n emit(\n {\n type: \"$choice_required\",\n id: req.id,\n question: payload.question,\n options: payload.options,\n allowCustom: payload.allowCustom,\n },\n tabId,\n );\n return;\n }\n if (req.kind === \"plan_proposed\") {\n const payload = req.payload as { plan: string; steps?: PlanStepLite[]; summary?: string };\n if (tab) {\n tab.completedStepIds.clear();\n tab.planTotalSteps = payload.steps?.length ?? 0;\n }\n emit(\n {\n type: \"$plan_required\",\n id: req.id,\n plan: payload.plan,\n steps: payload.steps,\n summary: payload.summary,\n },\n tabId,\n );\n return;\n }\n if (req.kind === \"plan_checkpoint\") {\n const payload = req.payload as {\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n };\n if (tab) tab.completedStepIds.add(payload.stepId);\n emit(\n {\n type: \"$step_completed\",\n stepId: payload.stepId,\n title: payload.title,\n result: payload.result,\n notes: payload.notes,\n },\n tabId,\n );\n emit(\n {\n type: \"$checkpoint_required\",\n id: req.id,\n stepId: payload.stepId,\n title: payload.title,\n result: payload.result,\n notes: payload.notes,\n completed: tab?.completedStepIds.size ?? 0,\n total: tab?.planTotalSteps ?? 0,\n },\n tabId,\n );\n return;\n }\n if (req.kind === \"plan_revision\") {\n const payload = req.payload as {\n reason: string;\n remainingSteps: PlanStepLite[];\n summary?: string;\n };\n emit(\n {\n type: \"$revision_required\",\n id: req.id,\n reason: payload.reason,\n remainingSteps: payload.remainingSteps,\n summary: payload.summary,\n },\n tabId,\n );\n return;\n }\n });\n\n emit({ type: \"$tab_opened\", workspaceDir: first.rootDir }, first.id);\n if (loadApiKey()) emit({ type: \"$ready\" }, first.id);\n else emit({ type: \"$needs_setup\", reason: \"no_api_key\" }, first.id);\n emitSessions(first);\n emitSettings(first);\n emitMcpSpecs(first);\n emitSkills(first);\n emitMemory(first);\n emitCtxBreakdown(first);\n void emitBalance(first);\n\n const rl = createInterface({ input: stdin });\n rl.on(\"line\", (line) => {\n const trimmed = line.trim();\n if (!trimmed) return;\n let msg: InMessage;\n try {\n msg = JSON.parse(trimmed) as InMessage;\n } catch {\n emit({ type: \"$error\", message: `bad json on stdin: ${trimmed.slice(0, 80)}` });\n return;\n }\n\n if (msg.cmd === \"tab_open\") {\n void (async () => {\n try {\n const tab = await createTab(msg.workspaceDir);\n emit({ type: \"$tab_opened\", workspaceDir: tab.rootDir }, tab.id);\n if (loadApiKey()) emit({ type: \"$ready\" }, tab.id);\n else emit({ type: \"$needs_setup\", reason: \"no_api_key\" }, tab.id);\n emitSessions(tab);\n emitSettings(tab);\n emitMcpSpecs(tab);\n emitSkills(tab);\n emitMemory(tab);\n emitCtxBreakdown(tab);\n void emitBalance(tab);\n } catch (err) {\n emit({ type: \"$error\", message: `tab_open failed: ${(err as Error).message}` });\n }\n })();\n return;\n }\n if (msg.cmd === \"confirm_response\") {\n forgetGate(msg.id);\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"choice_response\") {\n forgetGate(msg.id);\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"plan_response\") {\n const tab = forgetGate(msg.id);\n if (tab && msg.response.type === \"cancel\") {\n tab.completedStepIds.clear();\n tab.planTotalSteps = 0;\n emit({ type: \"$plan_cleared\" }, tab.id);\n }\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"checkpoint_response\") {\n const tab = forgetGate(msg.id);\n if (tab && msg.response.type === \"stop\") {\n tab.completedStepIds.clear();\n tab.planTotalSteps = 0;\n emit({ type: \"$plan_cleared\" }, tab.id);\n }\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"revision_response\") {\n forgetGate(msg.id);\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"setup_save_key\") {\n const key = msg.key.trim();\n if (!isPlausibleKey(key)) {\n emit({\n type: \"$error\",\n message: \"Key looks too short — paste the full token (16+ chars, no spaces).\",\n });\n return;\n }\n try {\n saveApiKey(key);\n process.env.DEEPSEEK_API_KEY = key;\n for (const tab of tabs.values()) {\n tab.runtime = buildRuntimeFor(tab);\n emit({ type: \"$ready\" }, tab.id);\n emitSettings(tab);\n void emitBalance(tab);\n }\n } catch (err) {\n emit({ type: \"$error\", message: `saveApiKey failed: ${(err as Error).message}` });\n }\n return;\n }\n\n const tab = msg.tabId ? tabs.get(msg.tabId) : first;\n if (!tab) {\n emit({ type: \"$error\", message: `unknown tab: ${msg.tabId}` });\n return;\n }\n\n if (msg.cmd === \"abort\") {\n tab.aborter?.abort();\n cancelPendingGates(tab);\n return;\n }\n if (msg.cmd === \"tab_close\") {\n void closeTab(tab);\n return;\n }\n if (msg.cmd === \"mcp_specs_get\") {\n emitMcpSpecs(tab);\n return;\n }\n if (msg.cmd === \"mcp_specs_add\") {\n const spec = msg.spec.trim();\n if (!spec) {\n emit({ type: \"$error\", message: \"mcp_specs_add: spec is empty\" }, tab.id);\n return;\n }\n try {\n parseMcpSpec(spec);\n } catch (err) {\n emit({ type: \"$error\", message: `mcp_specs_add: ${(err as Error).message}` }, tab.id);\n return;\n }\n try {\n const cfg = readConfig();\n const list = cfg.mcp ?? [];\n if (!list.includes(spec)) {\n cfg.mcp = [...list, spec];\n writeConfig(cfg);\n }\n emitMcpSpecs(tab);\n void bridgeTabMcp(tab);\n } catch (err) {\n emit({ type: \"$error\", message: `mcp_specs_add: ${(err as Error).message}` }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"mcp_specs_remove\") {\n try {\n const cfg = readConfig();\n const list = cfg.mcp ?? [];\n if (list.includes(msg.spec)) {\n cfg.mcp = list.filter((s) => s !== msg.spec);\n writeConfig(cfg);\n }\n tab.mcpStatuses.delete(msg.spec);\n emitMcpSpecs(tab);\n void bridgeTabMcp(tab);\n } catch (err) {\n emit({ type: \"$error\", message: `mcp_specs_remove: ${(err as Error).message}` }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"skills_get\") {\n emitSkills(tab);\n return;\n }\n if (msg.cmd === \"session_list\") {\n emitSessions(tab);\n return;\n }\n if (msg.cmd === \"session_delete\") {\n deleteSession(msg.name);\n emitSessions(tab);\n return;\n }\n if (msg.cmd === \"session_load\") {\n try {\n const records = loadSessionMessages(msg.name);\n const meta = loadSessionMeta(msg.name);\n tab.aborter?.abort();\n cancelPendingGates(tab);\n tab.currentSession = msg.name;\n if (tab.runtime) tab.runtime = buildRuntimeFor(tab);\n emit(\n {\n type: \"$session_loaded\",\n name: msg.name,\n messages: buildLoadedMessages(records),\n carryover: {\n totalCostUsd: meta.totalCostUsd ?? 0,\n cacheHitTokens: meta.cacheHitTokens ?? 0,\n cacheMissTokens: meta.cacheMissTokens ?? 0,\n },\n },\n tab.id,\n );\n } catch (err) {\n emit({ type: \"$error\", message: `session_load failed: ${(err as Error).message}` }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"new_chat\") {\n tab.aborter?.abort();\n cancelPendingGates(tab);\n tab.currentSession = mintSessionFor(tab.rootDir);\n if (tab.runtime) tab.runtime = buildRuntimeFor(tab);\n emitSessions(tab);\n return;\n }\n if (msg.cmd === \"settings_get\") {\n emitSettings(tab);\n return;\n }\n if (msg.cmd === \"settings_save\") {\n try {\n if (msg.reasoningEffort !== undefined) {\n saveReasoningEffort(msg.reasoningEffort);\n tab.runtime?.loop.configure({ reasoningEffort: msg.reasoningEffort });\n }\n if (msg.editMode !== undefined) saveEditMode(msg.editMode);\n if (msg.budgetUsd !== undefined) {\n tab.budgetUsd = msg.budgetUsd ?? undefined;\n tab.runtime?.loop.setBudget(msg.budgetUsd);\n }\n if (msg.baseUrl !== undefined) saveBaseUrl(msg.baseUrl);\n if (msg.workspaceDir !== undefined) {\n void switchWorkspace(tab, msg.workspaceDir);\n return;\n }\n if (msg.editor !== undefined) saveEditor(msg.editor);\n if (msg.preset !== undefined) {\n tab.currentPreset = canonicalPresetName(msg.preset);\n const resolved = resolvePreset(tab.currentPreset);\n tab.currentModel = resolved.model;\n savePreset(tab.currentPreset);\n tab.system = codeSystemPrompt(tab.rootDir, {\n hasSemanticSearch: tab.toolset.semantic.enabled,\n modelId: tab.currentModel,\n });\n if (tab.runtime) tab.runtime = buildRuntimeFor(tab);\n }\n emitSettings(tab);\n } catch (err) {\n emit(\n { type: \"$error\", message: `settings_save failed: ${(err as Error).message}` },\n tab.id,\n );\n }\n return;\n }\n if (msg.cmd === \"mention_query\") {\n const nonce = msg.nonce;\n const query = msg.query;\n const parsed = parseAtQuery(query);\n if (parsed.trailingSlash) {\n void listDirectory(tab.rootDir, parsed.dir)\n .then((entries) => {\n const results = entries.map((e) => (e.isDir ? `${e.path}/` : e.path));\n emit({ type: \"$mention_results\", nonce, query, results }, tab.id);\n })\n .catch((err) => {\n emit(\n { type: \"$error\", message: `mention_query (dir) failed: ${(err as Error).message}` },\n tab.id,\n );\n emit({ type: \"$mention_results\", nonce, query, results: [] }, tab.id);\n });\n return;\n }\n const wantSymbols = query.length >= 2 && !query.includes(\"/\");\n void (async () => {\n try {\n const files = await getFileIndexFor(tab);\n const fileResults = rankPickerCandidates(files, query, {\n limit: wantSymbols ? 19 : 25,\n recentlyUsed: tab.recentMentions,\n });\n let symResults: string[] = [];\n if (wantSymbols) {\n const syms = await getSymbolIndexFor(tab);\n symResults = rankSymbols(syms, query, 6);\n }\n emit(\n { type: \"$mention_results\", nonce, query, results: [...symResults, ...fileResults] },\n tab.id,\n );\n } catch (err) {\n emit(\n { type: \"$error\", message: `mention_query failed: ${(err as Error).message}` },\n tab.id,\n );\n emit({ type: \"$mention_results\", nonce, query, results: [] }, tab.id);\n }\n })();\n return;\n }\n if (msg.cmd === \"mention_picked\") {\n pushMentionRecent(tab, msg.path);\n return;\n }\n if (msg.cmd === \"mention_preview\") {\n const nonce = msg.nonce;\n const rel = msg.path;\n const abs = isAbsolute(rel) ? rel : join(tab.rootDir, rel);\n const safeAbs = resolve(abs);\n const safeRoot = resolve(tab.rootDir);\n if (!safeAbs.startsWith(safeRoot)) {\n emit({ type: \"$mention_preview\", nonce, path: rel, head: \"\", totalLines: 0 }, tab.id);\n return;\n }\n void readFile(safeAbs, \"utf8\")\n .then((text) => {\n const lines = text.split(/\\r?\\n/);\n if (lines.length > 0 && lines[lines.length - 1] === \"\") lines.pop();\n const head = lines.slice(0, 12).join(\"\\n\");\n emit(\n { type: \"$mention_preview\", nonce, path: rel, head, totalLines: lines.length },\n tab.id,\n );\n })\n .catch(() => {\n emit({ type: \"$mention_preview\", nonce, path: rel, head: \"\", totalLines: 0 }, tab.id);\n });\n return;\n }\n if (msg.cmd === \"user_input\") {\n if (!tab.runtime) {\n emit(\n { type: \"$error\", message: \"Not configured yet — paste your DeepSeek API key first.\" },\n tab.id,\n );\n return;\n }\n void runTurn(tab, msg.text);\n }\n });\n\n await new Promise<void>((resolve) => rl.on(\"close\", resolve));\n}\n"],"mappings":"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","names":["tab","resolve"]}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
RecordView
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-L7W3HJZQ.js";
|
|
5
5
|
import {
|
|
6
6
|
diffTranscripts,
|
|
7
7
|
findNextDivergence,
|
|
8
8
|
findPrevDivergence,
|
|
9
9
|
renderMarkdown,
|
|
10
10
|
renderSummaryTable
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-VFG4GIT3.js";
|
|
12
12
|
import {
|
|
13
13
|
readTranscript
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-7SPOFTMT.js";
|
|
15
|
+
import "./chunk-H4OLWRSX.js";
|
|
16
16
|
import {
|
|
17
17
|
t
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-MHGPBJ2T.js";
|
|
19
|
+
import "./chunk-65Q5HQ26.js";
|
|
20
20
|
import "./chunk-ORM6PK57.js";
|
|
21
21
|
|
|
22
22
|
// src/cli/commands/diff.ts
|
|
@@ -150,4 +150,4 @@ markdown report written to ${opts.mdPath}`);
|
|
|
150
150
|
export {
|
|
151
151
|
diffCommand
|
|
152
152
|
};
|
|
153
|
-
//# sourceMappingURL=diff-
|
|
153
|
+
//# sourceMappingURL=diff-YASCB7PU.js.map
|
|
@@ -3,22 +3,22 @@ import {
|
|
|
3
3
|
doctorCommand,
|
|
4
4
|
formatDoctorJson,
|
|
5
5
|
runDoctorChecks
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KZYLMMU5.js";
|
|
7
7
|
import "./chunk-AFFZF3MW.js";
|
|
8
8
|
import "./chunk-DAEAAVDF.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-H4OLWRSX.js";
|
|
10
10
|
import "./chunk-3Q3C4W66.js";
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-2CXPDAWX.js";
|
|
12
|
+
import "./chunk-4H3ZRJ2U.js";
|
|
13
|
+
import "./chunk-WE3YZULK.js";
|
|
14
14
|
import "./chunk-5X7LZJDE.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-YJFKFTAL.js";
|
|
16
|
+
import "./chunk-MHGPBJ2T.js";
|
|
17
|
+
import "./chunk-65Q5HQ26.js";
|
|
18
18
|
import "./chunk-CRPQUBP6.js";
|
|
19
19
|
export {
|
|
20
20
|
doctorCommand,
|
|
21
21
|
formatDoctorJson,
|
|
22
22
|
runDoctorChecks
|
|
23
23
|
};
|
|
24
|
-
//# sourceMappingURL=doctor-
|
|
24
|
+
//# sourceMappingURL=doctor-XCN5ETVP.js.map
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "./chunk-FWGEHRB7.js";
|
|
5
5
|
import {
|
|
6
6
|
eventLogPath
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-7VFNPMKG.js";
|
|
8
|
+
import "./chunk-YJFKFTAL.js";
|
|
9
9
|
|
|
10
10
|
// src/core/reducers.ts
|
|
11
11
|
function emptyConversation() {
|
|
@@ -335,4 +335,4 @@ function mapReplacer(_key, value) {
|
|
|
335
335
|
export {
|
|
336
336
|
eventsCommand
|
|
337
337
|
};
|
|
338
|
-
//# sourceMappingURL=events-
|
|
338
|
+
//# sourceMappingURL=events-2AJTXR7I.js.map
|