@deepwhale/coding-agent 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/modes/tui.d.ts +0 -5
- package/dist/modes/tui.d.ts.map +1 -1
- package/dist/modes/tui.js +4 -57
- package/dist/modes/tui.js.map +1 -1
- package/dist/repl/repl-command-router.d.ts +78 -0
- package/dist/repl/repl-command-router.d.ts.map +1 -0
- package/dist/repl/repl-command-router.js +112 -0
- package/dist/repl/repl-command-router.js.map +1 -0
- package/dist/repl/repl-session.d.ts +79 -0
- package/dist/repl/repl-session.d.ts.map +1 -0
- package/dist/repl/repl-session.js +129 -0
- package/dist/repl/repl-session.js.map +1 -0
- package/dist/repl/repl-signal-coordinator.d.ts +74 -0
- package/dist/repl/repl-signal-coordinator.d.ts.map +1 -0
- package/dist/repl/repl-signal-coordinator.js +73 -0
- package/dist/repl/repl-signal-coordinator.js.map +1 -0
- package/dist/repl.d.ts +3 -40
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +59 -213
- package/dist/repl.js.map +1 -1
- package/dist/tui-ink-bundle.js +78 -595
- package/package.json +1 -1
package/dist/tui-ink-bundle.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @deepwhale/tui-ink — D-24 full Ink TUI container. Self-contained ESM bundle.
|
|
3
|
-
// Built 2026-06-
|
|
3
|
+
// Built 2026-06-07T13:49:23.172Z
|
|
4
4
|
import { createRequire as __cr } from 'node:module';
|
|
5
5
|
import { fileURLToPath as __fpath } from 'node:url';
|
|
6
6
|
const require = __cr(__fpath(import.meta.url));
|
|
@@ -37641,7 +37641,7 @@ var import_react32 = __toESM(require_react(), 1);
|
|
|
37641
37641
|
var import_react33 = __toESM(require_react(), 1);
|
|
37642
37642
|
|
|
37643
37643
|
// src/app.tsx
|
|
37644
|
-
var
|
|
37644
|
+
var import_react43 = __toESM(require_react(), 1);
|
|
37645
37645
|
|
|
37646
37646
|
// src/theme/index.ts
|
|
37647
37647
|
import { stderr } from "node:process";
|
|
@@ -37875,16 +37875,6 @@ function sealLastAssistant() {
|
|
|
37875
37875
|
$transcript.set([...entries.slice(0, -1), { ...last, streaming: false }]);
|
|
37876
37876
|
}
|
|
37877
37877
|
}
|
|
37878
|
-
function appendReasoningChunk(delta) {
|
|
37879
|
-
const entries = $transcript.get();
|
|
37880
|
-
const last = entries[entries.length - 1];
|
|
37881
|
-
if (last && last.kind === "assistant") {
|
|
37882
|
-
const newReasoning = (last.reasoning ?? "") + delta;
|
|
37883
|
-
$transcript.set([...entries.slice(0, -1), { ...last, reasoning: newReasoning }]);
|
|
37884
|
-
} else {
|
|
37885
|
-
$transcript.set([...entries, { kind: "assistant", text: "", reasoning: delta }]);
|
|
37886
|
-
}
|
|
37887
|
-
}
|
|
37888
37878
|
|
|
37889
37879
|
// src/components/StatusBar.tsx
|
|
37890
37880
|
import { formatUsageStatus } from "@deepwhale/coding-agent";
|
|
@@ -37915,297 +37905,38 @@ function StatusBar({ theme = THEMES.default, usage: usageOverride }) {
|
|
|
37915
37905
|
] });
|
|
37916
37906
|
}
|
|
37917
37907
|
|
|
37918
|
-
// src/components/Markdown.tsx
|
|
37919
|
-
var import_react37 = __toESM(require_react(), 1);
|
|
37920
|
-
|
|
37921
|
-
// src/markdown/render.tsx
|
|
37922
|
-
var import_react36 = __toESM(require_react(), 1);
|
|
37923
|
-
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
37924
|
-
var INLINE_RE = /(?:\[([^\]]+)\]\(([^)\s]+)\)|`([^`]+)`|\*\*([^*]+)\*\*|\*([^*]+)\*|~~([^~]+)~~)/g;
|
|
37925
|
-
var MEDIA_LINE_RE = /^\s*[`"']?MEDIA:\s*(\S+?)[`"']?\s*$/;
|
|
37926
|
-
var AUDIO_DIRECTIVE_RE = /^\s*\[\[audio_as_voice\]\]\s*$/;
|
|
37927
|
-
var FENCE_RE = /^(\s*)(`{3,}|~{3,})(.*)$/;
|
|
37928
|
-
var HEADING_RE = /^(#{1,6})\s+(.*)$/;
|
|
37929
|
-
var LIST_RE = /^(\s*)([-*+])\s+(.*)$/;
|
|
37930
|
-
var OLIST_RE = /^(\s*)(\d+)\.\s+(.*)$/;
|
|
37931
|
-
var BLOCKQUOTE_RE = /^>\s+(.*)$/;
|
|
37932
|
-
var HR_RE = /^[-*_]{3,}$/;
|
|
37933
|
-
function renderInline(line, theme, keyBase) {
|
|
37934
|
-
const out = [];
|
|
37935
|
-
let lastIdx = 0;
|
|
37936
|
-
let m;
|
|
37937
|
-
let counter = 0;
|
|
37938
|
-
INLINE_RE.lastIndex = 0;
|
|
37939
|
-
while ((m = INLINE_RE.exec(line)) !== null) {
|
|
37940
|
-
if (m.index > lastIdx) {
|
|
37941
|
-
out.push(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react36.Fragment, { children: line.slice(lastIdx, m.index) }, `${keyBase}-t-${counter++}`));
|
|
37942
|
-
}
|
|
37943
|
-
if (m[1] !== void 0 && m[2] !== void 0) {
|
|
37944
|
-
out.push(
|
|
37945
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: theme.toolName, underline: true, children: [
|
|
37946
|
-
m[1],
|
|
37947
|
-
" (",
|
|
37948
|
-
m[2],
|
|
37949
|
-
")"
|
|
37950
|
-
] }, `${keyBase}-l-${counter++}`)
|
|
37951
|
-
);
|
|
37952
|
-
} else if (m[3] !== void 0) {
|
|
37953
|
-
out.push(
|
|
37954
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.model, children: `\`${m[3]}\`` }, `${keyBase}-c-${counter++}`)
|
|
37955
|
-
);
|
|
37956
|
-
} else if (m[4] !== void 0) {
|
|
37957
|
-
out.push(
|
|
37958
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: true, children: m[4] }, `${keyBase}-b-${counter++}`)
|
|
37959
|
-
);
|
|
37960
|
-
} else if (m[5] !== void 0) {
|
|
37961
|
-
out.push(
|
|
37962
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { italic: true, children: m[5] }, `${keyBase}-i-${counter++}`)
|
|
37963
|
-
);
|
|
37964
|
-
} else if (m[6] !== void 0) {
|
|
37965
|
-
out.push(
|
|
37966
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { strikethrough: true, children: m[6] }, `${keyBase}-s-${counter++}`)
|
|
37967
|
-
);
|
|
37968
|
-
}
|
|
37969
|
-
lastIdx = m.index + m[0].length;
|
|
37970
|
-
}
|
|
37971
|
-
if (lastIdx < line.length) {
|
|
37972
|
-
out.push(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react36.Fragment, { children: line.slice(lastIdx) }, `${keyBase}-t-${counter++}`));
|
|
37973
|
-
}
|
|
37974
|
-
return out.length > 0 ? out : [/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react36.Fragment, { children: line }, `${keyBase}-raw`)];
|
|
37975
|
-
}
|
|
37976
|
-
function renderFence(content, lang, keyBase, theme) {
|
|
37977
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", borderColor: theme.divider, paddingX: 1, marginY: 0, children: [
|
|
37978
|
-
lang && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.model, dimColor: true, children: lang }, `${keyBase}-lang`),
|
|
37979
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: content }, `${keyBase}-body`)
|
|
37980
|
-
] }, keyBase);
|
|
37981
|
-
}
|
|
37982
|
-
function tryParseFence(lines, startLine) {
|
|
37983
|
-
const firstLine = lines[startLine];
|
|
37984
|
-
const m = firstLine.match(FENCE_RE);
|
|
37985
|
-
if (!m) return null;
|
|
37986
|
-
const fenceChar = m[2][0];
|
|
37987
|
-
const fenceLen = m[2].length;
|
|
37988
|
-
const lang = m[3].trim();
|
|
37989
|
-
const bodyLines = [];
|
|
37990
|
-
let i = startLine + 1;
|
|
37991
|
-
while (i < lines.length) {
|
|
37992
|
-
const line = lines[i];
|
|
37993
|
-
const closeMatch = line.match(new RegExp(`^\\s*\\${fenceChar}{${fenceLen},}\\s*$`));
|
|
37994
|
-
if (closeMatch) {
|
|
37995
|
-
return {
|
|
37996
|
-
type: "fence",
|
|
37997
|
-
lang,
|
|
37998
|
-
body: bodyLines.join("\n"),
|
|
37999
|
-
endLine: i
|
|
38000
|
-
};
|
|
38001
|
-
}
|
|
38002
|
-
bodyLines.push(line.replace(/^ {0,3}/, ""));
|
|
38003
|
-
i++;
|
|
38004
|
-
}
|
|
38005
|
-
return null;
|
|
38006
|
-
}
|
|
38007
|
-
function tryParseTable(lines, startLine) {
|
|
38008
|
-
const line0 = lines[startLine];
|
|
38009
|
-
const line1 = lines[startLine + 1];
|
|
38010
|
-
if (!line1) return null;
|
|
38011
|
-
if (!line0.includes("|") || !line1.includes("|")) return null;
|
|
38012
|
-
const cells1 = line1.split("|").map((c) => c.trim()).filter((c) => c.length > 0);
|
|
38013
|
-
if (cells1.length < 2) return null;
|
|
38014
|
-
if (!cells1.every((c) => /^:?-+:?\s*$/.test(c))) return null;
|
|
38015
|
-
const header = line0.split("|").map((c) => c.trim()).filter((c) => c.length > 0);
|
|
38016
|
-
if (header.length !== cells1.length) return null;
|
|
38017
|
-
const rows = [];
|
|
38018
|
-
let i = startLine + 2;
|
|
38019
|
-
while (i < lines.length) {
|
|
38020
|
-
const line = lines[i];
|
|
38021
|
-
if (!line.includes("|")) break;
|
|
38022
|
-
const row = line.split("|").map((c) => c.trim()).filter((c) => c.length > 0);
|
|
38023
|
-
rows.push(row);
|
|
38024
|
-
i++;
|
|
38025
|
-
}
|
|
38026
|
-
return { type: "table", header, rows, endLine: i - 1 };
|
|
38027
|
-
}
|
|
38028
|
-
function renderMarkdown(text, theme) {
|
|
38029
|
-
const lines = text.split("\n");
|
|
38030
|
-
const out = [];
|
|
38031
|
-
let i = 0;
|
|
38032
|
-
let blockCounter = 0;
|
|
38033
|
-
while (i < lines.length) {
|
|
38034
|
-
const line = lines[i];
|
|
38035
|
-
const blockKey = `md-${blockCounter++}`;
|
|
38036
|
-
if (MEDIA_LINE_RE.test(line)) {
|
|
38037
|
-
const path = line.match(MEDIA_LINE_RE)[1];
|
|
38038
|
-
out.push(
|
|
38039
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.toolName, children: `[image: ${path}]` }, blockKey)
|
|
38040
|
-
);
|
|
38041
|
-
i++;
|
|
38042
|
-
continue;
|
|
38043
|
-
}
|
|
38044
|
-
if (AUDIO_DIRECTIVE_RE.test(line)) {
|
|
38045
|
-
out.push(
|
|
38046
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.model, children: "\u{1F50A} audio: (TTS pending \u2014 D-28+ \u5347\u7EA7 mmx-cli TTS)" }, blockKey)
|
|
38047
|
-
);
|
|
38048
|
-
i++;
|
|
38049
|
-
continue;
|
|
38050
|
-
}
|
|
38051
|
-
const fence = tryParseFence(lines, i);
|
|
38052
|
-
if (fence) {
|
|
38053
|
-
out.push(renderFence(fence.body, fence.lang, blockKey, theme));
|
|
38054
|
-
i = fence.endLine + 1;
|
|
38055
|
-
continue;
|
|
38056
|
-
}
|
|
38057
|
-
const table = tryParseTable(lines, i);
|
|
38058
|
-
if (table) {
|
|
38059
|
-
out.push(
|
|
38060
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", marginY: 0, children: [
|
|
38061
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { children: table.header.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: true, color: theme.header, children: ` ${cell.padEnd(15)} ` }, `${blockKey}-h-${idx}`)) }, `${blockKey}-hr`),
|
|
38062
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.divider, children: "\u2500".repeat(15 * table.header.length + 3) }, `${blockKey}-hr-sep`),
|
|
38063
|
-
table.rows.map((row, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { children: row.map((cell, cellIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: ` ${cell.padEnd(15)} ` }, `${blockKey}-r-${rowIdx}-c-${cellIdx}`)) }, `${blockKey}-r-${rowIdx}`))
|
|
38064
|
-
] }, blockKey)
|
|
38065
|
-
);
|
|
38066
|
-
i = table.endLine + 1;
|
|
38067
|
-
continue;
|
|
38068
|
-
}
|
|
38069
|
-
const headingMatch = line.match(HEADING_RE);
|
|
38070
|
-
if (headingMatch) {
|
|
38071
|
-
const level = headingMatch[1].length;
|
|
38072
|
-
const text2 = headingMatch[2];
|
|
38073
|
-
out.push(
|
|
38074
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: true, color: theme.header, children: "#".repeat(level) + " " + text2 }, blockKey)
|
|
38075
|
-
);
|
|
38076
|
-
i++;
|
|
38077
|
-
continue;
|
|
38078
|
-
}
|
|
38079
|
-
if (HR_RE.test(line)) {
|
|
38080
|
-
out.push(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.divider, children: "\u2500".repeat(40) }, blockKey));
|
|
38081
|
-
i++;
|
|
38082
|
-
continue;
|
|
38083
|
-
}
|
|
38084
|
-
const listMatch = line.match(LIST_RE);
|
|
38085
|
-
if (listMatch) {
|
|
38086
|
-
out.push(
|
|
38087
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: ` ${listMatch[1]}\u2022 ${listMatch[3]}` }, blockKey)
|
|
38088
|
-
);
|
|
38089
|
-
i++;
|
|
38090
|
-
continue;
|
|
38091
|
-
}
|
|
38092
|
-
const olistMatch = line.match(OLIST_RE);
|
|
38093
|
-
if (olistMatch) {
|
|
38094
|
-
out.push(
|
|
38095
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: ` ${olistMatch[1]}${olistMatch[2]}. ${olistMatch[3]}` }, blockKey)
|
|
38096
|
-
);
|
|
38097
|
-
i++;
|
|
38098
|
-
continue;
|
|
38099
|
-
}
|
|
38100
|
-
const bqMatch = line.match(BLOCKQUOTE_RE);
|
|
38101
|
-
if (bqMatch) {
|
|
38102
|
-
out.push(
|
|
38103
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: theme.divider, children: `\u2502 ${bqMatch[1]}` }, blockKey)
|
|
38104
|
-
);
|
|
38105
|
-
i++;
|
|
38106
|
-
continue;
|
|
38107
|
-
}
|
|
38108
|
-
if (line.trim().length > 0) {
|
|
38109
|
-
out.push(
|
|
38110
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: renderInline(line, theme, blockKey) }, blockKey)
|
|
38111
|
-
);
|
|
38112
|
-
} else {
|
|
38113
|
-
out.push(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: " " }, blockKey));
|
|
38114
|
-
}
|
|
38115
|
-
i++;
|
|
38116
|
-
}
|
|
38117
|
-
return out;
|
|
38118
|
-
}
|
|
38119
|
-
|
|
38120
|
-
// src/components/Markdown.tsx
|
|
38121
|
-
var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
|
|
38122
|
-
function Markdown({ text, theme, inline = false }) {
|
|
38123
|
-
const nodes = renderMarkdown(text, theme);
|
|
38124
|
-
if (inline) {
|
|
38125
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: nodes.map((node, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react37.Fragment, { children: node }, `md-inline-${i}`)) });
|
|
38126
|
-
}
|
|
38127
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { flexDirection: "column", children: nodes });
|
|
38128
|
-
}
|
|
38129
|
-
|
|
38130
|
-
// src/components/Thinking.tsx
|
|
38131
|
-
var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
|
|
38132
|
-
function Thinking({
|
|
38133
|
-
reasoning,
|
|
38134
|
-
theme,
|
|
38135
|
-
initialState = "collapsed"
|
|
38136
|
-
}) {
|
|
38137
|
-
if (!reasoning || reasoning.length === 0) return null;
|
|
38138
|
-
if (initialState === "hidden") return null;
|
|
38139
|
-
if (initialState === "collapsed") {
|
|
38140
|
-
const preview = reasoning.slice(0, 60).replace(/\n/g, " ");
|
|
38141
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
|
|
38142
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: colorize2("\u{1F4AD} ", "model", theme) }),
|
|
38143
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, children: [
|
|
38144
|
-
preview,
|
|
38145
|
-
reasoning.length > 60 ? "..." : ""
|
|
38146
|
-
] }),
|
|
38147
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: colorize2(" (press to expand)", "divider", theme) })
|
|
38148
|
-
] });
|
|
38149
|
-
}
|
|
38150
|
-
const lines = reasoning.split("\n");
|
|
38151
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: theme.divider, paddingX: 1, marginY: 0, children: [
|
|
38152
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
|
|
38153
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: colorize2("\u{1F4AD} thinking", "model", theme) }),
|
|
38154
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: colorize2(" (press to collapse)", "divider", theme) })
|
|
38155
|
-
] }),
|
|
38156
|
-
lines.map((line, idx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: line }, `think-${idx}`))
|
|
38157
|
-
] });
|
|
38158
|
-
}
|
|
38159
|
-
|
|
38160
37908
|
// src/components/Transcript.tsx
|
|
38161
|
-
var
|
|
38162
|
-
function Transcript({ theme = THEMES.default
|
|
37909
|
+
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
37910
|
+
function Transcript({ theme = THEMES.default }) {
|
|
38163
37911
|
const entries = useStore($transcript);
|
|
38164
37912
|
const lastStreaming = entries[entries.length - 1];
|
|
38165
37913
|
const isLastStreaming = lastStreaming?.kind === "assistant" && lastStreaming.streaming === true;
|
|
38166
37914
|
const sealedEntries = isLastStreaming ? entries.slice(0, -1) : entries;
|
|
38167
|
-
return /* @__PURE__ */ (0,
|
|
38168
|
-
/* @__PURE__ */ (0,
|
|
38169
|
-
isLastStreaming && lastStreaming ? /* @__PURE__ */ (0,
|
|
37915
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
37916
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Static, { items: sealedEntries, children: (entry, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TranscriptRow, { entry, theme }, `entry-${index}`) }),
|
|
37917
|
+
isLastStreaming && lastStreaming ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TranscriptRow, { entry: lastStreaming, theme }) : null
|
|
38170
37918
|
] });
|
|
38171
37919
|
}
|
|
38172
|
-
function TranscriptRow({
|
|
38173
|
-
entry,
|
|
38174
|
-
theme,
|
|
38175
|
-
markdown,
|
|
38176
|
-
thinking
|
|
38177
|
-
}) {
|
|
37920
|
+
function TranscriptRow({ entry, theme }) {
|
|
38178
37921
|
switch (entry.kind) {
|
|
38179
37922
|
case "user":
|
|
38180
|
-
return /* @__PURE__ */ (0,
|
|
37923
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
|
|
38181
37924
|
colorize2("\u203A ", "prompt", theme),
|
|
38182
37925
|
entry.text
|
|
38183
37926
|
] });
|
|
38184
37927
|
case "assistant": {
|
|
38185
37928
|
const prefix = colorize2(" ", "model", theme);
|
|
38186
|
-
|
|
38187
|
-
|
|
38188
|
-
|
|
38189
|
-
|
|
38190
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Markdown, { text: entry.text, theme, inline: true })
|
|
38191
|
-
] }),
|
|
38192
|
-
entry.streaming ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: colorize2("\u258C", "prompt", theme) }) : null
|
|
38193
|
-
] });
|
|
38194
|
-
}
|
|
38195
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
38196
|
-
thinking && entry.reasoning ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Thinking, { reasoning: entry.reasoning, theme }) : null,
|
|
38197
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { children: [
|
|
38198
|
-
prefix,
|
|
38199
|
-
entry.text,
|
|
38200
|
-
entry.streaming ? colorize2("\u258C", "prompt", theme) : ""
|
|
38201
|
-
] })
|
|
37929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
|
|
37930
|
+
prefix,
|
|
37931
|
+
entry.text,
|
|
37932
|
+
entry.streaming ? colorize2("\u258C", "prompt", theme) : ""
|
|
38202
37933
|
] });
|
|
38203
37934
|
}
|
|
38204
37935
|
case "tool": {
|
|
38205
37936
|
const statusGlyph = entry.status === "success" ? "\u2713" : "\u2717";
|
|
38206
37937
|
const statusColor = entry.status === "success" ? "success" : "error";
|
|
38207
37938
|
const nameColor = colorize2(entry.toolName ?? "tool", "toolName", theme);
|
|
38208
|
-
return /* @__PURE__ */ (0,
|
|
37939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
|
|
38209
37940
|
" ",
|
|
38210
37941
|
colorize2(statusGlyph, statusColor, theme),
|
|
38211
37942
|
" ",
|
|
@@ -38219,17 +37950,17 @@ function TranscriptRow({
|
|
|
38219
37950
|
}
|
|
38220
37951
|
|
|
38221
37952
|
// src/components/Prompt.tsx
|
|
38222
|
-
var
|
|
37953
|
+
var import_react38 = __toESM(require_react(), 1);
|
|
38223
37954
|
|
|
38224
37955
|
// ../../node_modules/.pnpm/ink-text-input@6.0.0_ink@7._2a39186227fe1d31183ab83244021d5b/node_modules/ink-text-input/build/index.js
|
|
38225
|
-
var
|
|
37956
|
+
var import_react37 = __toESM(require_react(), 1);
|
|
38226
37957
|
function TextInput({ value: originalValue, placeholder = "", focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit }) {
|
|
38227
|
-
const [state, setState] = (0,
|
|
37958
|
+
const [state, setState] = (0, import_react37.useState)({
|
|
38228
37959
|
cursorOffset: (originalValue || "").length,
|
|
38229
37960
|
cursorWidth: 0
|
|
38230
37961
|
});
|
|
38231
37962
|
const { cursorOffset, cursorWidth } = state;
|
|
38232
|
-
(0,
|
|
37963
|
+
(0, import_react37.useEffect)(() => {
|
|
38233
37964
|
setState((previousState) => {
|
|
38234
37965
|
if (!focus || !showCursor) {
|
|
38235
37966
|
return previousState;
|
|
@@ -38307,12 +38038,12 @@ function TextInput({ value: originalValue, placeholder = "", focus = true, mask,
|
|
|
38307
38038
|
onChange(nextValue);
|
|
38308
38039
|
}
|
|
38309
38040
|
}, { isActive: focus });
|
|
38310
|
-
return
|
|
38041
|
+
return import_react37.default.createElement(Text, null, placeholder ? value.length > 0 ? renderedValue : renderedPlaceholder : renderedValue);
|
|
38311
38042
|
}
|
|
38312
38043
|
var build_default = TextInput;
|
|
38313
38044
|
|
|
38314
38045
|
// src/components/Prompt.tsx
|
|
38315
|
-
var
|
|
38046
|
+
var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
|
|
38316
38047
|
function Prompt({
|
|
38317
38048
|
theme = THEMES.default,
|
|
38318
38049
|
history,
|
|
@@ -38320,8 +38051,8 @@ function Prompt({
|
|
|
38320
38051
|
placeholder = "\u203A message (\\ to continue, empty \\ to cancel)",
|
|
38321
38052
|
disabled = false
|
|
38322
38053
|
}) {
|
|
38323
|
-
const [cont, setCont] = (0,
|
|
38324
|
-
const [value, setValue] = (0,
|
|
38054
|
+
const [cont, setCont] = (0, import_react38.useState)(null);
|
|
38055
|
+
const [value, setValue] = (0, import_react38.useState)("");
|
|
38325
38056
|
const handleSubmit = (line) => {
|
|
38326
38057
|
if (line.endsWith("\\\\")) {
|
|
38327
38058
|
const unescaped = line.slice(0, -1) + "\\\\";
|
|
@@ -38349,12 +38080,12 @@ ${line}` : line;
|
|
|
38349
38080
|
setValue("");
|
|
38350
38081
|
};
|
|
38351
38082
|
if (disabled) {
|
|
38352
|
-
return /* @__PURE__ */ (0,
|
|
38083
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: theme.divider, children: "(turn in flight, Ctrl+C to abort)" }) });
|
|
38353
38084
|
}
|
|
38354
38085
|
const prefix = cont ? colorize2(`... (${cont.lineNo + 1}) > `, "prompt", theme) : colorize2("\u203A ", "prompt", theme);
|
|
38355
|
-
return /* @__PURE__ */ (0,
|
|
38356
|
-
/* @__PURE__ */ (0,
|
|
38357
|
-
/* @__PURE__ */ (0,
|
|
38086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { children: [
|
|
38087
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: prefix }),
|
|
38088
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
38358
38089
|
build_default,
|
|
38359
38090
|
{
|
|
38360
38091
|
value,
|
|
@@ -38368,16 +38099,16 @@ ${line}` : line;
|
|
|
38368
38099
|
}
|
|
38369
38100
|
|
|
38370
38101
|
// src/components/Confirm.tsx
|
|
38371
|
-
var
|
|
38102
|
+
var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
|
|
38372
38103
|
function Confirm({ theme = THEMES.default, controller }) {
|
|
38373
38104
|
const ui = useStore($uiState);
|
|
38374
38105
|
if (!ui.pendingConfirm) return null;
|
|
38375
|
-
return /* @__PURE__ */ (0,
|
|
38376
|
-
/* @__PURE__ */ (0,
|
|
38106
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
38107
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { children: [
|
|
38377
38108
|
colorize2(" ? ", "prompt", theme),
|
|
38378
38109
|
colorize2(ui.pendingConfirm.prompt, "prompt", theme)
|
|
38379
38110
|
] }),
|
|
38380
|
-
/* @__PURE__ */ (0,
|
|
38111
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: theme.divider, children: [
|
|
38381
38112
|
" ",
|
|
38382
38113
|
"y/N: ",
|
|
38383
38114
|
controller.hasPending() ? "(waiting for input)" : ""
|
|
@@ -38386,7 +38117,7 @@ function Confirm({ theme = THEMES.default, controller }) {
|
|
|
38386
38117
|
}
|
|
38387
38118
|
|
|
38388
38119
|
// src/hooks/useHistory.ts
|
|
38389
|
-
var
|
|
38120
|
+
var import_react40 = __toESM(require_react(), 1);
|
|
38390
38121
|
|
|
38391
38122
|
// src/history/index.ts
|
|
38392
38123
|
import {
|
|
@@ -38399,8 +38130,8 @@ import {
|
|
|
38399
38130
|
|
|
38400
38131
|
// src/hooks/useHistory.ts
|
|
38401
38132
|
function useHistory() {
|
|
38402
|
-
const [history, setHistory] = (0,
|
|
38403
|
-
const append = (0,
|
|
38133
|
+
const [history, setHistory] = (0, import_react40.useState)(() => tuiHistoryLoad());
|
|
38134
|
+
const append = (0, import_react40.useCallback)((line) => {
|
|
38404
38135
|
if (!line || !line.trim()) return;
|
|
38405
38136
|
tuiHistoryAppend(line);
|
|
38406
38137
|
setHistory((prev) => {
|
|
@@ -38413,15 +38144,15 @@ function useHistory() {
|
|
|
38413
38144
|
}
|
|
38414
38145
|
|
|
38415
38146
|
// src/hooks/useAbortController.ts
|
|
38416
|
-
var
|
|
38147
|
+
var import_react41 = __toESM(require_react(), 1);
|
|
38417
38148
|
function useAbortController(onSigint) {
|
|
38418
|
-
const ref = (0,
|
|
38419
|
-
const abort = (0,
|
|
38149
|
+
const ref = (0, import_react41.useRef)(new AbortController());
|
|
38150
|
+
const abort = (0, import_react41.useCallback)(() => {
|
|
38420
38151
|
if (!ref.current.signal.aborted) {
|
|
38421
38152
|
ref.current.abort();
|
|
38422
38153
|
}
|
|
38423
38154
|
}, []);
|
|
38424
|
-
const reset = (0,
|
|
38155
|
+
const reset = (0, import_react41.useCallback)(() => {
|
|
38425
38156
|
if (!ref.current.signal.aborted) {
|
|
38426
38157
|
console.warn("[tui-ink] useAbortController.reset called without prior abort()");
|
|
38427
38158
|
}
|
|
@@ -38433,7 +38164,7 @@ function useAbortController(onSigint) {
|
|
|
38433
38164
|
onSigint();
|
|
38434
38165
|
}
|
|
38435
38166
|
});
|
|
38436
|
-
(0,
|
|
38167
|
+
(0, import_react41.useEffect)(() => {
|
|
38437
38168
|
const handler = () => {
|
|
38438
38169
|
abort();
|
|
38439
38170
|
};
|
|
@@ -38446,7 +38177,7 @@ function useAbortController(onSigint) {
|
|
|
38446
38177
|
}
|
|
38447
38178
|
|
|
38448
38179
|
// src/hooks/useRunToolLoop.ts
|
|
38449
|
-
var
|
|
38180
|
+
var import_react42 = __toESM(require_react(), 1);
|
|
38450
38181
|
import {
|
|
38451
38182
|
runToolLoop,
|
|
38452
38183
|
persistToolLoopSteps,
|
|
@@ -38493,7 +38224,7 @@ function collectRanges(text, re, role, out) {
|
|
|
38493
38224
|
|
|
38494
38225
|
// src/hooks/useRunToolLoop.ts
|
|
38495
38226
|
function useRunToolLoop(args) {
|
|
38496
|
-
const runTurn = (0,
|
|
38227
|
+
const runTurn = (0, import_react42.useCallback)(
|
|
38497
38228
|
async (userPrompt) => {
|
|
38498
38229
|
const { options, theme, signal, writer, client, registry, workingMessages } = args;
|
|
38499
38230
|
const modelName = options.model ?? client.model ?? "model";
|
|
@@ -38514,9 +38245,6 @@ function useRunToolLoop(args) {
|
|
|
38514
38245
|
const colored = highlightChunk(chunk.content, theme, true);
|
|
38515
38246
|
appendToLastAssistant(colored);
|
|
38516
38247
|
}
|
|
38517
|
-
if (chunk.reasoning_content) {
|
|
38518
|
-
appendReasoningChunk(chunk.reasoning_content);
|
|
38519
|
-
}
|
|
38520
38248
|
},
|
|
38521
38249
|
maxSteps: options.maxSteps ?? 5,
|
|
38522
38250
|
policy: resolvedPolicy,
|
|
@@ -38566,235 +38294,8 @@ function useRunToolLoop(args) {
|
|
|
38566
38294
|
return { runTurn };
|
|
38567
38295
|
}
|
|
38568
38296
|
|
|
38569
|
-
// src/hooks/useSubmission.ts
|
|
38570
|
-
var import_react45 = __toESM(require_react(), 1);
|
|
38571
|
-
|
|
38572
|
-
// src/commands/core.ts
|
|
38573
|
-
var HELP_LINES = [
|
|
38574
|
-
["/help", "list 9 commands"],
|
|
38575
|
-
["/exit (q/quit)", "exit TUI"],
|
|
38576
|
-
["/clear", "clear transcript (no session close)"],
|
|
38577
|
-
["/verify", "run verify (build/lint/typecheck/test)"],
|
|
38578
|
-
["/status", "show model + session path + usage"],
|
|
38579
|
-
["/model <name>", "switch model"],
|
|
38580
|
-
["/resume", "list session paths (D-28 picker)"],
|
|
38581
|
-
["/personality <name>", "switch system prompt personality"],
|
|
38582
|
-
["/heapdump (mem)", "V8 heap snapshot + memory diagnostics"]
|
|
38583
|
-
];
|
|
38584
|
-
var coreCommands = [
|
|
38585
|
-
{
|
|
38586
|
-
name: "help",
|
|
38587
|
-
help: "list 9 commands + hotkeys",
|
|
38588
|
-
category: "core",
|
|
38589
|
-
run: (_arg, ctx) => {
|
|
38590
|
-
const lines = HELP_LINES.map(([cmd, desc]) => ` ${cmd.padEnd(24)} ${desc}`);
|
|
38591
|
-
const helpText = [
|
|
38592
|
-
" /help \u2014 9 commands",
|
|
38593
|
-
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
38594
|
-
...lines,
|
|
38595
|
-
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
38596
|
-
" (slash registry \u4E2D\u592E\u5316, \u8DDF Hermes ui-tui 1:1)"
|
|
38597
|
-
].join("\n");
|
|
38598
|
-
ctx.pushEntry({ kind: "assistant", text: `
|
|
38599
|
-
${helpText}
|
|
38600
|
-
` });
|
|
38601
|
-
}
|
|
38602
|
-
},
|
|
38603
|
-
{
|
|
38604
|
-
name: "exit",
|
|
38605
|
-
aliases: ["q", "quit"],
|
|
38606
|
-
help: "exit TUI (writer.close \u8D70 D-19.5 finish \u8DEF\u5F84)",
|
|
38607
|
-
category: "core",
|
|
38608
|
-
run: (_arg, ctx) => {
|
|
38609
|
-
ctx.exit({ exitCode: 0, reason: "user-exit" });
|
|
38610
|
-
}
|
|
38611
|
-
},
|
|
38612
|
-
{
|
|
38613
|
-
name: "clear",
|
|
38614
|
-
help: "clear transcript (0 \u5173 session, 0 \u5199 session event)",
|
|
38615
|
-
category: "core",
|
|
38616
|
-
run: (_arg, ctx) => {
|
|
38617
|
-
ctx.clearTranscript();
|
|
38618
|
-
ctx.pushEntry({ kind: "assistant", text: "\n transcript cleared\n" });
|
|
38619
|
-
}
|
|
38620
|
-
},
|
|
38621
|
-
{
|
|
38622
|
-
name: "verify",
|
|
38623
|
-
help: "run verify (build/lint/typecheck/test)",
|
|
38624
|
-
category: "core",
|
|
38625
|
-
run: async (_arg, ctx) => {
|
|
38626
|
-
const { runVerify } = await import("@deepwhale/coding-agent");
|
|
38627
|
-
ctx.pushEntry({ kind: "assistant", text: "\n /verify running...\n" });
|
|
38628
|
-
try {
|
|
38629
|
-
const report = await runVerify();
|
|
38630
|
-
const status = report.overallStatus;
|
|
38631
|
-
const summary = `
|
|
38632
|
-
/verify done: ${status} (${report.checks.length} checks)
|
|
38633
|
-
`;
|
|
38634
|
-
ctx.pushEntry({ kind: "assistant", text: summary });
|
|
38635
|
-
} catch (e) {
|
|
38636
|
-
const err = e instanceof Error ? e.message : String(e);
|
|
38637
|
-
ctx.pushEntry({ kind: "assistant", text: `
|
|
38638
|
-
/verify error: ${err}
|
|
38639
|
-
` });
|
|
38640
|
-
}
|
|
38641
|
-
}
|
|
38642
|
-
},
|
|
38643
|
-
{
|
|
38644
|
-
name: "status",
|
|
38645
|
-
help: "show model + session path + usage",
|
|
38646
|
-
category: "core",
|
|
38647
|
-
run: (_arg, ctx) => {
|
|
38648
|
-
const usage = ctx.ui.usage;
|
|
38649
|
-
const usageStr = usage ? `${usage.prompt_tokens ?? 0} prompt / ${usage.completion_tokens ?? 0} completion / ${usage.total_tokens ?? 0} total` : "(no usage yet)";
|
|
38650
|
-
const statusText = [
|
|
38651
|
-
" /status",
|
|
38652
|
-
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
38653
|
-
` model: ${ctx.model}`,
|
|
38654
|
-
` mode: ${ctx.ui.mode}`,
|
|
38655
|
-
` session: ${ctx.sessionPath ?? "(no session file)"}`,
|
|
38656
|
-
` usage: ${usageStr}`,
|
|
38657
|
-
` transcript: ${ctx.transcript.length} entries`,
|
|
38658
|
-
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
|
|
38659
|
-
].join("\n");
|
|
38660
|
-
ctx.pushEntry({ kind: "assistant", text: `
|
|
38661
|
-
${statusText}
|
|
38662
|
-
` });
|
|
38663
|
-
}
|
|
38664
|
-
}
|
|
38665
|
-
];
|
|
38666
|
-
|
|
38667
|
-
// src/commands/session.ts
|
|
38668
|
-
var sessionCommands = [
|
|
38669
|
-
{
|
|
38670
|
-
name: "model",
|
|
38671
|
-
help: "switch model (e.g. /model deepseek-v4-flash)",
|
|
38672
|
-
category: "session",
|
|
38673
|
-
run: (arg, ctx) => {
|
|
38674
|
-
const model = arg.trim();
|
|
38675
|
-
if (!model) {
|
|
38676
|
-
ctx.pushEntry({ kind: "assistant", text: "\n /model <name> requires a model name (e.g. /model deepseek-v4-flash)\n" });
|
|
38677
|
-
return;
|
|
38678
|
-
}
|
|
38679
|
-
const provider = model.startsWith("claude") ? "anthropic" : "deepseek";
|
|
38680
|
-
ctx.setModel(model, provider);
|
|
38681
|
-
ctx.pushEntry({ kind: "assistant", text: `
|
|
38682
|
-
/model set to ${model} (provider: ${provider})
|
|
38683
|
-
(note: D-26 \u62CD, \u5B9E\u9645 LLMClient \u91CD build \u7559 D-28+)
|
|
38684
|
-
` });
|
|
38685
|
-
}
|
|
38686
|
-
},
|
|
38687
|
-
{
|
|
38688
|
-
name: "resume",
|
|
38689
|
-
help: "list session paths (D-28 picker \u5347\u7EA7)",
|
|
38690
|
-
category: "session",
|
|
38691
|
-
run: (_arg, ctx) => {
|
|
38692
|
-
ctx.pushEntry({
|
|
38693
|
-
kind: "assistant",
|
|
38694
|
-
text: "\n /resume: D-28 picker \u5347\u7EA7 (\u8DDF Hermes sessionPicker 1:1)\n \u6682\u4E0D\u652F\u6301\u591A session \u5207\u6362, \u8DDF tui.ts \u5355 session 1:1\n"
|
|
38695
|
-
});
|
|
38696
|
-
}
|
|
38697
|
-
},
|
|
38698
|
-
{
|
|
38699
|
-
name: "personality",
|
|
38700
|
-
help: "switch system prompt personality (D-27 markdown \u6E32\u67D3\u63A5)",
|
|
38701
|
-
category: "session",
|
|
38702
|
-
run: (_arg, ctx) => {
|
|
38703
|
-
const name = _arg.trim();
|
|
38704
|
-
if (!name) {
|
|
38705
|
-
ctx.pushEntry({ kind: "assistant", text: "\n /personality <name> requires a name (D-27 \u5347\u7EA7)\n" });
|
|
38706
|
-
return;
|
|
38707
|
-
}
|
|
38708
|
-
ctx.pushEntry({
|
|
38709
|
-
kind: "assistant",
|
|
38710
|
-
text: `
|
|
38711
|
-
/personality set to ${name} (D-26 \u62CD placeholder, D-27 \u5347\u7EA7\u63A5)
|
|
38712
|
-
`
|
|
38713
|
-
});
|
|
38714
|
-
}
|
|
38715
|
-
}
|
|
38716
|
-
];
|
|
38717
|
-
|
|
38718
|
-
// src/commands/debug.ts
|
|
38719
|
-
function formatBytes(bytes) {
|
|
38720
|
-
const mb = bytes / 1024 / 1024;
|
|
38721
|
-
return mb < 1 ? `${(bytes / 1024).toFixed(1)}KB` : `${mb.toFixed(1)}MB`;
|
|
38722
|
-
}
|
|
38723
|
-
var debugCommands = [
|
|
38724
|
-
{
|
|
38725
|
-
name: "heapdump",
|
|
38726
|
-
aliases: ["mem"],
|
|
38727
|
-
help: "V8 heap snapshot + memory diagnostics (D-27 \u5347\u7EA7 full memory.ts)",
|
|
38728
|
-
category: "debug",
|
|
38729
|
-
run: (_arg, ctx) => {
|
|
38730
|
-
const mu = process.memoryUsage();
|
|
38731
|
-
const text = [
|
|
38732
|
-
" /heapdump \u2014 process.memoryUsage()",
|
|
38733
|
-
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
38734
|
-
` rss: ${formatBytes(mu.rss)}`,
|
|
38735
|
-
` heapTotal: ${formatBytes(mu.heapTotal)}`,
|
|
38736
|
-
` heapUsed: ${formatBytes(mu.heapUsed)}`,
|
|
38737
|
-
` external: ${formatBytes(mu.external)}`,
|
|
38738
|
-
` arrayBuffers: ${formatBytes(mu.arrayBuffers)}`,
|
|
38739
|
-
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
38740
|
-
" (D-27 \u5347\u7EA7: \u5199 v8.writeHeapSnapshot, D-29 \u5347\u7EA7: auto OOM \u9632\u62A4)"
|
|
38741
|
-
].join("\n");
|
|
38742
|
-
ctx.pushEntry({ kind: "assistant", text: `
|
|
38743
|
-
${text}
|
|
38744
|
-
` });
|
|
38745
|
-
}
|
|
38746
|
-
}
|
|
38747
|
-
];
|
|
38748
|
-
|
|
38749
|
-
// src/commands/registry.ts
|
|
38750
|
-
var SLASH_COMMANDS = [
|
|
38751
|
-
...coreCommands,
|
|
38752
|
-
...sessionCommands,
|
|
38753
|
-
...debugCommands
|
|
38754
|
-
];
|
|
38755
|
-
var byName = new Map(
|
|
38756
|
-
SLASH_COMMANDS.flatMap(
|
|
38757
|
-
(cmd) => [cmd.name, ...cmd.aliases ?? []].map((name) => [name.toLowerCase(), cmd])
|
|
38758
|
-
)
|
|
38759
|
-
);
|
|
38760
|
-
var findSlashCommand = (name) => byName.get(name.toLowerCase());
|
|
38761
|
-
var isSlashCommand = (input) => input.startsWith("/");
|
|
38762
|
-
|
|
38763
|
-
// src/hooks/useSubmission.ts
|
|
38764
|
-
function useSubmission(options) {
|
|
38765
|
-
const { slashContext, onChat } = options;
|
|
38766
|
-
const submit = (0, import_react45.useCallback)(
|
|
38767
|
-
(text) => {
|
|
38768
|
-
const trimmed = text.trim();
|
|
38769
|
-
if (!trimmed) return "empty";
|
|
38770
|
-
if (isSlashCommand(trimmed)) {
|
|
38771
|
-
const spaceIdx = trimmed.indexOf(" ");
|
|
38772
|
-
const cmdName = spaceIdx === -1 ? trimmed.slice(1) : trimmed.slice(1, spaceIdx);
|
|
38773
|
-
const arg = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1).trim();
|
|
38774
|
-
const cmd = findSlashCommand(cmdName);
|
|
38775
|
-
if (cmd) {
|
|
38776
|
-
cmd.run(arg, slashContext);
|
|
38777
|
-
return "slash";
|
|
38778
|
-
}
|
|
38779
|
-
slashContext.pushEntry({
|
|
38780
|
-
kind: "assistant",
|
|
38781
|
-
text: `
|
|
38782
|
-
unknown command: /${cmdName}
|
|
38783
|
-
(run /help for the 9 commands list)
|
|
38784
|
-
`
|
|
38785
|
-
});
|
|
38786
|
-
return "slash";
|
|
38787
|
-
}
|
|
38788
|
-
void onChat(trimmed);
|
|
38789
|
-
return "chat";
|
|
38790
|
-
},
|
|
38791
|
-
[slashContext, onChat]
|
|
38792
|
-
);
|
|
38793
|
-
return { submit };
|
|
38794
|
-
}
|
|
38795
|
-
|
|
38796
38297
|
// src/app.tsx
|
|
38797
|
-
var
|
|
38298
|
+
var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
|
|
38798
38299
|
import {
|
|
38799
38300
|
createReplConfirm,
|
|
38800
38301
|
staticToolPolicy as staticToolPolicy2,
|
|
@@ -38807,7 +38308,7 @@ import {
|
|
|
38807
38308
|
import { stdout as stdout2 } from "node:process";
|
|
38808
38309
|
function App2({ options, onExit }) {
|
|
38809
38310
|
const { exit } = use_app_default();
|
|
38810
|
-
const theme = (0,
|
|
38311
|
+
const theme = (0, import_react43.useMemo)(
|
|
38811
38312
|
() => THEMES[resolveTuiTheme(options.theme)],
|
|
38812
38313
|
[options.theme]
|
|
38813
38314
|
);
|
|
@@ -38815,16 +38316,16 @@ function App2({ options, onExit }) {
|
|
|
38815
38316
|
const { history, append: appendHistory } = useHistory();
|
|
38816
38317
|
const { controller: turnAbortController } = useAbortController(() => {
|
|
38817
38318
|
});
|
|
38818
|
-
const [workingMessages, setWorkingMessages] = (0,
|
|
38319
|
+
const [workingMessages, setWorkingMessages] = (0, import_react43.useState)([]);
|
|
38819
38320
|
const sessionPath = options.sessionPath;
|
|
38820
|
-
const writerRef = (0,
|
|
38821
|
-
const readerRef = (0,
|
|
38321
|
+
const writerRef = (0, import_react43.useRef)(null);
|
|
38322
|
+
const readerRef = (0, import_react43.useRef)(null);
|
|
38822
38323
|
if (writerRef.current === null && sessionPath) {
|
|
38823
38324
|
writerRef.current = new SessionWriter(sessionPath);
|
|
38824
38325
|
readerRef.current = new SessionReader(sessionPath);
|
|
38825
38326
|
}
|
|
38826
|
-
const [sessionLoaded, setSessionLoaded] = (0,
|
|
38827
|
-
(0,
|
|
38327
|
+
const [sessionLoaded, setSessionLoaded] = (0, import_react43.useState)(false);
|
|
38328
|
+
(0, import_react43.useEffect)(() => {
|
|
38828
38329
|
if (sessionLoaded) return;
|
|
38829
38330
|
const writer = writerRef.current;
|
|
38830
38331
|
const reader = readerRef.current;
|
|
@@ -38851,13 +38352,13 @@ function App2({ options, onExit }) {
|
|
|
38851
38352
|
setSessionLoaded(true);
|
|
38852
38353
|
}
|
|
38853
38354
|
}, [sessionLoaded]);
|
|
38854
|
-
const confirmControllerRef = (0,
|
|
38355
|
+
const confirmControllerRef = (0, import_react43.useRef)(null);
|
|
38855
38356
|
if (confirmControllerRef.current === null) {
|
|
38856
38357
|
confirmControllerRef.current = createReplConfirm({ output: stdout2 });
|
|
38857
38358
|
}
|
|
38858
38359
|
const confirmController = confirmControllerRef.current;
|
|
38859
|
-
const [turnInFlight, setTurnInFlight] = (0,
|
|
38860
|
-
const clientRef = (0,
|
|
38360
|
+
const [turnInFlight, setTurnInFlight] = (0, import_react43.useState)(false);
|
|
38361
|
+
const clientRef = (0, import_react43.useRef)(null);
|
|
38861
38362
|
if (clientRef.current === null) {
|
|
38862
38363
|
const providerNarrow = options.provider === "deepseek" || options.provider === "anthropic" ? options.provider : void 0;
|
|
38863
38364
|
clientRef.current = createDefaultClient({
|
|
@@ -38866,14 +38367,11 @@ function App2({ options, onExit }) {
|
|
|
38866
38367
|
});
|
|
38867
38368
|
}
|
|
38868
38369
|
const client = clientRef.current;
|
|
38869
|
-
const registryRef = (0,
|
|
38370
|
+
const registryRef = (0, import_react43.useRef)(null);
|
|
38870
38371
|
if (registryRef.current === null) {
|
|
38871
38372
|
registryRef.current = createDefaultRegistry();
|
|
38872
38373
|
}
|
|
38873
38374
|
const registry = registryRef.current;
|
|
38874
|
-
const [modelName, setModelName] = (0, import_react46.useState)(
|
|
38875
|
-
options.model ?? client.model ?? "model"
|
|
38876
|
-
);
|
|
38877
38375
|
const { runTurn } = useRunToolLoop({
|
|
38878
38376
|
options,
|
|
38879
38377
|
theme,
|
|
@@ -38884,7 +38382,7 @@ function App2({ options, onExit }) {
|
|
|
38884
38382
|
policy: staticToolPolicy2,
|
|
38885
38383
|
workingMessages
|
|
38886
38384
|
});
|
|
38887
|
-
(0,
|
|
38385
|
+
(0, import_react43.useEffect)(() => {
|
|
38888
38386
|
if (ui.mode === "idle" && turnInFlight) {
|
|
38889
38387
|
setTurnInFlight(false);
|
|
38890
38388
|
const entries = $transcript.get();
|
|
@@ -38900,53 +38398,38 @@ function App2({ options, onExit }) {
|
|
|
38900
38398
|
}
|
|
38901
38399
|
}
|
|
38902
38400
|
}, [ui.mode, turnInFlight]);
|
|
38903
|
-
const
|
|
38904
|
-
|
|
38905
|
-
|
|
38906
|
-
|
|
38907
|
-
transcript: $transcript.get(),
|
|
38908
|
-
model: modelName,
|
|
38909
|
-
sessionPath,
|
|
38910
|
-
pushEntry,
|
|
38911
|
-
clearTranscript: () => {
|
|
38912
|
-
$transcript.set([]);
|
|
38913
|
-
},
|
|
38914
|
-
setModel: (model) => {
|
|
38915
|
-
setModelName(model);
|
|
38916
|
-
},
|
|
38917
|
-
exit: (result) => {
|
|
38401
|
+
const handlePromptSubmit = (assembled) => {
|
|
38402
|
+
const trimmed = assembled.trim();
|
|
38403
|
+
if (!trimmed) return;
|
|
38404
|
+
if (trimmed === "/exit" || trimmed === "q" || trimmed === "quit") {
|
|
38918
38405
|
void writerRef.current?.close();
|
|
38919
|
-
onExit(
|
|
38406
|
+
onExit({ exitCode: 0, reason: "user-exit" });
|
|
38920
38407
|
exit();
|
|
38408
|
+
return;
|
|
38921
38409
|
}
|
|
38922
|
-
|
|
38923
|
-
|
|
38924
|
-
|
|
38925
|
-
onChat: (prompt) => {
|
|
38926
|
-
if (confirmController.hasPending()) {
|
|
38927
|
-
confirmController.offerLine(prompt);
|
|
38928
|
-
return;
|
|
38929
|
-
}
|
|
38930
|
-
if (turnInFlight) return;
|
|
38931
|
-
appendHistory(prompt);
|
|
38932
|
-
setTurnInFlight(true);
|
|
38933
|
-
void (async () => {
|
|
38934
|
-
await runTurn(prompt);
|
|
38935
|
-
})();
|
|
38410
|
+
if (confirmController.hasPending()) {
|
|
38411
|
+
confirmController.offerLine(trimmed);
|
|
38412
|
+
return;
|
|
38936
38413
|
}
|
|
38937
|
-
|
|
38938
|
-
|
|
38939
|
-
|
|
38940
|
-
|
|
38941
|
-
|
|
38942
|
-
|
|
38943
|
-
|
|
38944
|
-
|
|
38414
|
+
if (turnInFlight) return;
|
|
38415
|
+
appendHistory(trimmed);
|
|
38416
|
+
setTurnInFlight(true);
|
|
38417
|
+
void (async () => {
|
|
38418
|
+
await runTurn(trimmed);
|
|
38419
|
+
})();
|
|
38420
|
+
};
|
|
38421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, children: [
|
|
38422
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: theme.header, children: "\u232C deepwhale tui-ink v1.0.10" }),
|
|
38423
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Divider, { theme }),
|
|
38424
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StatusBar, { theme }),
|
|
38425
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Transcript, { theme }),
|
|
38426
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Confirm, { theme, controller: confirmController }),
|
|
38427
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
38945
38428
|
Prompt,
|
|
38946
38429
|
{
|
|
38947
38430
|
theme,
|
|
38948
38431
|
history,
|
|
38949
|
-
onSubmit:
|
|
38432
|
+
onSubmit: handlePromptSubmit,
|
|
38950
38433
|
disabled: turnInFlight
|
|
38951
38434
|
}
|
|
38952
38435
|
)
|
|
@@ -38954,14 +38437,14 @@ function App2({ options, onExit }) {
|
|
|
38954
38437
|
}
|
|
38955
38438
|
|
|
38956
38439
|
// src/index.tsx
|
|
38957
|
-
var
|
|
38440
|
+
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
38958
38441
|
async function runTuiInkMode(options = {}) {
|
|
38959
38442
|
if (!process.stdout.isTTY) {
|
|
38960
38443
|
return { exitCode: 0, reason: "not-tty" };
|
|
38961
38444
|
}
|
|
38962
38445
|
return new Promise((resolve) => {
|
|
38963
38446
|
const { waitUntilExit, unmount } = render_default(
|
|
38964
|
-
/* @__PURE__ */ (0,
|
|
38447
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
38965
38448
|
App2,
|
|
38966
38449
|
{
|
|
38967
38450
|
options,
|