pi-cc-extensions 0.8.53 → 0.8.55

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 (42) hide show
  1. package/README.en.md +12 -17
  2. package/README.md +18 -17
  3. package/assets/readme/hero.en.svg +101 -0
  4. package/extensions/config/config.ts +25 -17
  5. package/extensions/config/panel.ts +100 -4
  6. package/extensions/{utils/agent-summary.ts → feature/agent-summary/core.ts} +39 -47
  7. package/extensions/feature/{agent-summary.ts → agent-summary/index.ts} +2 -6
  8. package/extensions/feature/compact-thinking.ts +8 -3
  9. package/extensions/feature/{session-reference.ts → reference/index.ts} +1 -1
  10. package/extensions/feature/{agent-autocomplete.ts → reference/subagent.ts} +0 -1
  11. package/extensions/feature/{pi-startup-header.ts → shell/startup-header.ts} +2 -42
  12. package/extensions/feature/{working-message.ts → shell/working-message.ts} +5 -11
  13. package/extensions/index.ts +28 -38
  14. package/extensions/renderer/compact-mode.ts +394 -101
  15. package/extensions/renderer/default-mode.ts +747 -0
  16. package/extensions/renderer/index.ts +58 -775
  17. package/extensions/renderer/{mouse-hover.ts → mouse/hover.ts} +8 -6
  18. package/extensions/renderer/{mouse-interaction.ts → mouse/interaction.ts} +37 -36
  19. package/extensions/renderer/{mouse-layout.ts → mouse/layout.ts} +5 -21
  20. package/extensions/renderer/{mouse-packets.ts → mouse/packets.ts} +1 -1
  21. package/extensions/renderer/{mouse-scroll.ts → mouse/scroll.ts} +49 -36
  22. package/extensions/renderer/{tool-diff → tool/diff}/diff-renderer.ts +10 -45
  23. package/extensions/renderer/{tool-diff → tool/diff}/line-width-safety.ts +1 -1
  24. package/extensions/renderer/tool/diff/write-display-utils.ts +12 -0
  25. package/extensions/renderer/{tool-grouping.ts → tool/grouping.ts} +20 -16
  26. package/extensions/renderer/{tool-result.ts → tool/result.ts} +35 -27
  27. package/extensions/utils/ansi-color.ts +44 -0
  28. package/extensions/utils/format.ts +21 -0
  29. package/extensions/utils/fullscreen-detect.ts +0 -27
  30. package/package.json +4 -2
  31. package/extensions/renderer/tool-diff/write-display-utils.ts +0 -29
  32. /package/extensions/feature/{session-reference-core.ts → reference/session.ts} +0 -0
  33. /package/extensions/feature/{pi-aliases.ts → shell/aliases.ts} +0 -0
  34. /package/extensions/{feature → renderer}/markdown-enhance.ts +0 -0
  35. /package/extensions/renderer/{tool-diff → tool/diff}/ATTRIBUTION.md +0 -0
  36. /package/extensions/renderer/{tool-diff → tool/diff}/ansi-utils.ts +0 -0
  37. /package/extensions/renderer/{tool-diff → tool/diff}/diff-presentation.ts +0 -0
  38. /package/extensions/renderer/{tool-diff → tool/diff}/index.ts +0 -0
  39. /package/extensions/renderer/{tool-diff → tool/diff}/render-utils.ts +0 -0
  40. /package/extensions/renderer/{tool-diff → tool/diff}/shiki-highlight.ts +0 -0
  41. /package/extensions/renderer/{tool-diff → tool/diff}/types.ts +0 -0
  42. /package/extensions/renderer/{tool-diff → tool/diff}/write-execution.ts +0 -0
package/README.en.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="./assets/readme/hero.svg" width="100%" alt="pi-cc-extensions: a productivity extension suite for Pi">
2
+ <img src="./assets/readme/hero.en.svg" width="100%" alt="pi-cc-extensions: a productivity extension suite for Pi">
3
3
  </p>
4
4
 
5
5
  <p align="center">
@@ -10,7 +10,7 @@
10
10
  </p>
11
11
 
12
12
  <p align="center">
13
- Claude Code-style output, context inspection, and Agent / Session references.
13
+ Claude Code-style TUI output with some personal touches and handy utilities.
14
14
  </p>
