ClaudeMods
☰
EN
● 0 online · Views 0 times
SponsorsSubmit a project
Tutorial resources · by Avid

claude code on desktop feels bloated and slow.... so i used ONE prompt to fix it i

一則 X 貼文分享完整提示詞,指示 Claude Code 依官方 mods API 建立 file-explorer、workspace、ide-usage、ide-statusbar 四個外掛,包含 hooks 靜態分析規則、型別來源優先順序、測試與驗收條件。

Avid@Av1dlive

1/

claude code on desktop feels bloated and slow.... so i used ONE prompt to fix it : [start of the prompt] This will turn your terminal into a ultra-fast claude code app <role> You are a senior TypeScript engineer. You build Claude Code mods. You write small modules, you test each module, and you report only results that you verified. </role> <variables> AUTHOR_NAME = "Your public name" MARKETPLACE = "your-marketplace-name" LICENSE = "MIT" PANE_COLUMNS = 48 </variables> <context> A mod is a Claude Code plugin. The file hooks/hooks.json names one hooks module. The hooks module exports register(on, options). Each hook is on('event', matcher, async ($, e, next) => result). "$" is the mods API. "e" is the event. "next(e)" runs the other mods and then Claude Code. I want an IDE-style workspace inside a Claude Code terminal session. People read files, search, see diffs, run tasks, and move between sessions with no second window. Other people will install these mods from a public marketplace, so the mods must load on a clean machine and must not fail when a tool (git, rg, cargo) is absent. Official documentation (read the pages that you need): - https://code.claude.com/docs/en/plugins/mods - https://code.claude.com/docs/en/plugins/mods/create - https://code.claude.com/docs/en/plugins/mods/interface - https://code.claude.com/docs/en/plugins/mods/reference - Built-in mod source: https://github.com/anthropics/claude-code/tree/main/mods (read "diff" first; it is a pane with buttons and its own scroll) </context> <source_of_truth> The mods API changes between releases. Use this order when two sources disagree: 1. The type declarations that Claude Code writes into .claude-plugin/types/ of each mod. These describe the installed version. 2. The output of "claude plugin validate". 3. The documentation pages. 4. This prompt. Run /plugin-authoring before you write code. Read claude-code/index.d.ts before you use an event, a method, an element, or a prop. Search that file for the name. Do not use a name that is not in that file. If this prompt names something that the installed version does not have, do not invent a replacement. Build the nearest version that the API supports and record the difference in LIMITS.md. </source_of_truth> <api_rules> Claude Code does static analysis on the hooks module. These rules keep validation green: - Write each API call in full: $.fs.read(...), $.ui.open(...). Do not assign "$" or a namespace to a variable. Do not destructure "$". - Pass "$" only to a function declared at the top level of the same file. Do not pass "$" to an imported function, a method, or a function defined inside a hook. - Write each event name as a string literal in on(...). Do not loop over a list of event names. - Do not declare a second variable named "on" inside register. - Use ES modules. Use import declarations at the top of the file. No require. No dynamic import(). - Import only files inside the plugin directory, by relative path. The only bare import is "claude-code". - Do not start a plugin name with "claude-". Result: keep every "$" call in the hooks module. Put pure logic (parsers, tree model, search ranking, formatters) in separate files that take plain data and return plain data. Test the pure files directly. Limits to design for: - One hook has 10 seconds of its own execution time. - $.fs.read and $.fs.write: 4 MiB for one file. One Text string and one Code element: 10,000 characters. Page long files. - $.store: 4 MiB of JSON in total, shared by all sessions on the machine. Give each item its own key. Cap each list. - $.process.run: 30 seconds by default. - Redraws: 30 each second for the visible pane, 10 for other sites. - A pane that a mod opens by itself appears only at 144 columns or more. A pane that a user command or press opens appears at each width. Open panes from commands and presses. Keyboard rules: - A mod cannot bind Tab or the arrow keys. Tab moves between controls. Up and Down move between controls or scroll. - A Button hotkey is one digit or one lowercase letter. While an Input has the focus, each printable key goes to the Input. - Give each control a unique key. Tests press controls by key. - Claude Code has no tabs element. Draw tabs as a row of plain buttons. State: - Module variable: lost at each reload. Use for values that can be lost. - $.state: lasts for the session and redraws the sites that read the value. Declare each value in types/index.d.ts and name that file in the manifest. - $.store: lasts between sessions. Use for settings, recent sessions, and projects. </api_rules> <repository_layout> .claude-plugin/marketplace.json one entry for each plugin, marketplace name = MARKETPLACE plugins/file-explorer/ plugins/workspace/ plugins/ide-usage/ plugins/ide-statusbar/ README.md LICENSE PROGRESS.md LIMITS.md tests.json Each plugin: .claude-plugin/plugin.json name, version 0.1.0, description, author = AUTHOR_NAME, license = LICENSE, types when needed hooks/hooks.json { "modules": ["./register.ts"] } hooks/register.ts the only file that calls "$" hooks/lib/*.ts pure logic types/index.d.ts PluginState and any namespace that the mod adds tests/*.test.ts tests for "claude plugin test" </repository_layout> <mod name="file-explorer"> Command: /explorer opens the pane (id "explorer", title "Explorer", focus true, columns PANE_COLUMNS). Register the command with immediate: true so that it works during a turn. A second /explorer closes the pane. /explorer <path> opens that path. Header row: the word EXPLORER, then Back, Forward, Up, Close. Back and Forward move through the history of opened folders and files. One Input below the header. Its purpose changes with the tab: - Files tab: placeholder "Find files". Enter searches file names and paths below the root. The search ignores case. Stop at 500 matches and show: N files match "query" (first 500, scan stopped). Show the matches as a tree with their parent folders. Mark the matched text. An empty query restores the tree. - Code tab: placeholder "Find in file, :line, or /regex/". Plain text finds each occurrence. ":42" goes to line 42. "/re/" uses a regular expression. Show "match 2 of 5". Buttons n and p go to the next and the previous match. Tabs: Files, Code, Diff. Files tab: - Root line: the root folder name and the full path. The first root is the session working folder. Up moves the root to the parent folder. - Action row: New File, New Folder, Refresh, Collapse, More. New File and New Folder ask for a name with an Input and create the item in the selected folder. More holds Rename, Delete, Copy path, and Show hidden files. Delete asks for confirmation with $.ui.ask. - Tree: read one folder level when the user opens that folder. Sort folders first, then files, by name. Show a marker for the folder state, a short type tag for known file types (json, md, ts, js, py, rs, go, sh), and "name → target" for a symbolic link. Show "(empty)" in an empty folder. Skip .git and node_modules unless hidden files are on. - Selection and paging: one selected row. Buttons move the selection up and down, open a folder, close a folder, and open a file. Show the range, for example "7-49 of 329". Draw only the rows that fit in e.props.scroll.bodyRows. Code tab: - Breadcrumb of the path, then "N lines · size". - Line numbers and syntax colors. Use the Code element. Page the file so that no element is larger than 10,000 characters. - For a file larger than 4 MiB or a binary file, show the size and a message. Do not read the file. - Highlight the current match and the current line. Diff tab: - Show the uncommitted diff of the open file (git diff for that path). Use the Code element in diff mode. - Show the count of added and removed lines. - When Claude edits a file with Edit, Write, or MultiEdit, record the path in the http://tool.call hook after next(e) returns. If the pane is open, select that file and show the Diff tab. Do not open the pane by yourself. - If the folder is not a git repository, say so in one line. Other mods open a file through a namespace that this mod adds to the mods API: http://explorer.open({ path, line, tab }). Declare the namespace in types/index.d.ts. Read the "telemetry" built-in mod to see how a mod adds methods for other mods. </mod> <mod name="workspace"> Depends on file-explorer (list it under dependencies in plugin.json). Command: /workspace opens the navigator pane (id "workspace", title "Workspace", columns PANE_COLUMNS). Navigator placement: the documented position of a pane is a dock beside the transcript, and Claude Code gives each open pane a tab with its title. Search the types for a field that places a pane on the left side. If one exists, put the navigator on the left and the tools in the right dock. If none exists, the navigator is one more pane in the dock. Record the result in LIMITS.md. Navigator content, top to bottom: 1. Title CLAUDE CODE and a New chat button. New chat runs the built-in command that starts a new conversation. Find the command name with $.command.list. 2. WORKSPACE: one button for each tool, in this order: Files, Terminal, Browser, Source Control, Problems, Run Tasks, Outline, To-do Comments, Timeline, Usage, Model Router. A press opens that tool pane and gives it the focus. Mark the tools that are open. 3. RECENTS: the newest 5 sessions, with "Show more". Each row shows the title, the project name, and the age (8m, 22h, 3d). The title is the first prompt of the session, cut to fit. A press on a row shows the prompts of that session below the row. Mark the current session. 4. PROJECTS: each project folder with its session count. A press shows the sessions of that project. Session index: in the prompt.submit hook, write { id, cwd, repo, title, prompts[], updatedAt } to $.store under the key "session:<id>". Keep the newest 50 prompts for each session and the newest 200 sessions. Read the store again before each write, because other sessions write to the same store. Do not read or parse Claude Code's own transcript files. Open a recent session: check the types for a supported method to switch or resume a session. If none exists, copy "claude --resume <id>" with $.ui.copy and show a toast that says so. Tools. Each tool is one pane with its own id, a short title, and a Refresh button. Each tool shows one clear line when it has no data or when its program is absent. 1. Files: calls http://explorer.open with the session folder. It does not draw a second tree. 2. Terminal: an Input that runs one command with $.process.spawn in the session folder. Stream the output into the pane. Keep the last 500 lines. Show the exit code. Keep a history of 50 commands. A Stop button ends the process. This is a command runner, not a terminal emulator; say so in the README. 3. Browser: an Input for a URL. Fetch with $.http.fetch. Show the status code, the page title, and the readable text as Markdown, cut to the element limit. Show links as buttons that load the link. An "Open in system browser" button uses the open command of the operating system. Allow only http and https. 4. Source Control: branch, ahead and behind counts, and the changed files with status and "+added −removed" from git. A press on a file calls http://explorer.open with tab "diff". Buttons: Stage, Unstage, Stage all. A commit Input commits the staged files after a confirmation with $.ui.ask. Do not push, pull, reset, or discard changes. 5. Problems: run the check command of the project and list each problem as "file:line message" with a severity mark. Detect the command: tsc --noEmit for tsconfig.json, cargo check for Cargo.toml, go vet for go.mod, ruff check for pyproject.toml when ruff is installed. A user setting replaces the detected command. A press calls http://explorer.open with the line. Run only on Refresh and after a turn ends, and do not run two checks at the same time. 6. Run Tasks: show the session folder. Find tasks in package.json scripts, Makefile targets, justfile recipes, Cargo.toml (build, test, clippy), pyproject.toml scripts, and go.mod (build, test, vet). If none is found, show: No task found (package.json, Makefile, justfile, Cargo.toml, pyproject.toml, go.mod). One button for each task. One Input with the placeholder "Run a command, then Enter". Stream the output and show the exit code and the time. 7. Outline: the symbols of the file that is open in the explorer, with line numbers: functions, classes, structs, interfaces, constants, and Markdown headings. Use one small pattern table for each language (ts, js, py, rs, go, md). Indent nested symbols. A press calls http://explorer.open with the line. 8. To-do Comments: find TODO, FIXME, HACK, and NOTE comments in the project. Use rg when it is installed. If not, walk the tree with $.fs.list and skip .git, node_modules, target, and dist. Group by tag. Show "file:line text". Cap at 300 items. A press calls http://explorer.open with the line. 9. Timeline: one row for each prompt, tool call, and turn end in this session, newest first, with the clock time. For Edit and Write, show the path and the line counts. A press on an edit row calls http://explorer.open with tab "diff". Keep 300 rows. 10. Usage: read $.session.usage(). Show the context percent, tokens, and window with a bar. Show each rate limit with percent used and reset time. Show the cost if the field has a value. Record the token count of each turn in the session.measure hook and draw the last 30 turns as a small bar graph. Use Raster in the terminal and text on other surfaces (check e.surface). 11. Model Router: show the model of the main session and each subagent start with its type, its model, and its state. Three modes in a Select: Off, Suggest, Auto. Off records only. Suggest shows the model that the rules select and changes nothing. Auto sets the model of a subagent in the agent.spawn hook from a rule table (subagent type or task keyword → model) that the user edits in the pane and that is saved in $.store. Rules: never change the model of the main session, keep a model that the caller named, and let the start continue unchanged if a rule fails. Read the model names from the session and the settings. Do not write model names into the code. The default mode is Off. </mod> <mod name="ide-usage"> One status line with $.ui.status: "ctx 20% · <model>". Update it in the session.measure hook. No pane. </mod> <mod name="ide-statusbar"> One status line with $.ui.status: "<language> · <file name>" for the file that is open in the explorer, or the file that Claude last read or edited. Derive the language from the file extension. Show "Plain Text" for an unknown extension. No pane. </mod> <out_of_scope> - Window tabs for more than one session (for example ⌘1 and ⌘2). The terminal application draws these. A mod cannot. - A full text editor in the pane. An Input is one line. - Changes to the permission prompt. A mod cannot draw there. Do not add features that are not in this prompt. Do not add configuration options that no feature needs. </out_of_scope> <safety> A mod runs with the permissions of the user and is not sandboxed. Write code that a careful reviewer accepts: - Confirm with $.ui.ask before delete, rename, and commit. - Never run a destructive git command. Never approve a tool call for the user. Never send file content or prompts to the network. The Browser tool fetches only the URL that the user typed or pressed. - Do not read environment variables or settings that a feature does not need. "claude plugin validate" lists env reads and calls; keep that list short. - Pass arguments to $.process as an array. Do not build a shell string from file names. During this build, edit files only inside this repository. Do not push. Do not install the plugins into my user settings. Ask me before any action that is hard to undo. </safety> <workflow> This task is long. Your context is compacted automatically, so do not stop early to save tokens. Keep the state in files so that a new context can continue: - PROGRESS.md: what is done, what is next, and each decision with its reason. - tests.json: one entry for each acceptance test with the status not_started, failing, or passing. - LIMITS.md: each feature that the installed API cannot do, and what you built in its place. - One git commit for each feature that passes. At the start of each new context: read PROGRESS.md, tests.json, LIMITS.md, and the git log. Run the test suite before you add a feature. Phase 0, find out. Run /plugin-authoring. Run "claude --version". Read the documentation pages and the "diff" built-in mod. Then write PLAN.md: the events and methods that each feature uses, with the line from the types that proves each one exists. List each feature that needs a different design. Show me PLAN.md and continue unless I object. Phase 1, scaffold. Create the repository layout, the four manifests, hooks.json files, and empty register.ts files that register only their commands. Run "claude plugin validate --strict" on each plugin until it passes. Then stop and give me this command to restart with hot reload: claude --plugin-dir ./plugins/file-explorer --plugin-dir ./plugins/workspace --plugin-dir ./plugins/ide-usage --plugin-dir ./plugins/ide-statusbar After I type "continue", read the generated types in .claude-plugin/types/ and correct PLAN.md. Phase 2, file-explorer. Build in this order: tree model and Files tab, file search, Code tab with find, Diff tab, http://explorer.open. Write the tests for a feature before its code. Phase 3, workspace. Build the navigator and the session index first. Then build the tools in the listed order. Finish and test one tool before you start the next. Phase 4, status lines. Build ide-usage and ide-statusbar. Phase 5, release. Write marketplace.json, LICENSE, and README.md. The README gives: what each mod does, the install commands (claude plugin marketplace add, claude plugin install <name>@MARKETPLACE), the Claude Code version that you tested, the commands, the hotkeys, what each mod can reach (from the "hooks:" and "calls:" lines of validate), and the content of LIMITS.md. Run the full verification. Work directly. Use a subagent only for a search across many files that does not need your context. </workflow> <tests> Tests run with "claude plugin test" and need no session and no network. A test fires events, presses controls by key, and checks the drawing or the result. Stub $.fs, $.process, $.http, and $.store. Write tests that check behavior, for example: - A search for "auth" in a stub tree returns the correct files, marks the matched text, and stops at 500. - ":42" selects line 42. "/re(fresh)?/" finds the correct matches. An invalid regular expression shows an error line and does not throw. - A press on a Source Control row calls http://explorer.open with tab "diff". - Run Tasks with no manifest file shows the "No task found" line. - A git program that is absent gives one clear line and no error. - The session index keeps 200 sessions and merges with a newer write from another session. - Model Router in Off mode and in Suggest mode returns next(e) unchanged. Write general code that is correct for each valid input. Do not write code that only satisfies a test. Do not delete or weaken a test to make it pass. If a test is wrong or a feature is not possible, tell me. </tests> <done_when> 1. "claude plugin validate --strict" passes for each plugin. 2. "claude plugin test" passes for each plugin, and tests.json has no entry that is failing or not_started. 3. "tsc -p" on each plugin reports no error against the generated types. 4. Each command answers in "claude -p" (for example: claude -p "/explorer" --plugin-dir ./plugins/file-explorer) with no error. 5. LIMITS.md lists each difference from this prompt. 6. You give me a checklist of the items that only a person can check in a live session: each pane opens, the hotkeys work, and the layout fits at 110 and at 144 columns. </done_when> <reporting> After each phase, write a short report: what you built, the exact commands that you ran, their results, and what is not verified. Separate "the tests pass" from "I saw it work in a session". If you did not run something, say that you did not run it. </reporting> [end of the prompt]

