@epoch-agent/tui 3.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +14 -8
  2. package/dist/index.js +21 -17
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -255,22 +255,28 @@ Ink 的 `log-update` **只能擦除它上一帧写过的行数**。一旦动态
255
255
 
256
256
  ## `@` 补全:文件和会话两组
257
257
 
258
- 打 `@` 弹补全面板,**分两组**(方案 53 §1.3):
258
+ 打 `@` 弹补全面板,**分两组**(方案 53 §1.3;2026-11-05 起**会话在上**):
259
259
 
260
260
  ```
261
- ┌ 文件 ────────────────────────────
262
- │ packages/core/src/agent/loop.ts
263
- ├ 会话 ────────────────────────────
261
+ ┌ 会话 ────────────────────────────
264
262
  │ 接上后台任务的输出 12/03 · 42 条 · 本工作区
263
+ ├ 文件 ────────────────────────────
264
+ │ packages/core/src/agent/loop.ts
265
265
  └──────────────────────────────────
266
266
  ```
267
267
 
268
+ - **会话组**:`@` 一打就列出来,**不需要先知道 `@:` 这个前缀**(2026-11-05 之前
269
+ 只有 `@:` 才出会话,而那件事只写在文档里)。选中补进去的是 **sessionId**
270
+ (落成 `@:id`)而不是标题 —— 标题里几乎一定有空白,而提及的抽取规则遇到空白
271
+ 就断 —— 提交时那段会话的 **当前面**(模型当时还看得见的那些)作为一个独立
272
+ 部件发出去
268
273
  - **文件组**:子序列模糊匹配(`@c/a/loop` 命中 `packages/core/src/agent/loop.ts`),
269
274
  Tab / Enter 补全路径,提交时**文件内容随消息一起发出去**,省掉
270
- 「模型调 `file_read` → 再等一轮」。文件组排前面,因为它是高频的那个
271
- - **会话组**:`@:` 只显示这一组。选中补进去的是 **sessionId** 而不是标题
272
- (标题里几乎一定有空白,而提及的抽取规则遇到空白就断),提交时那段会话的
273
- **当前面**(模型当时还看得见的那些)作为一个独立部件发出去
275
+ 「模型调 `file_read` → 再等一轮」
276
+ - **`@:` 是缩窄**:打了它就只要会话,文件组整个不列。这是「我知道自己要哪段
277
+ 对话」时省掉下半屏的写法,不是另一种语法 —— 落进文本的仍然是 `@:id`
278
+ - 会话组排上面的判据是**影响范围**:引用一段会话改变的是整场对话的前提,
279
+ 一个文件是局部素材。`↑↓` 的高亮下标跨两组连着走(会话最后一条 → 文件第一条)
274
280
 
275
281
  > ⚠️ **会话组只按 sessionId / cwd / 标题匹配,永远不搜转录文本**(方案 53 §5.2)。
276
282
  > 这是**安全边界不是性能考虑**:面板边打边显示,能搜正文的话打 `@:密码` 就会在
package/dist/index.js CHANGED
@@ -3519,27 +3519,20 @@ function FilePalette({
3519
3519
  t("tui.palette.listing")
3520
3520
  ] }) });
3521
3521
  }
3522
- const start = visibleWindowStart(matched.length, selectedIndex, MAX_VISIBLE4);
3523
- const visible = matched.slice(start, start + MAX_VISIBLE4);
3522
+ const fileStart = visibleWindowStart(
3523
+ matched.length,
3524
+ Math.max(0, selectedIndex - sessions.length),
3525
+ MAX_VISIBLE4
3526
+ );
3527
+ const visible = matched.slice(fileStart, fileStart + MAX_VISIBLE4);
3524
3528
  const grouped = matched.length > 0 && sessions.length > 0;
3525
3529
  return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", paddingX: 1, children: [
