spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

mods/diff: under 110 columns /diff answers the built-in's resize line and opens nothingBrowse files
poteat authored on Sep 10, 2026 parent dbe663d · commit 37f19ef9d9a8
6 changed files+41 -20compared with dbe663d
Mmods/diff/README.md
Mmods/diff/hooks/limits/columns/open-min-columns.ts
Mmods/diff/hooks/names/texts/resize-terminal-text.ts
Mmods/diff/hooks/pane-toggle/pane-belief/pane-belief.ts
Mmods/diff/hooks/pane-toggle/pane-toggle-of.ts
Mmods/diff/hooks/register.ts
@@ -7,10 +7,10 @@
77 repository's HEAD so a commit or checkout made elsewhere shows too. The
88 first successful edit of a session opens the pane by itself where the
99 terminal is wide enough (144 columns when the person never chose, 110 when
10-they kept it open before; a person who closed it is left alone). Where the
11-surface seats the pane inline instead of beside the transcript (a terminal
12-under 110 columns), it shows only the built-in's line asking for a wider
13-terminal. A file's
10+they kept it open before; a person who closed it is left alone). On a
11+terminal under 110 columns `/diff` answers with the built-in's line asking
12+for a wider terminal and opens nothing; a pane opened wider that the surface
13+then seats inline shows only that line. A file's
1414 ask button arms that file: its hunks ride the next prompt as context, once.
1515
1616 The pane compares the working tree against HEAD, split at the session's
@@ -1,5 +1,6 @@
11 /**
2- * The terminal width from which the first edit opens the pane when the person
3- * kept it open before (the built-in sidebar's own minimum).
2+ * The terminal width from which `/diff` opens the pane, and the first edit
3+ * opens it when the person kept it open before (the built-in sidebar's own
4+ * minimum).
45 */
56 export const OPEN_MIN_COLUMNS = 110
@@ -1,6 +1,7 @@
11 /**
2- * The pane's one line where the surface seats it inline (no room beside the
3- * transcript), worded as the built-in words its refusal below that width.
2+ * `/diff`'s answer on a terminal narrower than the built-in panel shows on,
3+ * worded as the built-in words it; also the pane's one line where the
4+ * surface seats it inline (no room beside the transcript).
45 */
56 export const RESIZE_TERMINAL_TEXT =
67 'Resize your terminal to at least 110 columns to show the diff panel'
@@ -1,8 +1,10 @@
11 /**
22 * What the plugin knows of its pane when `/diff` runs: whether it opened
3- * it and never closed it, and whether it drew when a redraw was asked.
3+ * it and never closed it, whether it drew when a redraw was asked, and the
4+ * terminal's width as last drawn (null before any draw).
45 */
56 export type PaneBelief = {
67 isBelievedOpen: boolean
78 wasDrawnWhenProbed: boolean
9+ columns: number | null
810 }
@@ -1,14 +1,23 @@
1+import Limits from '../limits'
12 import type { PaneBelief } from './pane-belief'
23
34 /**
45 * What `/diff` does, the one place its toggle is decided: close only when
5- * the plugin opened the pane and it still draws; otherwise open, focused.
6+ * the plugin opened the pane and it still draws; otherwise open, focused,
7+ * unless the terminal is narrower than the built-in panel shows on, where
8+ * `/diff` answers the built-in's resize line instead (`too-narrow`).
69 *
710 * The person's close raises nothing this plugin hooks, so a pane believed
8- * open is probed with a redraw first.
11+ * open is probed with a redraw first. A width not drawn yet opens.
912 *
10- * @param pane the plugin's belief and the probe's answer
11- * @returns `close` or `open`
13+ * @param pane the plugin's belief, the probe's answer and the width
14+ * @returns `close`, `open` or `too-narrow`
1215 */
13-export const paneToggleOf = (pane: PaneBelief): 'open' | 'close' =>
14- pane.isBelievedOpen && pane.wasDrawnWhenProbed ? 'close' : 'open'
16+export const paneToggleOf = (
17+ pane: PaneBelief,
18+): 'open' | 'close' | 'too-narrow' =>
19+ pane.isBelievedOpen && pane.wasDrawnWhenProbed
20+ ? 'close'
21+ : pane.columns !== null && pane.columns < Limits.OPEN_MIN_COLUMNS
22+ ? 'too-narrow'
23+ : 'open'
@@ -24,6 +24,8 @@
2424 * `session.start` registers `/diff` (refused while the built-in holds it),
2525 * binds the host every pinned backend reads through, and pins the backend
2626 * (backendOf): one probe in flight, asked again on `/diff` until git answers.
27+ * On a terminal narrower than the built-in panel shows on, `/diff` answers
28+ * the built-in's resize line and opens nothing (paneToggleOf).
2729 *
2830 * @param on the engine's registrar
2931 */
@@ -513,11 +515,17 @@
513515 }
514516 }
515517
516- const isOpening =
517- PaneToggle.paneToggleOf({
518- isBelievedOpen: isPaneOpen,
519- wasDrawnWhenProbed: isPaneOpen && (await wasDrawnWhenProbed(host)),
520- }) === 'open'
518+ const toggle = PaneToggle.paneToggleOf({
519+ isBelievedOpen: isPaneOpen,
520+ wasDrawnWhenProbed: isPaneOpen && (await wasDrawnWhenProbed(host)),
521+ columns,
522+ })
523+
524+ if (toggle === 'too-narrow') {
525+ return { text: Names.RESIZE_TERMINAL_TEXT }
526+ }
527+
528+ const isOpening = toggle === 'open'
521529 await (isOpening ? openPane(host, 'manual') : closePane(host))
522530 await host.storeSet(Names.STORE_OPEN_KEY, isOpening).catch(() => undefined)
523531