Not yet translated

About this mod

貼文提供一段可重用的英文提示詞,角色設定為資深 TypeScript 工程師,目標是在 Claude Code 終端機內打造 IDE 風格工作區。內容包含:官方 mods 文件連結與內建 diff mod 參考、來源優先順序(產生的型別宣告 > claude plugin validate > 文件 > 提示詞)、hooks 模組靜態分析規則(不可將 $ 指定給變數、事件名稱須為字串字面值、僅能相對匯入等)、各項資源限制(單檔 4 MiB、元素 10,000 字元、store 4 MiB、process.run 30 秒、重繪頻率、面板寬度限制)、鍵盤與狀態管理規範、repo 目錄結構,以及四個 mod 的詳細規格:file-explorer(Files/Code/Diff 分頁、搜尋、行號跳轉、正規表示式、git diff、explorer.open 命名空間)、workspace(導覽面板、session 索引、Terminal/Browser/Source Control/Problems/Run Tasks/Outline/To-do Comments/Timeline/Usage/Model Router 等工具)、ide-usage 與 ide-statusbar 狀態列。另含安全準則、分階段工作流程、測試要求與完成條件。

Installation

See the original source for installation instructions.

Original text / README

claude code on desktop feels bloated and slow....

so i used ONE prompt to fix it :

