Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions docs/design/ctrl-o-detail-expand/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@

> **实现状态对照(当前 PR)**:
>
> | 部分 | 状态 |
> | ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
> | 删除全局 compactMode(context/settings/toggle/i18n key、`mergeCompactToolGroups`) | ✅ 已实现 |
> | `fullDetail` 管线(`HistoryItemDisplay`/`ToolGroupMessage`,并入 `forceExpandAll`/`forceShowResult`/思考块 expanded) | ✅ 已实现 |
> | `fullDetail` 不被 `ToolGroupMessage` 两个 early return 绕过(纯并行/ memory-only 守 `!fullDetail`) | ✅ 已实现 + 回归测试 |
> | `TranscriptView` + alt-screen 接入(Ctrl+O 开关、Esc/q/Ctrl+C 关闭、双段冻结、退出重绘、后台确认自动关闭、消息队列守卫) | ✅ 已实现 |
> | 基于 #5661 type-based partition 的 rebase(已合入 main) | ✅ 已实现 |
> | `AlternateScreen` 的 `process.stdout.isTTY` guard(§4.2) | ✅ 已实现 + 测试 |
> | i18n 旧 compact 文案清理(9 语言)+ KeyboardShortcuts `ctrl+o → view transcript` 文案(§5) | ✅ 已实现 |
> | **read/search/list 完整明细透传到 transcript(§4.9:`detailedDisplay` 提取 helper + 渲染拆分 + live/resume/replay)** | ✅ **已实现 + 测试**(方案 Y:core `getToolResponseDisplayText` + live/resume 派生 + `ToolMessage` 数据源切换;ACP 经 `transformPartsToToolCallContent` 已带全文,无需新增协议字段;截图 §3.4 待重录) |
> | **鼠标点击工具 block 就地展开(§4.8,follow-up)** | ⏭️ **follow-up(独立 PR,不在本 PR)**——理由见 §4.8:type-based 下无 per-tool 点击目标、~250–400 行、SGR 选区风险 |
> | 部分 | 状态 |
> | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
> | 删除全局 compactMode(context/settings/toggle/i18n key、`mergeCompactToolGroups`) | ✅ 已实现 |
> | `fullDetail` 管线(`HistoryItemDisplay`/`ToolGroupMessage`,并入 `forceExpandAll`/`forceShowResult`/思考块 expanded) | ✅ 已实现 |
> | `fullDetail` 不被 `ToolGroupMessage` 两个 early return 绕过(纯并行/ memory-only 守 `!fullDetail`) | ✅ 已实现 + 回归测试 |
> | `TranscriptView` + alt-screen 接入(Ctrl+O 开关、Esc/q/Ctrl+C 关闭、双段冻结、退出重绘、后台确认自动关闭、消息队列守卫) | ✅ 已实现 |
> | 基于 #5661 type-based partition 的 rebase(已合入 main) | ✅ 已实现 |
> | `AlternateScreen` 的 `process.stdout.isTTY` guard(§4.2) | ✅ 已实现 + 测试 |
> | i18n 旧 compact 文案清理(9 语言)+ KeyboardShortcuts `ctrl+o → view transcript` 文案(§5) | ✅ 已实现 |
> | **read/search/list 完整明细透传到 transcript(§4.9:`detailedDisplay` 提取 helper + 渲染拆分 + live/resume/replay)** | ✅ **已实现 + 测试**(方案 Y:core `getToolResponseDisplayText` + live/resume 派生 + `ToolMessage` 数据源切换;ACP 经 `transformPartsToToolCallContent` 已带全文,无需新增协议字段;截图 §3.4 待重录) |
> | **鼠标点击工具 block 就地展开(§4.8,follow-up)** | ⏭️ **follow-up(独立 PR,不在本 PR)**——理由见 §4.8:type-based 下无 per-tool 点击目标、~250–400 行、SGR 选区风险 |

---

Expand Down Expand Up @@ -386,7 +386,7 @@ claude code 的机制是"**存储层保留完整、显示层按 `verbose` 截断

