thincoder 0.12.64 → 0.12.65
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/CHANGELOG.md +24 -0
- package/README.md +99 -42
- package/bin/thincoder.mjs +18 -0
- package/package.json +2 -2
- package/src/acp/handlers-session.mjs +25 -1
- package/src/acp/handlers-slots.mjs +1 -1
- package/src/tui/agent-turn.mjs +5 -2
- package/src/tui/cmd-advisor.mjs +1 -1
- package/src/tui/cmd-eng.mjs +2 -1
- package/src/tui/cmd-mcp-form.mjs +11 -5
- package/src/tui/conversation-writer.mjs +62 -0
- package/src/tui/index.mjs +43 -305
- package/src/tui/input-face.mjs +187 -0
- package/src/tui/key-handler-busy.mjs +42 -0
- package/src/tui/key-handler-ctrlc.mjs +118 -0
- package/src/tui/key-handler-edit.mjs +115 -0
- package/src/tui/key-handler-modals.mjs +87 -0
- package/src/tui/key-handler-scroll.mjs +110 -0
- package/src/tui/key-handler.mjs +32 -382
- package/src/tui/render-frame.mjs +8 -3
- package/src/tui/subagent-freeze.mjs +3 -3
- package/src/tui/suspension-drive.mjs +10 -9
- package/src/tui/tui-state.mjs +65 -0
- package/src/tui/turn-face.mjs +64 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createInteraction } from "./interaction.mjs"
|
|
2
|
+
import { runAgentTurn } from "./agent-turn.mjs"
|
|
3
|
+
import { pasteClipboardImage as pasteClipboardImageImpl } from "./clipboard.mjs"
|
|
4
|
+
|
|
5
|
+
/** 回合面(2026-09-22 structure-debt §2.2 · #159):submit 门禁 / interaction 装配(权限 + 提问)/
|
|
6
|
+
* 剪贴板图片粘贴 / turnCtx / turn——块体自 index.mjs startTUI 逐字搬移;唯一改指 = turnCtx 的
|
|
7
|
+
* `assistantLabeled` 存取器两行改经 ctx.conversation(写入面单源)承接。
|
|
8
|
+
* `handleSlash` 由调用侧以惰性转发承接(命令层后定义——循环依赖语义逐字保持),turnCtx 由
|
|
9
|
+
* index.mjs 在命令层之后原址回填 `turnCtx.handleSlash`。
|
|
10
|
+
* @param {object} ctx
|
|
11
|
+
* @returns {{ submit: Function, turn: Function, turnCtx: object, askPermission: Function,
|
|
12
|
+
* askQuestion: Function, askBatchPermission: Function, pasteClipboardImage: Function }} */
|
|
13
|
+
export function createTurnFace(ctx) {
|
|
14
|
+
const { agent, state, pushLine, pushLabel, render, ensureAssistantLabel, summarize, handleSlash, conversation } = ctx
|
|
15
|
+
async function submit() {
|
|
16
|
+
const text = state.input.join("").trim()
|
|
17
|
+
if (!text) return
|
|
18
|
+
// INPUT-LOCK 防御(C'——2026-09-09 + F16 busy 单槽——2026-09-21):门禁在 key-handler
|
|
19
|
+
// (busy Enter 非模态 = 单槽注入 / 模态·斜杠·空·槽满 = 吞 + 提示,文本保留——TUI-INPUT-BOX.md
|
|
20
|
+
// §4.1);submit 只在非 busy 期达此;防御直呼/上游改动:busy 期拒绝(不清输入框不吞内容)。
|
|
21
|
+
if (state.processing) {
|
|
22
|
+
pushLine(`[主会话处理中 —— 消息未发送(回合结束后请重按 Enter)]`, C.warn)
|
|
23
|
+
render()
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
state.input = []
|
|
27
|
+
state.cursor = 0
|
|
28
|
+
const wasInHistory = state.historyIndex !== -1
|
|
29
|
+
state.history.push(text) // review #3 fix: single push (was duplicated — every submit appeared twice in ↑/↓ history)
|
|
30
|
+
state.historyIndex = -1
|
|
31
|
+
if (!wasInHistory) state._draft = null // submitted — the draft is now history. Keep draft when submitting from history mode (↓ can recover)
|
|
32
|
+
state.scroll = 0
|
|
33
|
+
state._followTail = true // 2026-08-31 会诊 deepseek:新消息恢复跟随(注释曾承诺、实现缺漏)
|
|
34
|
+
|
|
35
|
+
// Slash commands: handled locally, don't enter agent loop. 斜杠 busy 期提交在 key-handler
|
|
36
|
+
// 门禁被吞(白名单已删——斜杠同吞——INPUT-LOCK-BEHAVIOR-REVISED)——submit 仅非 busy 期可达。
|
|
37
|
+
if (text.startsWith("/")) {
|
|
38
|
+
await handleSlash(text)
|
|
39
|
+
render()
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await turn(text)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Interaction primitives: permission approval + Q&A input, implemented in interaction.mjs
|
|
47
|
+
const { askPermission, askQuestion, askBatchPermission } = createInteraction({
|
|
48
|
+
agent, state, pushLine, pushLabel, render, summarize,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// Clipboard image paste: implemented in clipboard.mjs
|
|
52
|
+
const pasteClipboardImage = () => pasteClipboardImageImpl({ agent, state, pushLine, render })
|
|
53
|
+
|
|
54
|
+
// Agent loop: implemented in agent-turn.mjs
|
|
55
|
+
const turnCtx = {
|
|
56
|
+
agent, state, pushLine, pushLabel, render, scheduleRender: render, ensureAssistantLabel,
|
|
57
|
+
askPermission, askQuestion, askBatchPermission, handleSlash: null,
|
|
58
|
+
get assistantLabeled() { return conversation.assistantLabeled },
|
|
59
|
+
set assistantLabeled(v) { conversation.assistantLabeled = v },
|
|
60
|
+
}
|
|
61
|
+
const turn = (text) => runAgentTurn(turnCtx, text)
|
|
62
|
+
|
|
63
|
+
return { submit, turn, turnCtx, askPermission, askQuestion, askBatchPermission, pasteClipboardImage }
|
|
64
|
+
}
|