[start of the prompt] This will turn your terminal into a ultra-fast claude code app

<role> You are a senior TypeScript engineer. You build Claude Code mods. You write small modules, you test each module, and you report only results that you verified. </role> <variables> AUTHOR_NAME = "Your public name" MARKETPLACE = "your-marketplace-name" LICENSE = "MIT" PANE_COLUMNS = 48 </variables> <context> A mod is a Claude Code plugin. The file hooks/hooks.json names one hooks module. The hooks module exports register(on, options). Each hook is on('event', matcher, async ($, e, next) => result). "$" is the mods API. "e" is the event. "next(e)" runs the other mods and then Claude Code.

I want an IDE-style workspace inside a Claude Code terminal session. People read files, search, see diffs, run tasks, and move between sessions with no second window. Other people will install these mods from a public marketplace, so the mods must load on a clean machine and must not fail when a tool (git, rg, cargo) is absent.

Official documentation (read the pages that you need):

  • https://code.claude.com/docs/en/plugins/mods
  • https://code.claude.com/docs/en/plugins/mods/create
  • https://code.claude.com/docs/en/plugins/mods/interface
  • https://code.claude.com/docs/en/plugins/mods/reference
  • Built-in mod source: https://github.com/anthropics/claude-code/tree/main/mods (read "diff" first; it is a pane with buttons and its own scroll) </context>

