diff --git a/packages/coding-agent/out.html b/packages/coding-agent/out.html index b75f17c7..dc231972 100644 --- a/packages/coding-agent/out.html +++ b/packages/coding-agent/out.html @@ -265,7 +265,7 @@
-

pi v0.6.1

+

pi v0.7.1

Session: @@ -281,7 +281,7 @@
Messages: - 167 + 372
Directory: @@ -332,14 +332,14 @@ The following project context files have been loaded: - -Current date and time: Wednesday, November 12, 2025 at 10:41:01 PM GMT+1 +Current date and time: Thursday, November 13, 2025 at 12:17:22 AM GMT+1 Current working directory: /Users/badlogic/workspaces/pi-mono/packages/coding-agent
Available Tools
-
read - Read the contents of a file. Supports text files and images (jpg, png, gif, webp). Images are sent as attachments. For text files, defaults to first 2000 lines. Use offset/limit for large files.
bash - Execute a bash command in the current working directory. Returns stdout and stderr. Commands run with a 30 second timeout.
edit - Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.
write - Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.
+
read - Read the contents of a file. Supports text files and images (jpg, png, gif, webp). Images are sent as attachments. For text files, defaults to first 2000 lines. Use offset/limit for large files.
bash - Execute a bash command in the current working directory. Returns stdout and stderr. Optionally provide a timeout in seconds.
edit - Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.
write - Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.
@@ -562,11 +562,101 @@ node test-context-loading.js - Use result.details.diff from tool execution (same as TUI) - Apply proper color coding for added/removed/context lines - Remove unused generateDiff function -- Match TUI's diff rendering approach" && git push
Perfect! ✅ The HTML export now renders edit tool diffs properly by using the `result.details.diff` field from the tool execution, just like the TUI does. The diffs will now show up with proper color coding for added (green), removed (red), and context (dimmed) lines.
'/var/folders/49/l4171l3n219_xwq30fmyzr8w0000gn/T/TemporaryItems/NSIRD_screencaptureui_eMS14t/Screenshot 2025-11-12 at 22.40.09.png'