15
15
 
16
16
  <p align="center">
@@ -38,15 +38,14 @@ Run `/reload` after installation.
38
38
 
39
39
  ## Features
40
40
 
41
-
42
- | Feature | Description | Entry point |
43
- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
44
- | Claude Code-style output | Tool summaries, expand/collapse, rich edit/write diffs, and`on` / `compact` / `off` modes | `/ccstyle` |
45
- | Fullscreen mouse interaction | Tool card/group click-to-toggle, previews, hover highlight, and a back-to-bottom button | `TUIMODE=fullscreen` or `--tui-mode fullscreen` |
46
- | Settings panel | `Style / Diff / Thinking / Feature` tabs: startup header toggle and wheel step | `/ccstyle` |
47
- | Context inspection | Usage breakdown and previews for the system prompt, tools, skills, and messages | `/context` |
48
- | Session references | Search and inject effective context from previous Sessions or existing SubAgents | `@session:` |
49
- | Theme | Bundled CC Dark and CC Light themes | `/theme` |
41
+ | Feature | Description | Entry point |
42
+ | --------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------- |
43
+ | Claude Code Output | Tool summaries, expand/collapse, rich edit/write diffs, and`on` / `compact` / `off` modes | `/ccstyle` |
44
+ | Fullscreen mode | Tool card/group click-to-toggle, previews, hover highlight, and a back-to-bottom button | `TUIMODE=fullscreen` or `--tui-mode fullscreen` |
45
+ | Settings panel | `Style / Diff / Thinking / Feature` tabs: startup header toggle and wheel step | `/ccstyle` |
46
+ | Context inspection | Usage breakdown and previews for the system prompt, tools, skills, and messages | `/context` |
47
+ | Session/Subagent references | Search and inject effective context from previous Sessions or existing SubAgents | `@` |
48
+ | Theme | Bundled CC Dark and CC Light themes | `/theme` |
50
49
 
51
50
  ## Configuration
52
51
 
@@ -78,26 +77,22 @@ npm run typecheck
78
77
  ./test.bat # or pi -e .