<source_of_truth> The mods API changes between releases. Use this order when two sources disagree:

  1. The type declarations that Claude Code writes into .claude-plugin/types/ of each mod. These describe the installed version.
  2. The output of "claude plugin validate".
  3. The documentation pages.
  4. This prompt.

Run /plugin-authoring before you write code. Read claude-code/index.d.ts before you use an event, a method, an element, or a prop. Search that file for the name. Do not use a name that is not in that file. If this prompt names something that the installed version does not have, do not invent a replacement. Build the nearest version that the API supports and record the difference in LIMITS.md. </source_of_truth>

<api_rules> Claude Code does static analysis on the hooks module. These rules keep validation green:

  • Write each API call in full: $.fs.read(...), $.ui.open(...). Do not assign "$" or a namespace to a variable. Do not destructure "$".
  • Pass "$" only to a function declared at the top level of the same file. Do not pass "$" to an imported function, a method, or a function defined inside a hook.
  • Write each event name as a string literal in on(...). Do not loop over a list of event names.
  • Do not declare a second variable named "on" inside register.
  • Use ES modules. Use import declarations at the top of the file. No require. No dynamic import().
  • Import only files inside the plugin directory, by relative path. The only bare import is "claude-code".
  • Do not start a plugin name with "claude-".

Result: keep every "$" call in the hooks module. Put pure logic (parsers, tree model, search ranking, formatters) in separate files that take plain data and return plain data. Test the pure files directly.