3526
- grouped && /* @__PURE__ */ jsxs20(Text21, { color: dim9, dimColor: true, children: [
3527
- " ",
3528
- t("tui.palette.files_head")
3529
- ] }),
3530
- visible.map((m, i) => {
3531
- const selected = start + i === selectedIndex;
3532
- return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", children: [
3533
- /* @__PURE__ */ jsx22(Text21, { color: selected ? accent6 : dim9, children: selected ? "\u276F " : " " }),
3534
- /* @__PURE__ */ jsx22(Text21, { color: selected ? accent6 : "#F8F8F2", bold: selected, children: highlight(m.item, m.positions) })
3535
- ] }, m.item);
3536
- }),
3537
3530
  grouped && /* @__PURE__ */ jsxs20(Text21, { color: dim9, dimColor: true, children: [
3538
3531
  " ",
3539
3532
  t("tui.palette.sessions_head")
3540
3533
  ] }),
3541
3534
  sessions.map((m, i) => {
3542
- const selected = matched.length + i === selectedIndex;
3535
+ const selected = i === selectedIndex;
3543
3536
  return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", children: [
3544
3537
  /* @__PURE__ */ jsx22(Text21, { color: selected ? accent6 : dim9, children: selected ? "\u276F " : " " }),
3545
3538
  /* @__PURE__ */ jsx22(Text21, { color: selected ? accent6 : "#F8F8F2", bold: selected, children: m.item.title }),
@@ -3549,6 +3542,17 @@ function FilePalette({
3549
3542
  ] })
3550
3543
  ] }, m.item.id);
3551
3544
  }),
3545
+ grouped && /* @__PURE__ */ jsxs20(Text21, { color: dim9, dimColor: true, children: [
3546
+ " ",
3547
+ t("tui.palette.files_head")
3548
+ ] }),
3549
+ visible.map((m, i) => {
3550
+ const selected = sessions.length + fileStart + i === selectedIndex;
3551
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "row", children: [
3552
+ /* @__PURE__ */ jsx22(Text21, { color: selected ? accent6 : dim9, children: selected ? "\u276F " : " " }),
3553
+ /* @__PURE__ */ jsx22(Text21, { color: selected ? accent6 : "#F8F8F2", bold: selected, children: highlight(m.item, m.positions) })
3554
+ ] }, m.item);
3555
+ }),
3552
3556
  /* @__PURE__ */ jsx22(Box20, { flexDirection: "row", children: /* @__PURE__ */ jsxs20(Text21, { color: dim9, dimColor: true, children: [
3553
3557
  " ",
3554
3558
  matched.length > MAX_VISIBLE4 ? t("tui.palette.total", { n: matched.length }) : "",
@@ -3681,10 +3685,10 @@ var InputBox = React11.forwardRef(function InputBox2({
3681
3685
  }
3682
3686
  if (action !== "complete" && action !== "submit") return false;
3683
3687
  const index = fileIndexRef.current < total ? fileIndexRef.current : 0;
3684
- const picked = index < matches.length ? matches[index]?.item : (() => {
3685
- const candidate = sessions[index - matches.length]?.item;
3688
+ const picked = index < sessions.length ? (() => {
3689
+ const candidate = sessions[index]?.item;
3686
3690
  return candidate ? sessionInsertion(candidate) : void 0;
3687
- })();
3691
+ })() : matches[index - sessions.length]?.item;
3688
3692
  if (picked === void 0) return false;
3689
3693
  const next = applyMention(curLines[row] ?? "", at, col, picked);
3690
3694
  const lines2 = [...curLines];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epoch-agent/tui",
3
- "version": "3.2.0",
3
+ "version": "4.0.0",
4
4
  "private": false,
5
5
  "description": "epoch-agent Ink TUI 界面",
6
6
  "repository": {
@@ -29,8 +29,8 @@
29
29
  "mnemonist": "0",
30
30
  "string-width": "8",
31
31
  "strip-ansi": "7",
32
- "@epoch-agent/protocol": "3.2.0",
33
- "@epoch-agent/view": "3.2.0"
32
+ "@epoch-agent/protocol": "4.0.0",
33
+ "@epoch-agent/view": "4.0.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^26.1.2",