79
78
  ```
80
79
 
81
- Run `/reload` after changing extensions.
82
-
83
80
  ## Compatibility
84
81
 
85
82
  - Node.js `>=22.19.0`, Pi `^0.84.0` (loaded through `pi.extensions` and `pi.themes` in the root `package.json`)
86
83
 
87
84
  ## Recommended companions
88
85
 
89
-
90
86
  | Extension | Purpose |
91
- | ------------------------------------------ | -------------------------------------------------------------- |
87
+ | ---------------------------------------- | ------------------------------------------------------------ |
92
88
  | `npm:@tintinweb/pi-subagents` | Parallel SubAgents, background tasks, and worktree isolation |
93
89
  | `npm:@tintinweb/pi-tasks` | Claude Code-style task tracking and coordination |
94
90
  | `npm:pi-mcp-adapter` | On-demand MCP tool discovery with lower context usage |
95
91
  | `npm:@ff-labs/pi-fff` | FFF-powered fuzzy file and content search (fffind / ffgrep) |
96
92
  | `npm:pi-web-access` | Web search, URL fetching, GitHub cloning, PDF/video parsing |
97
- | `npm:pi-theme-picker` | Theme search and live preview |
98
93
  | `npm:@narumitw/pi-usage` | Current-account usage for Codex / Copilot / OpenRouter |
99
94
  | `git:github.com/DietrichGebert/ponytail` | Lazy-mode coding: forces the simplest working solution |
100
95
 
101
96
  ## Credits
102
97
 
103
- - Rich diffs are adapted from [`MasuRii/pi-tool-display`](https://github.com/MasuRii/pi-tool-display) (MIT). See [`extensions/tool-diff/ATTRIBUTION.md`](./extensions/tool-diff/ATTRIBUTION.md).
98
+ - Rich diffs are adapted from [`MasuRii/pi-tool-display`](https://github.com/MasuRii/pi-tool-display) (MIT). See [`extensions/renderer/tool/diff/ATTRIBUTION.md`](./extensions/renderer/tool/diff/ATTRIBUTION.md).
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  </p>
11
11
 
12
12
  <p align="center">
13
- 类 Claude Code TUI 输出风格、上下文检查,以及 Agent / Session 引用。
13
+ 类 Claude Code TUI 输出风格,并融入了一些个人喜好,和一些实用小功能。
14
14
  </p>
15
15
 
16
16
  <p align="center">
@@ -38,15 +38,14 @@ pi install git:github.com/minuque/pi-cc-extensions
38
38
 
39
39
  ## 功能
40
40
 
41
-
42
- | 功能 | 说明 | 入口 |
43
- | ---------------------- | ---------------------------------------------------------------------------------------------------------- | ------------- |
44
- | Claude Code 风格输出 | 工具摘要、折叠展开、rich edit/write diff,以及`on` / `compact` / `off` 三种模式 | `/ccstyle` |
45
- | Fullscreen 鼠标交互 | 工具卡/group 点击展开与收起、预览、hover 高亮、回到底部按钮 | `TUIMODE=fullscreen` 或 `--tui-mode fullscreen` |
46
- | 配置面板 | `Style / Diff / Thinking / Feature` 四页签,含启动头开关与滚轮步进 | `/ccstyle` |
47
- | 上下文检查 | 查看上下文占用,并预览 System prompt、Tools、Skills 和消息内容 | `/context` |
48
- | Session 引用 | 搜索并注入历史 Session 或现有 SubAgent 的有效上下文 | `@session:` |
49
- | 主题 | 随包提供内置 CC Dark、CC Light 主题 | `/theme` |
41
+ | 功能 | 说明 | 入口 |
42
+ | --------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------- |
43
+ | Claude Code UI | 工具摘要、折叠展开、rich edit/write diff,以及`on` / `compact` / `off` 三种模式 | `/ccstyle` |
44
+ | Fullscreen mode | 工具卡/group 点击展开与收起、预览、hover 高亮、回到底部按钮 | `TUIMODE=fullscreen` 或 `--tui-mode fullscreen` |
45
+ | 配置面板 | `Style / Diff / Thinking / Feature` 四页签,含启动头开关与滚轮步进 | `/ccstyle` |
46
+ | 上下文检查 | 查看上下文占用,并预览 System prompt、Tools、Skills 和消息内容 | `/context` |
47
+ | Session/Subagent 引用 | 搜索并注入历史 Session 或现有 SubAgent 的有效上下文 | `@` |
48
+ | 主题 | 随包提供内置 CC Dark、CC Light 主题 | `/theme` |
50
49
 
51
50
  ## 配置
52
51
 
@@ -66,7 +65,13 @@ pi install git:github.com/minuque/pi-cc-extensions
66
65
  "previewLines": 3, // thinking 预览行数,0 隐藏预览正文
67
66
  "animationIntervalMs": 90, // thinking 标题动画间隔(毫秒)
68
67
  "showStartupHeader": true, // 自定义启动头(logo + tips)开关
69
- "scrollStepLines": 3 // fullscreen 滚轮滚动步进行数
68
+ "scrollStepLines": 3, // fullscreen 滚轮滚动步进行数
69
+ "enableSessionReference": true, // @ session 引用(搜历史会话注入上下文)
70
+ "enableSubagentAutocomplete": true, // @ subagent 自动补全与委派提示
71
+ "enableContextCommand": true, // /context 上下文占用检查
72
+ "enableAgentSummary": true, // 每回合工具统计摘要
73
+ "enableWorkingMessage": true, // Working... 底部 token/耗时展示
74
+ "enableAliases": true // /clear、/exit 别名
70
75
  }
71
76
  ```
72
77
 
@@ -78,26 +83,22 @@ npm run typecheck
78
83
  ./test.bat # or pi -e .