Limits to design for:

  • One hook has 10 seconds of its own execution time.
  • $.fs.read and $.fs.write: 4 MiB for one file. One Text string and one Code element: 10,000 characters. Page long files.
  • $.store: 4 MiB of JSON in total, shared by all sessions on the machine. Give each item its own key. Cap each list.
  • $.process.run: 30 seconds by default.
  • Redraws: 30 each second for the visible pane, 10 for other sites.
  • A pane that a mod opens by itself appears only at 144 columns or more. A pane that a user command or press opens appears at each width. Open panes from commands and presses.

Keyboard rules:

  • A mod cannot bind Tab or the arrow keys. Tab moves between controls. Up and Down move between controls or scroll.
  • A Button hotkey is one digit or one lowercase letter. While an Input has the focus, each printable key goes to the Input.
  • Give each control a unique key. Tests press controls by key.
  • Claude Code has no tabs element. Draw tabs as a row of plain buttons.

State:

  • Module variable: lost at each reload. Use for values that can be lost.
  • $.state: lasts for the session and redraws the sites that read the value. Declare each value in types/index.d.ts and name that file in the manifest.
  • $.store: lasts between sessions. Use for settings, recent sessions, and projects. </api_rules>

<repository_layout> .claude-plugin/marketplace.json one entry for each plugin, marketplace name = MARKETPLACE plugins/file-explorer/ plugins/workspace/ plugins/ide-usage/ plugins/ide-statusbar/ README.md LICENSE PROGRESS.md LIMITS.md tests.json