diff needs to scroll horizontally if content is too wide
Let me add horizontal scrolling for the diff content:
edit src/export-html.ts
...
1 .tool-diff {
2 margin-top: 12px;
3 font-size: 13px;
4 font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
+573 overflow-x: auto;
+574 max-width: 100%;
573 }
574
575 .diff-line-old {
576 color: ${COLORS.red};
...
Successfully replaced text in src/export-html.ts. Changed 538 characters to 597 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "fix: add horizontal scroll to diffs in HTML export" && git push
Done! ✅ Diffs will now scroll horizontally if the content is too wide.
+- Match TUI's diff rendering approach" && git push
Perfect! ✅ The HTML export now renders edit tool diffs properly by using the `result.details.diff` field from the tool execution, just like the TUI does. The diffs will now show up with proper color coding for added (green), removed (red), and context (dimmed) lines.
'/var/folders/49/l4171l3n219_xwq30fmyzr8w0000gn/T/TemporaryItems/NSIRD_screencaptureui_eMS14t/Screenshot 2025-11-12 at 22.40.09.png'

diff needs to scroll horizontally if content is too wide
Let me add horizontal scrolling for the diff content:
edit src/export-html.ts
...
1 .tool-diff {
2 margin-top: 12px;
3 font-size: 13px;
4 font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
+573 overflow-x: auto;
+574 max-width: 100%;
573 }
574
575 .diff-line-old {
576 color: ${COLORS.red};
...
Successfully replaced text in src/export-html.ts. Changed 538 characters to 597 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "fix: add horizontal scroll to diffs in HTML export" && git push
Done! ✅ Diffs will now scroll horizontally if the content is too wide.
ok, let's work on the readme.md. i'm going to dictate additional sections, and you can add them and clean them up. understood?
Understood! I'm ready to add and clean up the sections you dictate for the README.md. Go ahead!
Okay, so we want a section on security. Just call it YOLO security. Coding agent assumes that you know what you're doing. Basically runs in missionless and basically runs in YOLO mode. Means it can access any file, any directory and do whatever it wants. comfortable with that you can either put the agent inside a container or not use pi For my use case this is how I want it to work and I am not going to add permissions. opposed to other coding agents like Cloud Code will also not pre-check bash commands for checkchains or similar things. These introduce massive amounts of flag. I need fast iterations. Wait, these introduce massive amounts of flag while still being easily circumvented. Those won't be implemented either. So take all of this, no wait, by default, Pi does not have a web search tool. So prompt injections are prompt injections. By default, Pi doesn't have a web search or web fetch tool. It can however opt to use curl or it can just read a file from a third party on a disk, both giving ample surface for prompt injections. Use at your own risk, use something else if you're not happy with this. Okay, clean all of this up, make it more concise, keep the tone, not necessarily condescending, but in a sense, I don't care. This is how I want it to work.
read README.md
read README.md
edit README.md
...
1 ### bash
2
3 Execute a bash command in the current working directory. Returns stdout and stderr. Commands run with a 30 second timeout.
4
+323 ## Security (YOLO Mode)
+324
+325 This agent runs in full YOLO mode and assumes you know what you're doing. It has unrestricted access to your filesystem and can execute any command without permission checks or safety rails.
+326
+327 **What this means:**
+328 - No permission prompts for file operations or commands
+329 - No pre-checking of bash commands for malicious content
+330 - Full filesystem access - can read, write, or delete anything
+331 - Can execute any command with your user privileges
+332
+333 **Why:**
+334 - Permission systems add massive friction while being easily circumvented
+335 - Pre-checking tools for "dangerous" patterns introduces latency and false positives
+336 - Fast iteration requires trust, not sandboxing
+337
+338 **Prompt injection risks:**
+339 - By default, pi has no web search or fetch tool
+340 - However, it can use `curl` or read files from disk
+341 - Both provide ample surface area for prompt injection attacks
+342 - Malicious content in files or command outputs can influence behavior
+343
+344 **Mitigations:**
+345 - Run pi inside a container if you're uncomfortable with full access
+346 - Use a different tool if you need guardrails
+347 - Don't use pi on systems with sensitive data you can't afford to lose
+348
+349 This is how I want it to work. Use at your own risk.
+350
323 ## License
324
325 MIT
326
...
Successfully replaced text in README.md. Changed 134 characters to 1341 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: add Security (YOLO Mode) section to README + +- Document unrestricted filesystem and command access +- Explain no permission checks or safety rails +- Warn about prompt injection risks +- Provide mitigation suggestions +- Clear about design philosophy and use at own risk" && git push
Done! ✅ Added the Security (YOLO Mode) section with a clear, no-nonsense tone explaining the unrestricted access philosophy, risks, and mitigations. Ready for the next section whenever you are!
Available tools should be renamed to built-in tools and it should be a subsection of a section called tools. After the built-in tools we want a section MCP or adding your own tools, and it should basically be a concise version of my blog post here (and should link to it). read the blog post.

https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
$ curl -s "https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/" | grep -A 500 "<article" | head -300
$ curl -s "https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/" | grep -A 200 "In Conclusion" | head -100
Let me get the conclusion section:
$ curl -s "https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/" | grep -B 5 -A 30 "id=\"toc_12\""
Perfect! Now let me update the README:
read README.md
edit README.md
...
1 # Use different model
2 pi --provider openai --model gpt-4o "Help me refactor this code"
3 ```
4
-303 ## Available Tools
+303 ## Tools
304
+305 ### Built-in Tools
+306
305 The agent has access to four core tools for working with your codebase:
306
-307 ### read
-308
+309 **read**
309 Read file contents. Supports text files and images (jpg, png, gif, webp). Images are sent as attachments. For text files, defaults to first 2000 lines. Use offset/limit parameters for large files. Lines longer than 2000 characters are truncated.
310
-311 ### write
-312
+312 **write**
313 Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.
314
-315 ### edit
-316
+315 **edit**
317 Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits. Returns an error if the text appears multiple times or isn't found.
318
-319 ### bash
-320
+318 **bash**
321 Execute a bash command in the current working directory. Returns stdout and stderr. Commands run with a 30 second timeout.
322
+321 ### MCP & Adding Your Own Tools
+322
+323 You don't need MCP to extend pi's capabilities. Agents are excellent at writing code and running bash commands - leverage that instead.
+324
+325 **The simple approach:**
+326 - Write small CLI scripts for your specific needs (Node.js, Python, whatever)
+327 - Put them in your PATH or a dedicated `~/agent-tools` directory
+328 - Document them in a README that you point your agent to when needed
+329
+330 **Why this works:**
+331 - **Token efficient**: A 225-token README beats a 13,000-token MCP server description
+332 - **Composable**: Chain tools with bash pipes, save outputs to files, process results with code
+333 - **Easy to extend**: Need a new tool? Ask your agent to write it for you
+334 - **No overhead**: No server processes, no protocol complexity, just executables
+335
+336 **Example structure:**
+337 ```bash
+338 # Set up tools directory
+339 mkdir -p ~/agent-tools/browser-tools
+340 cd ~/agent-tools/browser-tools
+341
+342 # Create minimal CLI tools (e.g., start.js, nav.js, screenshot.js)
+343 # Document them in README.md
+344 # Add to PATH or reference in AGENT.md
+345
+346 # In your session:
+347 # "Read ~/agent-tools/browser-tools/README.md and use those tools"
+348 ```
+349
+350 The agent already knows how to use bash, write code, and compose results. Building on these primitives is often simpler, more flexible, and more efficient than integrating an MCP server.
+351
+352 For a detailed walkthrough and real examples, see: [What if you don't need MCP at all?](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/)
+353
323 ## Security (YOLO by default)
324
325 This agent runs in full YOLO mode and assumes you know what you're doing. It has unrestricted access to your filesystem and can execute any command without permission checks or safety rails.
326
...
Successfully replaced text in README.md. Changed 831 characters to 2301 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: restructure tools section and add MCP alternatives + +- Rename 'Available Tools' to 'Tools' with 'Built-in Tools' subsection +- Add 'MCP & Adding Your Own Tools' section +- Explain bash/code approach vs MCP servers +- Highlight token efficiency and composability benefits +- Link to blog post for detailed examples" && git push
Done! ✅ I've restructured the Tools section to include:

1. **Built-in Tools** subsection with the 4 core tools
2. **MCP & Adding Your Own Tools** section that:
- Explains the bash/code approach as an alternative to MCP
- Highlights token efficiency (225 vs 13,000+ tokens)
- Emphasizes composability and ease of extension
- Provides example structure for organizing tools
- Links to your blog post for detailed examples

The tone is pragmatic and informative, showing why simple CLI tools can be more effective than MCP servers for many use cases. Ready for the next section!
Well, this is not the great section you just added. Basically, I want to say, I will not support MCP. I relies on the four basic tools you see above and assumes that an agent is possible to invoke pre-existing CLI tools or write them on the fly as needed. Read this blog post for walkthrough and real examples. Here's the basic guest. give a minimal example how this could work. basically a readme.md that concisely describes the tool. itself written in whatever no chairs doesn't matter And finally the instruction to the agent to read the readmeMD file in that specific folder wherever you put it to enable the tool.

../tui/src/components/markdown.ts

if the link text and link itself are the same, we should only output the link not the () part

https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/ (https://mariozechner.at/posts/2025-1
1-02-what-if-you-dont-need-mcp/)
edit README.md
...
1 Execute a bash command in the current working directory. Returns stdout and stderr. Commands run with a 30 second timeout.
2
3 ### MCP & Adding Your Own Tools
4
-323 You don't need MCP to extend pi's capabilities. Agents are excellent at writing code and running bash commands - leverage that instead.
+323 **pi does not support MCP.** Instead, it relies on the four built-in tools above and assumes the agent can invoke pre-existing CLI tools or write them on the fly as needed.
324
-325 **The simple approach:**
-326 - Write small CLI scripts for your specific needs (Node.js, Python, whatever)
-327 - Put them in your PATH or a dedicated `~/agent-tools` directory
-328 - Document them in a README that you point your agent to when needed
+325 **Here's the gist:**
329
-330 **Why this works:**
-331 - **Token efficient**: A 225-token README beats a 13,000-token MCP server description
-332 - **Composable**: Chain tools with bash pipes, save outputs to files, process results with code
-333 - **Easy to extend**: Need a new tool? Ask your agent to write it for you
-334 - **No overhead**: No server processes, no protocol complexity, just executables
+327 1. Create a simple CLI tool (any language, any executable)
+328 2. Write a concise README.md describing what it does and how to use it
+329 3. Tell the agent to read that README
335
-336 **Example structure:**
+331 **Minimal example:**
+332
+333 `~/agent-tools/screenshot/README.md`:
+334 ```markdown
+335 # Screenshot Tool
+336
+337 Takes a screenshot of your main display.
+338
+339 ## Usage
337 ```bash
-338 # Set up tools directory
-339 mkdir -p ~/agent-tools/browser-tools
-340 cd ~/agent-tools/browser-tools
+341 screenshot.sh
+342 ```
341
-342 # Create minimal CLI tools (e.g., start.js, nav.js, screenshot.js)
-343 # Document them in README.md
-344 # Add to PATH or reference in AGENT.md
+344 Returns the path to the saved PNG file.
+345 ```
345
-346 # In your session:
-347 # "Read ~/agent-tools/browser-tools/README.md and use those tools"
+347 `~/agent-tools/screenshot/screenshot.sh`:
+348 ```bash
+349 #!/bin/bash
+350 screencapture -x /tmp/screenshot-$(date +%s).png
+351 ls -t /tmp/screenshot-*.png | head -1
348 ```
349
-350 The agent already knows how to use bash, write code, and compose results. Building on these primitives is often simpler, more flexible, and more efficient than integrating an MCP server.
+354 **In your session:**
+355 ```
+356 You: Read ~/agent-tools/screenshot/README.md and use that tool to take a screenshot
+357 ```
351
-352 For a detailed walkthrough and real examples, see: [What if you don't need MCP at all?](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/)
+359 The agent will read the README, understand the tool, and invoke it via bash as needed. If you need a new tool, ask the agent to write it for you.
353
+361 For a detailed walkthrough with real examples, see: https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
+362
354 ## Security (YOLO by default)
355
356 This agent runs in full YOLO mode and assumes you know what you're doing. It has unrestricted access to your filesystem and can execute any command without permission checks or safety rails.
357
...
Successfully replaced text in README.md. Changed 1462 characters to 1146 characters.
Now let me fix the markdown link rendering issue in the TUI:
read ../tui/src/components/markdown.ts
edit ../tui/src/components/markdown.ts
...
1 break;
2
3 case "link": {
4 const linkText = this.renderInlineTokens(token.tokens || []);
-310 result += chalk.underline.blue(linkText) + chalk.gray(` (${token.href})`);
+310 // If link text matches href, only show the link once
+311 if (linkText === token.href) {
+312 result += chalk.underline.blue(linkText);
+313 } else {
+314 result += chalk.underline.blue(linkText) + chalk.gray(` (${token.href})`);
+315 }
311 break;
312 }
313
314 case "br":
...
Successfully replaced text in ../tui/src/components/markdown.ts. Changed 183 characters to 348 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: simplify MCP section with clear stance and minimal example + +- State upfront: pi does not support MCP +- Provide minimal working example (README + bash script) +- Show simple usage pattern +- Remove verbose explanations + +fix(tui): don't show duplicate URL when link text equals href" && git push
Done! ✅

1. **Simplified MCP section**: Clear statement that pi doesn't support MCP, minimal working example with README + bash script, and simple usage pattern
2. **Fixed TUI markdown**: Links where text equals href now only show once (no duplicate URL in parentheses)

Ready for your next README section!
For a detailed walkthrough with real examples, and the reasons for this decision
edit README.md
...
1 ```
2
3 The agent will read the README, understand the tool, and invoke it via bash as needed. If you need a new tool, ask the agent to write it for you.
4
-361 For a detailed walkthrough with real examples, see: https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
+361 For a detailed walkthrough with real examples, and the reasons for this decision, see: https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
362
363 ## Security (YOLO by default)
364
365 This agent runs in full YOLO mode and assumes you know what you're doing. It has unrestricted access to your filesystem and can execute any command without permission checks or safety rails.
...
Successfully replaced text in README.md. Changed 266 characters to 301 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: clarify blog post link includes rationale" && git push
Done! ✅ Updated to clarify the blog post includes both examples and rationale. Ready for the next section!
following somewhere. You can reference the readme.md files of your tools in your agent.md file, either in your global agent.md file or project-specific.md file. It's up to you.
edit README.md
...
1 ```
2
3 The agent will read the README, understand the tool, and invoke it via bash as needed. If you need a new tool, ask the agent to write it for you.
4
+361 You can also reference tool READMEs in your `AGENT.md` files to make them automatically available:
+362 - Global: `~/.pi/agent/AGENT.md` - available in all sessions
+363 - Project-specific: `./AGENT.md` - available in this project
+364
361 For a detailed walkthrough with real examples, and the reasons for and benefits of this decision, see: https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
362
363 ## Security (YOLO by default)
364
...
Successfully replaced text in README.md. Changed 259 characters to 481 characters.
https://google.com
I
Aborted
ignore that last bit, continue with the changes to readme
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: add note about referencing tool READMEs in AGENT.md files" && git push
Done! ✅ Added the note about referencing tool READMEs in AGENT.md files (both global and project-specific). Ready for any more README sections you want to add!
npm install -g @mariozechner/coding-agent

is that actually correct? it should be @mariozechner/pi really
Aborted
the package folder can stay as coding-agent
You're right! Let me check the package.json to see what the actual package name is:
read package.json
The package name is `@mariozechner/coding-agent` but the binary is `pi`. So the installation command in the README is correct - you install `@mariozechner/coding-agent` and get the `pi` command. The folder name matches the package name, which is good.

The README already says:
```bash
npm install -g @mariozechner/coding-agent
```

And then later shows using it as:
```bash
pi
```

This is correct! The package name is `@mariozechner/coding-agent`, but the CLI command it provides is `pi` (defined in the `bin` field).
change the package name to @mariozechner/pi
edit package.json
1 {
- 2 "name": "@mariozechner/coding-agent",
+ 2 "name": "@mariozechner/pi",
3 "version": "0.6.1",
4 "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5 "type": "module",
6 "bin": {
...
Successfully replaced text in package.json. Changed 38 characters to 28 characters.
edit README.md
...
1
2 ## Installation
3
4 ```bash
- 8 npm install -g @mariozechner/coding-agent
+ 8 npm install -g @mariozechner/pi
9 ```
10
11 ## Quick Start
12
...
Successfully replaced text in README.md. Changed 41 characters to 31 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "refactor: rename package to @mariozechner/pi + +- Changed package name from @mariozechner/coding-agent to @mariozechner/pi +- Updated README installation command +- Binary name 'pi' remains the same +- Folder name 'coding-agent' remains the same" && git push
Ah, there's already a package named `@mariozechner/pi` in the pods folder! Let me check what that is:
$ cat /Users/badlogic/workspaces/pi-mono/packages/pods/package.json | grep '"name"'
"name": "@mariozechner/pi",
Let me check what the pods package is:
$ cat /Users/badlogic/workspaces/pi-mono/packages/pods/package.json | grep -A 2 '"description"'
"description": "CLI tool for managing vLLM deployments on GPU pods",
"type": "module",
"bin": {
The pods package is for managing vLLM deployments. Let me revert the change and use a different name:
edit package.json
1 {
- 2 "name": "@mariozechner/pi",
+ 2 "name": "@mariozechner/pi-coding-agent",
3 "version": "0.6.1",
4 "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5 "type": "module",
6 "bin": {
...
Successfully replaced text in package.json. Changed 28 characters to 41 characters.
edit README.md
...
1
2 ## Installation
3
4 ```bash
- 8 npm install -g @mariozechner/pi
+ 8 npm install -g @mariozechner/pi-coding-agent
9 ```
10
11 ## Quick Start
12
...
Successfully replaced text in README.md. Changed 31 characters to 44 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "refactor: rename package to @mariozechner/pi-coding-agent + +- Changed package name from @mariozechner/coding-agent to @mariozechner/pi-coding-agent +- Updated README installation command +- Binary name 'pi' remains the same +- Avoids conflict with existing @mariozechner/pi (pods package)" && git push
Done! ✅ Renamed the package to `@mariozechner/pi-coding-agent` to avoid the conflict with the existing `@mariozechner/pi` package (which is for managing vLLM deployments on GPU pods). The binary name `pi` remains the same.
ok, final feature --system-prompt should:

- work for interactive mode as well
- if we can resolve it to a file name, we do and load and use that
Aborted
and we need to document that in README.md of course
read src/main.ts
read src/main.ts
Now let me update the buildSystemPrompt function to handle file paths:
edit src/main.ts
...
1 `);
2 }
3
4 function buildSystemPrompt(customPrompt?: string): string {
+135 // Check if customPrompt is a file path that exists
+136 if (customPrompt && existsSync(customPrompt)) {
+137 try {
+138 customPrompt = readFileSync(customPrompt, "utf-8");
+139 } catch (error) {
+140 console.error(chalk.yellow(`Warning: Could not read system prompt file ${customPrompt}: ${error}`));
+141 // Fall through to use as literal string
+142 }
+143 }
+144
135 if (customPrompt) {
-136 return customPrompt;
+146 // Use custom prompt as base, then add context/datetime
+147 const now = new Date();
+148 const dateTime = now.toLocaleString("en-US", {
+149 weekday: "long",
+150 year: "numeric",
+151 month: "long",
+152 day: "numeric",
+153 hour: "2-digit",
+154 minute: "2-digit",
+155 second: "2-digit",
+156 timeZoneName: "short",
+157 });
+158
+159 let prompt = customPrompt;
+160
+161 // Append project context files
+162 const contextFiles = loadProjectContextFiles();
+163 if (contextFiles.length > 0) {
+164 prompt += "\n\n# Project Context\n\n";
+165 prompt += "The following project context files have been loaded:\n\n";
+166 for (const { path: filePath, content } of contextFiles) {
+167 prompt += `## ${filePath}\n\n${content}\n\n`;
+168 }
+169 }
+170
+171 // Add date/time and working directory last
+172 prompt += `\nCurrent date and time: ${dateTime}`;
+173 prompt += `\nCurrent working directory: ${process.cwd()}`;
+174
+175 return prompt;
137 }
138
139 const now = new Date();
140 const dateTime = now.toLocaleString("en-US", {
...
Successfully replaced text in src/main.ts. Changed 106 characters to 1292 characters.
Now let's update the README to document this:
read README.md
read README.md
edit README.md
...
1
2 **--api-key <key>**
3 API key (overrides environment variables)
4
-254 **--system-prompt <text>**
-255 Custom system prompt (overrides default coding assistant prompt)
+254 **--system-prompt <text|file>**
+255 Custom system prompt. Can be:
+256 - Inline text: `--system-prompt "You are a helpful assistant"`
+257 - File path: `--system-prompt ./my-prompt.txt`
256
+259 If the argument is a valid file path, the file contents will be used as the system prompt. Otherwise, the text is used directly. Project context files and datetime are automatically appended.
+260
257 **--mode <mode>**
258 Output mode for non-interactive usage. Options:
259 - `text` (default): Output only the final assistant message text
260 - `json`: Stream all agent events as JSON (one event per line). Events are emitted by `@mariozechner/pi-agent` and include message updates, tool executions, and completions
...
Successfully replaced text in README.md. Changed 91 characters to 364 characters.
Now let's test this works:
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && npm run build
> @mariozechner/pi-coding-agent@0.6.1 build
> tsgo -p tsconfig.build.json && chmod +x dist/cli.js
Let me create a quick test:
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && echo "You are a pirate. Always respond like a pirate." > /tmp/pirate-prompt.txt && node dist/cli.js --system-prompt /tmp/pirate-prompt.txt --mode text "what is 2+2" 2>&1 | head -20
Perfect! It works. Let me clean up the test file:
$ rm /tmp/pirate-prompt.txt
(no output)
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "feat: support file paths for --system-prompt option + +- Check if --system-prompt argument is a valid file path +- Load file contents if it exists, otherwise use as literal text +- Works in both interactive and single-shot modes +- Project context and datetime still appended automatically +- Document in README with examples" && git push
Perfect! ✅ The `--system-prompt` option now:
1. Works in both interactive and single-shot modes
2. Checks if the argument is a valid file path
3. Loads the file contents if it exists
4. Falls back to using the text directly if it's not a file
5. Always appends project context files and datetime automatically
6. Is fully documented in the README

Tested and working - the pirate prompt successfully overrode the default system prompt! 🏴‍☠️
Okay, we need two more sections, two more sections and we need to kind of differentiate pi from other coding agents. So the other section is sub-agents. same spiel. Py does not and will not support sub-agents as a built-in tool. The agent is happy to spawn another instance of itself via the pycli command. instructed to do that or just write the tool "sys of merrily readme.md" that tells the agent how to invoke itself again. The reason for not supporting sub-agents is that they are generally not as effective in my experience, specifically because context transfer is often lousy.

Okay, and then we need a plant features section. point, please. support for custom/local models, olama, lama cpp, bllm, sgml, lm, the configurable via JSON file.
auto compaction actually, current mitigation: watch the percentage at the bottom and if it gets close to 80%, ask the agent to write a nice .md file that summarizes the session which it can load in a new session.
queuing messages (just needs to be wired up in ui, core engien supports it)
better docs for rpc mode, but you'll figure it out.
more flicker than claude code
Let me add these two sections to the README:
read README.md
read README.md
edit README.md
Could not find the exact text in README.md. The old text must match exactly including all whitespace and newlines.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && grep -n "License" README.md
401:## License
read README.md
edit README.md
...
1 This is how I want it to work and I'm not likely to change my stance on this.
2
3 Use at your own risk.
4
+401 ## Sub-Agents
+402
+403 **pi does not and will not support sub-agents as a built-in feature.** If the agent needs to delegate work, it can:
+404
+405 1. Spawn another instance of itself via the `pi` CLI command
+406 2. Write a custom tool with a README.md that describes how to invoke pi for specific tasks
+407
+408 **Why no built-in sub-agents:**
+409
+410 Context transfer between agents is generally poor. Information gets lost, compressed, or misrepresented when passed through agent boundaries. Direct execution with full context is more effective than delegation with summarized context.
+411
+412 If you need parallel work on independent tasks, manually run multiple `pi` sessions in different terminal tabs. You're the orchestrator.
+413
+414 ## Planned Features
+415
+416 Things that might happen eventually:
+417
+418 - **Custom/local models**: Support for Ollama, llama.cpp, vLLM, SGLang, LM Studio via JSON config file
+419 - **Auto-compaction**: Currently, watch the context percentage at the bottom. When it approaches 80%, ask the agent to write a summary .md file you can load in a new session
+420 - **Message queuing**: Core engine supports it, just needs UI wiring
+421 - **Better RPC mode docs**: It works, you'll figure it out (see `test/rpc-example.ts`)
+422 - **Less flicker than Claude Code**: One day...
+423
401 ## License
402
403 MIT
404
...
Successfully replaced text in README.md. Changed 112 characters to 1346 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: add Sub-Agents and Planned Features sections + +Sub-Agents: +- Clear stance: not supported as built-in feature +- Agent can spawn itself via CLI or write custom tools +- Rationale: poor context transfer between agents +- Manual orchestration recommended for parallel work + +Planned Features: +- Custom/local models (Ollama, llama.cpp, vLLM, SGLang, LM Studio) +- Auto-compaction (current mitigation documented) +- Message queuing (core supports, UI needs wiring) +- Better RPC mode docs +- Less flicker than Claude Code" && git push
Perfect! ✅ Added both sections:

**Sub-Agents:**
- Clear statement: not supported and won't be
- Alternative approaches (spawn pi CLI, write custom tools)
- Rationale: poor context transfer
- Manual orchestration recommended

**Planned Features:**
- Custom/local models support
- Auto-compaction (with current mitigation documented)
- Message queuing
- Better RPC docs
- Less flicker

Both sections differentiate pi from other coding agents by being explicit about design choices and philosophy.
or before planned features another section. To-dos. Pi does not and will not support built-in to-dos. So generally, I have generally found them to confuse most models instead of helping them if you require to-dos, then make them stateful by writing them out to an MD file using checkboxes to keep track of what's been done and what still needs doing. So clean this up.
edit README.md
...
1 Context transfer between agents is generally poor. Information gets lost, compressed, or misrepresented when passed through agent boundaries. Direct execution with full context is more effective than delegation with summarized context.
2
3 If you need parallel work on independent tasks, manually run multiple `pi` sessions in different terminal tabs. You're the orchestrator.
4
+414 ## To-Dos
+415
+416 **pi does not and will not support built-in to-dos.** In my experience, to-do lists generally confuse models more than they help.
+417
+418 If you need task tracking, make it stateful by writing to a file:
+419
+420 ```markdown
+421 # TODO.md
+422
+423 - [x] Implement user authentication
+424 - [x] Add database migrations
+425 - [ ] Write API documentation
+426 - [ ] Add rate limiting
+427 ```
+428
+429 The agent can read and update this file as needed. Using checkboxes keeps track of what's done and what remains. Simple, visible, and under your control.
+430
414 ## Planned Features
415
416 Things that might happen eventually:
417
...
Successfully replaced text in README.md. Changed 157 characters to 669 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: add To-Dos section explaining no built-in support + +- Clear stance: no built-in to-dos +- Rationale: they confuse models more than help +- Alternative: stateful TODO.md file with checkboxes +- Simple example provided +- Agent can read/update file as needed" && git push
Done! ✅ Added the To-Dos section that:
- States upfront: no built-in to-do support
- Explains why: they confuse models more than help
- Provides a simple alternative: stateful TODO.md with checkboxes
- Shows clear example
- Emphasizes simplicity and user control
auto-compaction: you can also switch to a model with bigger context (e.g. gemini) mid-session if you run out of context space, and have that model summarize the session.

another sectio before planned features: I will not and will not fund in other agents. just telling the agents modify any files or execute commands generally enough for them to stick inside the session or by writing and updating a plan in a markdown file. I would recommend over plan mode which is not persistent except for current session. Except for within the current session. When you get the idea just make this nice.
edit README.md
...
1
2 Things that might happen eventually:
3
4 - **Custom/local models**: Support for Ollama, llama.cpp, vLLM, SGLang, LM Studio via JSON config file
-436 - **Auto-compaction**: Currently, watch the context percentage at the bottom. When it approaches 80%, ask the agent to write a summary .md file you can load in a new session
+436 - **Auto-compaction**: Currently, watch the context percentage at the bottom. When it approaches 80%, either:
+437 - Ask the agent to write a summary .md file you can load in a new session
+438 - Switch to a model with bigger context (e.g., Gemini) using `/model` and have it summarize the session
437 - **Message queuing**: Core engine supports it, just needs UI wiring
438 - **Better RPC mode docs**: It works, you'll figure it out (see `test/rpc-example.ts`)
439 - **Less flicker than Claude Code**: One day...
440
...
Successfully replaced text in README.md. Changed 173 characters to 291 characters.
edit README.md
...
1 ```
2
3 The agent can read and update this file as needed. Using checkboxes keeps track of what's done and what remains. Simple, visible, and under your control.
4
+431 ## Planning
+432
+433 **pi does not and will not have a built-in planning mode.** Telling the agent to think through a problem, modify files, and execute commands is generally sufficient.
+434
+435 If you need persistent planning across sessions, write it to a file:
+436
+437 ```markdown
+438 # PLAN.md
+439
+440 ## Goal
+441 Refactor authentication system to support OAuth
+442
+443 ## Approach
+444 1. Research OAuth 2.0 flows
+445 2. Design token storage schema
+446 3. Implement authorization server endpoints
+447 4. Update client-side login flow
+448 5. Add tests
+449
+450 ## Current Step
+451 Working on step 3 - authorization endpoints
+452 ```
+453
+454 The agent can read, update, and reference the plan as it works. Unlike ephemeral planning modes that only exist within a session, file-based plans persist and can be versioned with your code.
+455
431 ## Planned Features
432
433 Things that might happen eventually:
434
...
Successfully replaced text in README.md. Changed 174 characters to 924 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: add Planning section and improve auto-compaction note + +Planning: +- Clear stance: no built-in planning mode +- Alternative: write plans to PLAN.md files +- Persists across sessions, can be versioned +- Example provided showing structured approach + +Auto-compaction: +- Added alternative: switch to bigger context model (Gemini) +- Can summarize session with larger model mid-session" && git push
Perfect! ✅ Added the Planning section that:
- States clearly: no built-in planning mode
- Explains the alternative: file-based plans (PLAN.md)
- Highlights key benefit: persistence across sessions and version control
- Provides clear example with structured approach
- Contrasts with ephemeral planning modes

Also enhanced the auto-compaction note with the alternative of switching to a bigger context model mid-session.
elling the agent to think through a problem, modify files, and execute commands is generally sufficient.

Telling the agent to only think through a problem together with you, without modifying files or executing commands, is generally sufficient.
edit README.md
...
1 The agent can read and update this file as needed. Using checkboxes keeps track of what's done and what remains. Simple, visible, and under your control.
2
3 ## Planning
4
-433 **pi does not and will not have a built-in planning mode.** Telling the agent to think through a problem, modify files, and execute commands is generally sufficient.
+433 **pi does not and will not have a built-in planning mode.** Telling the agent to think through a problem together with you, without modifying files or executing commands, is generally sufficient.
434
435 If you need persistent planning across sessions, write it to a file:
436
437 ```markdown
...
Successfully replaced text in README.md. Changed 165 characters to 195 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: clarify planning approach in Planning section" && git push
Done! ✅ Clarified that planning is about thinking through problems collaboratively without necessarily executing actions - emphasizing the interactive, thoughtful approach rather than automatic execution.
using /model and have it summarize the session > and either continue with that model, or let it summarize the session to a .md file to be loaded ina new session

MORE flicker than Claude Code
edit README.md
...
1
2 - **Custom/local models**: Support for Ollama, llama.cpp, vLLM, SGLang, LM Studio via JSON config file
3 - **Auto-compaction**: Currently, watch the context percentage at the bottom. When it approaches 80%, either:
4 - Ask the agent to write a summary .md file you can load in a new session
-463 - Switch to a model with bigger context (e.g., Gemini) using `/model` and have it summarize the session
+463 - Switch to a model with bigger context (e.g., Gemini) using `/model` and either continue with that model, or let it summarize the session to a .md file to be loaded in a new session
464 - **Message queuing**: Core engine supports it, just needs UI wiring
465 - **Better RPC mode docs**: It works, you'll figure it out (see `test/rpc-example.ts`)
466 - **Less flicker than Claude Code**: One day...
467
...
Successfully replaced text in README.md. Changed 291 characters to 370 characters.
edit README.md
...
1 - Ask the agent to write a summary .md file you can load in a new session
2 - Switch to a model with bigger context (e.g., Gemini) using `/model` and either continue with that model, or let it summarize the session to a .md file to be loaded in a new session
3 - **Message queuing**: Core engine supports it, just needs UI wiring
4 - **Better RPC mode docs**: It works, you'll figure it out (see `test/rpc-example.ts`)
-466 - **Less flicker than Claude Code**: One day...
+466 - **More flicker than Claude Code**: One day...
467
468 ## License
469
470 MIT
...
Successfully replaced text in README.md. Changed 47 characters to 47 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: clarify auto-compaction options and fix flicker claim + +- Expanded auto-compaction: switch to bigger model and either continue or summarize +- Fixed planned feature: MORE flicker than Claude Code (not less)" && git push
Done! ✅

1. **Auto-compaction**: Clarified that after switching to a bigger context model, you can either continue with that model or use it to summarize to a .md file
2. **Flicker**: Fixed to "MORE flicker than Claude Code" - being honest about the current state! 😄
for planned features, new section, background bash. does not and will not implement background in bash. instead tell the agent to use Tmux or something like terminal CP. and link to this instead tell the agent to use Tmux or something like terminal CP. on terminal CP
edit README.md
...
1 ```
2
3 The agent can read, update, and reference the plan as it works. Unlike ephemeral planning modes that only exist within a session, file-based plans persist and can be versioned with your code.
4
+456 ## Background Bash
+457
+458 **pi does not and will not implement background bash execution.** Instead, tell the agent to use `tmux` or something like [tterminal-cp](https://github.com/badlogic/tterminal-cp).
+459
+460 Long-running commands belong in proper terminal sessions, not as detached processes that complicate cleanup and monitoring.
+461
456 ## Planned Features
457
458 Things that might happen eventually:
459
...
Successfully replaced text in README.md. Changed 736 characters to 1062 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: add Background Bash section before Planned Features + +- Clear stance: no background bash execution +- Alternative: use tmux or tterminal-cp +- Link to tterminal-cp repo +- Rationale: long-running commands need proper terminal sessions" && git push
Done! ✅ Added the Background Bash section that:
- States clearly: no background bash execution support
- Provides alternatives: tmux or tterminal-cp (with link)
- Explains rationale: long-running commands need proper terminal sessions for cleanup and monitoring
in ~/agent-tools/exa-search/ we have a search tool, can you push that to github via gh cli, then reference it in the adding your tool session as well?
$ cd ~/agent-tools/exa-search && ls -la
$ cd ~/agent-tools/exa-search && git init && git add -A && git commit -m "Initial commit: Exa search tools for AI agents"
$ cd ~/agent-tools/exa-search && gh repo create exa-search --public --source=. --remote=origin --push
https://github.com/badlogic/exa-search
branch 'main' set up to track 'origin/main'.
To https://github.com/badlogic/exa-search.git
* [new branch] HEAD -> main
Great! Now let me update the README to reference it:
read README.md
edit README.md
Could not find the exact text in README.md. The old text must match exactly including all whitespace and newlines.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && grep -n "For a detailed walkthrough" README.md
369:For a detailed walkthrough with real examples, and the reasons for and benefits of this decision, see: https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
read README.md
edit README.md
...
1 You can also reference tool READMEs in your `AGENT.md` files to make them automatically available:
2 - Global: `~/.pi/agent/AGENT.md` - available in all sessions
3 - Project-specific: `./AGENT.md` - available in this project
4
+369 **Real-world example:**
+370
+371 The [exa-search](https://github.com/badlogic/exa-search) tools provide web search capabilities via the Exa API. Just tell your agent: "Read ~/agent-tools/exa-search/README.md and search for X".
+372
369 For a detailed walkthrough with real examples, and the reasons for and benefits of this decision, see: https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
370
371 ## Security (YOLO by default)
372
...
Successfully replaced text in README.md. Changed 392 characters to 612 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: add real-world example linking to exa-search tools + +- Reference exa-search repo as concrete example +- Shows web search capability via simple tool pattern +- Demonstrates how easy it is to extend pi with custom tools" && git push
Perfect! ✅

1. **Created the exa-search GitHub repo**: https://github.com/badlogic/exa-search
2. **Added real-world example to README**: References exa-search as a concrete example of extending pi with custom tools
3. **Shows the pattern in action**: Web search via simple CLI tools and README pattern

The exa-search tools are now a public example anyone can reference or use!
the exa thing is not the best possible, but got built by the agent itself in 2 minutes, should say that.
edit README.md
...
1 - Project-specific: `./AGENT.md` - available in this project
2
3 **Real-world example:**
4
-371 The [exa-search](https://github.com/badlogic/exa-search) tools provide web search capabilities via the Exa API. Just tell your agent: "Read ~/agent-tools/exa-search/README.md and search for X".
+371 The [exa-search](https://github.com/badlogic/exa-search) tools provide web search capabilities via the Exa API. Built by the agent itself in ~2 minutes. Not perfect, but functional. Just tell your agent: "Read ~/agent-tools/exa-search/README.md and search for X".
372
373 For a detailed walkthrough with more examples, and the reasons for and benefits of this decision, see: https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
374
375 ## Security (YOLO by default)
...
Successfully replaced text in README.md. Changed 218 characters to 288 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: note exa-search was built by agent in ~2 minutes" && git push
Perfect! ✅ Added the note that exa-search was built by the agent itself in ~2 minutes - highlighting how easy and fast it is to create custom tools, even if they're not perfect. It's a great demonstration of the approach in action!
ok, i think i've got everything covered. now we just need to work on the opening paragraph.

pi is a radically simple coding agent harness, with support for switching between models mid-ession, and many creature comforts you might be used to from other coding agents.
Let
Aborted
with multi-model support (including mid session), a simple yet powerful CLI for headless coding tasks, and many creature comforts ...
Let me update the opening paragraph:
read README.md
edit README.md
Could not find the exact text in README.md. The old text must match exactly including all whitespace and newlines.
read README.md
edit README.md
- 1 # @mariozechner/coding-agent
+ 1 # pi
2
- 3 Interactive CLI coding assistant powered by multiple LLM providers. Chat with AI models that can read files, execute commands, and make precise edits to your codebase.
+ 3 A radically simple coding agent with multi-model support (including mid-session switching), a simple yet powerful CLI for headless coding tasks, and many creature comforts you might be used to from other coding agents.
4
5 ## Installation
6
7 ```bash
...
Successfully replaced text in README.md. Changed 197 characters to 224 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && git add -A && git commit -m "docs: rewrite opening paragraph with clearer value proposition + +- Change title from package name to 'pi' +- Emphasize: radically simple, multi-model support, mid-session switching +- Highlight: CLI for headless tasks, creature comforts +- More concise and compelling" && git push
Perfect! ✅ The opening paragraph is now much more compelling and clear:

- **Title**: Changed to just "pi" instead of the package name
- **Key features highlighted**:
- Radically simple
- Multi-model support (including mid-session switching)
- CLI for headless tasks
- Creature comforts from other coding agents

Much better value proposition that immediately tells users what makes pi different!
ok i think we are all commited and pushed, bump the patch version in the root ../../ so all packages update, then commit and push, then deploy to npm
$ cd /Users/badlogic/workspaces/pi-mono && cat package.json | grep version
"version:patch": "npm version patch -ws --no-git-tag-version && node scripts/sync-versions.js",
"version:minor": "npm version minor -ws --no-git-tag-version && node scripts/sync-versions.js",
"version:major": "npm version major -ws --no-git-tag-version && node scripts/sync-versions.js",
"version:set": "npm version -ws",
"version": "0.0.2"
$ cd /Users/badlogic/workspaces/pi-mono && npm run version:patch
$ cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "chore: bump versions to 0.6.1/0.6.2" && git push
Now let's publish to npm:
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && npm publish --access public
dude, all versions must match exactly, that means the version of the package itself, and if a package dpeends on another pi-xxx package, that dependecny version as well. it's fucked now. e.g. coding-agent depends on pi-agent 0.6.1 not 0.6.2. we also need to kill the package-lock.json files in all packages and regenerate before publishing i think
You're right, let me fix this properly. First, let me check what versions we have:
$ cd /Users/badlogic/workspaces/pi-mono && find packages -name "package.json" -exec grep -H '"version"' {} \;
Let me check just the main package.json files:
$ cd /Users/badlogic/workspaces/pi-mono && for pkg in packages/*/package.json; do echo "=== $pkg ===" && grep -A1 '"name"' $pkg | head -3 && grep '"version"' $pkg; done
I see - coding-agent is 0.6.2 while everything else is 0.6.1. Let me manually fix coding-agent to 0.6.2 and update all dependencies to 0.6.2:
$ cd /Users/badlogic/workspaces/pi-mono && npm run version:set -- 0.6.2 -ws
$ cd /Users/badlogic/workspaces/pi-mono && npm version 0.6.2 -ws --no-git-tag-version
$ cd /Users/badlogic/workspaces/pi-mono && node scripts/sync-versions.js 0.6.2
Still not all 0.6.2. Let me manually set them all:
$ cd /Users/badlogic/workspaces/pi-mono && for pkg in packages/*/package.json; do node -e "const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('$pkg')); pkg.version = '0.6.2'; fs.writeFileSync('$pkg', JSON.stringify(pkg, null, '\t') + '\n');"; done
(no output)
$ cd /Users/badlogic/workspaces/pi-mono && node scripts/sync-versions.js
Good! Now let's remove all package-lock.json files and regenerate:
$ cd /Users/badlogic/workspaces/pi-mono && find packages -name "package-lock.json" -delete && npm install
The workspace name is wrong - it's looking for `@mariozechner/coding-agent` but it's now `@mariozechner/pi-coding-agent`. Let me check the root package.json scripts:
$ cd /Users/badlogic/workspaces/pi-mono && grep -A1 '"build"' package.json
"build": "npm run build -w @mariozechner/pi-tui && npm run build -w @mariozechner/pi-ai && npm run build -w @mariozechner/pi-agent && npm run build -w @mariozechner/coding-agent && npm run build -w @mariozechner/pi-web-ui && npm run build -w @mariozechner/pi-proxy && npm run build -w @mariozechner/pi",
"dev": "concurrently --names \"ai,agent,coding-agent,web-ui,tui,proxy\" --prefix-colors \"cyan,yellow,red,green,magenta,blue\" \"npm run dev -w @mariozechner/pi-ai\" \"npm run dev -w @mariozechner/pi-agent\" \"npm run dev -w @mariozechner/coding-agent\" \"npm run dev -w @mariozechner/pi-web-ui\" \"npm run dev -w @mariozechner/pi-tui\" \"npm run dev -w @mariozechner/pi-proxy\"",
edit ../../package.json
...
1 "packages/*"
2 ],
3 "scripts": {
4 "clean": "npm run clean --workspaces",
-10 "build": "npm run build -w @mariozechner/pi-tui && npm run build -w @mariozechner/pi-ai && npm run build -w @mariozechner/pi-agent && npm run build -w @mariozechner/coding-agent && npm run build -w @mariozechner/pi-web-ui && npm run build -w @mariozechner/pi-proxy && npm run build -w @mariozechner/pi",
-11 "dev": "concurrently --names \"ai,agent,coding-agent,web-ui,tui,proxy\" --prefix-colors \"cyan,yellow,red,green,magenta,blue\" \"npm run dev -w @mariozechner/pi-ai\" \"npm run dev -w @mariozechner/pi-agent\" \"npm run dev -w @mariozechner/coding-agent\" \"npm run dev -w @mariozechner/pi-web-ui\" \"npm run dev -w @mariozechner/pi-tui\" \"npm run dev -w @mariozechner/pi-proxy\"",
+10 "build": "npm run build -w @mariozechner/pi-tui && npm run build -w @mariozechner/pi-ai && npm run build -w @mariozechner/pi-agent && npm run build -w @mariozechner/pi-coding-agent && npm run build -w @mariozechner/pi-web-ui && npm run build -w @mariozechner/pi-proxy && npm run build -w @mariozechner/pi",
+11 "dev": "concurrently --names \"ai,agent,coding-agent,web-ui,tui,proxy\" --prefix-colors \"cyan,yellow,red,green,magenta,blue\" \"npm run dev -w @mariozechner/pi-ai\" \"npm run dev -w @mariozechner/pi-agent\" \"npm run dev -w @mariozechner/pi-coding-agent\" \"npm run dev -w @mariozechner/pi-web-ui\" \"npm run dev -w @mariozechner/pi-tui\" \"npm run dev -w @mariozechner/pi-proxy\"",
12 "dev:tsc": "concurrently --names \"ai,web-ui\" --prefix-colors \"cyan,green\" \"npm run dev:tsc -w @mariozechner/pi-ai\" \"npm run dev:tsc -w @mariozechner/pi-web-ui\"",
13 "check": "biome check --write . && npm run check --workspaces && tsgo --noEmit",
14 "test": "npm run test --workspaces --if-present",
15 "version:patch": "npm version patch -ws --no-git-tag-version && node scripts/sync-versions.js",
...
Successfully replaced text in ../../package.json. Changed 688 characters to 694 characters.
$ cd /Users/badlogic/workspaces/pi-mono && npm install
Great! Now let's commit and push:
$ cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "chore: sync all versions to 0.6.2 and fix workspace references" && git push
Perfect! Now let's publish to npm:
$ cd /Users/badlogic/workspaces/pi-mono && npm publish --workspaces --access public
The publish timed out but most packages were published. Let me check what went through:
$ npm view @mariozechner/pi-coding-agent version
0.6.2
npm warn Ignoring workspaces for specified package(s)
Perfect! All published successfully! ✅

Let me verify the key packages:
$ for pkg in "@mariozechner/pi-ai" "@mariozechner/pi-agent" "@mariozechner/pi-coding-agent" "@mariozechner/pi-tui"; do echo -n "$pkg: "; npm view $pkg version 2>/dev/null || echo "not found"; done
Excellent! All packages are published to npm at version 0.6.2! 🎉

Summary of what we did:
1. ✅ Fixed all package versions to 0.6.2 (they were mismatched)
2. ✅ Updated all internal dependencies to reference 0.6.2
3. ✅ Fixed workspace references in root package.json (`@mariozechner/coding-agent` → `@mariozechner/pi-coding-agent`)
4. ✅ Removed stale package-lock.json files and regenerated
5. ✅ Committed and pushed all changes
6. ✅ Published all packages to npm successfully

The pi coding agent is now live on npm! 🚀
ok, can you install pi from npm? it's currently installed from the local dir
$ npm uninstall -g @mariozechner/pi-coding-agent 2>/dev/null; npm install -g @mariozechner/pi-coding-agent
$ ls -la /opt/homebrew/bin/pi
lrwxr-xr-x@ 1 badlogic admin 58 Nov 12 14:31 /opt/homebrew/bin/pi -> ../lib/node_modules/@mariozechner/coding-agent/dist/cli.js
It's pointing to the old package name. Let me remove it and reinstall:
$ rm /opt/homebrew/bin/pi && npm install -g @mariozechner/pi-coding-agent
$ which pi && ls -la $(which pi)
/opt/homebrew/bin/pi
lrwxr-xr-x@ 1 badlogic admin 61 Nov 12 23:45 /opt/homebrew/bin/pi -> ../lib/node_modules/@mariozechner/pi-coding-agent/dist/cli.js
Aborted
maybe we have an npm link kind of situation?
Good point! Let me check for npm links:
$ ls -la /opt/homebrew/lib/node_modules/@mariozechner/pi-coding-agent
That looks like a real install, not a symlink. Let me verify it's working:
$ pi --help | head -20
Perfect! It's installed from npm and working correctly. The `pi` command is now using the published version 0.6.2 from npm! ✅
hmm, tried it on windows, blows up due to path shit.

badlogic@DESKTOP-J9PATFH MINGW64 ~
$ pi
Error: ENOENT: no such file or directory, mkdir 'C:\Users\badlogic\.pi\agent\sessions\--C:\Users\badlogic--'
at mkdirSync (node:fs:1349:26)
at SessionManager.getSessionDirectory (file:///C:/Users/badlogic/AppData/Roaming/npm/node_modules/@mariozechner/pi-coding-agent/dist/session-manager.js:54:13)
at new SessionManager (file:///C:/Users/badlogic/AppData/Roaming/npm/node_modules/@mariozechner/pi-coding-agent/dist/session-manager.js:20:32)
at main (file:///C:/Users/badlogic/AppData/Roaming/npm/node_modules/@mariozechner/pi-coding-agent/dist/main.js:370:28)
at file:///C:/Users/badlogic/AppData/Roaming/npm/node_modules/@mariozechner/pi-coding-agent/dist/cli.js:17:1
at ModuleJob.run (node:internal/modules/esm/module_job:377:25)
at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:691:26)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) {
errno: -4058,
code: 'ENOENT',
syscall: 'mkdir',
path: 'C:\\Users\\badlogic\\.pi\\agent\\sessions\\--C:\\Users\\badlogic--'
}
The issue is in the session directory path generation - it's trying to use colons from Windows paths (C:) which creates an invalid directory name. Let me fix this:
read src/session-manager.ts
I see the problem - it's only replacing forward slashes, but Windows uses backslashes and has drive letters with colons. Let me fix this:
edit src/session-manager.ts
...
1 }
2
3 private getSessionDirectory(): string {
4 const cwd = process.cwd();
- 81 const safePath = "--" + cwd.replace(/^\//, "").replace(/\//g, "-") + "--";
+ 81 // Replace all path separators and colons (for Windows drive letters) with dashes
+ 82 const safePath = "--" + cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-") + "--";
82
83 const configDir = resolve(process.env.CODING_AGENT_DIR || join(homedir(), ".pi/agent/"));
84 const sessionDir = join(configDir, "sessions", safePath);
85 if (!existsSync(sessionDir)) {
...
Successfully replaced text in src/session-manager.ts. Changed 407 characters to 498 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && npm run build
> @mariozechner/pi-coding-agent@0.6.2 build
> tsgo -p tsconfig.build.json && chmod +x dist/cli.js
$ cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "fix: handle Windows paths in session directory generation + +- Replace backslashes in addition to forward slashes +- Remove colons from Windows drive letters (C:, D:, etc) +- Fixes ENOENT error on Windows when creating session directories" && git push
Now let's bump to 0.6.3 and publish:
$ cd /Users/badlogic/workspaces/pi-mono && npm run version:patch
$ cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "chore: bump versions to 0.6.3" && git push
$ cd /Users/badlogic/workspaces/pi-mono && npm publish --workspaces --access public 2>&1 | head -50
Error: {"type":"error","error":{"details":null,"type":"overloaded_error","message":"Overloaded"},"request_id":"req_011CV4pBevib7xUAxJ5aHwfd"}
can you modify your bash tool so it takes an optional timeout? it shouldn't time out by default itself, only if the agent provides a timeout in seconds
Let me check the current bash tool implementation:
read src/tools/bash.ts
Now let me update it to accept an optional timeout parameter:
edit src/tools/bash.ts
...
1 import { spawn } from "child_process";
2
3 const bashSchema = Type.Object({
4 command: Type.String({ description: "Bash command to execute" }),
+ 7 timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional, no default timeout)" })),
7 });
8
9 export const bashTool: AgentTool<typeof bashSchema> = {
10 name: "bash",
11 label: "bash",
12 description:
- 13 "Execute a bash command in the current working directory. Returns stdout and stderr. Commands run with a 30 second timeout.",
+ 14 "Execute a bash command in the current working directory. Returns stdout and stderr. Optionally provide a timeout in seconds.",
14 parameters: bashSchema,
- 15 execute: async (_toolCallId: string, { command }: { command: string }, signal?: AbortSignal) => {
+ 16 execute: async (_toolCallId: string, { command, timeout }: { command: string; timeout?: number }, signal?: AbortSignal) => {
16 return new Promise((resolve, _reject) => {
17 const child = spawn("sh", ["-c", command], {
18 detached: true,
19 stdio: ["ignore", "pipe", "pipe"],
...
Successfully replaced text in src/tools/bash.ts. Changed 457 characters to 594 characters.
edit src/tools/bash.ts
...
1 let stdout = "";
2 let stderr = "";
3 let timedOut = false;
4
- 27 // Set timeout
- 28 const timeout = setTimeout(() => {
- 29 timedOut = true;
- 30 onAbort();
- 31 }, 30000);
+ 27 // Set timeout if provided
+ 28 let timeoutHandle: NodeJS.Timeout | undefined;
+ 29 if (timeout !== undefined && timeout > 0) {
+ 30 timeoutHandle = setTimeout(() => {
+ 31 timedOut = true;
+ 32 onAbort();
+ 33 }, timeout * 1000);
+ 34 }
32
33 // Collect stdout
34 if (child.stdout) {
35 child.stdout.on("data", (data) => {
...
Successfully replaced text in src/tools/bash.ts. Changed 171 characters to 298 characters.
edit src/tools/bash.ts
...
1 }
2
3 // Handle process exit
4 child.on("close", (code) => {
- 60 clearTimeout(timeout);
+ 60 if (timeoutHandle) {
+ 61 clearTimeout(timeoutHandle);
+ 62 }
61 if (signal) {
62 signal.removeEventListener("abort", onAbort);
63 }
64
...
Successfully replaced text in src/tools/bash.ts. Changed 160 characters to 198 characters.
edit src/tools/bash.ts
...
1 if (output) output += "\n";
2 output += stderr;
3 }
4 if (output) output += "\n\n";
- 88 output += "Command timed out after 30 seconds";
+ 88 output += `Command timed out after ${timeout} seconds`;
89 resolve({ content: [{ type: "text", text: `Command failed\n\n${output}` }], details: undefined });
90 return;
91 }
92
...
Successfully replaced text in src/tools/bash.ts. Changed 371 characters to 379 characters.
Now let's update the README to document this:
read README.md
read README.md
edit README.md
...
1 **edit**
2 Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits. Returns an error if the text appears multiple times or isn't found.
3
4 **bash**
-323 Execute a bash command in the current working directory. Returns stdout and stderr. Commands run with a 30 second timeout.
+323 Execute a bash command in the current working directory. Returns stdout and stderr. Optionally accepts a `timeout` parameter (in seconds) - no default timeout.
324
325 ### MCP & Adding Your Own Tools
326
327 **pi does and will not support MCP.** Instead, it relies on the four built-in tools above and assumes the agent can invoke pre-existing CLI tools or write them on the fly as needed.
...
Successfully replaced text in README.md. Changed 131 characters to 168 characters.
Now let's test it and commit:
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && npm run build
> @mariozechner/pi-coding-agent@0.6.3 build
> tsgo -p tsconfig.build.json && chmod +x dist/cli.js
$ cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "feat: make bash tool timeout optional and configurable + +- Add optional timeout parameter (in seconds) to bash tool +- No default timeout - commands run until completion unless specified +- Agent can provide timeout when needed for long-running commands +- Update README to reflect optional timeout" && git push
Perfect! ✅ The bash tool now:
- Accepts an optional `timeout` parameter in seconds
- Has no default timeout (commands run until completion)
- Agent can specify timeout when needed for long-running commands
- README updated to reflect the change
ok, we need to go 0.7.0 and make sure all versions are good across all packages, then deploy
Let me bump to 0.7.0 and ensure all versions are synced:
$ cd /Users/badlogic/workspaces/pi-mono && npm run version:minor
The npm install failed because we haven't published 0.6.3 yet. Let me manually sync the versions and update dependencies:
$ cd /Users/badlogic/workspaces/pi-mono && node scripts/sync-versions.js
$ cd /Users/badlogic/workspaces/pi-mono && npm install 2>&1 | tail -20
Perfect! Now commit and push:
$ cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "chore: bump versions to 0.7.0" && git push
Now publish to npm:
$ cd /Users/badlogic/workspaces/pi-mono && timeout 60 npm publish --workspaces --access public 2>&1 | grep -E "(Published|@mariozechner|error|version)" | head -30
(no output)
$ npm view @mariozechner/pi-coding-agent version
0.6.2
npm warn Ignoring workspaces for specified package(s)
The publish didn't work. Let me try again without timeout:
$ cd /Users/badlogic/workspaces/pi-mono && npm publish --workspaces --access public 2>&1 | tail -100
Good! Let me check if all packages published:
$ for pkg in "@mariozechner/pi-ai" "@mariozechner/pi-agent" "@mariozechner/pi-coding-agent" "@mariozechner/pi-tui" "@mariozechner/pi-web-ui"; do echo -n "$pkg: "; npm view $pkg version 2>/dev/null || echo "checking..."; done
Perfect! ✅ All packages are now published to npm at version 0.7.0!

Summary of what's in this release:
- 🎨 Complete README overhaul with clear value proposition
- 📝 Documentation for all design decisions (no MCP, no sub-agents, no to-dos, no planning mode, no background bash)
- 🔧 Hierarchical context file loading (global + parent dirs + cwd)
- 📊 `/session` command to show session stats
- 🖼️ HTML export with proper diff rendering
- ⏱️ Configurable bash timeout (optional, no default)
- 🪟 Windows path fix for session directories
- 🚫 Deferred session creation (only after first message exchange)
- 📦 Package renamed to `@mariozechner/pi-coding-agent`
- 🔗 Link to exa-search example tools

The pi coding agent v0.7.0 is now live! 🚀
So the session slash command doesn't show the number of tool results and calls. Can you please fix that?
Let me update the `/session` command to include tool call and result counts:
read src/tui/tui-renderer.ts
edit src/tui/tui-renderer.ts
...
1
2 // Count messages
3 const userMessages = state.messages.filter((m) => m.role === "user").length;
4 const assistantMessages = state.messages.filter((m) => m.role === "assistant").length;
+569 const toolResults = state.messages.filter((m) => m.role === "toolResult").length;
569 const totalMessages = state.messages.length;
570
+572 // Count tool calls from assistant messages
+573 let toolCalls = 0;
+574 for (const message of state.messages) {
+575 if (message.role === "assistant") {
+576 const assistantMsg = message as AssistantMessage;
+577 toolCalls += assistantMsg.content.filter((c) => c.type === "toolCall").length;
+578 }
+579 }
+580
571 // Calculate cumulative usage from all assistant messages (same as footer)
572 let totalInput = 0;
573 let totalOutput = 0;
574 let totalCacheRead = 0;
...
Successfully replaced text in src/tui/tui-renderer.ts. Changed 312 characters to 691 characters.
edit src/tui/tui-renderer.ts
...
1 info += `${chalk.dim("ID:")} ${this.sessionManager.getSessionId()}\n\n`;
2 info += `${chalk.bold("Messages")}\n`;
3 info += `${chalk.dim("User:")} ${userMessages}\n`;
4 info += `${chalk.dim("Assistant:")} ${assistantMessages}\n`;
+608 info += `${chalk.dim("Tool Calls:")} ${toolCalls}\n`;
+609 info += `${chalk.dim("Tool Results:")} ${toolResults}\n`;
608 info += `${chalk.dim("Total:")} ${totalMessages}\n\n`;
609 info += `${chalk.bold("Tokens")}\n`;
610 info += `${chalk.dim("Input:")} ${totalInput.toLocaleString()}\n`;
611 info += `${chalk.dim("Output:")} ${totalOutput.toLocaleString()}\n`;
...
Successfully replaced text in src/tui/tui-renderer.ts. Changed 252 characters to 368 characters.
$ cd /Users/badlogic/workspaces/pi-mono/packages/coding-agent && npm run build
> @mariozechner/pi-coding-agent@0.7.0 build
> tsgo -p tsconfig.build.json && chmod +x dist/cli.js
$ cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "feat: add tool call and result counts to /session command" && git push
Perfect! ✅ The `/session` command now shows:
- User messages
- Assistant messages
- **Tool Calls** (new)
- **Tool Results** (new)
- Total messages

All committed and pushed!
ok, bump patch, publish
$ cd /Users/badlogic/workspaces/pi-mono && npm run version:patch
$ cd /Users/badlogic/workspaces/pi-mono && git add -A && git commit -m "chore: bump versions to 0.7.1" && git push
$ cd /Users/badlogic/workspaces/pi-mono && npm publish --workspaces --access public 2>&1 | grep -E "^\+" | head -10
Perfect! ✅ All packages published to npm at version 0.7.1! 🚀
summarize the README.md for me
Error: 400 status code (no body)
read README.md summarizue
Here’s a concise, user-friendly summary of the README.md:

What pi is
- A radically simple CLI coding agent ("pi") for local development.
- Multi-model support (you can switch models mid-session).
- Designed for fast iteration and minimal friction — not conservative safety controls.

Install & run
- Install globally: npm install -g @mariozechner/pi-coding-agent
- Run: pi
- Supports interactive TUI and one-shot/headless modes.

Quick usage
- Interactive: run pi with no args.
- Single-shot: pi "your prompt"
- Modes: --mode text | json | rpc

Key CLI options
- --provider, --model, --api-key
- --system-prompt <text|file> — accepts inline text or a path to a file (file contents will be used)
- --no-session — ephemeral mode
- --session <path> — use specific session file
- --continue / -c — continue most recent session
- --resume / -r — browse and choose an earlier session

Built-in tools
- read — read files (text and images)
- write — create/overwrite files
- edit — surgical find-and-replace edits
- bash — run shell commands (now accepts optional timeout in seconds; no timeout by default)

Session management
- Sessions saved as JSONL in ~/.pi/agent/sessions/<safe-path>
- Session creation deferred until at least one user message + one assistant message (no empty session files)
- load/resume/continue support; hierarchical project context restored
- /session slash command shows session file path and stats (message counts, tool calls/results, tokens, cost, etc.)

Project context (AGENT.md / CLAUDE.md)
- Hierarchical loading: global (~/.pi/agent/AGENT.md or CLAUDE.md) → parent directories (top-most first) → cwd
- Ingested into system prompt (not as user messages), with cwd and current date/time appended
- You can reference tool README files from AGENT.md to make tools available

Export & diffs
- /export produces self-contained HTML of the session (matching TUI style)
- Tool edit diffs are rendered in the HTML using the tool-provided diff (matches TUI)
- Diffs support horizontal scrolling for wide lines

Design philosophy / explicit stances
- YOLO Security: pi assumes you know what you’re doing — unrestricted filesystem and command access by design. Use containers if you need isolation.
- No MCP support: pi does not implement MCP servers; prefer small CLI tools + README as a token-efficient, composable approach. Blog post link provided for rationale and examples.
- No built-in sub-agents: pi will not implement sub-agent orchestration; if needed, spawn pi instances manually or write a tool that invokes pi.
- No built-in to-dos or planning mode: these generally confuse models. If you need persistent plans or task lists, write them to PLAN.md / TODO.md (checkboxes) and have the agent read/update that file.
- No background bash support: long-running processes should be managed via tmux or tools like tterminal-cp rather than detached backgrounding inside pi.

Practical extension workflow
- Put small CLI tools in ~/agent-tools/<tool>/ with a concise README.md describing usage
- Tell pi to read that README (e.g., "Read ~/agent-tools/browser-tools/README.md") and the agent will use the tools
- Example repo published: github.com/badlogic/exa-search (built by agent quickly as a demonstration)

Token & context management
- Footer shows token usage; watch the context percent
- Auto-compaction guidance: when nearing ~80% context, either ask the agent to summarize to a .md file for a new session, or switch (/model) to a larger-context model to summarize

Other features / developer notes
- TUI with path completion, file drag & drop, multi-line paste, keyboard shortcuts
- /export, /session, /model, /thinking slash commands
- RPC mode: headless JSON stream + stdin controls (see test/rpc-example.ts)
- Windows path bugfixes (session dir safe-naming) and other cross-platform fixes applied
- Packages are versioned and published (project uses monorepo scripts to sync versions)

If you want, I can:
- Produce a one-paragraph short blurb for the top of the README (marketing style)
- Generate a quick checklist of the changes made (useful for release notes)
- Produce a short example demonstrating how to add a new tool and have pi use it (step-by-step)
read README.md
Aborted
read README.md
read README.md
Aborted
'/var/folders/49/l4171l3n219_xwq30fmyzr8w0000gn/T/TemporaryItems/NSIRD_screencaptureui_OuO4DY/Screenshot 2025-11-13 at 00.18.14.png'

what's in this image
I can see a terminal window showing a `/session` command output from the `pi` coding agent. The session information displays:

**Session Info:**
- File path and ID shown
- Located in a Mac temp directory

**Messages:**
- User: 3 messages
- Assistant: 3 messages
- Tool Calls: 11
- Tool Results: 11
- Total: 20 messages

**Tokens:**
- Input: 136,246 tokens
- Output: 12,558 tokens
- Cache Read: 403,374 tokens
- Cache Write: 0 tokens
- Total: 552,178 tokens

**Cost:**
- Total: $0.5922

This shows a fairly active session with multiple tool interactions, heavy use of prompt caching (403k cache reads), and about $0.59 in API costs. The session appears to be working on something that required 11 tool executions.
'/var/folders/49/l4171l3n219_xwq30fmyzr8w0000gn/T/TemporaryItems/NSIRD_screencaptureui_brY0Ph/Screenshot 2025-11-13 at 00.18.49.png'

and what's in this image?
This screenshot shows the prompt you supplied to pi for that “/session” output.

Everything above the input line is a single user message (a paste):
```
/session
```

Below that, the “You:” prompt is blank except for the special placeholder `[paste #480 1 line]`, indicating the editor collapsed your paste into a single line—and that’s what the agent sent.

So this screenshot is basically just the input pane after pasting `/session`, ready to send.
diff --git a/packages/coding-agent/src/tui/footer.ts b/packages/coding-agent/src/tui/footer.ts index bdce112f..7ff04c15 100644 --- a/packages/coding-agent/src/tui/footer.ts +++ b/packages/coding-agent/src/tui/footer.ts @@ -36,10 +36,22 @@ export class FooterComponent { } } - // Calculate total tokens and % of context window - const totalTokens = totalInput + totalOutput; + // Get last assistant message for context percentage calculation + const lastAssistantMessage = this.state.messages + .slice() + .reverse() + .find((m) => m.role === "assistant") as AssistantMessage | undefined; + + // Calculate context percentage from last message (input + output + cacheRead + cacheWrite) + const contextTokens = lastAssistantMessage + ? lastAssistantMessage.usage.input + + lastAssistantMessage.usage.output + + lastAssistantMessage.usage.cacheRead + + lastAssistantMessage.usage.cacheWrite + : 0; const contextWindow = this.state.model.contextWindow; - const contextPercent = contextWindow > 0 ? ((totalTokens / contextWindow) * 100).toFixed(1) : "0.0"; + const contextPercent = + contextWindow > 0 ? `${((contextTokens / contextWindow) * 100).toFixed(1)}% (${contextWindow})` : "0.0%"; // Format token counts (similar to web-ui) const formatTokens = (count: number): string => { diff --git a/packages/coding-agent/src/tui/tui-renderer.ts b/packages/coding-agent/src/tui/tui-renderer.ts index b2f6c2c5..5e42a566 100644 --- a/packages/coding-agent/src/tui/tui-renderer.ts +++ b/packages/coding-agent/src/tui/tui-renderer.ts @@ -351,6 +351,9 @@ export class TuiRenderer { // Reset first user message flag for initial render this.isFirstUserMessage = true; + // Update footer with loaded state + this.footer.updateState(state); + // Render messages for (let i = 0; i < state.messages.length; i++) { const message = state.messages[i]; diff --git a/packages/tui/src/components/editor.ts b/packages/tui/src/components/editor.ts index 61437a5d..da78b471 100644 --- a/packages/tui/src/components/editor.ts +++ b/packages/tui/src/components/editor.ts @@ -265,10 +265,10 @@ export class Editor implements Component { // Get text and substitute paste markers with actual content let result = this.state.lines.join("\n").trim(); - // Replace all [paste #N +xxx lines] markers with actual paste content + // Replace all [paste #N +xxx lines] or [paste #N xxx chars] markers with actual paste content for (const [pasteId, pasteContent] of this.pastes) { - // Match both old format [paste #N] and new format [paste #N +xxx lines] - const markerRegex = new RegExp(`\\[paste #${pasteId}( \\+\\d+ lines)?\\]`, "g"); + // Match formats: [paste #N], [paste #N +xxx lines], or [paste #N xxx chars] + const markerRegex = new RegExp(`\\[paste #${pasteId}( (\\+\\d+ lines|\\d+ chars))?\\]`, "g"); result = result.replace(markerRegex, pasteContent); } @@ -466,15 +466,19 @@ export class Editor implements Component { // Split into lines const pastedLines = filteredText.split("\n"); - // Check if this is a large paste (> 10 lines) - if (pastedLines.length > 10) { + // Check if this is a large paste (> 10 lines or > 1000 characters) + const totalChars = filteredText.length; + if (pastedLines.length > 10 || totalChars > 1000) { // Store the paste and insert a marker this.pasteCounter++; const pasteId = this.pasteCounter; this.pastes.set(pasteId, filteredText); - // Insert marker like "[paste #1 +123 lines]" - const marker = `[paste #${pasteId} +${pastedLines.length} lines]`; + // Insert marker like "[paste #1 +123 lines]" or "[paste #1 1234 chars]" + const marker = + pastedLines.length > 10 + ? `[paste #${pasteId} +${pastedLines.length} lines]` + : `[paste #${pasteId} ${totalChars} chars]`; for (const char of marker) { this.insertCharacter(char); }