79
84
  ```
80
85
 
81
- 修改扩展后执行 `/reload`。
82
-
83
86
  ## 兼容性
84
87
 
85
88
  - Node.js `>=22.19.0`,Pi `^0.84.0`(通过根目录 `package.json` 的 `pi.extensions` 和 `pi.themes` 加载)
86
89
 
87
90
  ## 推荐搭配
88
91
 
89
-
90
92
  | 扩展 | 用途 |
91
- | ------------------------------------------ | -------------------------------------------------- |
93
+ | ---------------------------------------- | ------------------------------------------------ |
92
94
  | `npm:@tintinweb/pi-subagents` | 并行 SubAgent、后台任务与工作树隔离 |
93
95
  | `npm:@tintinweb/pi-tasks` | Claude Code 风格任务跟踪与协调 |
94
96
  | `npm:pi-mcp-adapter` | 按需发现 MCP 工具,减少上下文占用 |
95
97
  | `npm:@ff-labs/pi-fff` | 模糊文件与内容检索(fffind / ffgrep) |
96
98
  | `npm:pi-web-access` | 网页搜索、URL 抓取、GitHub 克隆、PDF/视频解析 |
97
- | `npm:pi-theme-picker` | 主题搜索和实时预览 |
98
99
  | `npm:@narumitw/pi-usage` | 查看当前账号用量(Codex / Copilot / OpenRouter) |
99
100
  | `git:github.com/DietrichGebert/ponytail` | 极简编码:强制最懒但有效的方案 |
100
101
 
101
102
  ## 致谢
102
103
 
103
- - Rich diff 改编自 [`MasuRii/pi-tool-display`](https://github.com/MasuRii/pi-tool-display)(MIT);详见 [`extensions/tool-diff/ATTRIBUTION.md`](./extensions/tool-diff/ATTRIBUTION.md)。
104
+ - Rich diff 改编自 [`MasuRii/pi-tool-display`](https://github.com/MasuRii/pi-tool-display)(MIT);详见 [`extensions/renderer/tool/diff/ATTRIBUTION.md`](./extensions/renderer/tool/diff/ATTRIBUTION.md)。
@@ -0,0 +1,101 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="400" viewBox="0 0 1200 400" role="img" aria-labelledby="title desc">
2
+ <title id="title">pi-cc-extensions
3
+ </title>
4
+ <desc id="desc">The Claude and Pi brand marks together connect three extension capabilities: Claude Code-style output, context inspection, and historical Session references.
5
+ </desc>
6
+ <defs>
7
+ <linearGradient id="panel" x1="0" y1="0" x2="1" y2="1">
8
+ <stop offset="0" stop-color="#0D131B"/>
9
+ <stop offset="1" stop-color="#090D12"/>
10
+ </linearGradient>
11
+ </defs>
12
+ <rect width="1200" height="400" rx="28" fill="url(#panel)"/>
13
+ <rect x="1" y="1" width="1198" height="398" rx="27" fill="none" stroke="#263241" stroke-width="2"/>
14
+ <g id="title-block" transform="translate(64 58)" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif">
15
+ <g font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="16" font-weight="600" letter-spacing="1.4">
16
+ <text x="0" y="0" fill="#66E3C4">PI EXTENSION
17
+ </text>
18
+ </g>
19
+ <text x="0" y="82" fill="#F4F7FA" font-size="54" font-weight="750" letter-spacing="-1.5">pi-cc-extensions
20
+ </text>
21
+ <text x="0" y="130" fill="#B8C3CF" font-size="23">Make Pi work like Claude Code 🙃
22
+ </text>
23
+ <g transform="translate(0 180)" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="17">
24
+ <rect width="488" height="58" rx="12" fill="#111923" stroke="#2B3948"/>
25
+ <text x="20" y="36" fill="#66E3C4">›
26
+ </text>
27
+ <text x="44" y="36" fill="#F4F7FA">/ccstyle
28
+ </text>
29
+ <text x="155" y="36" fill="#536172">·
30
+ </text>
31
+ <text x="178" y="36" fill="#7CC7FF">/context
32
+ </text>
33
+ <text x="292" y="36" fill="#536172">·
34
+ </text>
35
+ <text x="315" y="36" fill="#F2C879">@session:
36
+ </text>
37
+ <rect x="411" y="22" width="9" height="20" rx="2" fill="#66E3C4"/>
38
+ </g>
39
+ <g transform="translate(0 282)" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="15">
40
+ <circle cx="6" cy="-5" r="6" fill="#66E3C4"/>
41
+ <text x="22" y="0" fill="#8B9AAD">3 EXTENSIONS
42
+ </text>
43
+ <text x="160" y="0" fill="#3B4857">•
44
+ </text>
45
+ <text x="183" y="0" fill="#8B9AAD">TYPESCRIPT
46
+ </text>
47
+ <text x="303" y="0" fill="#3B4857">•
48
+ </text>
49
+ <text x="326" y="0" fill="#8B9AAD">NODE ≥ 22.19
50
+ </text>
51
+ </g>
52
+ </g>
53
+ <g id="extension-map" transform="translate(662 48)" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif">
54
+ <g id="claude-pi-mark" transform="translate(0 0)">
55
+ <!-- Official Claude starburst vector; source: Anthropic Claude brand mark. -->
56
+ <path transform="translate(2 2) scale(.34)" fill="#D97757" d="m19.6 66.5 19.7-11 .3-1-.3-.5h-1l-3.3-.2-11.2-.3L14 53l-9.5-.5-2.4-.5L0 49l.2-1.5 2-1.3 2.9.2 6.3.5 9.5.6 6.9.4L38 49.1h1.6l.2-.7-.5-.4-.4-.4L29 41l-10.6-7-5.6-4.1-3-2-1.5-2-.6-4.2 2.7-3 3.7.3.9.2 3.7 2.9 8 6.1L37 36l1.5 1.2.6-.4.1-.3-.7-1.1L33 25l-6-10.4-2.7-4.3-.7-2.6c-.3-1-.4-2-.4-3l3-4.2L28 0l4.2.6L33.8 2l2.6 6 4.1 9.3L47 29.9l2 3.8 1 3.4.3 1h.7v-.5l.5-7.2 1-8.7 1-11.2.3-3.2 1.6-3.8 3-2L61 2.6l2 2.9-.3 1.8-1.1 7.7L59 27.1l-1.5 8.2h.9l1-1.1 4.1-5.4 6.9-8.6 3-3.5L77 13l2.3-1.8h4.3l3.1 4.7-1.4 4.9-4.4 5.6-3.7 4.7-5.3 7.1-3.2 5.7.3.4h.7l12-2.6 6.4-1.1 7.6-1.3 3.5 1.6.4 1.6-1.4 3.4-8.2 2-9.6 2-14.3 3.3-.2.1.2.3 6.4.6 2.8.2h6.8l12.6 1 3.3 2 1.9 2.7-.3 2-5.1 2.6-6.8-1.6-16-3.8-5.4-1.3h-.8v.4l4.6 4.5 8.3 7.5L89 80.1l.5 2.4-1.3 2-1.4-.2-9.2-7-3.6-3-8-6.8h-.5v.7l1.8 2.7 9.8 14.7.5 4.5-.7 1.4-2.6 1-2.7-.6-5.8-8-6-9-4.7-8.2-.5.4-2.9 30.2-1.3 1.5-3 1.2-2.5-2-1.4-3 1.4-6.2 1.6-8 1.3-6.4 1.2-7.9.7-2.6v-.2H49L43 72l-9 12.3-7.2 7.6-1.7.7-3-1.5.3-2.8L24 86l10-12.8 6-7.9 4-4.6-.1-.5h-.3L17.2 77.4l-4.7.6-2-2 .2-3 1-1 8-5.5Z"/>
57
+ <path d="M50 3V35" stroke="#3A4857" stroke-width="2"/>
58
+ <!-- Official Pi logo vectors; source: https://pi.dev/logo-auto.svg -->
59
+ <g transform="translate(52 -5) scale(.06)" fill="#F4F7FA">
60
+ <path fill-rule="evenodd" d="M165.29 165.29H517.36V400H400V517.36H282.65V634.72H165.29ZM282.65 282.65V400H400V282.65Z"/>
61
+ <path d="M517.36 400H634.72V634.72H517.36Z"/>
62
+ </g>
63
+ <text x="104" y="15" fill="#F4F7FA" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="15" font-weight="700" letter-spacing=".8">CLAUDE CODE UX
64
+ </text>
65
+ <text x="104" y="34" fill="#7F8D9C" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="13" letter-spacing="1.2">FOR PI
66
+ </text>
67
+ </g>
68
+ <g transform="translate(0 52)">
69
+ <rect width="474" height="82" rx="14" fill="#101821" stroke="#2C3A48"/>
70
+ <rect width="5" height="82" rx="2.5" fill="#66E3C4"/>
71
+ <text x="26" y="32" fill="#F4F7FA" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="18" font-weight="700">/ccstyle
72
+ </text>
73
+ <text x="26" y="59" fill="#8B9AAD" font-size="16">Tool summaries · Diffs · Status bar
74
+ </text>
75
+ <circle cx="438" cy="29" r="9" fill="#66E3C4" opacity=".18"/>
76
+ <path d="M434 29l3 3 6-7" fill="none" stroke="#66E3C4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
77
+ </g>
78
+ <g transform="translate(0 144)">
79
+ <rect width="474" height="82" rx="14" fill="#101821" stroke="#2C3A48"/>
80
+ <rect width="5" height="82" rx="2.5" fill="#7CC7FF"/>
81
+ <text x="26" y="32" fill="#F4F7FA" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="18" font-weight="700">/context
82
+ </text>
83
+ <text x="26" y="59" fill="#8B9AAD" font-size="16">Usage breakdown · Injected content preview
84
+ </text>
85
+ <g transform="translate(416 23)">
86
+ <rect width="42" height="14" rx="7" fill="#1C2B38"/>
87
+ <rect width="27" height="14" rx="7" fill="#7CC7FF"/>
88
+ </g>
89
+ </g>
90
+ <g transform="translate(0 236)">
91
+ <rect width="474" height="82" rx="14" fill="#101821" stroke="#2C3A48"/>
92
+ <rect width="5" height="82" rx="2.5" fill="#F2C879"/>
93
+ <text x="26" y="32" fill="#F4F7FA" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="18" font-weight="700">@session:
94
+ </text>
95
+ <text x="26" y="59" fill="#8B9AAD" font-size="16">History completion · Cross-session references
96
+ </text>
97
+ <text x="431" y="40" fill="#F2C879" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="26">@
98
+ </text>
99
+ </g>
100
+ </g>
101
+ </svg>
@@ -4,7 +4,7 @@ import {
4
4
  type DiffIndicatorMode,
5
5
  type DiffViewMode,
6
6
  type ToolDisplayConfig,
7
- } from "../renderer/tool-diff/index.ts";
7
+ } from "../renderer/tool/diff/index.ts";
8
8
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
9
9
  import { homedir } from "node:os";
10
10
  import { join } from "node:path";
@@ -25,6 +25,12 @@ export type Config = {
25
25
  animationIntervalMs: number;
26
26
  showStartupHeader: boolean;
27
27
  scrollStepLines: number;
28
+ enableSessionReference: boolean;
29
+ enableSubagentAutocomplete: boolean;
30
+ enableContextCommand: boolean;
31
+ enableAgentSummary: boolean;
32
+ enableWorkingMessage: boolean;
33
+ enableAliases: boolean;
28
34
  };
29
35
 
30
36
  const AGENT_DIR = process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent");
@@ -67,6 +73,12 @@ export const DEFAULT_CONFIG: Config = {
67
73
  animationIntervalMs: 90,
68
74
  showStartupHeader: true,
69
75
  scrollStepLines: 3,
76
+ enableSessionReference: true,
77
+ enableSubagentAutocomplete: true,
78
+ enableContextCommand: true,
79
+ enableAgentSummary: true,
80
+ enableWorkingMessage: true,
81
+ enableAliases: true,
70
82
  };
71
83
 
72
84
  function pickEnum<T extends string>(value: unknown, allowed: readonly T[], fallback: T): T {
@@ -86,22 +98,6 @@ export function pickPositiveNumber(value: unknown, fallback: number, min = 1): n
86
98
  return Number.isFinite(n) ? Math.max(min, n) : fallback;
87
99
  }
88
100
 
89
- export function nearestPreset(value: number, presets: readonly string[]): string {
90
- const numeric = presets.map((p) => Number(p));
91
- let best = presets[0] ?? String(value);
92
- let bestDist = Number.POSITIVE_INFINITY;
93
- for (let i = 0; i < numeric.length; i++) {
94
- const dist = Math.abs((numeric[i] ?? 0) - value);
95
- if (dist < bestDist) {
96
- bestDist = dist;
97
- best = presets[i] ?? best;
98
- }
99
- }
100
- // Prefer exact match when value is already a preset.
101
- const exact = presets.find((p) => Number(p) === value);
102
- return exact ?? best;
103
- }
104
-
105
101
  export function normalizeConfig(input: unknown): Config {
106
102
  const source = (input && typeof input === "object" ? input : {}) as Record<string, unknown>;
107
103
  const mode = source.mode;
@@ -164,6 +160,12 @@ export function normalizeConfig(input: unknown): Config {
164
160
  ),
165
161
  showStartupHeader: source.showStartupHeader !== false,
166
162
  scrollStepLines: pickPositiveInt(source.scrollStepLines, DEFAULT_CONFIG.scrollStepLines, 1, 50),
163
+ enableSessionReference: source.enableSessionReference !== false,
164
+ enableSubagentAutocomplete: source.enableSubagentAutocomplete !== false,
165
+ enableContextCommand: source.enableContextCommand !== false,
166
+ enableAgentSummary: source.enableAgentSummary !== false,
167
+ enableWorkingMessage: source.enableWorkingMessage !== false,
168
+ enableAliases: source.enableAliases !== false,
167
169
  };
168
170
  }
169
171
 
@@ -205,6 +207,12 @@ export function formatConfigStatus(source: Config = config): string {
205
207
  `thinkingAnimation=${source.animationIntervalMs}ms`,
206
208
  `startupHeader=${source.showStartupHeader ? "on" : "off"}`,
207
209
  `scrollStep=${source.scrollStepLines}`,
210
+ `sessionRef=${source.enableSessionReference ? "on" : "off"}`,
211
+ `subagentAuto=${source.enableSubagentAutocomplete ? "on" : "off"}`,
212
+ `context=${source.enableContextCommand ? "on" : "off"}`,
213
+ `agentSummary=${source.enableAgentSummary ? "on" : "off"}`,
214
+ `workingMsg=${source.enableWorkingMessage ? "on" : "off"}`,
215
+ `aliases=${source.enableAliases ? "on" : "off"}`,
208
216
  ].join(" · ");
209
217
  }
210
218
 
@@ -7,9 +7,9 @@
7
7
  import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
8
8
  import { Input, SettingsList, matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
9
9
  import type { CompactThinkingController } from "../feature/compact-thinking.ts";
10
- import { applyStartupHeader } from "../feature/pi-startup-header.ts";
11
- import type { ToolGroupingHooks } from "../renderer/tool-grouping.ts";
12
- import type { DiffIndicatorMode, DiffViewMode } from "../renderer/tool-diff/index.ts";
10
+ import { applyStartupHeader } from "../feature/shell/startup-header.ts";
11
+ import type { ToolGroupingHooks } from "../renderer/tool/grouping.ts";
12
+ import type { DiffIndicatorMode, DiffViewMode } from "../renderer/tool/diff/index.ts";
13
13
  import {
14
14
  config,
15
15
  DEFAULT_CONFIG,
@@ -64,6 +64,30 @@ function diffIndicatorDescription(mode: DiffIndicatorMode): string {
64
64
  return "Vertical bar indicators on changed lines (default).";
65
65
  }
66
66
 
67
+ /** 额外功能开关项:on/off 二值,描述随状态切换;切换后需重启生效。 */
68
+ function featureToggleSetting(
69
+ id: string,
70
+ label: string,
71
+ onDescription: string,
72
+ offDescription: string,
73
+ current: boolean,
74
+ ) {
75
+ const setting = {
76
+ id,
77
+ label,
78
+ description: current ? onDescription : offDescription,
79
+ currentValue: current ? "on" : "off",
80
+ values: ["on", "off"],
81
+ };
82
+ return {
83
+ setting,
84
+ apply(on: boolean): void {
85
+ setting.currentValue = on ? "on" : "off";
86
+ setting.description = on ? onDescription : offDescription;
87
+ },
88
+ };
89
+ }
90
+
67
91
  function buildExcludeRenderersSubmenu(
68
92
  onClose: () => void,
69
93
  onLiveChange: () => void,
@@ -334,7 +358,68 @@ export async function showCcstylePanel(
334
358
  buildNumberInputSubmenu(theme, scrollStepSetting, closeSubmenu),
335
359
  };
336
360
 
361
+ // 额外功能开关:注册于扩展加载期,切换后需重启(/reload)生效。
362
+ const sessionReferenceToggle = featureToggleSetting(
363
+ "enableSessionReference",
364
+ "Session reference",
365
+ "@ session mentions search & inject referenced session context. Next restart applies.",
366
+ "Session reference disabled.",
367
+ config.enableSessionReference,
368
+ );
369
+ const subagentAutocompleteToggle = featureToggleSetting(
370
+ "enableSubagentAutocomplete",
371
+ "Subagent autocomplete",
372
+ "@ subagent mentions suggest agents and inject delegation instructions. Next restart applies.",
373
+ "Subagent autocomplete disabled.",
374
+ config.enableSubagentAutocomplete,
375
+ );
376
+ const contextCommandToggle = featureToggleSetting(
377
+ "enableContextCommand",
378
+ "Context usage",
379
+ "/context shows context-window distribution with previews. Next restart applies.",
380
+ "Context command disabled.",
381
+ config.enableContextCommand,
382
+ );
383
+ const agentSummaryToggle = featureToggleSetting(
384
+ "enableAgentSummary",
385
+ "Agent summary",
386
+ "Append per-round tool stats after each agent turn. Next restart applies.",
387
+ "Agent summary disabled.",
388
+ config.enableAgentSummary,
389
+ );
390
+ const workingMessageToggle = featureToggleSetting(
391
+ "enableWorkingMessage",
392
+ "Working message",
393
+ "Extend Working... footer with token count and elapsed time. Next restart applies.",
394
+ "Native Working... footer only.",
395
+ config.enableWorkingMessage,
396
+ );
397
+ const aliasesToggle = featureToggleSetting(
398
+ "enableAliases",
399
+ "Aliases",
400
+ "/clear and /exit aliases enabled. Next restart applies.",
401
+ "Aliases disabled.",
402
+ config.enableAliases,
403
+ );
404
+ const featureToggles: Record<string, { apply: (on: boolean) => void }> = {
405
+ enableSessionReference: sessionReferenceToggle,
406
+ enableSubagentAutocomplete: subagentAutocompleteToggle,
407
+ enableContextCommand: contextCommandToggle,
408
+ enableAgentSummary: agentSummaryToggle,
409
+ enableWorkingMessage: workingMessageToggle,
410
+ enableAliases: aliasesToggle,
411
+ };
412
+
337
413
  const onSettingChange = (id: string, value: string) => {
414
+ // 额外功能开关:字段名与配置布尔字段一一对应,切换后重启生效。
415
+ const featureToggle = featureToggles[id];
416
+ if (featureToggle) {
417
+ (config as unknown as Record<string, boolean>)[id] = value === "on";
418
+ featureToggle.apply(value === "on");
419
+ saveConfig();
420
+ ctx.ui.notify(`Updated ${id}: ${value} (next restart)`, "info");
421
+ return;
422
+ }
338
423
  switch (id) {
339
424
  case "mode": {
340
425
  // 选项值带 Experimental 标记,选择后还原为真实 mode 值。
@@ -450,7 +535,16 @@ export async function showCcstylePanel(
450
535
  {
451
536
  id: "feature",
452
537
  label: "Feature",
453
- items: [startupHeaderSetting, scrollStepSetting],
538
+ items: [
539
+ startupHeaderSetting,
540
+ scrollStepSetting,
541
+ sessionReferenceToggle.setting,
542
+ subagentAutocompleteToggle.setting,
543
+ contextCommandToggle.setting,
544
+ agentSummaryToggle.setting,
545
+ workingMessageToggle.setting,
546
+ aliasesToggle.setting,
547
+ ],
454
548
  },
455
549
  ];
456
550
 
@@ -553,4 +647,6 @@ export async function showCcstylePanel(
553
647
  },
554
648
  };
555
649
  });
650
+ // 面板卸下后主 transcript 重新挂载;再刷一次,吃掉打开期间扫树失败的切换。
651
+ hooks.refreshCurrentTranscript(ctx, toolGrouping);
556
652
  }