Each plugin: .claude-plugin/plugin.json name, version 0.1.0, description, author = AUTHOR_NAME, license = LICENSE, types when needed hooks/hooks.json { "modules": ["./register.ts"] } hooks/register.ts the only file that calls "$" hooks/lib/.ts pure logic types/index.d.ts PluginState and any namespace that the mod adds tests/.test.ts tests for "claude plugin test" </repository_layout>

<mod name="file-explorer"> Command: /explorer opens the pane (id "explorer", title "Explorer", focus true, columns PANE_COLUMNS). Register the command with immediate: true so that it works during a turn. A second /explorer closes the pane. /explorer <path> opens that path.

Header row: the word EXPLORER, then Back, Forward, Up, Close. Back and Forward move through the history of opened folders and files.

One Input below the header. Its purpose changes with the tab:

  • Files tab: placeholder "Find files". Enter searches file names and paths below the root. The search ignores case. Stop at 500 matches and show: N files match "query" (first 500, scan stopped). Show the matches as a tree with their parent folders. Mark the matched text. An empty query restores the tree.
  • Code tab: placeholder "Find in file, :line, or /regex/". Plain text finds each occurrence. ":42" goes to line 42. "/re/" uses a regular expression. Show "match 2 of 5". Buttons n and p go to the next and the previous match.

Tabs: Files, Code, Diff.

Files tab:

  • Root line: the root folder name and the full path. The first root is the session working folder. Up moves the root to the parent folder.
  • Action row: New File, New Folder, Refresh, Collapse, More. New File and New Folder ask for a name with an Input and create the item in the selected folder. More holds Rename, Delete, Copy path, and Show hidden files. Delete asks for confirmation with $.ui.ask.
  • Tree: read one folder level when the user opens that folder. Sort folders first, then files, by name. Show a marker for the folder state, a short type tag for known file types (json, md, ts, js, py, rs, go, sh), and "name → target" for a symbolic link. Show "(empty)" in an empty folder. Skip .git and node_modules unless hidden files are on.
  • Selection and paging: one selected row. Buttons move the selection up and down, open a folder, close a folder, and open a file. Show the range, for example "7-49 of 329". Draw only the rows that fit in e.props.scroll.bodyRows.

Code tab:

  • Breadcrumb of the path, then "N lines · size".
  • Line numbers and syntax colors. Use the Code element. Page the file so that no element is larger than 10,000 characters.
  • For a file larger than 4 MiB or a binary file, show the size and a message. Do not read the file.
  • Highlight the current match and the current line.

Diff tab:

  • Show the uncommitted diff of the open file (git diff for that path). Use the Code element in diff mode.
  • Show the count of added and removed lines.
  • When Claude edits a file with Edit, Write, or MultiEdit, record the path in the http://tool.call hook after next(e) returns. If the pane is open, select that file and show the Diff tab. Do not open the pane by yourself.
  • If the folder is not a git repository, say so in one line.

Other mods open a file through a namespace that this mod adds to the mods API: http://explorer.open({ path, line, tab }). Declare the namespace in types/index.d.ts. Read the "telemetry" built-in mod to see how a mod adds methods for other mods. </mod>

<mod name="workspace"> Depends on file-explorer (list it under dependencies in plugin.json).

Command: /workspace opens the navigator pane (id "workspace", title "Workspace", columns PANE_COLUMNS).

Navigator placement: the documented position of a pane is a dock beside the transcript, and Claude Code gives each open pane a tab with its title. Search the types for a field that places a pane on the left side. If one exists, put the navigator on the left and the tools in the right dock. If none exists, the navigator is one more pane in the dock. Record the result in LIMITS.md.

Navigator content, top to bottom:

  1. Title CLAUDE CODE and a New chat button. New chat runs the built-in command that starts a new conversation. Find the command name with $.command.list.
  2. WORKSPACE: one button for each tool, in this order: Files, Terminal, Browser, Source Control, Problems, Run Tasks, Outline, To-do Comments, Timeline, Usage, Model Router. A press opens that tool pane and gives it the focus. Mark the tools that are open.
  3. RECENTS: the newest 5 sessions, with "Show more". Each row shows the title, the project name, and the age (8m, 22h, 3d). The title is the first prompt of the session, cut to fit. A press on a row shows the prompts of that session below the row. Mark the current session.
  4. PROJECTS: each project folder with its session count. A press shows the sessions of that project.

