feat: 新增 /raw 命令交互与终端消息直出#89
Merged
Merged
Conversation
- 新增 RawMode 功能,包括 Normal、Lite 和 Raw scrollback 模式 - App 组件中集成 RawMode 上下文及切换逻辑,支持在 Raw 模式下直接向 stdout 渲染消息 - 增加 RawModeExitPrompt 组件,支持按 ESC 退出原始模式 - 新增 RawModelDropdown 组件,提供原始模式选择下拉菜单 - 在 PromptInput 中集成原始模式选择交互及状态管理 - 调整消息视图实现,拆分 MessageView 到 compoments 目录,支持根据 RawMode 呈现不同内容 - 新建 AppContainer 组件,包装 App 并提供版本上下文和 RawModeProvider - 修改 SlashCommand 体系,支持内置 /raw 命令及对应测试覆盖 - 更新 cli 入口,使用 AppContainer 替换直接渲染 App,传递版本信息 - 移除旧 MessageView 文件,重构消息渲染逻辑 - 优化 SlashCommandMenu 显示,支持命令参数提示显示 - 更新相关测试,支持原始模式功能验证
# Conflicts: # src/ui/MessageView.tsx # src/ui/PromptInput.tsx
- 提取状态行文本为 statusLine 变量 - 创建 ToolSummary 对象汇总工具信息 - 获取并渲染更新计划的预览行 - 当有计划内容时,追加显示计划标题和内容 - 保持无计划时返回单行状态信息
- 修改StatusLine组件的params传值逻辑 - 当content存在时,params传入空字符串,避免显示错误 - 保持了内容渲染的兼容性和逻辑清晰性
- 新增 renderMessageToStdout 函数的多场景测试,包括用户、助手、工具和系统消息的渲染行为 - 添加 getUpdatePlanPreviewLines 对 UpdatePlan 工具消息的计划内容提取测试 - 增加 parseToolPayload 函数对空内容、无效 JSON 和有效负载的解析测试 - 引入辅助函数 makeSessionMessage 以简化测试消息实例构造 - 确保各种边界条件和meta字段的渲染正确性验证
- 在 RawModeContext 中增加 previousMode 状态用于保存上一个模式 - 修改 setMode 逻辑以更新 previousMode,支持通过函数设置模式 - RawModeExitPrompt 捕获并使用快照 previousMode 作为退出时目标模式 - 调整 App.tsx 处理 RawMode 切换逻辑,避免界面闪烁并重置欢迎屏幕状态 - 处理无激活会话时显示欢迎屏幕,确保状态正确更新 - 优化 Raw 模式消息加载逻辑,避免活跃会话缺失时的错误 - 更新测试用例中消息构建函数支持更多可选属性与默认值设置 - 修改 renderMessageToStdout 测试示例以配合新的消息结构及元信息
- 在 README.md 和 README_en.md 文件中新增居中标题和统一头部样式 - README.md 中添加“[English](./README_en.md) · 中文”语言切换链接 - README_en.md 中添加“English · [中文](./README.md)”语言切换链接 - README.md 新增 `/raw` 命令介绍,补充命令表内容 - 删除冗余的 README_cn.md 文件,简化文档管理
- 修改 useAppContext 钩子,安全处理无上下文情况,返回默认版本信息 - 更新 cli.tsx 中 AppContainer 的导入方式,改为从统一入口导入 - 在 ui/index.ts 中导出 AppContainer 组件 - 新增 UI 共享常量 ARGS_SEPARATOR,提升分隔符一致性 feat(ui): 优化命令行提示参数分隔符显示 - 在 PromptInput 和 SlashCommandMenu 组件中使用 ARGS_SEPARATOR 替代硬编码分隔符 - 调整 SlashCommandMenu 中命令行长度计算逻辑,兼容新分隔符 fix(ui): 修正 slashCommands 过滤匹配逻辑 - 将命令匹配条件从包含改为完全相等,提高准确性 feat(ui): 扩展消息视图工具信息展示 - 增加对 tool 消息中 meta.resultMd 字段的渲染支持 - 在工具状态行后增加 Result 结果块,配合 Plan 预览一同展示 - 更新 renderMessageToStdout 相关测试,覆盖新展示逻辑
- 在 Raw 模式下,使用 process.stdout.write 直接输出所有可见消息 - 清屏并重置光标位置,避免 Ink 组件干扰 - 显示提示信息,指导用户按 ESC 退出 raw 模式 - 优化终端尺寸变化时的重绘逻辑 - 更新依赖,确保 raw 模式变动触发重新渲染
- 合并并调整了关于窗口宽度columns的使用,去除了stableColumns状态 - 引用lastRenderedColumnsRef改为直接使用columns,避免延迟更新 - 将多个相关的useRef(writeRef、rawModeRef、messagesRef、processStdoutRef)移至同一位置声明 - 调整useEffect依赖项,改为监听columns代替stableColumns - 优化RawMode下消息重绘逻辑,确保宽度变化时重新渲染 - 统一了screenWidth的计算逻辑,简化代码结构
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
新增
/raw命令,支持在 Lite / Normal / Raw scrollback 三种显示模式间切换。Raw scrollback 模式下绕过 Ink<Static>组件,直接使用process.stdout.write将消息输出到终端,实现传统命令行滚动效果。按Esc键可退出 Raw 模式回到 Normal 视图。Fixes: #82
Behavior Changes
/raw命令交互/raw弹出RawModelDropdown,提供三种模式选择:reasoning_content显示"(reasoning...)"reasoning_content显示完整文本process.stdoutEsc退出,切换回 Normal 模式的 chat 视图onAssistantMessage回调直接追加到 stdoutbuildThinkingSummary行为变更新增
mode?: RawMode参数,控制隐藏 reasoning content 的回显策略:RawMode.Lite:返回"(reasoning...)"RawMode.None/RawMode.Raw:返回完整reasoning_content文本MessageView 组件重构
src/ui/compoments/MessageView/目录,拆分为index.tsx、utils.ts、types.ts、markdown.tsbuildThinkingSummary、parseToolPayload、formatStatusName、truncate等)统一在utils.ts中导出renderMessageToStdout函数:将MessageView的 JSX 渲染逻辑转换为纯 ANSI 字符串,供 Raw 模式 stdout 输出getUpdatePlanPreviewLines:提取 UpdatePlan 工具的 Plan 内容renderMessageToStdout中支持 Plan 消息渲染(└ Plan+ 每行内容)StatusLine组件新增widthprop,Lite 模式下使用truncate-end换行策略Slash 命令增强
/raw命令新增args字段,支持输入框内联参数提示:/raw lite|normal|raw-scrollbackSlashCommandItem类型新增可选args字段New Files
src/ui/contexts/RawModeContext.tsxsrc/ui/contexts/AppContext.tsxsrc/ui/contexts/index.tssrc/ui/compoments/MessageView/index.tsxsrc/ui/compoments/MessageView/utils.tsrenderMessageToStdout+getUpdatePlanPreviewLinessrc/ui/compoments/MessageView/types.tssrc/ui/compoments/MessageView/markdown.tssrc/ui/compoments/RawModelDropdown/index.tsxsrc/ui/compoments/RawModeExitPrompt/index.tsxsrc/ui/compoments/index.tsModified Files
src/ui/App.tsxhandleRawModeChange清屏+stdout 输出、Raw 模式下渲染RawModeExitPrompt、staticItems在 Raw 模式返回空数组、onAssistantMessageRaw 模式下追加 stdout、移除已提取到utils.ts的函数src/ui/PromptInput.tsxonRawModeChange和projectRootprops、/raw命令打开RawModelDropdown、useInput的openRawModelDropdown守卫src/ui/slashCommands.tsrawkind 和args字段、SlashCommandItem新增args类型src/ui/index.tsparseDiffPreview、renderMarkdown导出src/tests/messageView.test.tsbuildThinkingSummary、新增 21 个测试用例覆盖renderMessageToStdout/getUpdatePlanPreviewLines/parseToolPayloadKey Technical Decisions
<Static>:staticItems在RawMode.Raw下返回[],<Static>不渲染消息,消息通过process.stdout.write直接输出rawModeRef模式:onAssistantMessage闭包在useMemo创建的SessionManager中,使用useRef读取最新 mode 值setMode双重调用:RawModelDropdown内部和handleRawModeChange均调用setMode,确保 context 始终同步useInput:RawModeExitPrompt使用 Ink 的useInputhook 而非直接监听process.stdin,避免与 Ink 内部输入机制冲突renderMessageToStdout提取到utils.ts:避免App.tsx和utils.ts中重复维护相同的渲染逻辑Verification
Test Coverage
新增 21 个测试用例,覆盖以下 Raw 模式核心函数:
renderMessageToStdoutgetUpdatePlanPreviewLinesparseToolPayloadok: false、name去空格