Uh oh!
There was an error while loading. Please reload this page.
fix(plan-mode): render plan_ready output as Markdown - #293
Conversation
tt-a1i
left a comment
There was a problem hiding this comment.
P1 Must-Fix:extensions/plan-mode/index.ts:455-462 的自定义 renderResult 忽略了 options.expanded,折叠态和展开态都会返回完整 Markdown。Pi 会把 expanded 状态传给自定义 renderer,但不会替它截断 renderer 返回的行;因此接近现有 48 KiB 上限的计划会在默认折叠态整段铺进 transcript,Ctrl+O 也不会产生任何折叠效果。新增测试 tests/extensions/plan-mode/result-rendering.test.ts:242-252 还把 collapsed/expanded 完全相同固定成了预期,这与 PR 中“Pi 已提供 expand/collapse,所以不需要第二层截断”的理由相矛盾。请在 expanded === false 时提供有界摘要/预览,在展开态再渲染完整 Markdown,并补一条长计划测试,证明默认输出行数有界且展开能恢复完整内容。
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe plan mode extension now renders completed ChangesPlan result rendering
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk:⚪ Minimal · up to This change only renders finalized plans as Markdown in the TUI without altering plan content, tools, state, or runtime behavior; no actionable merge-blocking risk remains after normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
plan_ready registered no renderResult, so the TUI fell back to its plain-text renderer and the recorded plan appeared as raw Markdown source. Render it with the Markdown component, the same treatment subagent results already get. Validated with bun run check (format, lint, tsc) and bun run test (959 node:test cases and 30 vitest cases pass) on Linux.
Nine cases pin that the renderer is registered and that a realistic plan survives it: headings, ordered and nested lists, block quotes, tables, inline code and bold, links, three fenced code shapes, a thematic break, a 40K plan, and unicode. Assertions strip ANSI first, because the Markdown component colors itself from the global theme rather than the theme passed to renderResult. Verified red against the pre-fix code (all nine fail with "plan_ready must supply renderResult"), so these catch the regression rather than just documenting it.
Collapsed state was identical to expanded: the custom renderResult ignored the expanded flag, so a plan near the 48KiB cap flooded the transcript and Ctrl+O produced no visible change. Pi never truncates custom renderer output; the renderer owns the collapsed/expanded contract (same pattern as git-read and renderWaitResult). Collapsed now renders one bounded line with the line count and an expand hint via keyHint; expanded renders the full Markdown as before. Replaces the old case that pinned collapsed == expanded with two cases: collapsed stay bounded and expanded restores the full plan.
bc0e564 to
80a6e2cCompareCodeRabbit docstring coverage scoped to diff-touched functions requires 80%. Adds JSDoc to plan_ready renderResult (index.ts) and the stripAnsi, loadPlanReady and renderPlan helpers (result-rendering.test.ts).
A bare line count made the collapsed result impossible to scan in a long session. Collapsed now shows the header (Plan ready · N lines · expand hint) followed by the first PLAN_PREVIEW_LINES (10) plan lines and a ... (N more lines) tail; the expand hint and tail disappear when the plan fits the preview, matching bash/fallback and git-read conventions. Tests: long-plan preview bounded with tail hidden, short plan without hint, count boundaries at the cap (1/10/11 lines), trailing newline semantics, narrow-width wrapping of unbroken lines, deterministic output, and the expanded tail sentinel restore. Red-verified: disabling the expanded gate fails the five collapsed cases.
Matt-qwq
commented
Aug 31, 2026
已按 P1 修复完毕:renderResult 现在遵循 expanded 契约——折叠态渲染有界预览(Plan ready · N lines · + 前 10 行内容 + ...(N more lines) 尾注),展开态渲染完整 Markdown。旧测试(断言折叠=展开)已替换为边界用例(行数边界1/10/11、尾换行、窄屏 wrap、幂等、末行 sentinel),红绿验证通过。请重新 review。 |
tt-a1i
left a comment
There was a problem hiding this comment.
复审 exact head c39f119373ad1a44402a46418d46144a030559c4。这次已实现 expanded 分支和多行摘要,旧版折叠/展开完全相同的问题已有实质修复。渲染计划为 Markdown 的价值成立,也没有改变模型正文或 Plan Mode 生命周期。
Standards
0 项确认违规;沿用 Pi renderResult,无需新抽象。
Spec
仍有 1 项 P2:预览只限制源文本行,不限制终端换行后的屏幕行。真实 renderer 输入47000字符单行(小于48KiB上限),width=40,折叠态输出1176行,且没有展开提示。默认输出仍可能刷屏;详见行内。
验证:bun run check通过;result-rendering专项15/15通过;上述独立renderer复现通过。完整测试并行尝试遇到setup集成子进程超时,不能记为全套通过;此复现不依赖那个失败。未做安装后真实TUI验收。只需补实际渲染行的裁剪和长单行回归,不需要新增组件框架。
| text += | ||
| theme.fg("muted", " · ") + keyHint("app.tools.expand", "to expand"); | ||
| } | ||
| for (const line of lines.slice(0, PLAN_PREVIEW_LINES)) { |
There was a problem hiding this comment.
[P2] 预览应限制渲染行,而不只是源文本行
这里 slice(0, PLAN_PREVIEW_LINES) 后仍返回会按终端宽度换行的 Text。合法输入 "a".repeat(47000) 只有一行,小于已有48KiB上限;实际 renderResult(...,{expanded:false},theme).render(40) 返回1176行,而且 lines.length === 1 使展开提示不出现。因而这条旧问题只修复了多行输入,长段落/minified内容仍刷屏。请按实际可见行约束折叠预览(并保留展开的完整内容),加一个长单行窄屏测试,断言总行数有界;当前窄屏测试只断言每行宽度。
tt-a1i
commented
Aug 31, 2026
当前 head c39f119 已复审:旧 expanded 分支已修好,但47000字符单行在40列折叠态仍输出1176行,无展开提示。请按实际渲染行裁剪,详见 #293 (review) 。check和15项专项通过;未宣称全套或真实TUI通过。本轮未改代码或合并。 |
Problem
plan_readyrenders the finalized plan as raw Markdown source in the TUI.extensions/plan-mode/index.tsregistersplan_readywith only anexecutehandler and norenderResult, so the TUI falls back to its default plain-text renderer: headings, lists, and code fences appear as literal#,-, and```characters instead of rendered text.
Affects every Plan Mode user — the plan is the one artifact Plan Mode exists to produce, and it is meant to be read, not inspected as source.
No existing issue tracks this. I searched
plan_ready,renderResult, and Markdown-rendering across open and closed issues inopenpi-dev/openpi; the closest hits (#28, #27, #18, #105, #101, #96, #93, #67, #40) are all about othersubsystems.
Value
Every other extension tool that returns human-readable prose already supplies a renderer — there are 19
renderResultimplementations acrossgoal,tasks,git-read,file-search,workflows,subagents,ask-user,background-terminals, andfile-mutation-display.plan_readyis the outlier. Rendering it makes Plan Mode's output consistent with the rest of OpenPI and lets the user read the plan without decoding Markdown syntax.Approach
Add
renderResultto theplan_readyregistration, renderingresult.details.planwith theMarkdowncomponent from@earendil-works/pi-tuiusinggetMarkdownTheme()— the same treatmentrenderWaitResult()gives subagent results(
extensions/subagents/src/ui/wait-result.ts:59).Two deliberate choices:
expandedflag to custom renderers but never truncates their output — the renderer owns the collapsed/expanded contract (same pattern asgit-readandrenderWaitResult). Collapsed rendersPlan ready · N lines · <to expand>plus the first 10 plan lines and a... (N more lines)tail; the hint and tail disappear when the plan fits the preview. Only the expanded state renders the full Markdown. Without this, a plan near the 48 KiB cap floods the transcript and Ctrl+O produces no visible change.executealready storessanitizeTerminalText(params.plan), sodetails.planis clean on the way in.Validation
Ran on WSL2 (Fedora 44), Node v22.23.1, bun 1.3.14:
bun run testgrows from 959 to 968 cases — the 9 intests/extensions/plan-mode/result-rendering.test.ts. Those were verified red against the pre-fix code: withrenderResultremoved, all nine fail withplan_ready must supply renderResult, so they catch the regression rather than document it.Manual TUI check. Loaded the checkout with
pi install, ran/plan, and calledplan_readywith a plan exercising headings, ordered and nested lists, a block quote, a table, inline code, bold, italics, links, three fenced code shapes,and a thematic break. In the TUI: heading markers are consumed, the table renders with box-drawing characters, the quote gets a
│gutter, links render aslabel (URL), the thematic break becomes a─rule, and fenced code bodies areindented two spaces.
Expanded-contract verification. Red/blue: with the
expandedgate disabled thebounded-preview case turns red, proving the tests catch a collapsed==expanded regression.
Real TUI with a 390-line plan: collapsed shows the header plus a preview of the plan body and a
... (N more lines)tail, andCtrl+O renders the full Markdown.
Two behaviors are pi-tui's design, not regressions:
```characters —Markdownrenders them viatheme.codeBlockBorder()(pi-tui/dist/components/markdown.js:384) and colors them rather than drawing a background block.###prefix; only levels 1–2 hide it (markdown.js:350). Level 3+ still receives heading color and bold.Impact
plan_readyoutput now goes through the TUI Markdown renderer instead of the plain-text fallback. Heading markers are consumed, list bullets and code fences are colored, inline code / bold / italic / linkmarkers are consumed, tables are drawn with box characters, and fenced code bodies are indented. Nothing else changes.
promptSnippet,promptGuidelines, parameters, or the text returned incontent— only how the result is drawn.renderResultis pure presentation;terminate: truesemantics and the plan-state commit are untouched.plan_readyremains parent-only (already inCHILD_EXCLUDED_TOOL_NAMES,extensions/shared/child-session.ts:452), so the child-session drift guard is unaffected — its test passes.Summary by CodeRabbit
New Features
Tests