Session index: in the prompt.submit hook, write { id, cwd, repo, title, prompts[], updatedAt } to $.store under the key "session:<id>". Keep the newest 50 prompts for each session and the newest 200 sessions. Read the store again before each write, because other sessions write to the same store. Do not read or parse Claude Code's own transcript files.

Open a recent session: check the types for a supported method to switch or resume a session. If none exists, copy "claude --resume <id>" with $.ui.copy and show a toast that says so.

Tools. Each tool is one pane with its own id, a short title, and a Refresh button. Each tool shows one clear line when it has no data or when its program is absent.

  1. Files: calls http://explorer.open with the session folder. It does not draw a second tree.
  2. Terminal: an Input that runs one command with $.process.spawn in the session folder. Stream the output into the pane. Keep the last 500 lines. Show the exit code. Keep a history of 50 commands. A Stop button ends the process. This is a command runner, not a terminal emulator; say so in the README.
  3. Browser: an Input for a URL. Fetch with $.http.fetch. Show the status code, the page title, and the readable text as Markdown, cut to the element limit. Show links as buttons that load the link. An "Open in system browser" button uses the open command of the operating system. Allow only http and https.
  4. Source Control: branch, ahead and behind counts, and the changed files with status and "+added −removed" from git. A press on a file calls http://explorer.open with tab "diff". Buttons: Stage, Unstage, Stage all. A commit Input commits the staged files after a confirmation with $.ui.ask. Do not push, pull, reset, or discard changes.
  5. Problems: run the check command of the project and list each problem as "file:line message" with a severity mark. Detect the command: tsc --noEmit for tsconfig.json, cargo check for Cargo.toml, go vet for go.mod, ruff check for pyproject.toml when ruff is installed. A user setting replaces the detected command. A press calls http://explorer.open with the line. Run only on Refresh and after a turn ends, and do not run two checks at the same time.
  6. Run Tasks: show the session folder. Find tasks in package.json scripts, Makefile targets, justfile recipes, Cargo.toml (build, test, clippy), pyproject.toml scripts, and go.mod (build, test, vet). If none is found, show: No task found (package.json, Makefile, justfile, Cargo.toml, pyproject.toml, go.mod). One button for each task. One Input with the placeholder "Run a command, then Enter". Stream the output and show the exit code and the time.
  7. Outline: the symbols of the file that is open in the explorer, with line numbers: functions, classes, structs, interfaces, constants, and Markdown headings. Use one small pattern table for each language (ts, js, py, rs, go, md). Indent nested symbols. A press calls http://explorer.open with the line.
  8. To-do Comments: find TODO, FIXME, HACK, and NOTE comments in the project. Use rg when it is installed. If not, walk the tree with $.fs.list and skip .git, node_modules, target, and dist. Group by tag. Show "file:line text". Cap at 300 items. A press calls http://explorer.open with the line.
  9. Timeline: one row for each prompt, tool call, and turn end in this session, newest first, with the clock time. For Edit and Write, show the path and the line counts. A press on an edit row calls http://explorer.open with tab "diff". Keep 300 rows.
  10. Usage: read $.session.usage(). Show the context percent, tokens, and window with a bar. Show each rate limit with percent used and reset time. Show the cost if the field has a value. Record the token count of each turn in the session.measure hook and draw the last 30 turns as a small bar graph. Use Raster in the terminal and text on other surfaces (check e.surface).
  11. Model Router: show the model of the main session and each subagent start with its type, its model, and its state. Three modes in a Select: Off, Suggest, Auto. Off records only. Suggest shows the model that the rules select and changes nothing. Auto sets the model of a subagent in the agent.spawn hook from a rule table (subagent type or task keyword → model) that the user edits in the pane and that is saved in $.store. Rules: never change the model of the main session, keep a model that the caller named, and let the start continue unchanged if a rule fails. Read the model names from the session and the settings. Do not write model names into the code. The default mode is Off. </mod>
<mod name="ide-usage"> One status line with $.ui.status: "ctx 20% · <model>". Update it in the session.measure hook. No pane. </mod> <mod name="ide-statusbar"> One status line with $.ui.status: "<language> · <file name>" for the file that is open in the explorer, or the file that Claude last read or edited. Derive the language from the file extension. Show "Plain Text" for an unknown extension. No pane. </mod>

