@mariozechner/pi-coding-agent 0.14.2 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +415 -1098
  3. package/dist/cli/args.d.ts +30 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +179 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/file-processor.d.ts +11 -0
  8. package/dist/cli/file-processor.d.ts.map +1 -0
  9. package/dist/cli/file-processor.js +82 -0
  10. package/dist/cli/file-processor.js.map +1 -0
  11. package/dist/cli/session-picker.d.ts +7 -0
  12. package/dist/cli/session-picker.d.ts.map +1 -0
  13. package/dist/cli/session-picker.js +29 -0
  14. package/dist/cli/session-picker.js.map +1 -0
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +7 -18
  17. package/dist/cli.js.map +1 -1
  18. package/dist/config.d.ts +2 -2
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +15 -9
  21. package/dist/config.js.map +1 -1
  22. package/dist/core/agent-session.d.ts +287 -0
  23. package/dist/core/agent-session.d.ts.map +1 -0
  24. package/dist/core/agent-session.js +735 -0
  25. package/dist/core/agent-session.js.map +1 -0
  26. package/dist/core/bash-executor.d.ts +41 -0
  27. package/dist/core/bash-executor.d.ts.map +1 -0
  28. package/dist/core/bash-executor.js +132 -0
  29. package/dist/core/bash-executor.js.map +1 -0
  30. package/dist/{compaction.d.ts → core/compaction.d.ts} +5 -1
  31. package/dist/core/compaction.d.ts.map +1 -0
  32. package/dist/{compaction.js → core/compaction.js} +23 -1
  33. package/dist/core/compaction.js.map +1 -0
  34. package/dist/core/export-html.d.ts.map +1 -0
  35. package/dist/{export-html.js → core/export-html.js} +1 -1
  36. package/dist/{export-html.d.ts.map → core/export-html.js.map} +1 -1
  37. package/dist/core/index.d.ts +6 -0
  38. package/dist/core/index.d.ts.map +1 -0
  39. package/dist/core/index.js +6 -0
  40. package/dist/core/index.js.map +1 -0
  41. package/dist/core/messages.d.ts.map +1 -0
  42. package/dist/core/messages.js.map +1 -0
  43. package/dist/core/model-config.d.ts.map +1 -0
  44. package/dist/{model-config.js → core/model-config.js} +1 -1
  45. package/dist/core/model-config.js.map +1 -0
  46. package/dist/core/model-resolver.d.ts +48 -0
  47. package/dist/core/model-resolver.d.ts.map +1 -0
  48. package/dist/core/model-resolver.js +244 -0
  49. package/dist/core/model-resolver.js.map +1 -0
  50. package/dist/core/oauth/anthropic.d.ts.map +1 -0
  51. package/dist/core/oauth/anthropic.js.map +1 -0
  52. package/dist/core/oauth/index.d.ts.map +1 -0
  53. package/dist/{oauth/index.d.ts.map → core/oauth/index.js.map} +1 -1
  54. package/dist/core/oauth/storage.d.ts.map +1 -0
  55. package/dist/{oauth → core/oauth}/storage.js +1 -1
  56. package/dist/core/oauth/storage.js.map +1 -0
  57. package/dist/core/session-manager.d.ts.map +1 -0
  58. package/dist/{session-manager.js → core/session-manager.js} +1 -1
  59. package/dist/core/session-manager.js.map +1 -0
  60. package/dist/core/settings-manager.d.ts.map +1 -0
  61. package/dist/{settings-manager.js → core/settings-manager.js} +1 -1
  62. package/dist/core/settings-manager.js.map +1 -0
  63. package/dist/core/slash-commands.d.ts.map +1 -0
  64. package/dist/{slash-commands.js → core/slash-commands.js} +1 -1
  65. package/dist/core/slash-commands.js.map +1 -0
  66. package/dist/core/system-prompt.d.ts +17 -0
  67. package/dist/core/system-prompt.d.ts.map +1 -0
  68. package/dist/core/system-prompt.js +203 -0
  69. package/dist/core/system-prompt.js.map +1 -0
  70. package/dist/core/tools/bash.d.ts.map +1 -0
  71. package/dist/{tools → core/tools}/bash.js +1 -1
  72. package/dist/core/tools/bash.js.map +1 -0
  73. package/dist/core/tools/edit.d.ts.map +1 -0
  74. package/dist/core/tools/edit.js.map +1 -0
  75. package/dist/core/tools/find.d.ts.map +1 -0
  76. package/dist/{tools → core/tools}/find.js +1 -1
  77. package/dist/core/tools/find.js.map +1 -0
  78. package/dist/core/tools/grep.d.ts.map +1 -0
  79. package/dist/{tools → core/tools}/grep.js +1 -1
  80. package/dist/core/tools/grep.js.map +1 -0
  81. package/dist/core/tools/index.d.ts.map +1 -0
  82. package/dist/core/tools/index.js.map +1 -0
  83. package/dist/core/tools/ls.d.ts.map +1 -0
  84. package/dist/core/tools/ls.js.map +1 -0
  85. package/dist/core/tools/read.d.ts.map +1 -0
  86. package/dist/core/tools/read.js.map +1 -0
  87. package/dist/core/tools/truncate.d.ts.map +1 -0
  88. package/dist/core/tools/truncate.js.map +1 -0
  89. package/dist/core/tools/write.d.ts.map +1 -0
  90. package/dist/core/tools/write.js.map +1 -0
  91. package/dist/index.d.ts +2 -2
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +2 -2
  94. package/dist/index.js.map +1 -1
  95. package/dist/main.d.ts +3 -0
  96. package/dist/main.d.ts.map +1 -1
  97. package/dist/main.js +176 -1082
  98. package/dist/main.js.map +1 -1
  99. package/dist/modes/index.d.ts +9 -0
  100. package/dist/modes/index.d.ts.map +1 -0
  101. package/dist/modes/index.js +8 -0
  102. package/dist/modes/index.js.map +1 -0
  103. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  104. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  105. package/dist/{tui → modes/interactive/components}/bash-execution.d.ts +1 -1
  106. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  107. package/dist/{tui → modes/interactive/components}/bash-execution.js +1 -1
  108. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  109. package/dist/modes/interactive/components/compaction.d.ts.map +1 -0
  110. package/dist/modes/interactive/components/compaction.js.map +1 -0
  111. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  112. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  113. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  114. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  115. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  116. package/dist/{tui → modes/interactive/components}/footer.js +1 -1
  117. package/dist/modes/interactive/components/footer.js.map +1 -0
  118. package/dist/{tui → modes/interactive/components}/model-selector.d.ts +1 -1
  119. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  120. package/dist/{tui → modes/interactive/components}/model-selector.js +3 -3
  121. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  122. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  123. package/dist/{tui → modes/interactive/components}/oauth-selector.js +2 -2
  124. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  125. package/dist/modes/interactive/components/queue-mode-selector.d.ts.map +1 -0
  126. package/dist/modes/interactive/components/queue-mode-selector.js.map +1 -0
  127. package/dist/{tui → modes/interactive/components}/session-selector.d.ts +1 -1
  128. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  129. package/dist/{tui → modes/interactive/components}/session-selector.js +1 -1
  130. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  131. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  132. package/dist/{tui/theme-selector.d.ts.map → modes/interactive/components/theme-selector.js.map} +1 -1
  133. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  134. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  135. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  136. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  137. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  138. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  139. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  140. package/dist/modes/interactive/components/user-message.js.map +1 -0
  141. package/dist/{tui/tui-renderer.d.ts → modes/interactive/interactive-mode.d.ts} +36 -38
  142. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  143. package/dist/modes/interactive/interactive-mode.js +1217 -0
  144. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  145. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  146. package/dist/{theme → modes/interactive/theme}/theme.js +1 -1
  147. package/dist/modes/interactive/theme/theme.js.map +1 -0
  148. package/dist/modes/print-mode.d.ts +21 -0
  149. package/dist/modes/print-mode.d.ts.map +1 -0
  150. package/dist/modes/print-mode.js +53 -0
  151. package/dist/modes/print-mode.js.map +1 -0
  152. package/dist/modes/rpc/rpc-client.d.ts +182 -0
  153. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  154. package/dist/modes/rpc/rpc-client.js +362 -0
  155. package/dist/modes/rpc/rpc-client.js.map +1 -0
  156. package/dist/modes/rpc/rpc-mode.d.ts +19 -0
  157. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  158. package/dist/modes/rpc/rpc-mode.js +204 -0
  159. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  160. package/dist/modes/rpc/rpc-types.d.ts +254 -0
  161. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  162. package/dist/modes/rpc/rpc-types.js +8 -0
  163. package/dist/modes/rpc/rpc-types.js.map +1 -0
  164. package/dist/{changelog.d.ts → utils/changelog.d.ts} +1 -1
  165. package/dist/{changelog.js.map → utils/changelog.d.ts.map} +1 -1
  166. package/dist/{changelog.js → utils/changelog.js} +1 -1
  167. package/dist/utils/changelog.js.map +1 -0
  168. package/dist/utils/clipboard.d.ts.map +1 -0
  169. package/dist/utils/clipboard.js.map +1 -0
  170. package/dist/utils/fuzzy.d.ts.map +1 -0
  171. package/dist/utils/fuzzy.js.map +1 -0
  172. package/dist/utils/shell.d.ts.map +1 -0
  173. package/dist/{shell.js → utils/shell.js} +1 -1
  174. package/dist/utils/shell.js.map +1 -0
  175. package/dist/utils/tools-manager.d.ts.map +1 -0
  176. package/dist/{tools-manager.js → utils/tools-manager.js} +1 -1
  177. package/dist/utils/tools-manager.js.map +1 -0
  178. package/package.json +6 -6
  179. package/dist/changelog.d.ts.map +0 -1
  180. package/dist/clipboard.d.ts.map +0 -1
  181. package/dist/clipboard.js.map +0 -1
  182. package/dist/compaction.d.ts.map +0 -1
  183. package/dist/compaction.js.map +0 -1
  184. package/dist/export-html.js.map +0 -1
  185. package/dist/fuzzy.d.ts.map +0 -1
  186. package/dist/fuzzy.js.map +0 -1
  187. package/dist/messages.d.ts.map +0 -1
  188. package/dist/messages.js.map +0 -1
  189. package/dist/model-config.d.ts.map +0 -1
  190. package/dist/model-config.js.map +0 -1
  191. package/dist/oauth/anthropic.d.ts.map +0 -1
  192. package/dist/oauth/anthropic.js.map +0 -1
  193. package/dist/oauth/index.js.map +0 -1
  194. package/dist/oauth/storage.d.ts.map +0 -1
  195. package/dist/oauth/storage.js.map +0 -1
  196. package/dist/session-manager.d.ts.map +0 -1
  197. package/dist/session-manager.js.map +0 -1
  198. package/dist/settings-manager.d.ts.map +0 -1
  199. package/dist/settings-manager.js.map +0 -1
  200. package/dist/shell.d.ts.map +0 -1
  201. package/dist/shell.js.map +0 -1
  202. package/dist/slash-commands.d.ts.map +0 -1
  203. package/dist/slash-commands.js.map +0 -1
  204. package/dist/theme/theme.d.ts.map +0 -1
  205. package/dist/theme/theme.js.map +0 -1
  206. package/dist/tools/bash.d.ts.map +0 -1
  207. package/dist/tools/bash.js.map +0 -1
  208. package/dist/tools/edit.d.ts.map +0 -1
  209. package/dist/tools/edit.js.map +0 -1
  210. package/dist/tools/find.d.ts.map +0 -1
  211. package/dist/tools/find.js.map +0 -1
  212. package/dist/tools/grep.d.ts.map +0 -1
  213. package/dist/tools/grep.js.map +0 -1
  214. package/dist/tools/index.d.ts.map +0 -1
  215. package/dist/tools/index.js.map +0 -1
  216. package/dist/tools/ls.d.ts.map +0 -1
  217. package/dist/tools/ls.js.map +0 -1
  218. package/dist/tools/read.d.ts.map +0 -1
  219. package/dist/tools/read.js.map +0 -1
  220. package/dist/tools/truncate.d.ts.map +0 -1
  221. package/dist/tools/truncate.js.map +0 -1
  222. package/dist/tools/write.d.ts.map +0 -1
  223. package/dist/tools/write.js.map +0 -1
  224. package/dist/tools-manager.d.ts.map +0 -1
  225. package/dist/tools-manager.js.map +0 -1
  226. package/dist/tui/assistant-message.d.ts.map +0 -1
  227. package/dist/tui/assistant-message.js.map +0 -1
  228. package/dist/tui/bash-execution.d.ts.map +0 -1
  229. package/dist/tui/bash-execution.js.map +0 -1
  230. package/dist/tui/compaction.d.ts.map +0 -1
  231. package/dist/tui/compaction.js.map +0 -1
  232. package/dist/tui/custom-editor.d.ts.map +0 -1
  233. package/dist/tui/custom-editor.js.map +0 -1
  234. package/dist/tui/dynamic-border.d.ts.map +0 -1
  235. package/dist/tui/dynamic-border.js.map +0 -1
  236. package/dist/tui/footer.d.ts.map +0 -1
  237. package/dist/tui/footer.js.map +0 -1
  238. package/dist/tui/model-selector.d.ts.map +0 -1
  239. package/dist/tui/model-selector.js.map +0 -1
  240. package/dist/tui/oauth-selector.d.ts.map +0 -1
  241. package/dist/tui/oauth-selector.js.map +0 -1
  242. package/dist/tui/queue-mode-selector.d.ts.map +0 -1
  243. package/dist/tui/queue-mode-selector.js.map +0 -1
  244. package/dist/tui/session-selector.d.ts.map +0 -1
  245. package/dist/tui/session-selector.js.map +0 -1
  246. package/dist/tui/theme-selector.js.map +0 -1
  247. package/dist/tui/thinking-selector.d.ts.map +0 -1
  248. package/dist/tui/thinking-selector.js.map +0 -1
  249. package/dist/tui/tool-execution.d.ts.map +0 -1
  250. package/dist/tui/tool-execution.js.map +0 -1
  251. package/dist/tui/tui-renderer.d.ts.map +0 -1
  252. package/dist/tui/tui-renderer.js +0 -1937
  253. package/dist/tui/tui-renderer.js.map +0 -1
  254. package/dist/tui/user-message-selector.d.ts.map +0 -1
  255. package/dist/tui/user-message-selector.js.map +0 -1
  256. package/dist/tui/user-message.d.ts.map +0 -1
  257. package/dist/tui/user-message.js.map +0 -1
  258. /package/dist/{export-html.d.ts → core/export-html.d.ts} +0 -0
  259. /package/dist/{messages.d.ts → core/messages.d.ts} +0 -0
  260. /package/dist/{messages.js → core/messages.js} +0 -0
  261. /package/dist/{model-config.d.ts → core/model-config.d.ts} +0 -0
  262. /package/dist/{oauth → core/oauth}/anthropic.d.ts +0 -0
  263. /package/dist/{oauth → core/oauth}/anthropic.js +0 -0
  264. /package/dist/{oauth → core/oauth}/index.d.ts +0 -0
  265. /package/dist/{oauth → core/oauth}/index.js +0 -0
  266. /package/dist/{oauth → core/oauth}/storage.d.ts +0 -0
  267. /package/dist/{session-manager.d.ts → core/session-manager.d.ts} +0 -0
  268. /package/dist/{settings-manager.d.ts → core/settings-manager.d.ts} +0 -0
  269. /package/dist/{slash-commands.d.ts → core/slash-commands.d.ts} +0 -0
  270. /package/dist/{tools → core/tools}/bash.d.ts +0 -0
  271. /package/dist/{tools → core/tools}/edit.d.ts +0 -0
  272. /package/dist/{tools → core/tools}/edit.js +0 -0
  273. /package/dist/{tools → core/tools}/find.d.ts +0 -0
  274. /package/dist/{tools → core/tools}/grep.d.ts +0 -0
  275. /package/dist/{tools → core/tools}/index.d.ts +0 -0
  276. /package/dist/{tools → core/tools}/index.js +0 -0
  277. /package/dist/{tools → core/tools}/ls.d.ts +0 -0
  278. /package/dist/{tools → core/tools}/ls.js +0 -0
  279. /package/dist/{tools → core/tools}/read.d.ts +0 -0
  280. /package/dist/{tools → core/tools}/read.js +0 -0
  281. /package/dist/{tools → core/tools}/truncate.d.ts +0 -0
  282. /package/dist/{tools → core/tools}/truncate.js +0 -0
  283. /package/dist/{tools → core/tools}/write.d.ts +0 -0
  284. /package/dist/{tools → core/tools}/write.js +0 -0
  285. /package/dist/{tui → modes/interactive/components}/assistant-message.d.ts +0 -0
  286. /package/dist/{tui → modes/interactive/components}/assistant-message.js +0 -0
  287. /package/dist/{tui → modes/interactive/components}/compaction.d.ts +0 -0
  288. /package/dist/{tui → modes/interactive/components}/compaction.js +0 -0
  289. /package/dist/{tui → modes/interactive/components}/custom-editor.d.ts +0 -0
  290. /package/dist/{tui → modes/interactive/components}/custom-editor.js +0 -0
  291. /package/dist/{tui → modes/interactive/components}/dynamic-border.d.ts +0 -0
  292. /package/dist/{tui → modes/interactive/components}/dynamic-border.js +0 -0
  293. /package/dist/{tui → modes/interactive/components}/footer.d.ts +0 -0
  294. /package/dist/{tui → modes/interactive/components}/oauth-selector.d.ts +0 -0
  295. /package/dist/{tui → modes/interactive/components}/queue-mode-selector.d.ts +0 -0
  296. /package/dist/{tui → modes/interactive/components}/queue-mode-selector.js +0 -0
  297. /package/dist/{tui → modes/interactive/components}/theme-selector.d.ts +0 -0
  298. /package/dist/{tui → modes/interactive/components}/theme-selector.js +0 -0
  299. /package/dist/{tui → modes/interactive/components}/thinking-selector.d.ts +0 -0
  300. /package/dist/{tui → modes/interactive/components}/thinking-selector.js +0 -0
  301. /package/dist/{tui → modes/interactive/components}/tool-execution.d.ts +0 -0
  302. /package/dist/{tui → modes/interactive/components}/tool-execution.js +0 -0
  303. /package/dist/{tui → modes/interactive/components}/user-message-selector.d.ts +0 -0
  304. /package/dist/{tui → modes/interactive/components}/user-message-selector.js +0 -0
  305. /package/dist/{tui → modes/interactive/components}/user-message.d.ts +0 -0
  306. /package/dist/{tui → modes/interactive/components}/user-message.js +0 -0
  307. /package/dist/{theme → modes/interactive/theme}/dark.json +0 -0
  308. /package/dist/{theme → modes/interactive/theme}/light.json +0 -0
  309. /package/dist/{theme → modes/interactive/theme}/theme-schema.json +0 -0
  310. /package/dist/{theme → modes/interactive/theme}/theme.d.ts +0 -0
  311. /package/dist/{clipboard.d.ts → utils/clipboard.d.ts} +0 -0
  312. /package/dist/{clipboard.js → utils/clipboard.js} +0 -0
  313. /package/dist/{fuzzy.d.ts → utils/fuzzy.d.ts} +0 -0
  314. /package/dist/{fuzzy.js → utils/fuzzy.js} +0 -0
  315. /package/dist/{shell.d.ts → utils/shell.d.ts} +0 -0
  316. /package/dist/{tools-manager.d.ts → utils/tools-manager.d.ts} +0 -0
