reasonix 0.41.0 → 0.44.0-rc.5
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 +73 -12
- package/README.zh-CN.md +35 -7
- package/dashboard/app.css +225 -4
- package/dashboard/dist/app.js +6538 -6082
- package/dashboard/dist/app.js.map +1 -1
- package/data/deepseek-tokenizer.json.gz +0 -0
- package/dist/cli/{acp-64VQZLDJ.js → acp-TYZ2CTDL.js} +40 -37
- package/dist/cli/acp-TYZ2CTDL.js.map +1 -0
- package/dist/cli/chat-TH7VNNCJ.js +51 -0
- package/dist/cli/{chunk-E46ECXJD.js → chunk-2425HK6U.js} +2 -1
- package/dist/cli/{chunk-E46ECXJD.js.map → chunk-2425HK6U.js.map} +1 -1
- package/dist/cli/chunk-25T6CVUP.js +172 -0
- package/dist/cli/chunk-25T6CVUP.js.map +1 -0
- package/dist/cli/{chunk-3Q3C4W66.js → chunk-2UQP6H6T.js} +2 -1
- package/dist/cli/{chunk-3Q3C4W66.js.map → chunk-2UQP6H6T.js.map} +1 -1
- package/dist/cli/{chunk-SXLJBFIV.js → chunk-2V6EAEUW.js} +99 -31
- package/dist/cli/chunk-2V6EAEUW.js.map +1 -0
- package/dist/cli/{chunk-4H3ZRJ2U.js → chunk-4CTDEJUF.js} +4 -3
- package/dist/cli/{chunk-4H3ZRJ2U.js.map → chunk-4CTDEJUF.js.map} +1 -1
- package/dist/cli/{chunk-7VFNPMKG.js → chunk-4QUNBQQ2.js} +3 -2
- package/dist/cli/{chunk-7VFNPMKG.js.map → chunk-4QUNBQQ2.js.map} +1 -1
- package/dist/cli/chunk-5QCB62C4.js +25319 -0
- package/dist/cli/chunk-5QCB62C4.js.map +1 -0
- package/dist/cli/chunk-6OWJV3YW.js +390 -0
- package/dist/cli/chunk-6OWJV3YW.js.map +1 -0
- package/dist/cli/{chunk-YJFKFTAL.js → chunk-6PBZN4VI.js} +15 -3
- package/dist/cli/chunk-6PBZN4VI.js.map +1 -0
- package/dist/cli/{chunk-WE3YZULK.js → chunk-7CIGMZT3.js} +3 -2
- package/dist/cli/{chunk-WE3YZULK.js.map → chunk-7CIGMZT3.js.map} +1 -1
- package/dist/cli/{chunk-LTXADNCO.js → chunk-7UCMM425.js} +8 -3
- package/dist/cli/chunk-7UCMM425.js.map +1 -0
- package/dist/cli/{chunk-UV7XJUJH.js → chunk-AB2RED3C.js} +16 -9
- package/dist/cli/{chunk-UV7XJUJH.js.map → chunk-AB2RED3C.js.map} +1 -1
- package/dist/cli/chunk-AVFXO2EZ.js +2996 -0
- package/dist/cli/chunk-AVFXO2EZ.js.map +1 -0
- package/dist/cli/{chunk-7SPOFTMT.js → chunk-C53JQES5.js} +4 -3
- package/dist/cli/{chunk-7SPOFTMT.js.map → chunk-C53JQES5.js.map} +1 -1
- package/dist/cli/{chunk-MHGPBJ2T.js → chunk-CGDR2ELH.js} +131 -34
- package/dist/cli/chunk-CGDR2ELH.js.map +1 -0
- package/dist/cli/{chunk-4DCHFFEY.js → chunk-CWZKQ5FE.js} +8 -4
- package/dist/cli/chunk-CWZKQ5FE.js.map +1 -0
- package/dist/cli/chunk-FEZK652I.js +3644 -0
- package/dist/cli/chunk-FEZK652I.js.map +1 -0
- package/dist/cli/{chunk-A7VHMMDE.js → chunk-HNXDZGC6.js} +114 -5
- package/dist/cli/chunk-HNXDZGC6.js.map +1 -0
- package/dist/cli/{chunk-FWGEHRB7.js → chunk-J5XJHLWM.js} +2 -1
- package/dist/cli/{chunk-FWGEHRB7.js.map → chunk-J5XJHLWM.js.map} +1 -1
- package/dist/cli/{chunk-Y5XNV3NX.js → chunk-JMBMLOBP.js} +2 -1
- package/dist/cli/{chunk-Y5XNV3NX.js.map → chunk-JMBMLOBP.js.map} +1 -1
- package/dist/cli/{chunk-ARF3N2SY.js → chunk-JNAQYELD.js} +17 -8
- package/dist/cli/{chunk-ARF3N2SY.js.map → chunk-JNAQYELD.js.map} +1 -1
- package/dist/cli/{chunk-AT6GGIBV.js → chunk-KGBG6M2X.js} +25 -18
- package/dist/cli/chunk-KGBG6M2X.js.map +1 -0
- package/dist/cli/{chunk-A3LL4XDV.js → chunk-KLQTAZIY.js} +69 -5
- package/dist/cli/chunk-KLQTAZIY.js.map +1 -0
- package/dist/cli/{chunk-KZYLMMU5.js → chunk-KM465GST.js} +13 -12
- package/dist/cli/{chunk-KZYLMMU5.js.map → chunk-KM465GST.js.map} +1 -1
- package/dist/cli/{chunk-2CXPDAWX.js → chunk-LIR2HBQH.js} +3 -2
- package/dist/cli/{chunk-2CXPDAWX.js.map → chunk-LIR2HBQH.js.map} +1 -1
- package/dist/cli/{chunk-RAUPWSYA.js → chunk-MJ6W5UN3.js} +3 -2
- package/dist/cli/{chunk-RAUPWSYA.js.map → chunk-MJ6W5UN3.js.map} +1 -1
- package/dist/cli/{chunk-4W2CICFQ.js → chunk-MRHHQJAQ.js} +72 -60
- package/dist/cli/chunk-MRHHQJAQ.js.map +1 -0
- package/dist/cli/{chunk-BOFL3T45.js → chunk-NVURFF27.js} +23 -11
- package/dist/cli/chunk-NVURFF27.js.map +1 -0
- package/dist/cli/chunk-OPFUUYHL.js +11645 -0
- package/dist/cli/chunk-OPFUUYHL.js.map +1 -0
- package/dist/cli/{chunk-FM57FNPJ.js → chunk-PLHAZOLZ.js} +2 -1
- package/dist/cli/{chunk-FM57FNPJ.js.map → chunk-PLHAZOLZ.js.map} +1 -1
- package/dist/cli/{chunk-ZTLZO42A.js → chunk-R3CTO2HM.js} +3 -2
- package/dist/cli/{chunk-ZTLZO42A.js.map → chunk-R3CTO2HM.js.map} +1 -1
- package/dist/cli/{chunk-BYZGO3BX.js → chunk-RDRC3XDT.js} +145 -39
- package/dist/cli/chunk-RDRC3XDT.js.map +1 -0
- package/dist/cli/chunk-S4XVGLRW.js +499 -0
- package/dist/cli/chunk-S4XVGLRW.js.map +1 -0
- package/dist/cli/{chunk-WJ3YX4PZ.js → chunk-SZ5XES2N.js} +3 -2
- package/dist/cli/{chunk-WJ3YX4PZ.js.map → chunk-SZ5XES2N.js.map} +1 -1
- package/dist/cli/{chunk-CD4SCQL4.js → chunk-TEUDEGX2.js} +64 -10
- package/dist/cli/chunk-TEUDEGX2.js.map +1 -0
- package/dist/cli/chunk-TKVXTQ3T.js +96 -0
- package/dist/cli/chunk-TKVXTQ3T.js.map +1 -0
- package/dist/cli/chunk-TUK7OWJA.js +51 -0
- package/dist/cli/chunk-TXJMRPIL.js +54 -0
- package/dist/cli/{chunk-L7W3HJZQ.js.map → chunk-TXJMRPIL.js.map} +1 -1
- package/dist/cli/{chunk-H4OLWRSX.js → chunk-V26WPN3J.js} +11 -7
- package/dist/cli/chunk-V26WPN3J.js.map +1 -0
- package/dist/cli/{chunk-VFG4GIT3.js → chunk-WK3UFQY3.js} +3 -2
- package/dist/cli/{chunk-VFG4GIT3.js.map → chunk-WK3UFQY3.js.map} +1 -1
- package/dist/cli/chunk-X53B3JIX.js +34320 -0
- package/dist/cli/chunk-X53B3JIX.js.map +1 -0
- package/dist/cli/{chunk-SOZE7V7V.js → chunk-XJXDHAES.js} +3 -2
- package/dist/cli/{chunk-SOZE7V7V.js.map → chunk-XJXDHAES.js.map} +1 -1
- package/dist/cli/{chunk-CFY2XLY6.js → chunk-XSU4QVFW.js} +7 -85
- package/dist/cli/chunk-XSU4QVFW.js.map +1 -0
- package/dist/cli/{chunk-CRPQUBP6.js → chunk-XXC2BYTV.js} +2 -1
- package/dist/cli/{chunk-CRPQUBP6.js.map → chunk-XXC2BYTV.js.map} +1 -1
- package/dist/cli/chunk-Z4S7EYXG.js +63813 -0
- package/dist/cli/chunk-Z4S7EYXG.js.map +1 -0
- package/dist/cli/chunk-ZZM6QJ4W.js +109 -0
- package/dist/cli/chunk-ZZM6QJ4W.js.map +1 -0
- package/dist/cli/{chunk-ORM6PK57.js → chunk-ZZYBBX5N.js} +14 -5
- package/dist/cli/chunk-ZZYBBX5N.js.map +1 -0
- package/dist/cli/code-PSVJ3KEN.js +166 -0
- package/dist/cli/code-PSVJ3KEN.js.map +1 -0
- package/dist/cli/{commands-QY7MSQG7.js → commands-OCU42XG4.js} +7 -5
- package/dist/cli/{commands-QY7MSQG7.js.map → commands-OCU42XG4.js.map} +1 -1
- package/dist/cli/{commit-BRCQ3OQO.js → commit-XCQIQCYG.js} +7 -4
- package/dist/cli/{commit-BRCQ3OQO.js.map → commit-XCQIQCYG.js.map} +1 -1
- package/dist/cli/{desktop-ZTMHQR2Y.js → desktop-KWGR4BNE.js} +327 -98
- package/dist/cli/desktop-KWGR4BNE.js.map +1 -0
- package/dist/cli/devtools-HW3WDT3Q.js +91 -0
- package/dist/cli/devtools-HW3WDT3Q.js.map +1 -0
- package/dist/cli/diff-NHANTNC3.js +165 -0
- package/dist/cli/{diff-YASCB7PU.js.map → diff-NHANTNC3.js.map} +1 -1
- package/dist/cli/doctor-CC5CLOGG.js +27 -0
- package/dist/cli/{events-2AJTXR7I.js → events-XEFAD5VX.js} +6 -4
- package/dist/cli/{events-2AJTXR7I.js.map → events-XEFAD5VX.js.map} +1 -1
- package/dist/cli/index.js +3266 -152
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-YMWBLRR7.js → mcp-MPVGBBJF.js} +6 -4
- package/dist/cli/{mcp-YMWBLRR7.js.map → mcp-MPVGBBJF.js.map} +1 -1
- package/dist/cli/{mcp-browse-XLDUE6SB.js → mcp-browse-4XOTC3FJ.js} +32 -21
- package/dist/cli/{mcp-browse-XLDUE6SB.js.map → mcp-browse-4XOTC3FJ.js.map} +1 -1
- package/dist/cli/{mcp-inspect-H4D2HSJP.js → mcp-inspect-CEMGKKAH.js} +18 -10
- package/dist/cli/mcp-inspect-CEMGKKAH.js.map +1 -0
- package/dist/cli/package.json +3 -0
- package/dist/cli/prompt-2D7ID24X.js +16 -0
- package/dist/cli/{prune-sessions-4N3BVST2.js → prune-sessions-3RWUBYRS.js} +4 -2
- package/dist/cli/{prune-sessions-4N3BVST2.js.map → prune-sessions-3RWUBYRS.js.map} +1 -1
- package/dist/cli/{replay-3GTWM75X.js → replay-SR44E6RS.js} +42 -30
- package/dist/cli/{replay-3GTWM75X.js.map → replay-SR44E6RS.js.map} +1 -1
- package/dist/cli/{run-BLZPTRDX.js → run-MDGL27WL.js} +42 -40
- package/dist/cli/run-MDGL27WL.js.map +1 -0
- package/dist/cli/{server-DRFPXXSH.js → server-27ARQXIZ.js} +95 -55
- package/dist/cli/server-27ARQXIZ.js.map +1 -0
- package/dist/cli/{sessions-BOWFPTXT.js → sessions-CKQXCYGP.js} +25 -22
- package/dist/cli/sessions-CKQXCYGP.js.map +1 -0
- package/dist/cli/setup-TPAGSVXO.js +618 -0
- package/dist/cli/setup-TPAGSVXO.js.map +1 -0
- package/dist/cli/stats-DPUBZNVX.js +16 -0
- package/dist/cli/update-6ITLPRDV.js +15 -0
- package/dist/cli/version-2X3BHVVK.js +33 -0
- package/dist/cli/{version-XQXYSJ5L.js.map → version-2X3BHVVK.js.map} +1 -1
- package/dist/index.d.ts +182 -45
- package/dist/index.js +1420 -546
- package/dist/index.js.map +1 -1
- package/package.json +21 -8
- package/dist/cli/.-3G6VX5S7.js +0 -327
- package/dist/cli/.-6YRPB2C7.js +0 -329
- package/dist/cli/.-EYSVINK3.js +0 -317
- package/dist/cli/acp-64VQZLDJ.js.map +0 -1
- package/dist/cli/chat-ZAGX52RV.js +0 -46
- package/dist/cli/chunk-4DCHFFEY.js.map +0 -1
- package/dist/cli/chunk-4W2CICFQ.js.map +0 -1
- package/dist/cli/chunk-5X7LZJDE.js +0 -36
- package/dist/cli/chunk-5X7LZJDE.js.map +0 -1
- package/dist/cli/chunk-65Q5HQ26.js +0 -892
- package/dist/cli/chunk-65Q5HQ26.js.map +0 -1
- package/dist/cli/chunk-A3LL4XDV.js.map +0 -1
- package/dist/cli/chunk-A7VHMMDE.js.map +0 -1
- package/dist/cli/chunk-AFFZF3MW.js +0 -36
- package/dist/cli/chunk-AFFZF3MW.js.map +0 -1
- package/dist/cli/chunk-AT6GGIBV.js.map +0 -1
- package/dist/cli/chunk-BOFL3T45.js.map +0 -1
- package/dist/cli/chunk-BYZGO3BX.js.map +0 -1
- package/dist/cli/chunk-CD4SCQL4.js.map +0 -1
- package/dist/cli/chunk-CFY2XLY6.js.map +0 -1
- package/dist/cli/chunk-CPOV2O73.js +0 -39
- package/dist/cli/chunk-CPOV2O73.js.map +0 -1
- package/dist/cli/chunk-DAEAAVDF.js +0 -199
- package/dist/cli/chunk-DAEAAVDF.js.map +0 -1
- package/dist/cli/chunk-F2AV2QDK.js +0 -16514
- package/dist/cli/chunk-F2AV2QDK.js.map +0 -1
- package/dist/cli/chunk-H4OLWRSX.js.map +0 -1
- package/dist/cli/chunk-IEA6JOIP.js +0 -5430
- package/dist/cli/chunk-IEA6JOIP.js.map +0 -1
- package/dist/cli/chunk-L7W3HJZQ.js +0 -46
- package/dist/cli/chunk-LN27AKV3.js +0 -26
- package/dist/cli/chunk-LN27AKV3.js.map +0 -1
- package/dist/cli/chunk-LTXADNCO.js.map +0 -1
- package/dist/cli/chunk-MHGPBJ2T.js.map +0 -1
- package/dist/cli/chunk-ORM6PK57.js.map +0 -1
- package/dist/cli/chunk-SXLJBFIV.js.map +0 -1
- package/dist/cli/chunk-YJFKFTAL.js.map +0 -1
- package/dist/cli/code-X3M6ENTQ.js +0 -150
- package/dist/cli/code-X3M6ENTQ.js.map +0 -1
- package/dist/cli/desktop-ZTMHQR2Y.js.map +0 -1
- package/dist/cli/diff-YASCB7PU.js +0 -153
- package/dist/cli/doctor-XCN5ETVP.js +0 -24
- package/dist/cli/mcp-inspect-H4D2HSJP.js.map +0 -1
- package/dist/cli/prompt-RSIHN62V.js +0 -14
- package/dist/cli/run-BLZPTRDX.js.map +0 -1
- package/dist/cli/server-DRFPXXSH.js.map +0 -1
- package/dist/cli/sessions-BOWFPTXT.js.map +0 -1
- package/dist/cli/setup-FQL2JJC2.js +0 -516
- package/dist/cli/setup-FQL2JJC2.js.map +0 -1
- package/dist/cli/stats-5RJCATCE.js +0 -12
- package/dist/cli/stats-5RJCATCE.js.map +0 -1
- package/dist/cli/update-GUCWB4UN.js +0 -13
- package/dist/cli/update-GUCWB4UN.js.map +0 -1
- package/dist/cli/version-XQXYSJ5L.js +0 -30
- /package/dist/cli/{.-3G6VX5S7.js.map → chat-TH7VNNCJ.js.map} +0 -0
- /package/dist/cli/{.-6YRPB2C7.js.map → chunk-TUK7OWJA.js.map} +0 -0
- /package/dist/cli/{.-EYSVINK3.js.map → doctor-CC5CLOGG.js.map} +0 -0
- /package/dist/cli/{chat-ZAGX52RV.js.map → prompt-2D7ID24X.js.map} +0 -0
- /package/dist/cli/{doctor-XCN5ETVP.js.map → stats-DPUBZNVX.js.map} +0 -0
- /package/dist/cli/{prompt-RSIHN62V.js.map → update-6ITLPRDV.js.map} +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
3
|
+
|
|
4
|
+
// src/cli/cpu-prof.ts
|
|
5
|
+
import { writeFileSync } from "fs";
|
|
6
|
+
import { Session } from "inspector/promises";
|
|
7
|
+
import { resolve } from "path";
|
|
8
|
+
import { gzipSync } from "zlib";
|
|
9
|
+
var session = null;
|
|
10
|
+
var outPath = null;
|
|
11
|
+
var signalHandlerInstalled = false;
|
|
12
|
+
var stopping = false;
|
|
13
|
+
function defaultOutPath() {
|
|
14
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").replace("Z", "");
|
|
15
|
+
return resolve(process.cwd(), `reasonix-cpu-${stamp}.cpuprofile`);
|
|
16
|
+
}
|
|
17
|
+
async function startCpuProfile(pathArg) {
|
|
18
|
+
if (session) return outPath ?? defaultOutPath();
|
|
19
|
+
outPath = typeof pathArg === "string" ? resolve(pathArg) : defaultOutPath();
|
|
20
|
+
session = new Session();
|
|
21
|
+
session.connect();
|
|
22
|
+
await session.post("Profiler.enable");
|
|
23
|
+
await session.post("Profiler.start");
|
|
24
|
+
process.stderr.write(`\u25B8 cpu profile recording \u2014 will save to ${outPath} on exit
|
|
25
|
+
`);
|
|
26
|
+
installSignalHandler();
|
|
27
|
+
return outPath;
|
|
28
|
+
}
|
|
29
|
+
async function stopAndSaveCpuProfile() {
|
|
30
|
+
if (!session || !outPath || stopping) return;
|
|
31
|
+
stopping = true;
|
|
32
|
+
const s = session;
|
|
33
|
+
const baseOut = outPath;
|
|
34
|
+
session = null;
|
|
35
|
+
try {
|
|
36
|
+
const { profile } = await s.post("Profiler.stop");
|
|
37
|
+
const json = JSON.stringify(profile);
|
|
38
|
+
const gz = gzipSync(json);
|
|
39
|
+
const gzPath = `${baseOut}.gz`;
|
|
40
|
+
writeFileSync(gzPath, gz);
|
|
41
|
+
const mb = (gz.length / (1024 * 1024)).toFixed(2);
|
|
42
|
+
process.stderr.write(
|
|
43
|
+
`\u25B8 cpu profile saved \u2192 ${gzPath} (${mb} MB gzipped)
|
|
44
|
+
drag into a GitHub issue comment, or:
|
|
45
|
+
gh issue comment <N> --repo esengine/DeepSeek-Reasonix -F "${gzPath}"
|
|
46
|
+
`
|
|
47
|
+
);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
process.stderr.write(`\u25B2 cpu profile save failed: ${e.message}
|
|
50
|
+
`);
|
|
51
|
+
} finally {
|
|
52
|
+
try {
|
|
53
|
+
s.disconnect();
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function installSignalHandler() {
|
|
59
|
+
if (signalHandlerInstalled) return;
|
|
60
|
+
signalHandlerInstalled = true;
|
|
61
|
+
for (const sig of ["SIGINT", "SIGTERM", "SIGHUP"]) {
|
|
62
|
+
process.on(sig, () => {
|
|
63
|
+
void (async () => {
|
|
64
|
+
await stopAndSaveCpuProfile();
|
|
65
|
+
process.exit(sig === "SIGINT" ? 130 : 0);
|
|
66
|
+
})();
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/cli/startup-profile.ts
|
|
72
|
+
import { performance } from "perf_hooks";
|
|
73
|
+
var marks = [];
|
|
74
|
+
var dumped = false;
|
|
75
|
+
function envFlag() {
|
|
76
|
+
const v = process.env.REASONIX_PROFILE_STARTUP;
|
|
77
|
+
return v === "1" || v === "true" || v === "yes";
|
|
78
|
+
}
|
|
79
|
+
function markPhase(name) {
|
|
80
|
+
if (!envFlag()) return;
|
|
81
|
+
marks.push({ name, t: performance.now() });
|
|
82
|
+
}
|
|
83
|
+
function dumpStartupProfile(stream = process.stderr) {
|
|
84
|
+
if (!envFlag() || dumped || marks.length === 0) return;
|
|
85
|
+
dumped = true;
|
|
86
|
+
const totalMs = marks[marks.length - 1].t;
|
|
87
|
+
const widest = String(Math.round(totalMs)).length;
|
|
88
|
+
const lines = ["[startup-profile]"];
|
|
89
|
+
let prev = 0;
|
|
90
|
+
for (const m of marks) {
|
|
91
|
+
const cum = Math.round(m.t).toString().padStart(widest);
|
|
92
|
+
const delta = Math.round(m.t - prev);
|
|
93
|
+
lines.push(` ${cum}ms ${m.name.padEnd(28)} (+${delta})`);
|
|
94
|
+
prev = m.t;
|
|
95
|
+
}
|
|
96
|
+
lines.push(
|
|
97
|
+
`\u2500\u2500\u2500 ${Math.round(totalMs)}ms total \xB7 last phase ${marks[marks.length - 1].name} \xB7 set REASONIX_PROFILE_STARTUP=0 to silence`
|
|
98
|
+
);
|
|
99
|
+
stream.write(`${lines.join("\n")}
|
|
100
|
+
`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
startCpuProfile,
|
|
105
|
+
stopAndSaveCpuProfile,
|
|
106
|
+
markPhase,
|
|
107
|
+
dumpStartupProfile
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=chunk-ZZM6QJ4W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/cpu-prof.ts","../../src/cli/startup-profile.ts"],"sourcesContent":["import { writeFileSync } from \"node:fs\";\nimport { Session } from \"node:inspector/promises\";\nimport { resolve } from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\n\nlet session: Session | null = null;\nlet outPath: string | null = null;\nlet signalHandlerInstalled = false;\nlet stopping = false;\n\nfunction defaultOutPath(): string {\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\").replace(\"Z\", \"\");\n return resolve(process.cwd(), `reasonix-cpu-${stamp}.cpuprofile`);\n}\n\nexport async function startCpuProfile(pathArg?: string | true): Promise<string> {\n if (session) return outPath ?? defaultOutPath();\n outPath = typeof pathArg === \"string\" ? resolve(pathArg) : defaultOutPath();\n session = new Session();\n session.connect();\n await session.post(\"Profiler.enable\");\n await session.post(\"Profiler.start\");\n process.stderr.write(`▸ cpu profile recording — will save to ${outPath} on exit\\n`);\n installSignalHandler();\n return outPath;\n}\n\nexport async function stopAndSaveCpuProfile(): Promise<void> {\n if (!session || !outPath || stopping) return;\n stopping = true;\n const s = session;\n const baseOut = outPath;\n session = null;\n try {\n const { profile } = (await s.post(\"Profiler.stop\")) as { profile: unknown };\n const json = JSON.stringify(profile);\n const gz = gzipSync(json);\n const gzPath = `${baseOut}.gz`;\n writeFileSync(gzPath, gz);\n const mb = (gz.length / (1024 * 1024)).toFixed(2);\n process.stderr.write(\n `▸ cpu profile saved → ${gzPath} (${mb} MB gzipped)\\n drag into a GitHub issue comment, or:\\n gh issue comment <N> --repo esengine/DeepSeek-Reasonix -F \"${gzPath}\"\\n`,\n );\n } catch (e) {\n process.stderr.write(`▲ cpu profile save failed: ${(e as Error).message}\\n`);\n } finally {\n try {\n s.disconnect();\n } catch {\n /* ignore */\n }\n }\n}\n\nfunction installSignalHandler(): void {\n if (signalHandlerInstalled) return;\n signalHandlerInstalled = true;\n for (const sig of [\"SIGINT\", \"SIGTERM\", \"SIGHUP\"] as const) {\n process.on(sig, () => {\n void (async () => {\n await stopAndSaveCpuProfile();\n process.exit(sig === \"SIGINT\" ? 130 : 0);\n })();\n });\n }\n}\n","import { performance } from \"node:perf_hooks\";\n\ninterface PhaseMark {\n name: string;\n t: number;\n}\n\nconst marks: PhaseMark[] = [];\nlet dumped = false;\n\nfunction envFlag(): boolean {\n const v = process.env.REASONIX_PROFILE_STARTUP;\n return v === \"1\" || v === \"true\" || v === \"yes\";\n}\n\nexport function isStartupProfileEnabled(): boolean {\n return envFlag();\n}\n\nexport function markPhase(name: string): void {\n if (!envFlag()) return;\n marks.push({ name, t: performance.now() });\n}\n\nexport function dumpStartupProfile(stream: NodeJS.WriteStream = process.stderr): void {\n if (!envFlag() || dumped || marks.length === 0) return;\n dumped = true;\n const totalMs = marks[marks.length - 1]!.t;\n const widest = String(Math.round(totalMs)).length;\n const lines: string[] = [\"[startup-profile]\"];\n let prev = 0;\n for (const m of marks) {\n const cum = Math.round(m.t).toString().padStart(widest);\n const delta = Math.round(m.t - prev);\n lines.push(` ${cum}ms ${m.name.padEnd(28)} (+${delta})`);\n prev = m.t;\n }\n lines.push(\n `─── ${Math.round(totalMs)}ms total · last phase ${marks[marks.length - 1]!.name} · set REASONIX_PROFILE_STARTUP=0 to silence`,\n );\n stream.write(`${lines.join(\"\\n\")}\\n`);\n}\n\nexport function _resetForTests(): void {\n marks.length = 0;\n dumped = false;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
2
3
|
|
|
3
4
|
// src/telemetry/stats.ts
|
|
4
5
|
var DEEPSEEK_PRICING = {
|
|
5
|
-
"deepseek-v4-flash": { inputCacheHit:
|
|
6
|
-
"deepseek-v4-pro": { inputCacheHit:
|
|
6
|
+
"deepseek-v4-flash": { inputCacheHit: 28e-4, inputCacheMiss: 0.14, output: 0.28 },
|
|
7
|
+
"deepseek-v4-pro": { inputCacheHit: 3625e-6, inputCacheMiss: 0.435, output: 0.87 },
|
|
7
8
|
// Compat aliases — priced as v4-flash per the deprecation notice.
|
|
8
|
-
"deepseek-chat": { inputCacheHit:
|
|
9
|
-
"deepseek-reasoner": { inputCacheHit:
|
|
9
|
+
"deepseek-chat": { inputCacheHit: 28e-4, inputCacheMiss: 0.14, output: 0.28 },
|
|
10
|
+
"deepseek-reasoner": { inputCacheHit: 28e-4, inputCacheMiss: 0.14, output: 0.28 }
|
|
10
11
|
};
|
|
11
12
|
var CLAUDE_SONNET_PRICING = { input: 3, output: 15 };
|
|
12
13
|
var DEEPSEEK_CONTEXT_TOKENS = {
|
|
@@ -68,6 +69,14 @@ var SessionStats = class {
|
|
|
68
69
|
this._carryoverLastPromptTokens = opts.lastPromptTokens;
|
|
69
70
|
}
|
|
70
71
|
}
|
|
72
|
+
reset() {
|
|
73
|
+
this.turns.length = 0;
|
|
74
|
+
this._carryoverCost = 0;
|
|
75
|
+
this._carryoverTurns = 0;
|
|
76
|
+
this._carryoverCacheHit = 0;
|
|
77
|
+
this._carryoverCacheMiss = 0;
|
|
78
|
+
this._carryoverLastPromptTokens = 0;
|
|
79
|
+
}
|
|
71
80
|
record(turn, model, usage) {
|
|
72
81
|
const cost = costUsd(model, usage);
|
|
73
82
|
const stats = {
|
|
@@ -137,4 +146,4 @@ export {
|
|
|
137
146
|
claudeEquivalentCost,
|
|
138
147
|
SessionStats
|
|
139
148
|
};
|
|
140
|
-
//# sourceMappingURL=chunk-
|
|
149
|
+
//# sourceMappingURL=chunk-ZZYBBX5N.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/stats.ts"],"sourcesContent":["import type { Usage } from \"../client.js\";\n\n/** USD per 1M tokens; display currency conversion happens at the UI boundary. */\nexport const DEEPSEEK_PRICING: Record<\n string,\n { inputCacheHit: number; inputCacheMiss: number; output: number }\n> = {\n \"deepseek-v4-flash\": { inputCacheHit: 0.0028, inputCacheMiss: 0.14, output: 0.28 },\n \"deepseek-v4-pro\": { inputCacheHit: 0.003625, inputCacheMiss: 0.435, output: 0.87 },\n // Compat aliases — priced as v4-flash per the deprecation notice.\n \"deepseek-chat\": { inputCacheHit: 0.0028, inputCacheMiss: 0.14, output: 0.28 },\n \"deepseek-reasoner\": { inputCacheHit: 0.0028, inputCacheMiss: 0.14, output: 0.28 },\n};\n\n/** Reference Claude Sonnet 4.6 pricing (USD per 1M tokens). */\nexport const CLAUDE_SONNET_PRICING = { input: 3.0, output: 15.0 };\n\n/** Prompt-side window only; completion caps live server-side and don't affect this gauge. */\nexport const DEEPSEEK_CONTEXT_TOKENS: Record<string, number> = {\n \"deepseek-v4-flash\": 1_000_000,\n \"deepseek-v4-pro\": 1_000_000,\n \"deepseek-chat\": 1_000_000,\n \"deepseek-reasoner\": 1_000_000,\n};\n\n/** Fallback when the caller's model id isn't in the table — safe lower bound. */\nexport const DEFAULT_CONTEXT_TOKENS = 131_072;\n\nexport function costUsd(model: string, usage: Usage): number {\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (\n (usage.promptCacheHitTokens * p.inputCacheHit +\n usage.promptCacheMissTokens * p.inputCacheMiss +\n usage.completionTokens * p.output) /\n 1_000_000\n );\n}\n\n/** Input-side cost only (prompt, cache hit + miss). Used for the panel breakdown. */\nexport function inputCostUsd(model: string, usage: Usage): number {\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (\n (usage.promptCacheHitTokens * p.inputCacheHit +\n usage.promptCacheMissTokens * p.inputCacheMiss) /\n 1_000_000\n );\n}\n\n/** Output-side cost only (completion tokens). Used for the panel breakdown. */\nexport function outputCostUsd(model: string, usage: Usage): number {\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (usage.completionTokens * p.output) / 1_000_000;\n}\n\nexport function cacheSavingsUsd(model: string, hitTokens: number): number {\n if (hitTokens <= 0) return 0;\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (hitTokens * (p.inputCacheMiss - p.inputCacheHit)) / 1_000_000;\n}\n\nexport function claudeEquivalentCost(usage: Usage): number {\n return (\n (usage.promptTokens * CLAUDE_SONNET_PRICING.input +\n usage.completionTokens * CLAUDE_SONNET_PRICING.output) /\n 1_000_000\n );\n}\n\nexport interface TurnStats {\n turn: number;\n model: string;\n usage: Usage;\n cost: number;\n cacheHitRatio: number;\n}\n\nexport interface SessionSummary {\n turns: number;\n totalCostUsd: number;\n totalInputCostUsd: number;\n /** Output-side (completion) cost aggregated across the session. */\n totalOutputCostUsd: number;\n /** @deprecated Claude reference; kept for benchmarks + replay compat, no longer surfaced in the TUI. */\n claudeEquivalentUsd: number;\n /** @deprecated. Same as claudeEquivalentUsd — synthetic ratio, not a real measurement. */\n savingsVsClaudePct: number;\n cacheHitRatio: number;\n /** Floor estimate for next call — actual cost = this + user delta + new tool outputs. */\n lastPromptTokens: number;\n lastTurnCostUsd: number;\n}\n\nexport class SessionStats {\n readonly turns: TurnStats[] = [];\n /** Cost from prior runs of a resumed session, restored from session meta. */\n private _carryoverCost = 0;\n /** Turn count from prior runs of a resumed session. */\n private _carryoverTurns = 0;\n private _carryoverCacheHit = 0;\n private _carryoverCacheMiss = 0;\n /** Last turn's promptTokens before exit — surfaced via summary() until the next live turn lands. */\n private _carryoverLastPromptTokens = 0;\n\n /** Seed totals from a resumed session's persisted meta — only call once at construction. */\n seedCarryover(opts: {\n totalCostUsd?: number;\n turnCount?: number;\n cacheHitTokens?: number;\n cacheMissTokens?: number;\n lastPromptTokens?: number;\n }): void {\n if (typeof opts.totalCostUsd === \"number\" && opts.totalCostUsd > 0) {\n this._carryoverCost = opts.totalCostUsd;\n }\n if (typeof opts.turnCount === \"number\" && opts.turnCount > 0) {\n this._carryoverTurns = opts.turnCount;\n }\n if (typeof opts.cacheHitTokens === \"number\" && opts.cacheHitTokens > 0) {\n this._carryoverCacheHit = opts.cacheHitTokens;\n }\n if (typeof opts.cacheMissTokens === \"number\" && opts.cacheMissTokens > 0) {\n this._carryoverCacheMiss = opts.cacheMissTokens;\n }\n if (typeof opts.lastPromptTokens === \"number\" && opts.lastPromptTokens > 0) {\n this._carryoverLastPromptTokens = opts.lastPromptTokens;\n }\n }\n\n reset(): void {\n this.turns.length = 0;\n this._carryoverCost = 0;\n this._carryoverTurns = 0;\n this._carryoverCacheHit = 0;\n this._carryoverCacheMiss = 0;\n this._carryoverLastPromptTokens = 0;\n }\n\n record(turn: number, model: string, usage: Usage): TurnStats {\n const cost = costUsd(model, usage);\n const stats: TurnStats = {\n turn,\n model,\n usage,\n cost,\n cacheHitRatio: usage.cacheHitRatio,\n };\n this.turns.push(stats);\n return stats;\n }\n\n get totalCost(): number {\n return this._carryoverCost + this.turns.reduce((sum, t) => sum + t.cost, 0);\n }\n\n get totalClaudeEquivalent(): number {\n return this.turns.reduce((sum, t) => sum + claudeEquivalentCost(t.usage), 0);\n }\n\n get savingsVsClaude(): number {\n const c = this.totalClaudeEquivalent;\n return c > 0 ? 1 - this.totalCost / c : 0;\n }\n\n get totalInputCost(): number {\n return this.turns.reduce((sum, t) => sum + inputCostUsd(t.model, t.usage), 0);\n }\n\n get totalOutputCost(): number {\n return this.turns.reduce((sum, t) => sum + outputCostUsd(t.model, t.usage), 0);\n }\n\n get aggregateCacheHitRatio(): number {\n let hit = this._carryoverCacheHit;\n let miss = this._carryoverCacheMiss;\n for (const t of this.turns) {\n hit += t.usage.promptCacheHitTokens;\n miss += t.usage.promptCacheMissTokens;\n }\n const denom = hit + miss;\n return denom > 0 ? hit / denom : 0;\n }\n\n summary(): SessionSummary {\n const last = this.turns[this.turns.length - 1];\n return {\n turns: this.turns.length + this._carryoverTurns,\n totalCostUsd: round(this.totalCost, 6),\n totalInputCostUsd: round(this.totalInputCost, 6),\n totalOutputCostUsd: round(this.totalOutputCost, 6),\n claudeEquivalentUsd: round(this.totalClaudeEquivalent, 6),\n savingsVsClaudePct: round(this.savingsVsClaude * 100, 2),\n cacheHitRatio: round(this.aggregateCacheHitRatio, 4),\n lastPromptTokens: last?.usage.promptTokens ?? this._carryoverLastPromptTokens,\n lastTurnCostUsd: round(last?.cost ?? 0, 6),\n };\n }\n}\n\nfunction round(n: number, digits: number): number {\n const f = 10 ** digits;\n return Math.round(n * f) / f;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
3
|
+
import {
|
|
4
|
+
chatCommand
|
|
5
|
+
} from "./chunk-Z4S7EYXG.js";
|
|
6
|
+
import "./chunk-TKVXTQ3T.js";
|
|
7
|
+
import "./chunk-JMBMLOBP.js";
|
|
8
|
+
import "./chunk-2V6EAEUW.js";
|
|
9
|
+
import {
|
|
10
|
+
buildCodeToolset
|
|
11
|
+
} from "./chunk-KGBG6M2X.js";
|
|
12
|
+
import "./chunk-HNXDZGC6.js";
|
|
13
|
+
import "./chunk-7UCMM425.js";
|
|
14
|
+
import "./chunk-NVURFF27.js";
|
|
15
|
+
import {
|
|
16
|
+
markPhase
|
|
17
|
+
} from "./chunk-ZZM6QJ4W.js";
|
|
18
|
+
import "./chunk-OPFUUYHL.js";
|
|
19
|
+
import "./chunk-WK3UFQY3.js";
|
|
20
|
+
import "./chunk-C53JQES5.js";
|
|
21
|
+
import "./chunk-XSU4QVFW.js";
|
|
22
|
+
import "./chunk-JNAQYELD.js";
|
|
23
|
+
import "./chunk-FEZK652I.js";
|
|
24
|
+
import "./chunk-MRHHQJAQ.js";
|
|
25
|
+
import "./chunk-AB2RED3C.js";
|
|
26
|
+
import "./chunk-X53B3JIX.js";
|
|
27
|
+
import {
|
|
28
|
+
resolvePreset
|
|
29
|
+
} from "./chunk-2425HK6U.js";
|
|
30
|
+
import "./chunk-KM465GST.js";
|
|
31
|
+
import "./chunk-5QCB62C4.js";
|
|
32
|
+
import "./chunk-6OWJV3YW.js";
|
|
33
|
+
import "./chunk-V26WPN3J.js";
|
|
34
|
+
import "./chunk-25T6CVUP.js";
|
|
35
|
+
import {
|
|
36
|
+
loadDotenv
|
|
37
|
+
} from "./chunk-2UQP6H6T.js";
|
|
38
|
+
import "./chunk-CWZKQ5FE.js";
|
|
39
|
+
import "./chunk-SZ5XES2N.js";
|
|
40
|
+
import "./chunk-KLQTAZIY.js";
|
|
41
|
+
import "./chunk-4QUNBQQ2.js";
|
|
42
|
+
import "./chunk-XJXDHAES.js";
|
|
43
|
+
import "./chunk-MJ6W5UN3.js";
|
|
44
|
+
import "./chunk-RDRC3XDT.js";
|
|
45
|
+
import {
|
|
46
|
+
detectForeignAgentPlatform
|
|
47
|
+
} from "./chunk-TEUDEGX2.js";
|
|
48
|
+
import "./chunk-PLHAZOLZ.js";
|
|
49
|
+
import "./chunk-LIR2HBQH.js";
|
|
50
|
+
import "./chunk-4CTDEJUF.js";
|
|
51
|
+
import "./chunk-7CIGMZT3.js";
|
|
52
|
+
import "./chunk-S4XVGLRW.js";
|
|
53
|
+
import {
|
|
54
|
+
sanitizeName
|
|
55
|
+
} from "./chunk-6PBZN4VI.js";
|
|
56
|
+
import "./chunk-R3CTO2HM.js";
|
|
57
|
+
import "./chunk-ZZYBBX5N.js";
|
|
58
|
+
import {
|
|
59
|
+
t
|
|
60
|
+
} from "./chunk-CGDR2ELH.js";
|
|
61
|
+
import {
|
|
62
|
+
loadApiKey,
|
|
63
|
+
loadPreset,
|
|
64
|
+
readConfig
|
|
65
|
+
} from "./chunk-AVFXO2EZ.js";
|
|
66
|
+
import "./chunk-XXC2BYTV.js";
|
|
67
|
+
import "./chunk-TUK7OWJA.js";
|
|
68
|
+
|
|
69
|
+
// src/cli/commands/code.tsx
|
|
70
|
+
import { readFileSync } from "fs";
|
|
71
|
+
import { basename, resolve } from "path";
|
|
72
|
+
async function codeCommand(opts = {}) {
|
|
73
|
+
markPhase("code_command_enter");
|
|
74
|
+
const resolvedModel = opts.model ?? resolvePreset(loadPreset()).model;
|
|
75
|
+
loadDotenv();
|
|
76
|
+
const cfgKey = loadApiKey();
|
|
77
|
+
if (cfgKey && !process.env.DEEPSEEK_API_KEY) {
|
|
78
|
+
process.env.DEEPSEEK_API_KEY = cfgKey;
|
|
79
|
+
}
|
|
80
|
+
const { codeSystemPrompt } = await import("./prompt-2D7ID24X.js");
|
|
81
|
+
const rootDir = resolve(opts.dir ?? process.cwd());
|
|
82
|
+
const session = opts.noSession ? void 0 : `code-${sanitizeName(basename(rootDir))}`;
|
|
83
|
+
markPhase("semantic_bootstrap_start");
|
|
84
|
+
const { tools, jobs, registerRooted, reBootstrapSemantic, semantic } = await buildCodeToolset({
|
|
85
|
+
rootDir
|
|
86
|
+
});
|
|
87
|
+
markPhase(
|
|
88
|
+
semantic.enabled ? "semantic_bootstrap_done_enabled" : "semantic_bootstrap_done_skipped"
|
|
89
|
+
);
|
|
90
|
+
process.stderr.write(
|
|
91
|
+
`${t("startup.codeRooted", {
|
|
92
|
+
rootDir,
|
|
93
|
+
session: session ?? t("startup.ephemeral"),
|
|
94
|
+
tools: tools.size,
|
|
95
|
+
semantic: semantic.enabled ? t("startup.semanticOn") : ""
|
|
96
|
+
})}
|
|
97
|
+
`
|
|
98
|
+
);
|
|
99
|
+
const foreign = detectForeignAgentPlatform(rootDir);
|
|
100
|
+
if (foreign) {
|
|
101
|
+
process.stderr.write(t("code.workspaceConflict", { platforms: foreign.join(", ") }));
|
|
102
|
+
}
|
|
103
|
+
process.once("exit", () => {
|
|
104
|
+
void jobs.shutdown();
|
|
105
|
+
});
|
|
106
|
+
let systemAppendFileContents;
|
|
107
|
+
if (opts.systemAppend !== void 0 && opts.systemAppend.trim().length === 0) {
|
|
108
|
+
process.stderr.write(t("code.systemAppendEmpty"));
|
|
109
|
+
}
|
|
110
|
+
if (opts.systemAppendFile) {
|
|
111
|
+
const filePath = resolve(opts.systemAppendFile);
|
|
112
|
+
try {
|
|
113
|
+
systemAppendFileContents = readFileSync(filePath, "utf8");
|
|
114
|
+
} catch (err) {
|
|
115
|
+
const e = err;
|
|
116
|
+
const errorDetails = e.code ? `[${e.code}] ${e.message}` : e.message;
|
|
117
|
+
process.stderr.write(t("code.systemAppendFileReadError", { filePath, errorDetails }));
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
let currentRoot = rootDir;
|
|
122
|
+
let semanticEnabled = semantic.enabled;
|
|
123
|
+
const codeRebuildSystem = () => codeSystemPrompt(currentRoot, {
|
|
124
|
+
hasSemanticSearch: semanticEnabled,
|
|
125
|
+
systemAppend: opts.systemAppend,
|
|
126
|
+
systemAppendFile: systemAppendFileContents,
|
|
127
|
+
modelId: resolvedModel
|
|
128
|
+
});
|
|
129
|
+
await chatCommand({
|
|
130
|
+
model: resolvedModel,
|
|
131
|
+
budgetUsd: opts.budgetUsd,
|
|
132
|
+
failureThreshold: opts.failureThreshold,
|
|
133
|
+
system: codeRebuildSystem(),
|
|
134
|
+
rebuildSystem: codeRebuildSystem,
|
|
135
|
+
transcript: opts.transcript,
|
|
136
|
+
session,
|
|
137
|
+
seedTools: tools,
|
|
138
|
+
codeMode: {
|
|
139
|
+
rootDir,
|
|
140
|
+
jobs,
|
|
141
|
+
reregisterTools: registerRooted,
|
|
142
|
+
reBootstrapSemantic: async (root) => {
|
|
143
|
+
const r = await reBootstrapSemantic(root);
|
|
144
|
+
semanticEnabled = r.enabled;
|
|
145
|
+
return r;
|
|
146
|
+
},
|
|
147
|
+
onRootChange: (newRoot) => {
|
|
148
|
+
currentRoot = newRoot;
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
mcp: readConfig().mcp,
|
|
152
|
+
forceResume: opts.forceResume,
|
|
153
|
+
forceNew: opts.forceNew,
|
|
154
|
+
noDashboard: opts.noDashboard,
|
|
155
|
+
openDashboard: opts.openDashboard,
|
|
156
|
+
dashboardPort: opts.dashboardPort,
|
|
157
|
+
dashboardHost: opts.dashboardHost,
|
|
158
|
+
dashboardToken: opts.dashboardToken,
|
|
159
|
+
altScreen: opts.altScreen,
|
|
160
|
+
mouse: opts.mouse
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
export {
|
|
164
|
+
codeCommand
|
|
165
|
+
};
|
|
166
|
+
//# sourceMappingURL=code-PSVJ3KEN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/code.tsx"],"sourcesContent":["/**\n * `reasonix code [dir]` — opinionated wrapper around `reasonix chat` for\n * code-editing workflows.\n *\n * What it does differently from plain chat:\n * - Registers native filesystem tools rooted at the given directory\n * (CWD by default). No subprocess, no `npx install` step, R1-\n * friendly schemas. Replaced the old `@modelcontextprotocol/server-filesystem`\n * subprocess in 0.4.9 because its `edit_file` argv shape was the\n * biggest driver of R1 DSML hallucinations.\n * - Uses a coding-focused system prompt (src/code/prompt.ts) that\n * teaches the model to propose edits as SEARCH/REPLACE blocks.\n * - Defaults to the `smart` preset (reasoner + harvest) because\n * coding tasks pay back R1 thinking.\n * - Scopes its session to the directory so projects don't share\n * conversation history.\n * - Hooks `codeMode` into the TUI so assistant replies get parsed\n * for SEARCH/REPLACE blocks and applied on disk after each turn.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { basename, resolve } from \"node:path\";\nimport { buildCodeToolset } from \"../../code/setup.js\";\nimport { loadApiKey, loadPreset, readConfig } from \"../../config.js\";\nimport { loadDotenv } from \"../../env.js\";\nimport { t } from \"../../i18n/index.js\";\nimport { detectForeignAgentPlatform } from \"../../memory/project.js\";\nimport { sanitizeName } from \"../../memory/session.js\";\nimport { markPhase } from \"../startup-profile.js\";\nimport { resolvePreset } from \"../ui/presets.js\";\nimport { chatCommand } from \"./chat.js\";\n\nexport interface CodeOptions {\n /** Directory to root the filesystem tools at. Defaults to process.cwd(). */\n dir?: string;\n /** Override the default `smart` model. */\n model?: string;\n /** Disable session persistence. */\n noSession?: boolean;\n /** Transcript file for replay/diff. */\n transcript?: string;\n /** Skip the session picker — always resume prior messages. */\n forceResume?: boolean;\n /** Skip the session picker — always wipe prior messages and start fresh. */\n forceNew?: boolean;\n /**\n * Soft USD spend cap. Off by default. Same semantics as `chat`:\n * warns at 80%, refuses next turn at 100%. Mid-session adjustable\n * via `/budget <usd>` slash command.\n */\n budgetUsd?: number;\n /** Per-turn repair-signal count required to escalate flash→pro. Undefined → loop default (3). */\n failureThreshold?: number;\n /** Suppress the auto-launched embedded web dashboard. */\n noDashboard?: boolean;\n /** When true and the dashboard is enabled, open its URL in the system default browser as soon as the server is ready. */\n openDashboard?: boolean;\n /** Pin the dashboard to a fixed port. `undefined` keeps ephemeral assignment. */\n dashboardPort?: number;\n /** Dashboard bind address (#968). `undefined` keeps the default 127.0.0.1. */\n dashboardHost?: string;\n /** Stable dashboard URL token (#968). `undefined` mints a fresh per-boot token. */\n dashboardToken?: string;\n /** Inline string appended to the code system prompt after the generated base prompt. */\n systemAppend?: string;\n /** Path to a UTF-8 text file whose contents are appended to the code system prompt. */\n systemAppendFile?: string;\n /** Default true. Pass false (CLI: `--no-alt-screen`) to keep chat output in shell scrollback. */\n altScreen?: boolean;\n /** Default true. Pass false (CLI: `--no-mouse`) to keep terminal-native drag-select unmodified. */\n mouse?: boolean;\n}\n\nexport async function codeCommand(opts: CodeOptions = {}): Promise<void> {\n markPhase(\"code_command_enter\");\n const resolvedModel = opts.model ?? resolvePreset(loadPreset()).model;\n // Bridge .env + ~/.reasonix/config.json into process.env so buildCodeToolset's\n // eager DeepSeekClient constructions (subagent client; semantic embedder) can\n // pick up a key the user already configured via `reasonix setup`. chatCommand\n // does the same dance — code.tsx wraps chatCommand but must also seed env\n // before buildCodeToolset runs, which is BEFORE chatCommand.\n loadDotenv();\n const cfgKey = loadApiKey();\n if (cfgKey && !process.env.DEEPSEEK_API_KEY) {\n process.env.DEEPSEEK_API_KEY = cfgKey;\n }\n const { codeSystemPrompt } = await import(\"../../code/prompt.js\");\n const rootDir = resolve(opts.dir ?? process.cwd());\n // Per-directory session so switching projects doesn't mix histories.\n // `code-<sanitized-basename>` fits the session name rules without\n // truncating most project names.\n const session = opts.noSession ? undefined : `code-${sanitizeName(basename(rootDir))}`;\n\n markPhase(\"semantic_bootstrap_start\");\n const { tools, jobs, registerRooted, reBootstrapSemantic, semantic } = await buildCodeToolset({\n rootDir,\n });\n markPhase(\n semantic.enabled ? \"semantic_bootstrap_done_enabled\" : \"semantic_bootstrap_done_skipped\",\n );\n\n process.stderr.write(\n `${t(\"startup.codeRooted\", {\n rootDir,\n session: session ?? t(\"startup.ephemeral\"),\n tools: tools.size,\n semantic: semantic.enabled ? t(\"startup.semanticOn\") : \"\",\n })}\\n`,\n );\n\n const foreign = detectForeignAgentPlatform(rootDir);\n if (foreign) {\n process.stderr.write(t(\"code.workspaceConflict\", { platforms: foreign.join(\", \") }));\n }\n\n // Belt-and-suspenders cleanup: even though spawn(detached:false)\n // should tie child processes to the parent's lifetime, Windows cmd.exe\n // wrappers occasionally leak. We DON'T install SIGINT/SIGTERM\n // handlers here — that overrode Node's default \"exit on Ctrl+C\" with\n // a silent no-op, which made Ctrl+C feel broken in the TUI. App.tsx\n // owns the SIGINT path now (it shows the quit-armed banner and calls\n // exit() on confirmation); this 'exit' hook just guarantees the job\n // registry is drained on the way out, regardless of which exit path\n // fired.\n process.once(\"exit\", () => {\n void jobs.shutdown();\n });\n\n let systemAppendFileContents: string | undefined;\n if (opts.systemAppend !== undefined && opts.systemAppend.trim().length === 0) {\n process.stderr.write(t(\"code.systemAppendEmpty\"));\n }\n if (opts.systemAppendFile) {\n const filePath = resolve(opts.systemAppendFile);\n try {\n systemAppendFileContents = readFileSync(filePath, \"utf8\");\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n const errorDetails = e.code ? `[${e.code}] ${e.message}` : e.message;\n process.stderr.write(t(\"code.systemAppendFileReadError\", { filePath, errorDetails }));\n process.exit(1);\n }\n }\n\n // The rebuilder is re-invoked on `/new` and `/cwd`. `currentRoot` is the live\n // pointer; `/cwd` updates it via `onRootChange` so the rebuild picks up the\n // new workspace's REASONIX.md / memory without restarting the loop.\n let currentRoot = rootDir;\n let semanticEnabled = semantic.enabled;\n const codeRebuildSystem = () =>\n codeSystemPrompt(currentRoot, {\n hasSemanticSearch: semanticEnabled,\n systemAppend: opts.systemAppend,\n systemAppendFile: systemAppendFileContents,\n modelId: resolvedModel,\n });\n await chatCommand({\n model: resolvedModel,\n budgetUsd: opts.budgetUsd,\n failureThreshold: opts.failureThreshold,\n system: codeRebuildSystem(),\n rebuildSystem: codeRebuildSystem,\n transcript: opts.transcript,\n session,\n seedTools: tools,\n codeMode: {\n rootDir,\n jobs,\n reregisterTools: registerRooted,\n reBootstrapSemantic: async (root: string) => {\n const r = await reBootstrapSemantic(root);\n semanticEnabled = r.enabled;\n return r;\n },\n onRootChange: (newRoot: string) => {\n currentRoot = newRoot;\n },\n },\n mcp: readConfig().mcp,\n forceResume: opts.forceResume,\n forceNew: opts.forceNew,\n noDashboard: opts.noDashboard,\n openDashboard: opts.openDashboard,\n dashboardPort: opts.dashboardPort,\n dashboardHost: opts.dashboardHost,\n dashboardToken: opts.dashboardToken,\n altScreen: opts.altScreen,\n mouse: opts.mouse,\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
2
3
|
import {
|
|
3
4
|
checkOllamaStatus,
|
|
4
5
|
pullOllamaModel,
|
|
5
6
|
startOllamaDaemon
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-LIR2HBQH.js";
|
|
7
8
|
import {
|
|
8
9
|
buildIndex
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-4CTDEJUF.js";
|
|
11
|
+
import "./chunk-S4XVGLRW.js";
|
|
11
12
|
import {
|
|
12
13
|
loadIndexConfig,
|
|
13
14
|
resolveSemanticEmbeddingConfig
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-AVFXO2EZ.js";
|
|
16
|
+
import "./chunk-TUK7OWJA.js";
|
|
15
17
|
|
|
16
18
|
// src/cli/commands/index.ts
|
|
17
19
|
import { resolve } from "path";
|
|
@@ -351,4 +353,4 @@ function makeTtyWriter() {
|
|
|
351
353
|
export {
|
|
352
354
|
indexCommand
|
|
353
355
|
};
|
|
354
|
-
//# sourceMappingURL=commands-
|
|
356
|
+
//# sourceMappingURL=commands-OCU42XG4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/index.ts","../../src/index/semantic/i18n.ts","../../src/index/semantic/preflight.ts"],"sourcesContent":["/** `reasonix index` — progress writes go to stderr so stdout stays pipeable. */\n\nimport { resolve } from \"node:path\";\nimport { loadIndexConfig, resolveSemanticEmbeddingConfig } from \"../../config.js\";\nimport { buildIndex } from \"../../index/semantic/builder.js\";\nimport type { BuildProgress, BuildResult, SkipBuckets } from \"../../index/semantic/builder.js\";\nimport { t } from \"../../index/semantic/i18n.js\";\nimport { semanticPreflight } from \"../../index/semantic/preflight.js\";\n\nexport interface IndexCommandOptions {\n rebuild?: boolean;\n model?: string;\n dir?: string;\n ollamaUrl?: string;\n yes?: boolean;\n}\n\nexport async function indexCommand(opts: IndexCommandOptions = {}): Promise<void> {\n const root = resolve(opts.dir ?? process.cwd());\n const tty = process.stderr.isTTY === true && process.stdin.isTTY === true;\n const resolved = resolveSemanticEmbeddingConfig();\n const embedding =\n resolved.provider === \"ollama\"\n ? {\n ...resolved,\n model: opts.model ?? resolved.model,\n baseUrl: opts.ollamaUrl ?? resolved.baseUrl,\n }\n : {\n ...resolved,\n model: opts.model ?? resolved.model,\n };\n\n const preflightOk = await semanticPreflight(embedding, {\n interactive: tty && !opts.yes,\n yesToAll: opts.yes ?? false,\n });\n if (!preflightOk) process.exit(1);\n\n const writer = makeProgressWriter(tty);\n\n const t0 = Date.now();\n let result: BuildResult;\n try {\n result = await buildIndex(root, {\n ...embedding,\n rebuild: opts.rebuild,\n indexConfig: loadIndexConfig(),\n onProgress: (p) => writer.update(p),\n });\n } catch (err) {\n writer.clear();\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(t(\"indexFailed\", { msg }));\n process.exit(1);\n }\n writer.clear();\n\n const seconds = ((Date.now() - t0) / 1000).toFixed(1);\n const successKey = result.chunksSkipped > 0 ? \"indexSuccessWithSkips\" : \"indexSuccess\";\n process.stderr.write(\n t(successKey, {\n scanned: result.filesScanned,\n changed: result.filesChanged,\n added: result.chunksAdded,\n removed: result.chunksRemoved,\n skipped: result.chunksSkipped,\n seconds,\n }),\n );\n const breakdown = renderSkipBreakdown(result.skipBuckets);\n if (breakdown) process.stderr.write(`${breakdown}\\n`);\n if (result.filesChanged === 0 && !opts.rebuild) {\n process.stderr.write(t(\"indexNothingToDo\"));\n }\n}\n\nfunction renderSkipBreakdown(buckets: SkipBuckets): string {\n const total = Object.values(buckets).reduce((a, b) => a + b, 0);\n if (total === 0) return \"\";\n const parts: string[] = [];\n if (buckets.gitignore) parts.push(`gitignore: ${buckets.gitignore}`);\n if (buckets.pattern) parts.push(`pattern: ${buckets.pattern}`);\n if (buckets.defaultDir) parts.push(`defaultDir: ${buckets.defaultDir}`);\n if (buckets.defaultFile) parts.push(`defaultFile: ${buckets.defaultFile}`);\n if (buckets.binaryExt) parts.push(`binaryExt: ${buckets.binaryExt}`);\n if (buckets.binaryContent) parts.push(`binaryContent: ${buckets.binaryContent}`);\n if (buckets.tooLarge) parts.push(`tooLarge: ${buckets.tooLarge}`);\n if (buckets.readError) parts.push(`readError: ${buckets.readError}`);\n return ` · skipped ${total} files (${parts.join(\", \")})`;\n}\n\ninterface ProgressWriter {\n update(p: BuildProgress): void;\n clear(): void;\n}\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst SPINNER_INTERVAL_MS = 120;\n\nfunction makeProgressWriter(tty: boolean): ProgressWriter {\n if (!tty) return makeNonTtyWriter();\n return makeTtyWriter();\n}\n\nfunction makeNonTtyWriter(): ProgressWriter {\n let lastPhase: BuildProgress[\"phase\"] | null = null;\n let lastChunks = 0;\n return {\n update(p) {\n if (p.phase !== lastPhase) {\n lastPhase = p.phase;\n if (p.phase === \"scan\") {\n process.stderr.write(t(\"progressScanLine\"));\n } else if (p.phase === \"embed\") {\n process.stderr.write(\n t(\"progressEmbedLine\", {\n total: p.chunksTotal ?? 0,\n files: p.filesChanged ?? 0,\n }),\n );\n }\n }\n if (p.phase === \"embed\" && p.chunksDone !== undefined && p.chunksDone - lastChunks >= 50) {\n lastChunks = p.chunksDone;\n process.stderr.write(\n t(\"progressEmbedHeartbeat\", {\n done: p.chunksDone,\n total: p.chunksTotal ?? \"?\",\n }),\n );\n }\n },\n clear() {\n /* non-TTY keeps its accumulated lines */\n },\n };\n}\n\nfunction makeTtyWriter(): ProgressWriter {\n let status = t(\"progressStarting\");\n let lastLineLen = 0;\n let frameIdx = 0;\n const startTs = Date.now();\n\n const repaint = () => {\n const frame = SPINNER_FRAMES[frameIdx % SPINNER_FRAMES.length];\n frameIdx++;\n const elapsed = ((Date.now() - startTs) / 1000).toFixed(1);\n const line = `${frame} ${status} ${elapsed}s`;\n const padded = line + \" \".repeat(Math.max(0, lastLineLen - line.length));\n process.stderr.write(`\\r${padded}`);\n lastLineLen = line.length;\n };\n\n repaint();\n const interval = setInterval(repaint, SPINNER_INTERVAL_MS);\n\n return {\n update(p) {\n if (p.phase === \"scan\") {\n status = t(\"progressScan\", { files: p.filesScanned ?? 0 });\n } else if (p.phase === \"embed\") {\n const done = p.chunksDone ?? 0;\n const total = p.chunksTotal ?? 0;\n const pct = total > 0 ? ((done / total) * 100).toFixed(0) : \"0\";\n status = t(\"progressEmbed\", { done, total, pct });\n }\n repaint();\n },\n clear() {\n clearInterval(interval);\n if (lastLineLen > 0) {\n process.stderr.write(`\\r${\" \".repeat(lastLineLen)}\\r`);\n lastLineLen = 0;\n }\n },\n };\n}\n","/** EN+ZH for semantic-search prompts only; tool descriptions stay English to preserve prompt-cache. */\n\nexport type Locale = \"en\" | \"zh\";\n\nlet cachedLocale: Locale | null = null;\n\nexport function detectLocale(): Locale {\n if (cachedLocale) return cachedLocale;\n const override = (process.env.REASONIX_LANG ?? \"\").toLowerCase();\n if (override === \"zh\" || override === \"en\") {\n cachedLocale = override;\n return cachedLocale;\n }\n const env = process.env.LANG ?? process.env.LC_ALL ?? process.env.LC_MESSAGES ?? \"\";\n if (/^zh[-_]/i.test(env)) {\n cachedLocale = \"zh\";\n return \"zh\";\n }\n try {\n const sys = new Intl.DateTimeFormat().resolvedOptions().locale ?? \"\";\n if (/^zh[-_]/i.test(sys)) {\n cachedLocale = \"zh\";\n return \"zh\";\n }\n } catch {\n /* ignore — fall through to default */\n }\n cachedLocale = \"en\";\n return \"en\";\n}\n\n/** Reset the cached locale. Tests use this; production never needs it. */\nexport function resetLocaleCache(): void {\n cachedLocale = null;\n}\n\n/** Falls back to English so partial dictionary updates never show \"[missing]\". */\nexport function t(key: keyof typeof EN, vars: Record<string, string | number> = {}): string {\n const loc = detectLocale();\n const dict = loc === \"zh\" ? ZH : EN;\n const tpl = dict[key] ?? EN[key];\n return tpl.replace(/\\{(\\w+)\\}/g, (_m, name) => {\n const v = vars[name];\n return v === undefined ? `{${name}}` : String(v);\n });\n}\n\nconst EN = {\n // ── preflight ─────────────────────────────────────────────────────\n ollamaNotFound:\n \"✗ `ollama` not found on PATH.\\n Install from https://ollama.com (one-time, ~150 MB), then retry.\\n\",\n daemonNotReachableHint:\n \"✗ Ollama daemon not reachable. Run `ollama serve` and retry, or pass --yes to start it automatically.\\n\",\n daemonStartConfirm: \"Ollama daemon isn't running. Start `ollama serve` now?\",\n daemonAbortStart: \"✗ aborted — start `ollama serve` yourself and retry.\\n\",\n daemonStarting: \"▸ starting `ollama serve`…\\n\",\n daemonStartTimeout:\n \"✗ daemon didn't come up within 15s. Try `ollama serve` in a separate terminal and retry.\\n\",\n daemonReady: \"✓ daemon up{pid}\\n\",\n modelNotPulledHint:\n '✗ embedding model \"{model}\" not pulled. Run `ollama pull {model}` and retry, or pass --yes to pull it automatically.\\n',\n modelPullConfirm:\n 'Embedding model \"{model}\" isn\\'t pulled yet. Pull it now? (~274 MB for nomic-embed-text)',\n modelAbortPull: \"✗ aborted — pull the model yourself and retry.\\n\",\n modelPulling: \"▸ pulling {model}…\\n\",\n modelPullFailed: \"✗ `ollama pull {model}` failed (exit {code}).\\n\",\n modelPulled: \"✓ {model} pulled\\n\",\n\n // ── progress ─────────────────────────────────────────────────────\n // The TTY-mode progress writer paints `<spinner> <status> <elapsed>s`\n // every 120ms. The status itself comes from one of these keys based\n // on the current phase. {files}, {done}, {total}, {pct} are\n // substituted by the writer.\n progressStarting: \"starting…\",\n progressScan: \"scanning project · {files} files\",\n progressEmbed: \"embedding {done}/{total} chunks · {pct}%\",\n progressEmbedHeartbeat: \" {done}/{total}\\n\",\n progressScanLine: \"scanning files…\\n\",\n progressEmbedLine: \"embedding {total} chunks across {files} files…\\n\",\n // Final result line after a successful build.\n indexSuccess:\n \"✓ indexed {scanned} files ({changed} changed, {added} new chunks, {removed} stale removed) in {seconds}s\\n\",\n indexSuccessWithSkips:\n \"✓ indexed {scanned} files ({changed} changed, {added} new chunks, {removed} stale removed, {skipped} skipped due to embed errors) in {seconds}s\\n\",\n indexNothingToDo: \" (nothing to do — re-run with --rebuild to force a full rebuild)\\n\",\n indexFailed: \"✗ index failed: {msg}\\n\",\n\n // ── /semantic slash ──────────────────────────────────────────────\n slashHeader: \"semantic_search status\",\n slashEnabled: \"✓ enabled — index built, tool registered.\",\n slashEnabledDetail: \" index size: {chunks} chunks across {files} files\",\n slashEnabledHowto: \" the model will call semantic_search automatically when it fits.\",\n slashIndexMissing: \"✗ no index built yet for this project.\",\n slashHowToBuild: \" to enable, exit Reasonix and run in your shell:\\n reasonix index\",\n slashOllamaMissing: \" prerequisite: install Ollama from https://ollama.com\",\n slashDaemonDown:\n \" Ollama is installed but the daemon isn't running. start it with: ollama serve\",\n slashIndexInfo:\n \" what semantic_search does: cross-language code understanding via local embeddings.\\n better than grep when you describe WHAT something does, not WHICH token to find.\",\n} as const;\n\nconst ZH: Partial<Record<keyof typeof EN, string>> = {\n ollamaNotFound:\n \"✗ 未找到 `ollama`。\\n 请访问 https://ollama.com 安装(一次性,约 150 MB),然后重试。\\n\",\n daemonNotReachableHint:\n \"✗ Ollama 守护进程未启动。请运行 `ollama serve` 后重试,或加 --yes 让我自动启动。\\n\",\n daemonStartConfirm: \"Ollama 守护进程未运行。现在启动 `ollama serve` 吗?\",\n daemonAbortStart: \"✗ 已取消——请自行运行 `ollama serve` 后重试。\\n\",\n daemonStarting: \"▸ 正在启动 `ollama serve`…\\n\",\n daemonStartTimeout: \"✗ 15 秒内守护进程未就绪。请在另一个终端运行 `ollama serve` 后重试。\\n\",\n daemonReady: \"✓ 守护进程已启动{pid}\\n\",\n modelNotPulledHint:\n '✗ 嵌入模型 \"{model}\" 未下载。请运行 `ollama pull {model}` 后重试,或加 --yes 让我自动下载。\\n',\n modelPullConfirm: '嵌入模型 \"{model}\" 还未下载。现在下载吗?(nomic-embed-text 约 274 MB)',\n modelAbortPull: \"✗ 已取消——请自行下载模型后重试。\\n\",\n modelPulling: \"▸ 正在下载 {model}…\\n\",\n modelPullFailed: \"✗ `ollama pull {model}` 失败(退出码 {code})。\\n\",\n modelPulled: \"✓ {model} 下载完成\\n\",\n\n progressStarting: \"正在启动…\",\n progressScan: \"扫描项目 · 已扫描 {files} 个文件\",\n progressEmbed: \"正在向量化 {done}/{total} 个片段 · {pct}%\",\n progressEmbedHeartbeat: \" {done}/{total}\\n\",\n progressScanLine: \"正在扫描文件…\\n\",\n progressEmbedLine: \"正在向量化 {total} 个片段(涉及 {files} 个文件)…\\n\",\n indexSuccess:\n \"✓ 已建立索引:扫描 {scanned} 个文件({changed} 个有变化,新增 {added} 个片段,移除 {removed} 个过期);耗时 {seconds}s\\n\",\n indexSuccessWithSkips:\n \"✓ 已建立索引:扫描 {scanned} 个文件({changed} 个有变化,新增 {added} 个片段,移除 {removed} 个过期,跳过 {skipped} 个嵌入失败的片段);耗时 {seconds}s\\n\",\n indexNothingToDo: \" (没有变化——加 --rebuild 强制重建)\\n\",\n indexFailed: \"✗ 建立索引失败:{msg}\\n\",\n\n slashHeader: \"semantic_search 状态\",\n slashEnabled: \"✓ 已启用——索引已建好,工具已注册。\",\n slashEnabledDetail: \" 索引规模:{chunks} 个片段,{files} 个文件\",\n slashEnabledHowto: \" 模型在合适的时候会自动调用 semantic_search。\",\n slashIndexMissing: \"✗ 当前项目还没有索引。\",\n slashHowToBuild: \" 启用方式:退出 Reasonix,在终端运行:\\n reasonix index\",\n slashOllamaMissing: \" 前置依赖:从 https://ollama.com 安装 Ollama\",\n slashDaemonDown: \" 已装 Ollama 但守护进程未启动,请运行:ollama serve\",\n slashIndexInfo:\n ' semantic_search 用本地 embedding 做跨语言代码理解。\\n 当你描述\"做什么\"而不是具体 token 时,比 grep 更好。',\n};\n","import { stdin, stdout } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\nimport type { ResolvedEmbeddingConfig } from \"../../config.js\";\nimport { t } from \"./i18n.js\";\nimport { checkOllamaStatus, pullOllamaModel, startOllamaDaemon } from \"./ollama-launcher.js\";\n\nexport interface PreflightOptions {\n model: string;\n baseUrl?: string | undefined;\n interactive: boolean;\n yesToAll: boolean;\n log?: (line: string) => void;\n}\n\nexport async function ollamaPreflight(opts: PreflightOptions): Promise<boolean> {\n const log = opts.log ?? ((line: string) => process.stderr.write(line));\n const status = await checkOllamaStatus(opts.model, opts.baseUrl);\n\n if (!status.binaryFound) {\n log(t(\"ollamaNotFound\"));\n return false;\n }\n\n if (!status.daemonRunning) {\n if (!opts.interactive && !opts.yesToAll) {\n log(t(\"daemonNotReachableHint\"));\n return false;\n }\n const ok = opts.yesToAll || (await confirm(t(\"daemonStartConfirm\"), true));\n if (!ok) {\n log(t(\"daemonAbortStart\"));\n return false;\n }\n log(t(\"daemonStarting\"));\n const started = await startOllamaDaemon({ baseUrl: opts.baseUrl, timeoutMs: 15_000 });\n if (!started.ready) {\n log(t(\"daemonStartTimeout\"));\n return false;\n }\n log(t(\"daemonReady\", { pid: started.pid ? ` (pid ${started.pid})` : \"\" }));\n }\n\n const after = status.daemonRunning ? status : await checkOllamaStatus(opts.model, opts.baseUrl);\n\n if (!after.modelPulled) {\n if (!opts.interactive && !opts.yesToAll) {\n log(t(\"modelNotPulledHint\", { model: opts.model }));\n return false;\n }\n const ok = opts.yesToAll || (await confirm(t(\"modelPullConfirm\", { model: opts.model }), true));\n if (!ok) {\n log(t(\"modelAbortPull\"));\n return false;\n }\n log(t(\"modelPulling\", { model: opts.model }));\n const ESC = String.fromCharCode(0x1b);\n const ANSI_CSI = new RegExp(`${ESC}\\\\[[0-9;]*[A-Za-z]`, \"g\");\n const code = await pullOllamaModel(opts.model, {\n onLine: (line) => {\n const cleaned = line.replace(ANSI_CSI, \"\").trim();\n if (cleaned.length === 0) return;\n log(` ${cleaned}\\n`);\n },\n });\n if (code !== 0) {\n log(t(\"modelPullFailed\", { model: opts.model, code }));\n return false;\n }\n log(t(\"modelPulled\", { model: opts.model }));\n }\n\n return true;\n}\n\nexport async function semanticPreflight(\n config: ResolvedEmbeddingConfig,\n opts: Omit<PreflightOptions, \"model\" | \"baseUrl\">,\n): Promise<boolean> {\n if (config.provider === \"openai-compat\") return true;\n return await ollamaPreflight({\n ...opts,\n model: config.model,\n baseUrl: config.baseUrl,\n });\n}\n\nexport async function confirm(question: string, defaultYes: boolean): Promise<boolean> {\n const suffix = defaultYes ? \"[Y/n]\" : \"[y/N]\";\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n const raw = (await rl.question(`${question} ${suffix} `)).trim().toLowerCase();\n if (raw === \"\") return defaultYes;\n return raw === \"y\" || raw === \"yes\";\n } finally {\n rl.close();\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/index.ts","../../src/index/semantic/i18n.ts","../../src/index/semantic/preflight.ts"],"sourcesContent":["/** `reasonix index` — progress writes go to stderr so stdout stays pipeable. */\n\nimport { resolve } from \"node:path\";\nimport { loadIndexConfig, resolveSemanticEmbeddingConfig } from \"../../config.js\";\nimport { buildIndex } from \"../../index/semantic/builder.js\";\nimport type { BuildProgress, BuildResult, SkipBuckets } from \"../../index/semantic/builder.js\";\nimport { t } from \"../../index/semantic/i18n.js\";\nimport { semanticPreflight } from \"../../index/semantic/preflight.js\";\n\nexport interface IndexCommandOptions {\n rebuild?: boolean;\n model?: string;\n dir?: string;\n ollamaUrl?: string;\n yes?: boolean;\n}\n\nexport async function indexCommand(opts: IndexCommandOptions = {}): Promise<void> {\n const root = resolve(opts.dir ?? process.cwd());\n const tty = process.stderr.isTTY === true && process.stdin.isTTY === true;\n const resolved = resolveSemanticEmbeddingConfig();\n const embedding =\n resolved.provider === \"ollama\"\n ? {\n ...resolved,\n model: opts.model ?? resolved.model,\n baseUrl: opts.ollamaUrl ?? resolved.baseUrl,\n }\n : {\n ...resolved,\n model: opts.model ?? resolved.model,\n };\n\n const preflightOk = await semanticPreflight(embedding, {\n interactive: tty && !opts.yes,\n yesToAll: opts.yes ?? false,\n });\n if (!preflightOk) process.exit(1);\n\n const writer = makeProgressWriter(tty);\n\n const t0 = Date.now();\n let result: BuildResult;\n try {\n result = await buildIndex(root, {\n ...embedding,\n rebuild: opts.rebuild,\n indexConfig: loadIndexConfig(),\n onProgress: (p) => writer.update(p),\n });\n } catch (err) {\n writer.clear();\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(t(\"indexFailed\", { msg }));\n process.exit(1);\n }\n writer.clear();\n\n const seconds = ((Date.now() - t0) / 1000).toFixed(1);\n const successKey = result.chunksSkipped > 0 ? \"indexSuccessWithSkips\" : \"indexSuccess\";\n process.stderr.write(\n t(successKey, {\n scanned: result.filesScanned,\n changed: result.filesChanged,\n added: result.chunksAdded,\n removed: result.chunksRemoved,\n skipped: result.chunksSkipped,\n seconds,\n }),\n );\n const breakdown = renderSkipBreakdown(result.skipBuckets);\n if (breakdown) process.stderr.write(`${breakdown}\\n`);\n if (result.filesChanged === 0 && !opts.rebuild) {\n process.stderr.write(t(\"indexNothingToDo\"));\n }\n}\n\nfunction renderSkipBreakdown(buckets: SkipBuckets): string {\n const total = Object.values(buckets).reduce((a, b) => a + b, 0);\n if (total === 0) return \"\";\n const parts: string[] = [];\n if (buckets.gitignore) parts.push(`gitignore: ${buckets.gitignore}`);\n if (buckets.pattern) parts.push(`pattern: ${buckets.pattern}`);\n if (buckets.defaultDir) parts.push(`defaultDir: ${buckets.defaultDir}`);\n if (buckets.defaultFile) parts.push(`defaultFile: ${buckets.defaultFile}`);\n if (buckets.binaryExt) parts.push(`binaryExt: ${buckets.binaryExt}`);\n if (buckets.binaryContent) parts.push(`binaryContent: ${buckets.binaryContent}`);\n if (buckets.tooLarge) parts.push(`tooLarge: ${buckets.tooLarge}`);\n if (buckets.readError) parts.push(`readError: ${buckets.readError}`);\n return ` · skipped ${total} files (${parts.join(\", \")})`;\n}\n\ninterface ProgressWriter {\n update(p: BuildProgress): void;\n clear(): void;\n}\n\nconst SPINNER_FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst SPINNER_INTERVAL_MS = 120;\n\nfunction makeProgressWriter(tty: boolean): ProgressWriter {\n if (!tty) return makeNonTtyWriter();\n return makeTtyWriter();\n}\n\nfunction makeNonTtyWriter(): ProgressWriter {\n let lastPhase: BuildProgress[\"phase\"] | null = null;\n let lastChunks = 0;\n return {\n update(p) {\n if (p.phase !== lastPhase) {\n lastPhase = p.phase;\n if (p.phase === \"scan\") {\n process.stderr.write(t(\"progressScanLine\"));\n } else if (p.phase === \"embed\") {\n process.stderr.write(\n t(\"progressEmbedLine\", {\n total: p.chunksTotal ?? 0,\n files: p.filesChanged ?? 0,\n }),\n );\n }\n }\n if (p.phase === \"embed\" && p.chunksDone !== undefined && p.chunksDone - lastChunks >= 50) {\n lastChunks = p.chunksDone;\n process.stderr.write(\n t(\"progressEmbedHeartbeat\", {\n done: p.chunksDone,\n total: p.chunksTotal ?? \"?\",\n }),\n );\n }\n },\n clear() {\n /* non-TTY keeps its accumulated lines */\n },\n };\n}\n\nfunction makeTtyWriter(): ProgressWriter {\n let status = t(\"progressStarting\");\n let lastLineLen = 0;\n let frameIdx = 0;\n const startTs = Date.now();\n\n const repaint = () => {\n const frame = SPINNER_FRAMES[frameIdx % SPINNER_FRAMES.length];\n frameIdx++;\n const elapsed = ((Date.now() - startTs) / 1000).toFixed(1);\n const line = `${frame} ${status} ${elapsed}s`;\n const padded = line + \" \".repeat(Math.max(0, lastLineLen - line.length));\n process.stderr.write(`\\r${padded}`);\n lastLineLen = line.length;\n };\n\n repaint();\n const interval = setInterval(repaint, SPINNER_INTERVAL_MS);\n\n return {\n update(p) {\n if (p.phase === \"scan\") {\n status = t(\"progressScan\", { files: p.filesScanned ?? 0 });\n } else if (p.phase === \"embed\") {\n const done = p.chunksDone ?? 0;\n const total = p.chunksTotal ?? 0;\n const pct = total > 0 ? ((done / total) * 100).toFixed(0) : \"0\";\n status = t(\"progressEmbed\", { done, total, pct });\n }\n repaint();\n },\n clear() {\n clearInterval(interval);\n if (lastLineLen > 0) {\n process.stderr.write(`\\r${\" \".repeat(lastLineLen)}\\r`);\n lastLineLen = 0;\n }\n },\n };\n}\n","/** EN+ZH for semantic-search prompts only; tool descriptions stay English to preserve prompt-cache. */\n\nexport type Locale = \"en\" | \"zh\";\n\nlet cachedLocale: Locale | null = null;\n\nexport function detectLocale(): Locale {\n if (cachedLocale) return cachedLocale;\n const override = (process.env.REASONIX_LANG ?? \"\").toLowerCase();\n if (override === \"zh\" || override === \"en\") {\n cachedLocale = override;\n return cachedLocale;\n }\n const env = process.env.LANG ?? process.env.LC_ALL ?? process.env.LC_MESSAGES ?? \"\";\n if (/^zh[-_]/i.test(env)) {\n cachedLocale = \"zh\";\n return \"zh\";\n }\n try {\n const sys = new Intl.DateTimeFormat().resolvedOptions().locale ?? \"\";\n if (/^zh[-_]/i.test(sys)) {\n cachedLocale = \"zh\";\n return \"zh\";\n }\n } catch {\n /* ignore — fall through to default */\n }\n cachedLocale = \"en\";\n return \"en\";\n}\n\n/** Reset the cached locale. Tests use this; production never needs it. */\nexport function resetLocaleCache(): void {\n cachedLocale = null;\n}\n\n/** Falls back to English so partial dictionary updates never show \"[missing]\". */\nexport function t(key: keyof typeof EN, vars: Record<string, string | number> = {}): string {\n const loc = detectLocale();\n const dict = loc === \"zh\" ? ZH : EN;\n const tpl = dict[key] ?? EN[key];\n return tpl.replace(/\\{(\\w+)\\}/g, (_m, name) => {\n const v = vars[name];\n return v === undefined ? `{${name}}` : String(v);\n });\n}\n\nconst EN = {\n // ── preflight ─────────────────────────────────────────────────────\n ollamaNotFound:\n \"✗ `ollama` not found on PATH.\\n Install from https://ollama.com (one-time, ~150 MB), then retry.\\n\",\n daemonNotReachableHint:\n \"✗ Ollama daemon not reachable. Run `ollama serve` and retry, or pass --yes to start it automatically.\\n\",\n daemonStartConfirm: \"Ollama daemon isn't running. Start `ollama serve` now?\",\n daemonAbortStart: \"✗ aborted — start `ollama serve` yourself and retry.\\n\",\n daemonStarting: \"▸ starting `ollama serve`…\\n\",\n daemonStartTimeout:\n \"✗ daemon didn't come up within 15s. Try `ollama serve` in a separate terminal and retry.\\n\",\n daemonReady: \"✓ daemon up{pid}\\n\",\n modelNotPulledHint:\n '✗ embedding model \"{model}\" not pulled. Run `ollama pull {model}` and retry, or pass --yes to pull it automatically.\\n',\n modelPullConfirm:\n 'Embedding model \"{model}\" isn\\'t pulled yet. Pull it now? (~274 MB for nomic-embed-text)',\n modelAbortPull: \"✗ aborted — pull the model yourself and retry.\\n\",\n modelPulling: \"▸ pulling {model}…\\n\",\n modelPullFailed: \"✗ `ollama pull {model}` failed (exit {code}).\\n\",\n modelPulled: \"✓ {model} pulled\\n\",\n\n // ── progress ─────────────────────────────────────────────────────\n // The TTY-mode progress writer paints `<spinner> <status> <elapsed>s`\n // every 120ms. The status itself comes from one of these keys based\n // on the current phase. {files}, {done}, {total}, {pct} are\n // substituted by the writer.\n progressStarting: \"starting…\",\n progressScan: \"scanning project · {files} files\",\n progressEmbed: \"embedding {done}/{total} chunks · {pct}%\",\n progressEmbedHeartbeat: \" {done}/{total}\\n\",\n progressScanLine: \"scanning files…\\n\",\n progressEmbedLine: \"embedding {total} chunks across {files} files…\\n\",\n // Final result line after a successful build.\n indexSuccess:\n \"✓ indexed {scanned} files ({changed} changed, {added} new chunks, {removed} stale removed) in {seconds}s\\n\",\n indexSuccessWithSkips:\n \"✓ indexed {scanned} files ({changed} changed, {added} new chunks, {removed} stale removed, {skipped} skipped due to embed errors) in {seconds}s\\n\",\n indexNothingToDo: \" (nothing to do — re-run with --rebuild to force a full rebuild)\\n\",\n indexFailed: \"✗ index failed: {msg}\\n\",\n\n // ── /semantic slash ──────────────────────────────────────────────\n slashHeader: \"semantic_search status\",\n slashEnabled: \"✓ enabled — index built, tool registered.\",\n slashEnabledDetail: \" index size: {chunks} chunks across {files} files\",\n slashEnabledHowto: \" the model will call semantic_search automatically when it fits.\",\n slashIndexMissing: \"✗ no index built yet for this project.\",\n slashHowToBuild: \" to enable, exit Reasonix and run in your shell:\\n reasonix index\",\n slashOllamaMissing: \" prerequisite: install Ollama from https://ollama.com\",\n slashDaemonDown:\n \" Ollama is installed but the daemon isn't running. start it with: ollama serve\",\n slashIndexInfo:\n \" what semantic_search does: cross-language code understanding via local embeddings.\\n better than grep when you describe WHAT something does, not WHICH token to find.\",\n} as const;\n\nconst ZH: Partial<Record<keyof typeof EN, string>> = {\n ollamaNotFound:\n \"✗ 未找到 `ollama`。\\n 请访问 https://ollama.com 安装(一次性,约 150 MB),然后重试。\\n\",\n daemonNotReachableHint:\n \"✗ Ollama 守护进程未启动。请运行 `ollama serve` 后重试,或加 --yes 让我自动启动。\\n\",\n daemonStartConfirm: \"Ollama 守护进程未运行。现在启动 `ollama serve` 吗?\",\n daemonAbortStart: \"✗ 已取消——请自行运行 `ollama serve` 后重试。\\n\",\n daemonStarting: \"▸ 正在启动 `ollama serve`…\\n\",\n daemonStartTimeout: \"✗ 15 秒内守护进程未就绪。请在另一个终端运行 `ollama serve` 后重试。\\n\",\n daemonReady: \"✓ 守护进程已启动{pid}\\n\",\n modelNotPulledHint:\n '✗ 嵌入模型 \"{model}\" 未下载。请运行 `ollama pull {model}` 后重试,或加 --yes 让我自动下载。\\n',\n modelPullConfirm: '嵌入模型 \"{model}\" 还未下载。现在下载吗?(nomic-embed-text 约 274 MB)',\n modelAbortPull: \"✗ 已取消——请自行下载模型后重试。\\n\",\n modelPulling: \"▸ 正在下载 {model}…\\n\",\n modelPullFailed: \"✗ `ollama pull {model}` 失败(退出码 {code})。\\n\",\n modelPulled: \"✓ {model} 下载完成\\n\",\n\n progressStarting: \"正在启动…\",\n progressScan: \"扫描项目 · 已扫描 {files} 个文件\",\n progressEmbed: \"正在向量化 {done}/{total} 个片段 · {pct}%\",\n progressEmbedHeartbeat: \" {done}/{total}\\n\",\n progressScanLine: \"正在扫描文件…\\n\",\n progressEmbedLine: \"正在向量化 {total} 个片段(涉及 {files} 个文件)…\\n\",\n indexSuccess:\n \"✓ 已建立索引:扫描 {scanned} 个文件({changed} 个有变化,新增 {added} 个片段,移除 {removed} 个过期);耗时 {seconds}s\\n\",\n indexSuccessWithSkips:\n \"✓ 已建立索引:扫描 {scanned} 个文件({changed} 个有变化,新增 {added} 个片段,移除 {removed} 个过期,跳过 {skipped} 个嵌入失败的片段);耗时 {seconds}s\\n\",\n indexNothingToDo: \" (没有变化——加 --rebuild 强制重建)\\n\",\n indexFailed: \"✗ 建立索引失败:{msg}\\n\",\n\n slashHeader: \"semantic_search 状态\",\n slashEnabled: \"✓ 已启用——索引已建好,工具已注册。\",\n slashEnabledDetail: \" 索引规模:{chunks} 个片段,{files} 个文件\",\n slashEnabledHowto: \" 模型在合适的时候会自动调用 semantic_search。\",\n slashIndexMissing: \"✗ 当前项目还没有索引。\",\n slashHowToBuild: \" 启用方式:退出 Reasonix,在终端运行:\\n reasonix index\",\n slashOllamaMissing: \" 前置依赖:从 https://ollama.com 安装 Ollama\",\n slashDaemonDown: \" 已装 Ollama 但守护进程未启动,请运行:ollama serve\",\n slashIndexInfo:\n ' semantic_search 用本地 embedding 做跨语言代码理解。\\n 当你描述\"做什么\"而不是具体 token 时,比 grep 更好。',\n};\n","import { stdin, stdout } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\nimport type { ResolvedEmbeddingConfig } from \"../../config.js\";\nimport { t } from \"./i18n.js\";\nimport { checkOllamaStatus, pullOllamaModel, startOllamaDaemon } from \"./ollama-launcher.js\";\n\nexport interface PreflightOptions {\n model: string;\n baseUrl?: string | undefined;\n interactive: boolean;\n yesToAll: boolean;\n log?: (line: string) => void;\n}\n\nexport async function ollamaPreflight(opts: PreflightOptions): Promise<boolean> {\n const log = opts.log ?? ((line: string) => process.stderr.write(line));\n const status = await checkOllamaStatus(opts.model, opts.baseUrl);\n\n if (!status.binaryFound) {\n log(t(\"ollamaNotFound\"));\n return false;\n }\n\n if (!status.daemonRunning) {\n if (!opts.interactive && !opts.yesToAll) {\n log(t(\"daemonNotReachableHint\"));\n return false;\n }\n const ok = opts.yesToAll || (await confirm(t(\"daemonStartConfirm\"), true));\n if (!ok) {\n log(t(\"daemonAbortStart\"));\n return false;\n }\n log(t(\"daemonStarting\"));\n const started = await startOllamaDaemon({ baseUrl: opts.baseUrl, timeoutMs: 15_000 });\n if (!started.ready) {\n log(t(\"daemonStartTimeout\"));\n return false;\n }\n log(t(\"daemonReady\", { pid: started.pid ? ` (pid ${started.pid})` : \"\" }));\n }\n\n const after = status.daemonRunning ? status : await checkOllamaStatus(opts.model, opts.baseUrl);\n\n if (!after.modelPulled) {\n if (!opts.interactive && !opts.yesToAll) {\n log(t(\"modelNotPulledHint\", { model: opts.model }));\n return false;\n }\n const ok = opts.yesToAll || (await confirm(t(\"modelPullConfirm\", { model: opts.model }), true));\n if (!ok) {\n log(t(\"modelAbortPull\"));\n return false;\n }\n log(t(\"modelPulling\", { model: opts.model }));\n const ESC = String.fromCharCode(0x1b);\n const ANSI_CSI = new RegExp(`${ESC}\\\\[[0-9;]*[A-Za-z]`, \"g\");\n const code = await pullOllamaModel(opts.model, {\n onLine: (line) => {\n const cleaned = line.replace(ANSI_CSI, \"\").trim();\n if (cleaned.length === 0) return;\n log(` ${cleaned}\\n`);\n },\n });\n if (code !== 0) {\n log(t(\"modelPullFailed\", { model: opts.model, code }));\n return false;\n }\n log(t(\"modelPulled\", { model: opts.model }));\n }\n\n return true;\n}\n\nexport async function semanticPreflight(\n config: ResolvedEmbeddingConfig,\n opts: Omit<PreflightOptions, \"model\" | \"baseUrl\">,\n): Promise<boolean> {\n if (config.provider === \"openai-compat\") return true;\n return await ollamaPreflight({\n ...opts,\n model: config.model,\n baseUrl: config.baseUrl,\n });\n}\n\nexport async function confirm(question: string, defaultYes: boolean): Promise<boolean> {\n const suffix = defaultYes ? \"[Y/n]\" : \"[y/N]\";\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n const raw = (await rl.question(`${question} ${suffix} `)).trim().toLowerCase();\n if (raw === \"\") return defaultYes;\n return raw === \"y\" || raw === \"yes\";\n } finally {\n rl.close();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
2
3
|
import {
|
|
3
4
|
DeepSeekClient
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-V26WPN3J.js";
|
|
6
|
+
import "./chunk-25T6CVUP.js";
|
|
5
7
|
import {
|
|
6
8
|
loadDotenv
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2UQP6H6T.js";
|
|
8
10
|
import {
|
|
9
11
|
loadApiKey,
|
|
10
12
|
loadBaseUrl
|
|
11
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-AVFXO2EZ.js";
|
|
14
|
+
import "./chunk-TUK7OWJA.js";
|
|
12
15
|
|
|
13
16
|
// src/cli/commands/commit.ts
|
|
14
17
|
import { spawn, spawnSync } from "child_process";
|
|
@@ -286,4 +289,4 @@ async function commitCommand(opts = {}) {
|
|
|
286
289
|
export {
|
|
287
290
|
commitCommand
|
|
288
291
|
};
|
|
289
|
-
//# sourceMappingURL=commit-
|
|
292
|
+
//# sourceMappingURL=commit-XCQIQCYG.js.map
|