| 文件 | 动作 |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `packages/cli/src/config/keyBindings.ts` | 删 `TOGGLE_COMPACT_MODE`;加 `TOGGLE_TRANSCRIPT='toggleTranscript'`,默认绑 Ctrl+O;保留 `SHOW_MORE_LINES`(Ctrl+S) 不动。启动迁移检测**当前不适用**——代码库无用户可配置 keybinding 覆盖(`keyMatchers` 恒用硬编码默认值),无残留绑定可扫描(见 §6) |
| `packages/cli/src/config/keyBindings.ts` | 删 `TOGGLE_COMPACT_MODE`;加 `TOGGLE_TRANSCRIPT='toggleTranscript'`,默认绑 Ctrl+O;保留 `SHOW_MORE_LINES`(Ctrl+S) 不动。启动迁移检测**当前不适用**——代码库无用户可配置 keybinding 覆盖(`keyMatchers` 恒用硬编码默认值),无残留绑定可扫描(见 §6) |
| `packages/cli/src/ui/keyMatchers.ts` | 同步增删 matcher |
| `packages/cli/src/ui/AppContainer.tsx` | 删 `compactMode/compactInline/setCompactMode` 状态、`CompactModeProvider`、Ctrl+O 旧分支、`compactToggleHasVisualEffect` 调用;加 `isTranscriptOpen`(canonical useState,§4.2)+ `isTranscriptOpenRef` + `transcriptFreeze` + `toggleTranscript/openTranscript/closeTranscript`;全局 Ctrl+O→`toggleTranscript`;Esc/q/Ctrl+C **handleGlobalKeypress 第一分支**关闭(早于 QUIT/EXIT/ESCAPE 及 vim INSERT 守卫,§4.3);`useEffect` 监听**全部阻塞确认/对话框**自动关闭(§4.6 #1);消息队列 drain 守卫加 `\|\| isTranscriptOpenRef.current`(§4.6 #3);`refreshStatic`用`isTranscriptOpenRef`守卫、退出时重绘一次(§4.4)。**不并入 `dialogsVisible`,不改 `useDialogClose`** |
| `packages/cli/src/ui/contexts/UIStateContext.tsx` | **不改**:transcript 态留 `AppContainer` 本地、顶层消费,**不 surface**(取证:ThinkingViewer / claude-code REPL-local 先例,§4.2)。实现代码已如此 |
Expand Down
4 changes: 1 addition & 3 deletions packages/cli/src/ui/components/TranscriptView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ describe('<TranscriptView />', () => {

it('enters and exits the alternate screen by default (useAlternateScreen defaults to true)', () => {
setTTY(true);
const { unmount } = renderWithProviders(
<TranscriptView items={items} />,
);
const { unmount } = renderWithProviders(<TranscriptView items={items} />);
// The default path drives AlternateScreen with disabled=false, which writes
// the enter-alt-screen escape on mount.
expect(writeRaw).toHaveBeenCalledWith(
Expand Down
10 changes: 4 additions & 6 deletions packages/mobile-mcp/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,10 @@ const startSseServer = async (host: string, port: number) => {

app.get('/mcp', (req, res) => {
if (transport) {
res
.status(409)
.json({
error:
'Another client is already connected. Disconnect the existing client first.',
});
res.status(409).json({
error:
'Another client is already connected. Disconnect the existing client first.',
});
return;
}

Expand Down
30 changes: 30 additions & 0 deletions packages/web-shell/client/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ import {
type WebShellMarkdownCustomization,
type ToolHeaderExtraRenderer,
type UserMessageContentRenderer,
type UserMessageContentParser,
type AssistantTurnFooterRenderer,
type WelcomeHeaderRenderer,
type WelcomeFooterRenderer,
Expand All @@ -185,6 +186,9 @@ import {
type MarkdownTableMode,
type WebShellTaskInfo,
type WebShellAtProvider,
type WebShellBuiltinAtProvidersConfig,
type ComposerTagClickHandler,
type ComposerTagRenderer,
type WebShellComposerTagIconMap,
type WebShellBottomStatusItem,
} from './customization';
Expand Down Expand Up @@ -415,6 +419,8 @@ export interface WebShellProps {
hiddenSlashCommands?: string[];
/** Slash command category order. Defaults to custom, skill, system. */
slashCommandCategoryOrder?: CommandDisplayCategoryOrder;
/** Built-in @ mention providers to enable. Defaults to all built-ins. */
builtinAtProviders?: WebShellBuiltinAtProvidersConfig;
/** Additional @ mention categories shown alongside built-in files/extensions. */
atProviders?: readonly WebShellAtProvider[];
/** Icon URLs for custom composer tag kinds used by @ mention chips. */
Expand All @@ -425,8 +431,16 @@ export interface WebShellProps {
renderWelcomeHeader?: WelcomeHeaderRenderer;
/** Custom renderer shown below the chat composer in the empty welcome state. */
renderWelcomeFooter?: WelcomeFooterRenderer;
/** Parse user-message text into display parts such as chips. */
parseUserMessageContent?: UserMessageContentParser;
/** Custom renderer for the inside of user chat bubbles. Defaults to plain text. */
renderUserMessageContent?: UserMessageContentRenderer;
/** Custom renderer for composer and user-message tags. */
renderComposerTag?: ComposerTagRenderer;
/** Custom hover content for composer and user-message tags. */
renderComposerTagTooltip?: ComposerTagRenderer;
/** Click handler for composer and user-message tags. */
onComposerTagClick?: ComposerTagClickHandler;
/** Custom renderer displayed after the final assistant message of each turn. */
renderAssistantTurnFooter?: AssistantTurnFooterRenderer;
/** Custom renderer inserted before the built-in chat composer toolbar controls. */
Expand Down Expand Up @@ -839,12 +853,17 @@ export function App({
onBugReport,
hiddenSlashCommands,
slashCommandCategoryOrder,
builtinAtProviders,
atProviders,
composerTagIcons,
renderToolHeaderExtra,
renderWelcomeHeader,
renderWelcomeFooter,
parseUserMessageContent,
renderUserMessageContent,
renderComposerTag,
renderComposerTagTooltip,
onComposerTagClick,
renderAssistantTurnFooter,
renderComposerToolbarStart,
renderComposerToolbarEnd,
Expand Down Expand Up @@ -961,7 +980,12 @@ export function App({
renderToolHeaderExtra,
renderWelcomeHeader,
renderWelcomeFooter,
parseUserMessageContent,
renderUserMessageContent,
composerTagIcons,
renderComposerTag,
renderComposerTagTooltip,
onComposerTagClick,
renderAssistantTurnFooter,
renderComposerToolbarStart,
renderComposerToolbarEnd,
Expand All @@ -977,7 +1001,12 @@ export function App({
renderToolHeaderExtra,
renderWelcomeHeader,
renderWelcomeFooter,
parseUserMessageContent,
renderUserMessageContent,
composerTagIcons,
renderComposerTag,
renderComposerTagTooltip,
onComposerTagClick,
renderAssistantTurnFooter,
renderComposerToolbarStart,
renderComposerToolbarEnd,
Expand Down Expand Up @@ -5156,6 +5185,7 @@ export function App({
commands={commands}
skills={loadedSkills}
slashCommandCategoryOrder={slashCommandCategoryOrder}
builtinAtProviders={builtinAtProviders}
atProviders={atProviders}
composerTagIcons={composerTagIcons}
queuedMessages={queuedTexts}
Expand Down
Loading
Loading