<out_of_scope>

  • Window tabs for more than one session (for example ⌘1 and ⌘2). The terminal application draws these. A mod cannot.
  • A full text editor in the pane. An Input is one line.
  • Changes to the permission prompt. A mod cannot draw there. Do not add features that are not in this prompt. Do not add configuration options that no feature needs. </out_of_scope>
<safety> A mod runs with the permissions of the user and is not sandboxed. Write code that a careful reviewer accepts: - Confirm with $.ui.ask before delete, rename, and commit. - Never run a destructive git command. Never approve a tool call for the user. Never send file content or prompts to the network. The Browser tool fetches only the URL that the user typed or pressed. - Do not read environment variables or settings that a feature does not need. "claude plugin validate" lists env reads and calls; keep that list short. - Pass arguments to $.process as an array. Do not build a shell string from file names. During this build, edit files only inside this repository. Do not push. Do not install the plugins into my user settings. Ask me before any action that is hard to undo. </safety> <workflow> This task is long. Your context is compacted automatically, so do not stop early to save tokens. Keep the state in files so that a new context can continue: - PROGRESS.md: what is done, what is next, and each decision with its reason. - tests.json: one entry for each acceptance test with the status not_started, failing, or passing. - LIMITS.md: each feature that the installed API cannot do, and what you built in its place. - One git commit for each feature that passes. At the start of each new context: read PROGRESS.md, tests.json, LIMITS.md, and the git log. Run the test suite before you add a feature.

Phase 0, find out. Run /plugin-authoring. Run "claude --version". Read the documentation pages and the "diff" built-in mod. Then write PLAN.md: the events and methods that each feature uses, with the line from the types that proves each one exists. List each feature that needs a different design. Show me PLAN.md and continue unless I object.

Phase 1, scaffold. Create the repository layout, the four manifests, hooks.json files, and empty register.ts files that register only their commands. Run "claude plugin validate --strict" on each plugin until it passes. Then stop and give me this command to restart with hot reload: claude --plugin-dir ./plugins/file-explorer --plugin-dir ./plugins/workspace --plugin-dir ./plugins/ide-usage --plugin-dir ./plugins/ide-statusbar After I type "continue", read the generated types in .claude-plugin/types/ and correct PLAN.md.

Phase 2, file-explorer. Build in this order: tree model and Files tab, file search, Code tab with find, Diff tab, http://explorer.open. Write the tests for a feature before its code.

Phase 3, workspace. Build the navigator and the session index first. Then build the tools in the listed order. Finish and test one tool before you start the next.

Phase 4, status lines. Build ide-usage and ide-statusbar.

Phase 5, release. Write marketplace.json, LICENSE, and README.md. The README gives: what each mod does, the install commands (claude plugin marketplace add, claude plugin install <name>@MARKETPLACE), the Claude Code version that you tested, the commands, the hotkeys, what each mod can reach (from the "hooks:" and "calls:" lines of validate), and the content of LIMITS.md. Run the full verification.

Work directly. Use a subagent only for a search across many files that does not need your context. </workflow>

<tests> Tests run with "claude plugin test" and need no session and no network. A test fires events, presses controls by key, and checks the drawing or the result. Stub $.fs, $.process, $.http, and $.store.

Write tests that check behavior, for example:

  • A search for "auth" in a stub tree returns the correct files, marks the matched text, and stops at 500.
  • ":42" selects line 42. "/re(fresh)?/" finds the correct matches. An invalid regular expression shows an error line and does not throw.
  • A press on a Source Control row calls http://explorer.open with tab "diff".
  • Run Tasks with no manifest file shows the "No task found" line.
  • A git program that is absent gives one clear line and no error.
  • The session index keeps 200 sessions and merges with a newer write from another session.
  • Model Router in Off mode and in Suggest mode returns next(e) unchanged.

Write general code that is correct for each valid input. Do not write code that only satisfies a test. Do not delete or weaken a test to make it pass. If a test is wrong or a feature is not possible, tell me. </tests>

<done_when>

  1. "claude plugin validate --strict" passes for each plugin.
  2. "claude plugin test" passes for each plugin, and tests.json has no entry that is failing or not_started.
  3. "tsc -p" on each plugin reports no error against the generated types.
  4. Each command answers in "claude -p" (for example: claude -p "/explorer" --plugin-dir ./plugins/file-explorer) with no error.
  5. LIMITS.md lists each difference from this prompt.
  6. You give me a checklist of the items that only a person can check in a live session: each pane opens, the hotkeys work, and the layout fits at 110 and at 144 columns. </done_when>
<reporting> After each phase, write a short report: what you built, the exact commands that you ran, their results, and what is not verified. Separate "the tests pass" from "I saw it work in a session". If you did not run something, say that you did not run it. </reporting>

[end of the prompt]

Similar projects