package/README.md CHANGED
@@ -1,54 +1,62 @@
1
1
  # pi
2
2
 
3
- A radically simple and opinionated 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.
3
+ A terminal-based coding agent with multi-model support, mid-session model switching, and a simple CLI for headless coding tasks.
4
4
 
5
- Works on Linux, macOS, and Windows (needs a bash shell, see [Windows Shell Configuration](#windows-shell-configuration)).
5
+ Works on Linux, macOS, and Windows (requires bash; see [Windows Setup](#windows-setup)).
6
6
 
7
7
  ## Table of Contents
8
8
 
9
- - [Installation](#installation)
10
- - [Windows Shell Configuration](#windows-shell-configuration)
11
- - [Quick Start](#quick-start)
12
- - [API Keys](#api-keys)
13
- - [OAuth Authentication (Optional)](#oauth-authentication-optional)
14
- - [Custom Models and Providers](#custom-models-and-providers)
15
- - [Themes](#themes)
16
- - [Slash Commands](#slash-commands)
17
- - [Editor Features](#editor-features)
18
- - [Project Context Files](#project-context-files)
19
- - [Image Support](#image-support)
20
- - [Session Management](#session-management)
21
- - [Context Compaction](#context-compaction)
22
- - [CLI Options](#cli-options)
23
- - [Tools](#tools)
9
+ - [Getting Started](#getting-started)
10
+ - [Installation](#installation)
11
+ - [Windows Setup](#windows-setup)
12
+ - [API Keys](#api-keys)
13
+ - [Quick Start](#quick-start)
24
14
  - [Usage](#usage)
25
- - [Security (YOLO by default)](#security-yolo-by-default)
26
- - [Sub-Agents](#sub-agents)
27
- - [To-Dos](#to-dos)
28
- - [Planning](#planning)
29
- - [Background Bash](#background-bash)
15
+ - [Slash Commands](#slash-commands)
16
+ - [Editor Features](#editor-features)
17
+ - [Keyboard Shortcuts](#keyboard-shortcuts)
18
+ - [Bash Mode](#bash-mode)
19
+ - [Image Support](#image-support)
20
+ - [Sessions](#sessions)
21
+ - [Session Management](#session-management)
22
+ - [Context Compaction](#context-compaction)
23
+ - [Branching](#branching)
24
+ - [Configuration](#configuration)
25
+ - [Project Context Files](#project-context-files)
26
+ - [Custom Models and Providers](#custom-models-and-providers)
27
+ - [Themes](#themes)
28
+ - [Custom Slash Commands](#custom-slash-commands)
29
+ - [Settings File](#settings-file)
30
+ - [CLI Reference](#cli-reference)
31
+ - [Tools](#tools)
32
+ - [Programmatic Usage](#programmatic-usage)
33
+ - [Philosophy](#philosophy)
34
+ - [Development](#development)
30
35
  - [License](#license)
31
- - [See Also](#see-also)
32
36
 
33
- ## Installation
37
+ ---
38
+
39
+ ## Getting Started
34
40
 
35
- ### npm (recommended)
41
+ ### Installation
42
+
43
+ **npm (recommended):**
36
44
 
37
45
  ```bash
38
46
  npm install -g @mariozechner/pi-coding-agent
39
47
  ```
40
48
 
41
- ### Standalone Binary
42
-
43
- Pre-built binaries are available on the [GitHub Releases](https://github.com/badlogic/pi-mono/releases) page. Download the archive for your platform:
49
+ **Standalone binary:**
44
50
 
45
- - `pi-darwin-arm64.tar.gz` - macOS Apple Silicon
46
- - `pi-darwin-x64.tar.gz` - macOS Intel
47
- - `pi-linux-x64.tar.gz` - Linux x64
48
- - `pi-linux-arm64.tar.gz` - Linux ARM64
49
- - `pi-windows-x64.zip` - Windows x64
51
+ Download from [GitHub Releases](https://github.com/badlogic/pi-mono/releases):
50
52
 
51
- Extract and run:
53
+ | Platform | Archive |
54
+ |----------|---------|
55
+ | macOS Apple Silicon | `pi-darwin-arm64.tar.gz` |
56
+ | macOS Intel | `pi-darwin-x64.tar.gz` |
57
+ | Linux x64 | `pi-linux-x64.tar.gz` |
58
+ | Linux ARM64 | `pi-linux-arm64.tar.gz` |
59
+ | Windows x64 | `pi-windows-x64.zip` |
52
60
 
53
61
  ```bash
54
62
  # macOS/Linux
@@ -60,41 +68,28 @@ unzip pi-windows-x64.zip
60
68
  pi.exe
61
69
  ```
62
70
 
63
- The archive includes the binary plus supporting files (README, CHANGELOG, themes). Keep them together in the same directory.
64
-
65
- **macOS users**: The binary is not signed. macOS may block it on first run. To fix:
66
- ```bash
67
- xattr -c ./pi
68
- ```
69
-
70
- ### Build Binary from Source
71
+ **macOS note:** The binary is unsigned. If blocked, run: `xattr -c ./pi`
71
72
 
72
- Requires [Bun](https://bun.sh) 1.0+:
73
+ **Build from source** (requires [Bun](https://bun.sh) 1.0+):
73
74
 
74
75
  ```bash
75
76
  git clone https://github.com/badlogic/pi-mono.git
76
- cd pi-mono
77
- npm install
78
- cd packages/coding-agent
79
- npm run build:binary
80
-
81
- # Binary and supporting files are in dist/
77
+ cd pi-mono && npm install
78
+ cd packages/coding-agent && npm run build:binary
82
79
  ./dist/pi
83
80
  ```
84
81
 
85
- ## Windows Shell Configuration
82
+ ### Windows Setup
86
83
 
87
- On Windows, pi requires a bash shell. The following locations are checked in order:
84
+ Pi requires a bash shell on Windows. Checked locations (in order):
88
85
 
89
- 1. **Custom shell path** from `~/.pi/agent/settings.json` (if configured)
90
- 2. **Git Bash** in standard locations (`C:\Program Files\Git\bin\bash.exe`)
91
- 3. **bash.exe on PATH** (Cygwin, MSYS2, WSL, etc.)
86
+ 1. Custom path from `~/.pi/agent/settings.json`
87
+ 2. Git Bash (`C:\Program Files\Git\bin\bash.exe`)
88
+ 3. `bash.exe` on PATH (Cygwin, MSYS2, WSL)
92
89
 
93
- For most users, installing [Git for Windows](https://git-scm.com/download/win) is sufficient.
90
+ For most users, [Git for Windows](https://git-scm.com/download/win) is sufficient.
94
91
 
95
- ### Custom Shell Path
96
-
97
- If you use Cygwin, MSYS2, or have bash in a non-standard location, add the path to your settings:
92
+ **Custom shell path:**
98
93
 
99
94
  ```json
100
95
  // ~/.pi/agent/settings.json
@@ -103,550 +98,337 @@ If you use Cygwin, MSYS2, or have bash in a non-standard location, add the path
103
98
  }
104
99
  ```
105
100
 
106
- Alternatively, ensure your bash is on the system PATH.
107
-
108
- ## Quick Start
109
-
110
- ```bash
111
- # Set your API key (see API Keys section)
112
- export ANTHROPIC_API_KEY=sk-ant-...
113
-
114
- # Start the interactive CLI
115
- pi
116
- ```
117
-
118
- Once in the CLI, you can chat with the AI:
101
+ ### API Keys
119
102
 
120
- ```
121
- You: Create a simple Express server in src/server.ts
122
- ```
103
+ Set the environment variable for your provider:
123
104
 
124
- The agent will use its tools to read, write, and edit files as needed, and execute commands via Bash.
105
+ | Provider | Environment Variable |
106
+ |----------|---------------------|
107
+ | Anthropic | `ANTHROPIC_API_KEY` or `ANTHROPIC_OAUTH_TOKEN` |
108
+ | OpenAI | `OPENAI_API_KEY` |
109
+ | Google | `GEMINI_API_KEY` |
110
+ | Groq | `GROQ_API_KEY` |
111
+ | Cerebras | `CEREBRAS_API_KEY` |
112
+ | xAI | `XAI_API_KEY` |
113
+ | OpenRouter | `OPENROUTER_API_KEY` |
114
+ | ZAI | `ZAI_API_KEY` |
125
115
 
126
- ## API Keys
116
+ The `/model` command only shows models for providers with configured API keys.
127
117
 
128
- The CLI supports multiple LLM providers. Set the appropriate environment variable for your chosen provider:
118
+ **OAuth (Claude Pro/Max subscribers):**
129
119
 
130
120
  ```bash
131
- # Anthropic (Claude)
132
- export ANTHROPIC_API_KEY=sk-ant-...
133
- # Or use OAuth token (retrieved via: claude setup-token)
134
- export ANTHROPIC_OAUTH_TOKEN=...
135
-
136
- # OpenAI (GPT)
137
- export OPENAI_API_KEY=sk-...
138
-
139
- # Google (Gemini)
140
- export GEMINI_API_KEY=...
141
-
142
- # Groq
143
- export GROQ_API_KEY=gsk_...
144
-
145
- # Cerebras
146
- export CEREBRAS_API_KEY=csk-...
147
-
148
- # xAI (Grok)
149
- export XAI_API_KEY=xai-...
150
-
151
- # OpenRouter
152
- export OPENROUTER_API_KEY=sk-or-...
153
-
154
- # ZAI
155
- export ZAI_API_KEY=...
121
+ pi
122
+ /login # Select "Anthropic (Claude Pro/Max)", authorize in browser
156
123
  ```
157
124
 
158
- If no API key is set, the CLI will prompt you to configure one on first run.
125
+ Tokens stored in `~/.pi/agent/oauth.json` (mode 0600). Use `/logout` to clear.
159
126
 
160
- **Note:** The `/model` command only shows models for which API keys are configured in your environment. If you don't see a model you expect, check that you've set the corresponding environment variable.
161
-
162
- ## OAuth Authentication (Optional)
163
-
164
- If you have a Claude Pro/Max subscription, you can use OAuth instead of API keys:
127
+ ### Quick Start
165
128
 
166
129
  ```bash
130
+ export ANTHROPIC_API_KEY=sk-ant-...
167
131
  pi
168
- # In the interactive session:
169
- /login
170
- # Select "Anthropic (Claude Pro/Max)"
171
- # Authorize in browser
172
- # Paste authorization code
173
132
  ```
174
133
 
175
- This gives you:
176
- - Free access to Claude models (included in your subscription)
177
- - No need to manage API keys
178
- - Automatic token refresh
134
+ Then chat:
179
135
 
180
- To logout:
181
136
  ```
182
- /logout
183
- ```
184
-
185
- **Note:** OAuth tokens are stored in `~/.pi/agent/oauth.json` with restricted permissions (0600).
186
-
187
- ## Custom Models and Providers
188
-
189
- You can add custom models and providers (like Ollama, vLLM, LM Studio, or any custom API endpoint) via `~/.pi/agent/models.json`. Supports OpenAI-compatible APIs (`openai-completions`, `openai-responses`), Anthropic Messages API (`anthropic-messages`), and Google Generative AI API (`google-generative-ai`). This file is loaded fresh every time you open the `/model` selector, allowing live updates without restarting.
190
-
191
- ### Configuration File Structure
192
-
193
- ```json
194
- {
195
- "providers": {
196
- "ollama": {
197
- "baseUrl": "http://localhost:11434/v1",
198
- "apiKey": "OLLAMA_API_KEY",
199
- "api": "openai-completions",
200
- "models": [
201
- {
202
- "id": "llama-3.1-8b",
203
- "name": "Llama 3.1 8B (Local)",
204
- "reasoning": false,
205
- "input": ["text"],
206
- "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
207
- "contextWindow": 128000,
208
- "maxTokens": 32000
209
- }
210
- ]
211
- },
212
- "vllm": {
213
- "baseUrl": "http://your-server:8000/v1",
214
- "apiKey": "VLLM_API_KEY",
215
- "api": "openai-completions",
216
- "models": [
217
- {
218
- "id": "custom-model",
219
- "name": "Custom Fine-tuned Model",
220
- "reasoning": false,
221
- "input": ["text", "image"],
222
- "cost": {"input": 0.5, "output": 1.0, "cacheRead": 0, "cacheWrite": 0},
223
- "contextWindow": 32768,
224
- "maxTokens": 8192
225
- }
226
- ]
227
- },
228
- "mixed-api-provider": {
229
- "baseUrl": "https://api.example.com/v1",
230
- "apiKey": "CUSTOM_API_KEY",
231
- "api": "openai-completions",
232
- "models": [
233
- {
234
- "id": "legacy-model",
235
- "name": "Legacy Model",
236
- "reasoning": false,
237
- "input": ["text"],
238
- "cost": {"input": 1.0, "output": 2.0, "cacheRead": 0, "cacheWrite": 0},
239
- "contextWindow": 8192,
240
- "maxTokens": 4096
241
- },
242
- {
243
- "id": "new-model",
244
- "name": "New Model",
245
- "api": "openai-responses",
246
- "reasoning": true,
247
- "input": ["text", "image"],
248
- "cost": {"input": 0.5, "output": 1.0, "cacheRead": 0.1, "cacheWrite": 0.2},
249
- "contextWindow": 128000,
250
- "maxTokens": 32000
251
- }
252
- ]
253
- }
254
- }
255
- }
137
+ You: Create a simple Express server in src/server.ts
256
138
  ```
257
139
 
258
- ### API Key Resolution
140
+ The agent reads, writes, and edits files, and executes commands via bash.
259
141
 
260
- The `apiKey` field can be either an environment variable name or a literal API key:
142
+ ---
261
143
 
262
- 1. First, `pi` checks if an environment variable with that name exists
263
- 2. If found, uses the environment variable's value
264
- 3. Otherwise, treats it as a literal API key
144
+ ## Usage
265
145
 
266
- Examples:
267
- - `"apiKey": "OLLAMA_API_KEY"` → checks `$OLLAMA_API_KEY`, then treats as literal "OLLAMA_API_KEY"
268
- - `"apiKey": "sk-1234..."` → checks `$sk-1234...` (unlikely to exist), then uses literal value
146
+ ### Slash Commands
269
147
 
270
- This allows both secure env var usage and literal keys for local servers.
148
+ | Command | Description |
149
+ |---------|-------------|
150
+ | `/model` | Switch models mid-session (fuzzy search, arrow keys, Enter to select) |
151
+ | `/thinking` | Adjust thinking level for reasoning models (off/minimal/low/medium/high) |
152
+ | `/queue` | Set message queue mode: one-at-a-time (default) or all-at-once |
153
+ | `/export [file]` | Export session to self-contained HTML |
154
+ | `/session` | Show session info: path, message counts, token usage, cost |
155
+ | `/changelog` | Display full version history |
156
+ | `/branch` | Create new conversation branch from a previous message |
157
+ | `/resume` | Switch to a different session (interactive selector) |
158
+ | `/login` | OAuth login for subscription-based models |
159
+ | `/logout` | Clear OAuth tokens |
160
+ | `/clear` | Clear context and start fresh session |
161
+ | `/copy` | Copy last agent message to clipboard |
162
+ | `/compact [instructions]` | Manually compact conversation context |
163
+ | `/autocompact` | Toggle automatic context compaction |
164
+ | `/theme` | Select color theme |
271
165
 
272
- ### API Override
166
+ ### Editor Features
273
167
 
274
- - **Provider-level `api`**: Sets the default API for all models in that provider
275
- - **Model-level `api`**: Overrides the provider default for specific models
276
- - Supported APIs: `openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`
168
+ **File reference (`@`):** Type `@` to fuzzy-search project files. Respects `.gitignore`.
277
169
 
278
- This is useful when a provider supports multiple API standards through the same base URL.
170
+ **Path completion (Tab):** Complete relative paths, `../`, `~/`, etc.
279
171
 
280
- ### Custom Headers
172
+ **Drag & drop:** Drag files from your file manager into the terminal.
281
173
 
282
- You can add custom HTTP headers to bypass Cloudflare bot detection, add authentication tokens, or meet other proxy requirements:
174
+ **Multi-line paste:** Pasted content is collapsed to `[paste #N <lines> lines]` but sent in full.
283
175
 
284
- ```json
285
- {
286
- "providers": {
287
- "custom-proxy": {
288
- "baseUrl": "https://proxy.example.com/v1",
289
- "apiKey": "YOUR_API_KEY",
290
- "api": "anthropic-messages",
291
- "headers": {
292
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
293
- "X-Custom-Auth": "bearer-token-here"
294
- },
295
- "models": [
296
- {
297
- "id": "claude-sonnet-4",
298
- "name": "Claude Sonnet 4 (Proxied)",
299
- "reasoning": true,
300
- "input": ["text", "image"],
301
- "cost": {"input": 3, "output": 15, "cacheRead": 0.3, "cacheWrite": 3.75},
302
- "contextWindow": 200000,
303
- "maxTokens": 8192,
304
- "headers": {
305
- "X-Model-Specific-Header": "value"
306
- }
307
- }
308
- ]
309
- }
310
- }
311
- }
312
- ```
176
+ **Message queuing:** Submit messages while the agent is working. They queue and process based on `/queue` mode. Press Escape to abort and restore queued messages to editor.
313
177
 
314
- - **Provider-level `headers`**: Applied to all requests for models in that provider
315
- - **Model-level `headers`**: Additional headers for specific models (merged with provider headers)
316
- - Model headers override provider headers when keys conflict
178
+ ### Keyboard Shortcuts
317
179
 
318
- ### OpenAI Compatibility Settings
180
+ **Navigation:**
319
181
 
320
- The `openai-completions` API is implemented by many providers with minor differences (Ollama, vLLM, LiteLLM, llama.cpp, etc.). By default, compatibility settings are auto-detected from the `baseUrl`. For custom proxies or unknown endpoints, you can override these via the `compat` field on models:
182
+ | Key | Action |
183
+ |-----|--------|
184
+ | Arrow keys | Move cursor / browse history (Up when empty) |
185
+ | Option+Left/Right | Move by word |
186
+ | Ctrl+A / Home | Start of line |
187
+ | Ctrl+E / End | End of line |
321
188
 
322
- ```json
323
- {
324
- "providers": {
325
- "litellm": {
326
- "baseUrl": "http://localhost:4000/v1",
327
- "apiKey": "LITELLM_API_KEY",
328
- "api": "openai-completions",
329
- "models": [
330
- {
331
- "id": "gpt-4o",
332
- "name": "GPT-4o (via LiteLLM)",
333
- "reasoning": false,
334
- "input": ["text", "image"],
335
- "cost": {"input": 2.5, "output": 10, "cacheRead": 0, "cacheWrite": 0},
336
- "contextWindow": 128000,
337
- "maxTokens": 16384,
338
- "compat": {
339
- "supportsStore": false
340
- }
341
- }
342
- ]
343
- }
344
- }
345
- }
346
- ```
189
+ **Editing:**
347
190
 
348
- Available `compat` fields (all optional, auto-detected if not set):
191
+ | Key | Action |
192
+ |-----|--------|
193
+ | Enter | Send message |
194
+ | Shift+Enter / Alt+Enter | New line (Ctrl+Enter on WSL) |
195
+ | Ctrl+W / Option+Backspace | Delete word backwards |
196
+ | Ctrl+U | Delete to start of line |
197
+ | Ctrl+K | Delete to end of line |
349
198
 
350
- | Field | Type | Default | Description |
351
- |-------|------|---------|-------------|
352
- | `supportsStore` | boolean | auto | Whether provider supports the `store` field |
353
- | `supportsDeveloperRole` | boolean | auto | Whether provider supports `developer` role (vs `system`) |
354
- | `supportsReasoningEffort` | boolean | auto | Whether provider supports `reasoning_effort` parameter |
355
- | `maxTokensField` | string | auto | Use `"max_completion_tokens"` or `"max_tokens"` |
199
+ **Other:**
356
200
 
357
- If `compat` is partially set, unspecified fields use auto-detected values.
201
+ | Key | Action |
202
+ |-----|--------|
203
+ | Tab | Path completion / accept autocomplete |
204
+ | Escape | Cancel autocomplete / abort streaming |
205
+ | Ctrl+C | Clear editor (first) / exit (second) |
206
+ | Shift+Tab | Cycle thinking level |
207
+ | Ctrl+P | Cycle models (scoped by `--models`) |
208
+ | Ctrl+O | Toggle tool output expansion |
209
+ | Ctrl+T | Toggle thinking block visibility |
358
210
 
359
- ### Authorization Header
211
+ ### Bash Mode
360
212
 
361
- Some providers require an explicit `Authorization: Bearer <token>` header. Set `authHeader: true` to automatically add this header using the resolved `apiKey`:
213
+ Prefix commands with `!` to execute them and add output to context:
362
214
 
363
- ```json
364
- {
365
- "providers": {
366
- "qwen": {
367
- "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
368
- "apiKey": "QWEN_API_KEY",
369
- "authHeader": true,
370
- "api": "openai-completions",
371
- "models": [
372
- {
373
- "id": "qwen3-coder-plus",
374
- "name": "Qwen3 Coder Plus",
375
- "reasoning": true,
376
- "input": ["text"],
377
- "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
378
- "contextWindow": 1000000,
379
- "maxTokens": 65536
380
- }
381
- ]
382
- }
383
- }
384
- }
215
+ ```
216
+ !ls -la
217
+ !git status
218
+ !cat package.json | jq '.dependencies'
385
219
  ```
386
220
 
387
- When `authHeader: true`, the resolved API key is added as `Authorization: Bearer <apiKey>` to the model headers. This is useful for providers that don't use the standard OpenAI authentication mechanism.
388
-
389
- ### Model Selection Priority
390
-
391
- When starting `pi`, models are selected in this order:
392
-
393
- 1. **CLI args**: `--provider` and `--model` flags
394
- 2. **First from `--models` scope**: If `--models` is provided (skipped when using `--continue` or `--resume`)
395
- 3. **Restored from session**: If using `--continue` or `--resume`
396
- 4. **Saved default**: From `~/.pi/agent/settings.json` (set when you select a model with `/model`)
397
- 5. **First available**: First model with a valid API key
398
- 6. **None**: Allowed in interactive mode (shows error on message submission)
221
+ Output streams in real-time. Press Escape to cancel. Large outputs truncate at 2000 lines / 50KB.
399
222
 
400
- ### Provider Defaults
223
+ The output becomes part of your next prompt, formatted as:
401
224
 
402
- When multiple providers are available, pi prefers sensible defaults before falling back to "first available":
225
+ ```
226
+ Ran `ls -la`
227
+ ```
228
+ <output here>
229
+ ```
230
+ ```
403
231
 
404
- | Provider | Default Model |
405
- |------------|--------------------------|
406
- | anthropic | claude-sonnet-4-5 |
407
- | openai | gpt-5.1-codex |
408
- | google | gemini-2.5-pro |
409
- | openrouter | openai/gpt-5.1-codex |
410
- | xai | grok-4-fast-non-reasoning|
411
- | groq | openai/gpt-oss-120b |
412
- | cerebras | zai-glm-4.6 |
413
- | zai | glm-4.6 |
232
+ Run multiple commands before prompting; all outputs are included together.
414
233
 
415
- ### Live Reload & Errors
234
+ ### Image Support
416
235
 
417
- The models.json file is reloaded every time you open the `/model` selector. This means:
236
+ Include image paths in your message:
418
237
 
419
- - Edit models.json during a session
420
- - Or have the agent write/update it for you
421
- - Use `/model` to see changes immediately
422
- - No restart needed!
238
+ ```
239
+ You: What's in this screenshot? /path/to/image.png
240
+ ```
423
241
 
424
- If the file contains errors (JSON syntax, schema violations, missing fields), the selector shows the exact validation error and file path in red so you can fix it immediately.
242
+ Supported: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`
425
243
 
426
- ### Example: Adding Ollama Models
244
+ ---
427
245
 
428
- See the configuration structure above. Create `~/.pi/agent/models.json` with your Ollama setup, then use `/model` to select your local models. The agent can also help you write this file if you point it to this README.
246
+ ## Sessions
429
247
 
430
- ## Themes
248
+ ### Session Management
431
249
 
432
- Pi supports customizable color themes for the TUI. Two built-in themes are available: `dark` (default) and `light`.
250
+ Sessions auto-save to `~/.pi/agent/sessions/` organized by working directory.
433
251
 
434
- ### Selecting a Theme
252
+ ```bash
253
+ pi --continue # Continue most recent session
254
+ pi -c # Short form
435
255
 
436
- Use the `/theme` command to interactively select a theme, or edit your settings file:
256
+ pi --resume # Browse and select from past sessions
257
+ pi -r # Short form
437
258
 
438
- ```bash
439
- # Interactive selector
440
- pi
441
- /theme
259
+ pi --no-session # Ephemeral mode (don't save)
442
260
 
443
- # Or edit ~/.pi/agent/settings.json
444
- {
445
- "theme": "dark" # or "light"
446
- }
261
+ pi --session /path/to/file.jsonl # Use specific session file
447
262
  ```
448
263
 
449
- On first run, Pi auto-detects your terminal background (dark/light) and selects an appropriate theme.
264
+ ### Context Compaction
450
265
 
451
- ### Custom Themes
266
+ Long sessions can exhaust context windows. Compaction summarizes older messages while keeping recent ones.
452
267
 
453
- Create custom themes in `~/.pi/agent/themes/*.json`. Custom themes support **live editing** - when you select a custom theme, Pi watches the file and automatically reloads when you save changes.
268
+ **Manual:** `/compact` or `/compact Focus on the API changes`
454
269
 
455
- **Workflow for creating themes:**
456
- 1. Copy a built-in theme as a starting point:
457
- ```bash
458
- mkdir -p ~/.pi/agent/themes
459
- # Copy dark theme
460
- cp $(npm root -g)/@mariozechner/pi-coding-agent/dist/theme/dark.json ~/.pi/agent/themes/my-theme.json
461
- # Or copy light theme
462
- cp $(npm root -g)/@mariozechner/pi-coding-agent/dist/theme/light.json ~/.pi/agent/themes/my-theme.json
463
- ```
464
- 2. Use `/theme` to select "my-theme"
465
- 3. Edit `~/.pi/agent/themes/my-theme.json` - changes apply immediately on save
466
- 4. Iterate until satisfied (no need to re-select the theme)
270
+ **Automatic:** Enable with `/autocompact`. Triggers when context exceeds threshold.
467
271
 
468
- See [Theme Documentation](docs/theme.md) for:
469
- - Complete list of 44 color tokens
470
- - Theme format and examples
471
- - Color value formats (hex, RGB, terminal default)
272
+ **How it works:**
273
+ 1. Cut point calculated to keep ~20k tokens of recent messages
274
+ 2. Messages before cut point are summarized
275
+ 3. Summary replaces old messages as "context handoff"
276
+ 4. Previous compaction summaries chain into new ones
472
277
 
473
- Example custom theme:
278
+ **Configuration** (`~/.pi/agent/settings.json`):
474
279
 
475
280
  ```json
476
281
  {
477
- "$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/theme-schema.json",
478
- "name": "my-theme",
479
- "vars": {
480
- "accent": "#00aaff",
481
- "muted": "#6c6c6c"
482
- },
483
- "colors": {
484
- "accent": "accent",
485
- "muted": "muted",
486
- ...
282
+ "compaction": {
283
+ "enabled": true,
284
+ "reserveTokens": 16384,
285
+ "keepRecentTokens": 20000
487
286
  }
488
287
  }
489
288
  ```
490
289
 
491
- ### VS Code Terminal Color Issue
492
-
493
- **Important:** VS Code's integrated terminal has a known issue with rendering truecolor (24-bit RGB) values. By default, it applies a "minimum contrast ratio" adjustment that can make colors look washed out or identical.
290
+ > **Note:** Compaction is lossy. The agent loses full conversation access afterward. Size tasks to avoid context limits when possible. For critical context, ask the agent to write a summary to a file, then start a new session with that file. The full session history is preserved in the JSONL file; use `/branch` to revisit any previous point.
494
291
 
495
- To fix this, set the contrast ratio to 1 in VS Code settings:
292
+ ### Branching
496
293
 
497
- 1. Open Settings (Cmd/Ctrl + ,)
498
- 2. Search for: `terminal.integrated.minimumContrastRatio`
499
- 3. Set to: `1`
294
+ Use `/branch` to explore alternative conversation paths:
500
295
 
501
- This ensures VS Code renders the exact RGB colors defined in your theme.
296
+ 1. Opens selector showing all your user messages
297
+ 2. Select a message to branch from
298
+ 3. Creates new session with history up to that point
299
+ 4. Selected message placed in editor for modification
502
300
 
503
- ## Slash Commands
504
-
505
- The CLI supports several commands to control its behavior:
506
-
507
- ### /model
508
-
509
- Switch models mid-session. Opens an interactive selector where you can type to search (by provider or model name), use arrow keys to navigate, Enter to select, or Escape to cancel.
510
-
511
- The selector only displays models for which API keys are configured in your environment (see API Keys section).
512
-
513
- ### /thinking
514
-
515
- Adjust thinking/reasoning level for supported models (Claude Sonnet 4, GPT-5, Gemini 2.5). Opens an interactive selector where you can use arrow keys to navigate, Enter to select, or Escape to cancel.
516
-
517
- ### /queue
518
-
519
- Select message queue mode. Opens an interactive selector where you can choose between:
520
- - **one-at-a-time** (default): Process queued messages one by one. When you submit messages while the agent is processing, they're queued and sent individually after each agent response completes.
521
- - **all**: Process all queued messages at once. All queued messages are injected into the context together before the next agent response.
522
-
523
- The queue mode setting is saved and persists across sessions.
524
-
525
- ### /export [filename]
526
-
527
- Export the current session to a self-contained HTML file:
528
-
529
- ```
530
- /export # Auto-generates filename
531
- /export my-session.html # Custom filename
532
- ```
533
-
534
- The HTML file includes the full conversation with syntax highlighting and is viewable in any browser.
535
-
536
- ### /session
537
-
538
- Show session information and statistics:
539
-
540
- ```
541
- /session
542
- ```
543
-
544
- Displays:
545
- - Session file path and ID
546
- - Message counts (user, assistant, total)
547
- - Token usage (input, output, cache read/write, total)
548
- - Total cost (if available)
301
+ ---
549
302
 
550
- ### /changelog
303
+ ## Configuration
551
304
 
552
- Display the full changelog with all version history (newest last):
305
+ ### Project Context Files
553
306
 
554
- ```
555
- /changelog
556
- ```
307
+ Pi loads `AGENTS.md` (or `CLAUDE.md`) files at startup in this order:
557
308
 
558
- ### /branch
309
+ 1. **Global:** `~/.pi/agent/AGENTS.md`
310
+ 2. **Parent directories:** Walking up from current directory
311
+ 3. **Current directory:** `./AGENTS.md`
559
312
 
560
- Create a new conversation branch from a previous message. Opens an interactive selector showing all your user messages in chronological order. Select a message to:
561
- 1. Create a new session with all messages before the selected one
562
- 2. Place the selected message in the editor for modification or resubmission
313
+ Use these for:
314
+ - Project instructions and guidelines
315
+ - Common commands and workflows
316
+ - Architecture documentation
317
+ - Coding conventions
318
+ - Testing instructions
563
319
 
564
- This allows you to explore alternative conversation paths without losing your current session.
320
+ ```markdown
321
+ # Common Commands
322
+ - npm run build: Build the project
323
+ - npm test: Run tests
565
324
 
325
+ # Code Style
326
+ - Use TypeScript strict mode
327
+ - Prefer async/await over promises
566
328
  ```
567
- /branch
568
- ```
569
-
570
- ### /resume
571
329
 
572
- Switch to a different session. Opens an interactive selector showing all available sessions. Select a session to load it and continue where you left off.
330
+ ### Custom Models and Providers
573
331
 
574
- This is equivalent to the `--resume` CLI flag but can be used mid-session.
332
+ Add custom models (Ollama, vLLM, LM Studio, etc.) via `~/.pi/agent/models.json`:
575
333
 
334
+ ```json
335
+ {
336
+ "providers": {
337
+ "ollama": {
338
+ "baseUrl": "http://localhost:11434/v1",
339
+ "apiKey": "OLLAMA_API_KEY",
340
+ "api": "openai-completions",
341
+ "models": [
342
+ {
343
+ "id": "llama-3.1-8b",
344
+ "name": "Llama 3.1 8B (Local)",
345
+ "reasoning": false,
346
+ "input": ["text"],
347
+ "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
348
+ "contextWindow": 128000,
349
+ "maxTokens": 32000
350
+ }
351
+ ]
352
+ }
353
+ }
354
+ }
576
355
  ```
577
- /resume
578
- ```
579
-
580
- ### /login
581
356
 
582
- Login with OAuth to use subscription-based models (Claude Pro/Max):
357
+ **Supported APIs:** `openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`
583
358
 
584
- ```
585
- /login
586
- ```
359
+ **API key resolution:** The `apiKey` field is checked as environment variable name first, then used as literal value.
587
360
 
588
- Opens an interactive selector to choose provider, then guides you through the OAuth flow in your browser.
361
+ **API override:** Set `api` at provider level (default for all models) or model level (override per model).
589
362
 
590
- ### /logout
363
+ **Custom headers:**
591
364
 
592
- Logout from OAuth providers:
593
-
594
- ```
595
- /logout
365
+ ```json
366
+ {
367
+ "providers": {
368
+ "custom-proxy": {
369
+ "baseUrl": "https://proxy.example.com/v1",
370
+ "apiKey": "YOUR_API_KEY",
371
+ "api": "anthropic-messages",
372
+ "headers": {
373
+ "User-Agent": "Mozilla/5.0 ...",
374
+ "X-Custom-Auth": "token"
375
+ },
376
+ "models": [...]
377
+ }
378
+ }
379
+ }
596
380
  ```
597
381
 
598
- Shows a list of logged-in providers to logout from.
382
+ **Authorization header:** Set `authHeader: true` to add `Authorization: Bearer <apiKey>` automatically.
599
383
 
600
- ### /clear
384
+ **OpenAI compatibility (`compat` field):**
601
385
 
602
- Clear the conversation context and start a fresh session:
386
+ | Field | Description |
387
+ |-------|-------------|
388
+ | `supportsStore` | Whether provider supports `store` field |
389
+ | `supportsDeveloperRole` | Use `developer` vs `system` role |
390
+ | `supportsReasoningEffort` | Support for `reasoning_effort` parameter |
391
+ | `maxTokensField` | Use `max_completion_tokens` or `max_tokens` |
603
392
 
604
- ```
605
- /clear
606
- ```
393
+ **Live reload:** The file reloads each time you open `/model`. Edit during session; no restart needed.
607
394
 
608
- Aborts any in-flight agent work, clears all messages, and creates a new session file.
395
+ **Model selection priority:**
396
+ 1. CLI args (`--provider`, `--model`)
397
+ 2. First from `--models` scope (new sessions only)
398
+ 3. Restored from session (`--continue`, `--resume`)
399
+ 4. Saved default from settings
400
+ 5. First available model with valid API key
609
401
 
610
- ### /copy
402
+ ### Themes
611
403
 
612
- Copy the last agent message to clipboard:
404
+ Built-in themes: `dark` (default), `light`. Auto-detected on first run.
613
405
 
406
+ ```bash
407
+ /theme # Interactive selector
614
408
  ```
615
- /copy
616
- ```
617
-
618
- Extracts text content from the most recent assistant message and copies it to the system clipboard. Works cross-platform (macOS, Windows, Linux). On Linux, requires `xclip` or `xsel` to be installed.
619
-
620
- ### /compact
621
409
 
622
- Manually compact the conversation context to reduce token usage:
410
+ **Custom themes:** Create `~/.pi/agent/themes/*.json`. Custom themes support live reload.
623
411
 
412
+ ```bash
413
+ mkdir -p ~/.pi/agent/themes
414
+ cp $(npm root -g)/@mariozechner/pi-coding-agent/dist/theme/dark.json ~/.pi/agent/themes/my-theme.json
624
415
  ```
625
- /compact # Use default summary instructions
626
- /compact Focus on the API changes # Custom instructions for summary
627
- ```
628
-
629
- Creates a summary of the conversation so far, replacing the message history with a condensed version. See [Context Compaction](#context-compaction) for details.
630
416
 
631
- ### /autocompact
417
+ Select with `/theme`, then edit the file. Changes apply on save.
632
418
 
633
- Toggle automatic context compaction:
419
+ See [Theme Documentation](docs/theme.md) for all 44 color tokens.
634
420
 
635
- ```
636
- /autocompact
637
- ```
638
-
639
- When enabled, the agent automatically compacts context when usage exceeds the configured threshold. The current state (enabled/disabled) is shown after toggling. See [Context Compaction](#context-compaction) for details.
421
+ **VS Code terminal fix:** Set `terminal.integrated.minimumContrastRatio` to `1` for accurate colors.
640
422
 
641
423
  ### Custom Slash Commands
642
424
 
643
- Define reusable prompt templates as Markdown files that appear in the `/` autocomplete.
425
+ Define reusable prompts as Markdown files:
644
426
 
645
427
  **Locations:**
646
- - **Global:** `~/.pi/agent/commands/*.md` - available in all sessions
647
- - **Project:** `.pi/commands/*.md` - project-specific commands
428
+ - Global: `~/.pi/agent/commands/*.md`
429
+ - Project: `.pi/commands/*.md`
648
430
 
649
- **File format:**
431
+ **Format:**
650
432
 
651
433
  ```markdown
652
434
  ---
@@ -656,596 +438,159 @@ Review the staged changes (`git diff --cached`). Focus on:
656
438
  - Bugs and logic errors
657
439
  - Security issues
658
440
  - Error handling gaps
659
- - Code style per AGENTS.md
660
441
  ```
661
442
 
662
- The filename (without `.md`) becomes the command name. The optional `description` frontmatter field is shown in autocomplete. If omitted, the first line of content is used.
663
-
664
- **Arguments (bash-style):**
443
+ Filename (without `.md`) becomes the command name. Description shown in autocomplete.
665
444
 
666
- Commands support positional arguments with quote-aware parsing:
445
+ **Arguments:**
667
446
 
668
447
  ```markdown
669
448
  ---
670
- description: Create a component with features
449
+ description: Create a component
671
450
  ---
672
- Create a React component named $1 with these features: $@
451
+ Create a React component named $1 with features: $@
673
452
  ```
674
453
 
675
- Usage: `/component Button "has onClick handler" "supports disabled"`
454
+ Usage: `/component Button "onClick handler" "disabled support"`
676
455
  - `$1` = `Button`
677
- - `$2` = `has onClick handler`
678
- - `$@` = `Button has onClick handler supports disabled`
679
-
680
- **Namespacing:**
681
-
682
- Subdirectories create namespaced commands. A file at `.pi/commands/frontend/component.md` creates `/component` with description showing `(project:frontend)`.
683
-
684
- **Source indicators:**
685
-
686
- Commands show their source in autocomplete:
687
- - `(user)` - from `~/.pi/agent/commands/`
688
- - `(project)` - from `.pi/commands/`
689
- - `(project:subdir)` - from `.pi/commands/subdir/`
690
-
691
- **CLI usage:**
692
-
693
- Custom slash commands also work from the command line:
694
-
695
- ```bash
696
- # Non-interactive mode
697
- pi -p "/review"
698
-
699
- # With arguments
700
- pi -p '/component Button "handles click events"'
701
-
702
- # Interactive mode with initial command
703
- pi "/review"
704
- ```
705
-
706
- ## Editor Features
707
-
708
- The interactive input editor includes several productivity features:
709
-
710
- ### File Reference (`@`)
711
-
712
- Type **`@`** to fuzzy-search for files and folders in your project:
713
- - `@editor` → finds files/folders with "editor" in the name
714
- - `@readme` → finds README files anywhere in the project
715
- - `@src` → finds folders like `src/`, `resources/`, etc.
716
- - Directories are prioritized and shown with trailing `/`
717
- - Autocomplete triggers immediately when you type `@`
718
- - Use **Up/Down arrows** to navigate, **Tab**/**Enter** to select
719
-
720
- Respects `.gitignore` files and skips hidden files/directories.
721
-
722
- ### Path Completion
723
-
724
- Press **Tab** to autocomplete file and directory paths:
725
- - Works with relative paths: `./src/` + Tab → complete files in src/
726
- - Works with parent directories: `../../` + Tab → navigate up and complete
727
- - Works with home directory: `~/Des` + Tab → `~/Desktop/`
728
- - Use **Up/Down arrows** to navigate completion suggestions
729
- - Press **Enter** to select a completion
730
- - Shows matching files and directories as you type
731
-
732
- ### File Drag & Drop
733
-
734
- Drag files from your OS file explorer (Finder on macOS, Explorer on Windows) directly onto the terminal. The file path will be automatically inserted into the editor. Works great with screenshots from macOS screenshot tool.
735
-
736
- ### Multi-line Paste
737
-
738
- Paste multiple lines of text (e.g., code snippets, logs) and they'll be automatically coalesced into a compact `[paste #123 <N> lines]` reference in the editor. The full content is still sent to the model.
739
-
740
- ### Message Queuing
741
-
742
- You can submit multiple messages while the agent is processing without waiting for responses. Messages are queued and processed based on your queue mode setting:
743
-
744
- **One-at-a-time mode (default):**
745
- - Each queued message is processed sequentially with its own response
746
- - Example: Queue "task 1", "task 2", "task 3" → agent completes task 1 → processes task 2 → completes task 2 → processes task 3
747
- - Recommended for most use cases
748
-
749
- **All mode:**
750
- - All queued messages are sent to the model at once in a single context
751
- - Example: Queue "task 1", "task 2", "task 3" → agent receives all three together → responds considering all tasks
752
- - Useful when tasks should be considered together
753
-
754
- **Visual feedback:**
755
- - Queued messages appear below the chat with "Queued: <message text>"
756
- - Messages disappear from the queue as they're processed
757
-
758
- **Abort and restore:**
759
- - Press **Escape** while streaming to abort the current operation
760
- - All queued messages (plus any text in the editor) are restored to the editor
761
- - Allows you to modify or remove queued messages before resubmitting
762
-
763
- Change queue mode with `/queue` command. Setting is saved in `~/.pi/agent/settings.json`.
764
-
765
- ### Bash Mode (`!`)
766
-
767
- Execute shell commands directly and add output to the LLM context by prefixing with `!`:
768
-
769
- ```
770
- !ls -la
771
- !git status
772
- !cat package.json | jq '.dependencies'
773
- ```
774
-
775
- **Features:**
776
- - **Streaming output**: Command output streams in real-time as it executes
777
- - **Multiline commands**: Write complex commands across multiple lines
778
- - **Cancellation**: Press **Escape** to cancel a running command
779
- - **Truncation**: Large outputs are truncated (2000 lines / 50KB) with full output saved to a temp file
780
- - **Preview mode**: Shows last 20 lines by default; press **Ctrl+O** to expand
781
- - **History**: Commands are added to editor history (navigate with Up/Down arrows)
782
- - **Visual feedback**: Editor border turns green in bash mode; cancelled commands show yellow warning
456
+ - `$@` = all arguments joined
783
457
 
784
- Output is automatically added to the conversation context, allowing the LLM to see command results without manual copy-paste.
458
+ **Namespacing:** Subdirectories create prefixes. `.pi/commands/frontend/component.md` `/component (project:frontend)`
785
459
 
786
- ### Keyboard Shortcuts
787
-
788
- **Navigation:**
789
- - **Arrow keys**: Move cursor (Up/Down navigate visual lines, Left/Right move by character)
790
- - **Up Arrow** (empty editor): Browse previous prompts (history)
791
- - **Down Arrow** (browsing history): Browse newer prompts or return to empty editor
792
- - **Option+Left** / **Ctrl+Left**: Move word backwards
793
- - **Option+Right** / **Ctrl+Right**: Move word forwards
794
- - **Ctrl+A** / **Home**: Jump to start of line
795
- - **Ctrl+E** / **End**: Jump to end of line
796
-
797
- **Editing:**
798
- - **Enter**: Send message
799
- - **Shift+Enter** / **Alt+Enter**: Insert new line (multi-line input). On WSL, use **Ctrl+Enter** instead.
800
- - **Backspace**: Delete character backwards
801
- - **Delete** (or **Fn+Backspace**): Delete character forwards
802
- - **Ctrl+W** / **Option+Backspace**: Delete word backwards (stops at whitespace or punctuation)
803
- - **Ctrl+U**: Delete to start of line (at line start: merge with previous line)
804
- - **Ctrl+K**: Delete to end of line (at line end: merge with next line)
805
-
806
- **Completion:**
807
- - **Tab**: Path completion / Apply autocomplete selection
808
- - **Escape**: Cancel autocomplete (when autocomplete is active)
809
-
810
- **Other:**
811
- - **Ctrl+C**: Clear editor (first press) / Exit pi (second press)
812
- - **Shift+Tab**: Cycle thinking level (for reasoning-capable models)
813
- - **Ctrl+P**: Cycle models (use `--models` to scope)
814
- - **Ctrl+O**: Toggle tool output expansion (collapsed ↔ full output)
815
- - **Ctrl+T**: Toggle thinking block visibility (shows full content ↔ static "Thinking..." label)
816
-
817
- ## Project Context Files
818
-
819
- The agent automatically loads context from `AGENTS.md` or `CLAUDE.md` files at startup. These files are loaded in hierarchical order to support both global preferences and monorepo structures.
820
-
821
- ### File Locations
822
-
823
- Context files are loaded in this order:
824
-
825
- 1. **Global context**: `~/.pi/agent/AGENTS.md` or `CLAUDE.md`
826
- - Applies to all your coding sessions
827
- - Great for personal coding preferences and workflows
828
-
829
- 2. **Parent directories** (top-most first down to current directory)
830
- - Walks up from current directory to filesystem root
831
- - Each directory can have its own `AGENTS.md` or `CLAUDE.md`
832
- - Perfect for monorepos with shared context at higher levels
833
-
834
- 3. **Current directory**: Your project's `AGENTS.md` or `CLAUDE.md`
835
- - Most specific context, loaded last
836
- - Overwrites or extends parent/global context
837
-
838
- **File preference**: In each directory, `AGENTS.md` is preferred over `CLAUDE.md` if both exist.
839
-
840
- ### What to Include
841
-
842
- Context files are useful for:
843
- - Project-specific instructions and guidelines
844
- - Common bash commands and workflows
845
- - Architecture documentation
846
- - Coding conventions and style guides
847
- - Dependencies and setup information
848
- - Testing instructions
849
- - Repository etiquette (branch naming, merge vs. rebase, etc.)
850
-
851
- ### Example
852
-
853
- ```markdown
854
- # Common Commands
855
- - npm run build: Build the project
856
- - npm test: Run tests
857
-
858
- # Code Style
859
- - Use TypeScript strict mode
860
- - Prefer async/await over promises
861
-
862
- # Workflow
863
- - Always run tests before committing
864
- - Update CHANGELOG.md for user-facing changes
865
- ```
866
-
867
- All context files are automatically included in the system prompt at session start, along with the current date/time and working directory. This ensures the AI has complete project context from the very first message.
868
-
869
- ## Image Support
870
-
871
- Send images to vision-capable models by providing file paths:
872
-
873
- ```
874
- You: What is in this screenshot? /path/to/image.png
875
- ```
876
-
877
- Supported formats: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`
878
-
879
- The image will be automatically encoded and sent with your message. JPEG and PNG are supported across all vision models. Other formats may only be supported by some models.
880
-
881
- ## Session Management
882
-
883
- Sessions are automatically saved in `~/.pi/agent/sessions/` organized by working directory. Each session is stored as a JSONL file with a unique timestamp-based ID.
884
-
885
- To continue the most recent session:
460
+ ### Settings File
886
461
 
887
- ```bash
888
- pi --continue
889
- # or
890
- pi -c
891
- ```
892
-
893
- To browse and select from past sessions:
894
-
895
- ```bash
896
- pi --resume
897
- # or
898
- pi -r
899
- ```
900
-
901
- This opens an interactive session selector where you can:
902
- - Type to search through session messages
903
- - Use arrow keys to navigate the list
904
- - Press Enter to resume a session
905
- - Press Escape to cancel
906
-
907
- Sessions include all conversation messages, tool calls and results, model switches, and thinking level changes.
908
-
909
- To run without saving a session (ephemeral mode):
910
-
911
- ```bash
912
- pi --no-session
913
- ```
914
-
915
- To use a specific session file instead of auto-generating one:
916
-
917
- ```bash
918
- pi --session /path/to/my-session.jsonl
919
- ```
920
-
921
- ## Context Compaction
922
-
923
- > **Note:** Compaction is lossy and should generally be avoided. The agent loses access to the full conversation after compaction. Size your tasks to avoid hitting context limits. Alternatively, when context usage approaches 85-90%, ask the agent to write a summary to a markdown file, iterate until it captures everything important, then start a new session with that file.
924
- >
925
- > That said, compaction does not destroy history. The full session is preserved in the session file with compaction events as markers. You can branch (`/branch`) from any previous message, and branched sessions include the complete history. If compaction missed something, you can ask the agent to read the session file directly.
926
-
927
- Long sessions can exhaust the model's context window. Context compaction summarizes older conversation history while preserving recent messages, allowing sessions to continue indefinitely.
928
-
929
- ### How It Works
930
-
931
- When compaction runs (manually via `/compact` or automatically):
932
-
933
- 1. A **cut point** is calculated to keep approximately `keepRecentTokens` (default: 20k) worth of recent messages
934
- 2. Messages **before** the cut point are sent to the model for summarization
935
- 3. Messages **after** the cut point are kept verbatim
936
- 4. The summary replaces the older messages as a "context handoff" message
937
- 5. If there was a previous compaction, its summary is included as context for the new summary (chaining)
938
-
939
- Cut points are always placed at user message boundaries to preserve turn integrity.
940
-
941
- The summary is displayed in the TUI as a collapsible block (toggle with `o` key). HTML exports also show compaction summaries as collapsible sections.
942
-
943
- ### Manual Compaction
944
-
945
- Use `/compact` to manually trigger compaction at any time:
946
-
947
- ```
948
- /compact # Default summary
949
- /compact Focus on the API changes # Custom instructions guide what to emphasize
950
- ```
951
-
952
- Custom instructions are appended to the default summary prompt, letting you focus the summary on specific aspects of the conversation.
953
-
954
- ### Automatic Compaction
955
-
956
- Enable auto-compaction with `/autocompact`. When enabled, compaction triggers automatically when context usage exceeds `contextWindow - reserveTokens`.
957
-
958
- The context percentage is shown in the footer. When it approaches 100%, auto-compaction kicks in (if enabled) or you should manually compact.
959
-
960
- ### Configuration
961
-
962
- Power users can tune compaction behavior in `~/.pi/agent/settings.json`:
462
+ `~/.pi/agent/settings.json` stores persistent preferences:
963
463
 
964
464
  ```json
965
465
  {
466
+ "theme": "dark",
467
+ "shellPath": "C:\\path\\to\\bash.exe",
468
+ "queueMode": "one-at-a-time",
966
469
  "compaction": {
967
- "enabled": true,
470
+ "enabled": false,
968
471
  "reserveTokens": 16384,
969
472
  "keepRecentTokens": 20000
970
473
  }
971
474
  }
972
475
  ```
973
476
 
974
- - **enabled**: Whether auto-compaction is active (toggle with `/autocompact`)
975
- - **reserveTokens**: Token buffer to keep free (default: 16,384). Auto-compaction triggers when `contextTokens > contextWindow - reserveTokens`
976
- - **keepRecentTokens**: How many tokens worth of recent messages to preserve verbatim (default: 20,000). Older messages are summarized.
977
-
978
- ### Supported Modes
979
-
980
- Context compaction works in both interactive and RPC modes:
981
-
982
- - **Interactive**: Use `/compact` and `/autocompact` commands
983
- - **RPC**: Send `{"type":"compact"}` for manual compaction. Auto-compaction emits `{"type":"compaction","auto":true}` events. See [RPC documentation](docs/rpc.md) for details.
477
+ ---
984
478
 
985
- ## CLI Options
479
+ ## CLI Reference
986
480
 
987
481
  ```bash
988
482
  pi [options] [@files...] [messages...]
989
483
  ```
990
484
 
991
- ### File Arguments (`@file`)
485
+ ### Options
992
486
 
993
- You can include files directly in your initial message using the `@` prefix:
487
+ | Option | Description |
488
+ |--------|-------------|
489
+ | `--provider <name>` | Provider: `anthropic`, `openai`, `google`, `xai`, `groq`, `cerebras`, `openrouter`, `zai`, or custom |
490
+ | `--model <id>` | Model ID |
491
+ | `--api-key <key>` | API key (overrides environment) |
492
+ | `--system-prompt <text\|file>` | Custom system prompt (text or file path) |
493
+ | `--append-system-prompt <text\|file>` | Append to system prompt |
494
+ | `--mode <mode>` | Output mode: `text`, `json`, `rpc` (implies `--print`) |
495
+ | `--print`, `-p` | Non-interactive: process prompt and exit |
496
+ | `--no-session` | Don't save session |
497
+ | `--session <path>` | Use specific session file |
498
+ | `--continue`, `-c` | Continue most recent session |
499
+ | `--resume`, `-r` | Select session to resume |
500
+ | `--models <patterns>` | Comma-separated patterns for Ctrl+P cycling (e.g., `sonnet:high,haiku:low`) |
501
+ | `--tools <tools>` | Comma-separated tool list (default: `read,bash,edit,write`) |
502
+ | `--thinking <level>` | Thinking level: `off`, `minimal`, `low`, `medium`, `high` |
503
+ | `--export <file> [output]` | Export session to HTML |
504
+ | `--help`, `-h` | Show help |
505
+
506
+ ### File Arguments
507
+
508
+ Include files with `@` prefix:
994
509
 
995
510
  ```bash
996
- # Include a text file in your prompt
997
- pi @prompt.md "Answer the question"
998
-
999
- # Include multiple files
1000
- pi @requirements.md @context.txt "Summarize these"
1001
-
1002
- # Include images (vision-capable models only)
511
+ pi @prompt.md "Answer this"
1003
512
  pi @screenshot.png "What's in this image?"
1004
-
1005
- # Mix text and images
1006
- pi @prompt.md @diagram.png "Explain based on the diagram"
1007
-
1008
- # Files without additional text
1009
- pi @task.md
1010
- ```
1011
-
1012
- **How it works:**
1013
- - All `@file` arguments are combined into the first user message
1014
- - Text files are wrapped in `<file name="path">content</file>` tags
1015
- - Images (`.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`) are attached as base64-encoded attachments
1016
- - Paths support `~` for home directory and relative/absolute paths
1017
- - Empty files are skipped
1018
- - Non-existent files cause an immediate error
1019
-
1020
- **Examples:**
1021
- ```bash
1022
- # All files go into first message, regardless of position
1023
- pi @file1.md @file2.txt "prompt" @file3.md
1024
-
1025
- # This sends:
1026
- # Message 1: file1 + file2 + file3 + "prompt"
1027
- # (Any additional plain text arguments become separate messages)
1028
-
1029
- # Home directory expansion works
1030
- pi @~/Documents/notes.md "Summarize"
1031
-
1032
- # Combine with other options
1033
- pi --print @requirements.md "List the main points"
513
+ pi @requirements.md @design.png "Implement this"
1034
514
  ```
1035
515
 
1036
- **Limitations:**
1037
- - Not supported in `--mode rpc` (will error)
1038
- - Images require vision-capable models (e.g., Claude, GPT-4o, Gemini)
1039
-
1040
- ### Options
1041
-
1042
- **--provider <name>**
1043
- Provider name. Available: `anthropic`, `openai`, `google`, `xai`, `groq`, `cerebras`, `openrouter`, `zai`, plus any custom providers defined in `~/.pi/agent/models.json`.
1044
-
1045
- **--model <id>**
1046
- Model ID. If not specified, uses: (1) saved default from settings, (2) first available model with valid API key, or (3) none (interactive mode only).
1047
-
1048
- **--api-key <key>**
1049
- API key (overrides environment variables)
1050
-
1051
- **--system-prompt <text|file>**
1052
- Custom system prompt. Can be:
1053
- - Inline text: `--system-prompt "You are a helpful assistant"`
1054
- - File path: `--system-prompt ./my-prompt.txt`
1055
-
1056
- 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.
1057
-
1058
- **--append-system-prompt <text|file>**
1059
- Append additional text or file contents to the system prompt. Can be:
1060
- - Inline text: `--append-system-prompt "Also consider edge cases"`
1061
- - File path: `--append-system-prompt ./extra-instructions.txt`
1062
-
1063
- If the argument is a valid file path, the file contents will be appended. Otherwise, the text is appended directly. This complements `--system-prompt` for layering custom instructions without replacing the base system prompt. Works in both custom and default system prompts.
1064
-
1065
- **--mode <mode>**
1066
- Output mode for non-interactive usage (implies `--print`). Options:
1067
- - `text` (default): Output only the final assistant message text
1068
- - `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
1069
- - `rpc`: JSON mode plus stdin listener for headless operation. Send JSON commands on stdin: `{"type":"prompt","message":"..."}` or `{"type":"abort"}`. See [test/rpc-example.ts](test/rpc-example.ts) for a complete example
1070
-
1071
- **--print, -p**
1072
- Non-interactive mode: process the prompt(s) and exit. Without this flag, passing a prompt starts interactive mode with the prompt pre-submitted. Similar to Claude's `-p` flag and Codex's `exec` command.
1073
-
1074
- **--no-session**
1075
- Don't save session (ephemeral mode)
1076
-
1077
- **--session <path>**
1078
- Use specific session file path instead of auto-generating one
1079
-
1080
- **--continue, -c**
1081
- Continue the most recent session
1082
-
1083
- **--resume, -r**
1084
- Select a session to resume (opens interactive selector)
1085
-
1086
- **--models <patterns>**
1087
- Comma-separated model patterns for quick cycling with `Ctrl+P`. Matching priority:
1088
- 1. `provider/modelId` exact match (e.g., `openrouter/openai/gpt-5.1-codex`)
1089
- 2. Exact model ID match (e.g., `gpt-5.1-codex`)
1090
- 3. Partial match against model IDs and names (case-insensitive)
1091
-
1092
- When multiple partial matches exist, prefers aliases over dated versions (e.g., `claude-sonnet-4-5` over `claude-sonnet-4-5-20250929`). Without this flag, `Ctrl+P` cycles through all available models.
1093
-
1094
- Each pattern can optionally include a thinking level suffix: `pattern:level` where level is one of `off`, `minimal`, `low`, `medium`, or `high`. When cycling models, the associated thinking level is automatically applied. The first model in the list is used as the initial model when starting a new session.
1095
-
1096
- Examples:
1097
- - `--models openrouter/openai/gpt-5.1-codex` - Exact provider/model match
1098
- - `--models gpt-5.1-codex` - Exact ID match (not `openai/gpt-5.1-codex-mini`)
1099
- - `--models sonnet:high,haiku:low` - Sonnet with high thinking, Haiku with low thinking
1100
- - `--models sonnet,haiku` - Partial match for any model containing "sonnet" or "haiku"
1101
-
1102
- **--tools <tools>**
1103
- Comma-separated list of tools to enable. By default, pi uses `read,bash,edit,write`. This flag allows restricting or changing the available tools.
1104
-
1105
- Available tools:
1106
- - `read` - Read file contents
1107
- - `bash` - Execute bash commands
1108
- - `edit` - Make surgical edits to files
1109
- - `write` - Create or overwrite files
1110
- - `grep` - Search file contents for patterns (read-only, off by default)
1111
- - `find` - Find files by glob pattern (read-only, off by default)
1112
- - `ls` - List directory contents (read-only, off by default)
1113
-
1114
- Examples:
1115
- - `--tools read,grep,find,ls` - Read-only mode for code review/exploration
1116
- - `--tools read,bash` - Only allow reading and bash commands
1117
-
1118
- **--thinking <level>**
1119
- Set thinking level for reasoning-capable models. Valid values: `off`, `minimal`, `low`, `medium`, `high`. Takes highest priority over all other thinking level sources (saved settings, `--models` pattern levels, session restore).
1120
-
1121
- Examples:
1122
- - `--thinking high` - Start with high thinking level
1123
- - `--thinking off` - Disable thinking even if saved setting was different
1124
-
1125
- **--export <file>**
1126
- Export a session file to a self-contained HTML file and exit. Auto-detects format (session manager format or streaming event format). Optionally provide an output filename as the second argument.
1127
-
1128
- **Note:** When exporting streaming event logs (e.g., `pi-output.jsonl` from `--mode json`), the system prompt and tool definitions are not available since they are not recorded in the event stream. The exported HTML will include a notice about this.
1129
-
1130
- Examples:
1131
- - `--export session.jsonl` - Export to `pi-session-session.html`
1132
- - `--export session.jsonl output.html` - Export to custom filename
1133
-
1134
- **--help, -h**
1135
- Show help message
516
+ Text files wrapped in `<file name="path">content</file>`. Images attached as base64.
1136
517
 
1137
518
  ### Examples
1138
519
 
1139
520
  ```bash
1140
- # Start interactive mode
521
+ # Interactive mode
1141
522
  pi
1142
523
 
1143
- # Interactive mode with initial prompt (stays running after completion)
524
+ # Interactive with initial prompt
1144
525
  pi "List all .ts files in src/"
1145
526
 
1146
- # Include files in your prompt
1147
- pi @requirements.md @design.png "Implement this feature"
1148
-
1149
- # Non-interactive mode (process prompt and exit)
527
+ # Non-interactive
1150
528
  pi -p "List all .ts files in src/"
1151
529
 
1152
- # Non-interactive with files
1153
- pi -p @code.ts "Review this code for bugs"
530
+ # With files
531
+ pi -p @code.ts "Review this code"
1154
532
 
1155
- # JSON mode - stream all agent events (non-interactive)
1156
- pi --mode json "List all .ts files in src/"
533
+ # JSON event stream
534
+ pi --mode json "List files"
1157
535
 
1158
- # RPC mode - headless operation (see test/rpc-example.ts)
536
+ # RPC mode (headless)
1159
537
  pi --mode rpc --no-session
1160
- # Then send JSON on stdin:
1161
- # {"type":"prompt","message":"List all .ts files"}
1162
- # {"type":"abort"}
1163
538
 
1164
- # Continue previous session
539
+ # Continue session
1165
540
  pi -c "What did we discuss?"
1166
541
 
1167
- # Use different model
1168
- pi --provider openai --model gpt-4o "Help me refactor this code"
1169
-
1170
- # Limit model cycling to specific models
1171
- pi --models claude-sonnet,claude-haiku,gpt-4o
1172
- # Now Ctrl+P cycles only through those models
542
+ # Specific model
543
+ pi --provider openai --model gpt-4o "Help me refactor"
1173
544
 
1174
545
  # Model cycling with thinking levels
1175
546
  pi --models sonnet:high,haiku:low
1176
- # Starts with sonnet at high thinking, Ctrl+P switches to haiku at low thinking
1177
-
1178
- # Start with specific thinking level
1179
- pi --thinking high "Solve this complex algorithm problem"
1180
-
1181
- # Read-only mode (no file modifications possible)
1182
- pi --tools read,grep,find,ls -p "Review the architecture in src/"
1183
547
 
1184
- # Oracle-style subagent (bash for git/gh, no file modifications)
1185
- pi --tools read,bash,grep,find,ls \
1186
- --no-session \
1187
- -p "Use bash only for read-only operations. Read issue #74 with gh, then review the implementation"
548
+ # Read-only mode
549
+ pi --tools read,grep,find,ls -p "Review the architecture"
1188
550
 
1189
- # Export a session file to HTML
1190
- pi --export ~/.pi/agent/sessions/--myproject--/session.jsonl
1191
- pi --export session.jsonl my-export.html
551
+ # Export session
552
+ pi --export session.jsonl output.html
1192
553
  ```
1193
554
 
555
+ ---
556
+
1194
557
  ## Tools
1195
558
 
1196
559
  ### Default Tools
1197
560
 
1198
- By default, the agent has access to four core tools:
1199
-
1200
- **read**
1201
- 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.
1202
-
1203
- **write**
1204
- Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.
1205
-
1206
- **edit**
1207
- 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.
1208
-
1209
- **bash**
1210
- Execute a bash command in the current working directory. Returns stdout and stderr. Optionally accepts a `timeout` parameter (in seconds) - no default timeout.
1211
-
1212
- ### Read-Only Exploration Tools
561
+ | Tool | Description |
562
+ |------|-------------|
563
+ | `read` | Read file contents. Images sent as attachments. Text: first 2000 lines, lines truncated at 2000 chars. Use offset/limit for large files. |
564
+ | `write` | Write/overwrite file. Creates parent directories. |
565
+ | `edit` | Replace exact text in file. Must match exactly including whitespace. Fails if text appears multiple times or not found. |
566
+ | `bash` | Execute command. Returns stdout/stderr. Optional `timeout` parameter. |
1213
567
 
1214
- These tools are available via `--tools` flag for read-only code exploration:
568
+ ### Read-Only Tools
1215
569
 
1216
- **grep**
1217
- Search file contents for a pattern (regex or literal). Returns matching lines with file paths and line numbers. Respects `.gitignore`. Parameters: `pattern` (required), `path`, `glob`, `ignoreCase`, `literal`, `context`, `limit`.
570
+ Available via `--tools` flag:
1218
571
 
1219
- **find**
1220
- Search for files by glob pattern (e.g., `**/*.ts`). Returns matching file paths relative to the search directory. Respects `.gitignore`. Parameters: `pattern` (required), `path`, `limit`.
572
+ | Tool | Description |
573
+ |------|-------------|
574
+ | `grep` | Search file contents (regex or literal). Respects `.gitignore`. |
575
+ | `find` | Search for files by glob pattern. Respects `.gitignore`. |
576
+ | `ls` | List directory contents. Includes dotfiles. |
1221
577
 
1222
- **ls**
1223
- List directory contents. Returns entries sorted alphabetically with `/` suffix for directories. Includes dotfiles. Parameters: `path`, `limit`.
578
+ Example: `--tools read,grep,find,ls` for code review without modification.
1224
579
 
1225
- ### MCP & Adding Your Own Tools
580
+ ### Custom Tools
1226
581
 
1227
- **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.
1228
-
1229
- **Here's the gist:**
1230
-
1231
- 1. Create a simple CLI tool (any language, any executable)
1232
- 2. Write a concise README.md describing what it does and how to use it
1233
- 3. Tell the agent to read that README
1234
-
1235
- **Minimal example:**
582
+ Pi relies on CLI tools invoked via bash rather than MCP. Create a tool with a README:
1236
583
 
1237
584
  `~/agent-tools/screenshot/README.md`:
1238
585
  ```markdown
1239
586
  # Screenshot Tool
1240
-
1241
587
  Takes a screenshot of your main display.
1242
588
 
1243
589
  ## Usage
1244
590
  ```bash
1245
591
  screenshot.sh
1246
592
  ```
1247
-
1248
- Returns the path to the saved PNG file.
593
+ Returns the path to the saved PNG.
1249
594
  ```
1250
595
 
1251
596
  `~/agent-tools/screenshot/screenshot.sh`:
@@ -1255,117 +600,106 @@ screencapture -x /tmp/screenshot-$(date +%s).png
1255
600
  ls -t /tmp/screenshot-*.png | head -1
1256
601
  ```
1257
602
 
1258
- **In your session:**
1259
- ```
1260
- You: Read ~/agent-tools/screenshot/README.md and use that tool to take a screenshot
1261
- ```
603
+ Usage: "Read ~/agent-tools/screenshot/README.md and take a screenshot"
1262
604
 
1263
- 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.
605
+ Reference tool READMEs in `AGENTS.md` to make them automatically available.
1264
606
 
1265
- You can also reference tool READMEs in your `AGENTS.md` files to make them automatically available:
1266
- - Global: `~/.pi/agent/AGENTS.md` - available in all sessions
1267
- - Project-specific: `./AGENTS.md` - available in this project
607
+ ---
1268
608
 
1269
- **Real-world example:**
609
+ ## Programmatic Usage
1270
610
 
1271
- 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. Far from perfect, but functional. Just tell your agent: "Read ~/agent-tools/exa-search/README.md and search for X".
611
+ ### RPC Mode
1272
612
 
1273
- 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/
613
+ For embedding pi in other applications:
1274
614
 
1275
- ## Security (YOLO by default)
615
+ ```bash
616
+ pi --mode rpc --no-session
617
+ ```
1276
618
 
1277
- 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.
619
+ Send JSON commands on stdin:
620
+ ```json
621
+ {"type":"prompt","message":"List all .ts files"}
622
+ {"type":"abort"}
623
+ ```
1278
624
 
1279
- **What this means:**
1280
- - No permission prompts for file operations or commands
1281
- - No pre-checking of bash commands for malicious content
1282
- - Full filesystem access - can read, write, or delete anything
1283
- - Can execute any command with your user privileges
625
+ See [RPC documentation](docs/rpc.md) for full protocol.
1284
626
 
1285
- **Why:**
1286
- - Permission systems add massive friction while being easily circumvented
1287
- - Pre-checking tools for "dangerous" patterns introduces latency, false positives, and is ineffective
627
+ **Node.js/TypeScript:** Consider using `AgentSession` directly from `@mariozechner/pi-coding-agent` instead of subprocess. See [`src/core/agent-session.ts`](src/core/agent-session.ts) and [`src/modes/rpc/rpc-client.ts`](src/modes/rpc/rpc-client.ts).
1288
628
 
1289
- **Prompt injection risks:**
1290
- - By default, pi has no web search or fetch tool
1291
- - However, it can use `curl` or read files from disk
1292
- - Both provide ample surface area for prompt injection attacks
1293
- - Malicious content in files or command outputs can influence behavior
629
+ ### HTML Export
1294
630
 
1295
- **Mitigations:**
1296
- - Run pi inside a container if you're uncomfortable with full access
1297
- - Use a different tool if you need guardrails
1298
- - Don't use pi on systems with sensitive data you can't afford to lose
1299
- - Fork pi and add all of the above
631
+ ```bash
632
+ pi --export session.jsonl # Auto-generated filename
633
+ pi --export session.jsonl output.html # Custom filename
634
+ ```
1300
635
 
1301
- This is how I want it to work and I'm not likely to change my stance on this.
636
+ Works with both session files and streaming event logs from `--mode json`.
637
+
638
+ ---
1302
639
 
1303
- Use at your own risk.
640
+ ## Philosophy
1304
641
 
1305
- ## Sub-Agents
642
+ Pi is opinionated about what it won't do. These are intentional design decisions.
1306
643
 
1307
- **pi does not and will not support sub-agents as a built-in feature.** If the agent needs to delegate work, it can:
644
+ ### No MCP
1308
645
 
1309
- 1. Spawn another instance of itself via the `pi` CLI command
1310
- 2. Write a custom tool with a README.md that describes how to invoke pi for specific tasks
646
+ Pi does not support MCP (Model Context Protocol). Instead, it relies on four core tools (read, write, edit, bash) and assumes the agent can invoke CLI tools or write them as needed.
1311
647
 
1312
- **Why no built-in sub-agents:**
648
+ CLI tools are simpler: any executable with a README works. No protocol overhead, no server management. The agent reads the README and uses bash.
1313
649
 
1314
- 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.
650
+ See: [What if you don't need MCP?](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/)
1315
651
 
1316
- If you need parallel work on independent tasks, manually run multiple `pi` sessions in different terminal tabs. You're the orchestrator.
652
+ ### No Sub-Agents
1317
653
 
1318
- ## To-Dos
654
+ If the agent needs to delegate, it can spawn `pi` via bash or write a custom tool. Built-in sub-agents transfer context poorly; information gets lost or misrepresented. For parallel work, run multiple `pi` sessions in different terminals.
1319
655
 
1320
- **pi does not and will not support built-in to-dos.** In my experience, to-do lists generally confuse models more than they help.
656
+ ### No Built-in To-Dos
1321
657
 
1322
- If you need task tracking, make it stateful by writing to a file:
658
+ To-do lists confuse models more than they help. For task tracking, use a file:
1323
659
 
1324
660
  ```markdown
1325
661
  # TODO.md
1326
-
1327
- - [x] Implement user authentication
1328
- - [x] Add database migrations
1329
- - [ ] Write API documentation
1330
- - [ ] Add rate limiting
662
+ - [x] Implement authentication
663
+ - [ ] Write API docs
1331
664
  ```
1332
665
 
1333
- 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.
1334
-
1335
- ## Planning
1336
-
1337
- **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.
666
+ ### No Planning Mode
1338
667
 
1339
- If you need persistent planning across sessions, write it to a file:
668
+ Tell the agent to think through problems without modifying files. For persistent plans, write to a file:
1340
669
 
1341
670
  ```markdown
1342
671
  # PLAN.md
1343
-
1344
672
  ## Goal
1345
- Refactor authentication system to support OAuth
1346
-
1347
- ## Approach
1348
- 1. Research OAuth 2.0 flows
1349
- 2. Design token storage schema
1350
- 3. Implement authorization server endpoints
1351
- 4. Update client-side login flow
1352
- 5. Add tests
1353
-
673
+ Refactor auth to support OAuth
1354
674
  ## Current Step
1355
- Working on step 3 - authorization endpoints
675
+ Working on authorization endpoints
1356
676
  ```
1357
677
 
1358
- 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.
678
+ ### No Permission System (YOLO Mode)
679
+
680
+ Pi runs with full filesystem access and no permission prompts. Why:
681
+ - Permission systems add friction while being easily circumvented
682
+ - Pre-checking for "dangerous" patterns causes latency and false positives
683
+
684
+ **Risks:**
685
+ - Can read, write, delete anything with your user privileges
686
+ - Prompt injection via files or command output can influence behavior
687
+
688
+ **Mitigations:**
689
+ - Run in a container if uncomfortable
690
+ - Don't use on systems with sensitive data you can't afford to lose
1359
691
 
1360
- ## Background Bash
692
+ ### No Background Bash
1361
693
 
1362
- **pi does not and will not implement background bash execution.** Instead, tell the agent to use `tmux` or something like [tterminal-cp](https://mariozechner.at/posts/2025-08-15-mcp-vs-cli/). Bonus points: you can watch the agent interact with a CLI like a debugger and even intervene if necessary.
694
+ Use `tmux` or similar. Bonus: you can watch the agent interact with CLIs and intervene if needed.
695
+
696
+ ---
1363
697
 
1364
698
  ## Development
1365
699
 
1366
700
  ### Forking / Rebranding
1367
701
 
1368
- All branding (app name, config directory) is configurable via `package.json`:
702
+ Configure via `package.json`:
1369
703
 
1370
704
  ```json
1371
705
  {
@@ -1376,44 +710,27 @@ All branding (app name, config directory) is configurable via `package.json`:
1376
710
  }
1377
711
  ```
1378
712
 
1379
- To create a fork with different branding:
1380
- 1. Change `piConfig.name` to your app name (e.g., `"tau"`)
1381
- 2. Change `piConfig.configDir` to your config directory (e.g., `".tau"`)
1382
- 3. Change the `bin` field to your command name: `"bin": { "tau": "dist/cli.js" }`
1383
-
1384
- This affects:
1385
- - CLI banner and help text
1386
- - Config directory (`~/.pi/agent/` → `~/.tau/agent/`)
1387
- - Environment variable name (`PI_CODING_AGENT_DIR` → `TAU_CODING_AGENT_DIR`)
1388
- - All user-facing paths in error messages and documentation
713
+ Change `name`, `configDir`, and `bin` field for your fork. Affects CLI banner, config paths, and environment variable names.
1389
714
 
1390
715
  ### Path Resolution
1391
716
 
1392
- The codebase supports three execution modes:
1393
- - **npm**: Running via `node dist/cli.js` after npm install
1394
- - **Bun binary**: Standalone compiled binary with files alongside
1395
- - **tsx**: Running directly from source via `npx tsx src/cli.ts`
717
+ Three execution modes: npm install, standalone binary, tsx from source.
1396
718
 
1397
- All path resolution for package assets (package.json, README.md, CHANGELOG.md, themes) must go through `src/paths.ts`:
719
+ **Always use `src/paths.ts`** for package assets:
1398
720
 
1399
721
  ```typescript
1400
- import { getPackageDir, getThemeDir, getPackageJsonPath, getReadmePath, getChangelogPath } from "./paths.js";
722
+ import { getPackageDir, getThemeDir } from "./paths.js";
1401
723
  ```
1402
724
 
1403
- **Never use `__dirname` directly** for resolving package assets. The `paths.ts` module handles the differences between execution modes automatically.
725
+ Never use `__dirname` directly for package assets.
1404
726
 
1405
727
  ### Debug Command
1406
728
 
1407
- The `/debug` command is a hidden development feature (not shown in autocomplete) that writes all currently rendered lines with their visible widths and ANSI escape sequences to `~/.pi/agent/pi-debug.log`. This is useful for debugging TUI rendering issues, especially when lines don't extend to the terminal edge or contain unexpected invisible characters.
729
+ `/debug` (hidden) writes rendered lines with ANSI codes to `~/.pi/agent/pi-debug.log` for TUI debugging.
1408
730
 
1409
- ```
1410
- /debug
1411
- ```
731
+ For architecture and contribution guidelines, see [DEVELOPMENT.md](./DEVELOPMENT.md).
1412
732
 
1413
- The debug log includes:
1414
- - Terminal width at time of capture
1415
- - Total number of rendered lines
1416
- - Each line with its index, visible width, and JSON-escaped content showing all ANSI codes
733
+ ---
1417
734
 
1418
735
  ## License
1419
736
 
@@ -1421,5 +738,5 @@ MIT
1421
738
 
1422
739
  ## See Also
1423
740
 
1424
- - [@mariozechner/pi-ai](https://www.npmjs.com/package/@mariozechner/pi-ai): Core LLM toolkit with multi-provider support
1425
- - [@mariozechner/pi-agent](https://www.npmjs.com/package/@mariozechner/pi-agent): Agent framework with tool execution
741
+ - [@mariozechner/pi-ai](https://www.npmjs.com/package/@mariozechner/pi-ai): Core LLM toolkit
742
+ - [@mariozechner/pi-agent](https://www.npmjs.com/package/@mariozechner/pi-agent): Agent framework