@vandeepunk/pi-coding-agent 0.0.6 → 1.0.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 (459) hide show
  1. package/CHANGELOG.md +814 -16
  2. package/README.md +66 -27
  3. package/dist/bun/cli.d.ts +3 -0
  4. package/dist/bun/cli.d.ts.map +1 -0
  5. package/dist/bun/cli.js +7 -0
  6. package/dist/bun/cli.js.map +1 -0
  7. package/dist/bun/register-bedrock.d.ts +2 -0
  8. package/dist/bun/register-bedrock.d.ts.map +1 -0
  9. package/dist/bun/register-bedrock.js +4 -0
  10. package/dist/bun/register-bedrock.js.map +1 -0
  11. package/dist/cli/args.d.ts +9 -4
  12. package/dist/cli/args.d.ts.map +1 -1
  13. package/dist/cli/args.js +61 -22
  14. package/dist/cli/args.js.map +1 -1
  15. package/dist/cli/file-processor.d.ts.map +1 -1
  16. package/dist/cli/file-processor.js +4 -0
  17. package/dist/cli/file-processor.js.map +1 -1
  18. package/dist/cli/initial-message.d.ts +18 -0
  19. package/dist/cli/initial-message.d.ts.map +1 -0
  20. package/dist/cli/initial-message.js +22 -0
  21. package/dist/cli/initial-message.js.map +1 -0
  22. package/dist/cli/session-picker.d.ts.map +1 -1
  23. package/dist/cli/session-picker.js +2 -1
  24. package/dist/cli/session-picker.js.map +1 -1
  25. package/dist/cli.d.ts.map +1 -1
  26. package/dist/cli.js +3 -0
  27. package/dist/cli.js.map +1 -1
  28. package/dist/config.d.ts +1 -1
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/config.js +2 -2
  31. package/dist/config.js.map +1 -1
  32. package/dist/core/agent-session-runtime.d.ts +83 -0
  33. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  34. package/dist/core/agent-session-runtime.js +236 -0
  35. package/dist/core/agent-session-runtime.js.map +1 -0
  36. package/dist/core/agent-session-services.d.ts +86 -0
  37. package/dist/core/agent-session-services.d.ts.map +1 -0
  38. package/dist/core/agent-session-services.js +116 -0
  39. package/dist/core/agent-session-services.js.map +1 -0
  40. package/dist/core/agent-session.d.ts +63 -49
  41. package/dist/core/agent-session.d.ts.map +1 -1
  42. package/dist/core/agent-session.js +599 -370
  43. package/dist/core/agent-session.js.map +1 -1
  44. package/dist/core/auth-storage.d.ts +38 -8
  45. package/dist/core/auth-storage.d.ts.map +1 -1
  46. package/dist/core/auth-storage.js +220 -96
  47. package/dist/core/auth-storage.js.map +1 -1
  48. package/dist/core/bash-executor.d.ts +6 -7
  49. package/dist/core/bash-executor.d.ts.map +1 -1
  50. package/dist/core/bash-executor.js +27 -114
  51. package/dist/core/bash-executor.js.map +1 -1
  52. package/dist/core/compaction/branch-summarization.d.ts +2 -0
  53. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  54. package/dist/core/compaction/branch-summarization.js +3 -2
  55. package/dist/core/compaction/branch-summarization.js.map +1 -1
  56. package/dist/core/compaction/compaction.d.ts +3 -3
  57. package/dist/core/compaction/compaction.d.ts.map +1 -1
  58. package/dist/core/compaction/compaction.js +31 -25
  59. package/dist/core/compaction/compaction.js.map +1 -1
  60. package/dist/core/compaction/utils.d.ts +3 -0
  61. package/dist/core/compaction/utils.d.ts.map +1 -1
  62. package/dist/core/compaction/utils.js +16 -1
  63. package/dist/core/compaction/utils.js.map +1 -1
  64. package/dist/core/exec.d.ts.map +1 -1
  65. package/dist/core/exec.js +7 -3
  66. package/dist/core/exec.js.map +1 -1
  67. package/dist/core/export-html/index.d.ts +7 -4
  68. package/dist/core/export-html/index.d.ts.map +1 -1
  69. package/dist/core/export-html/index.js +10 -8
  70. package/dist/core/export-html/index.js.map +1 -1
  71. package/dist/core/export-html/template.css +43 -13
  72. package/dist/core/export-html/template.html +1 -0
  73. package/dist/core/export-html/template.js +118 -14
  74. package/dist/core/export-html/tool-renderer.d.ts +9 -4
  75. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  76. package/dist/core/export-html/tool-renderer.js +48 -10
  77. package/dist/core/export-html/tool-renderer.js.map +1 -1
  78. package/dist/core/extensions/index.d.ts +5 -4
  79. package/dist/core/extensions/index.d.ts.map +1 -1
  80. package/dist/core/extensions/index.js +2 -2
  81. package/dist/core/extensions/index.js.map +1 -1
  82. package/dist/core/extensions/loader.d.ts.map +1 -1
  83. package/dist/core/extensions/loader.js +49 -13
  84. package/dist/core/extensions/loader.js.map +1 -1
  85. package/dist/core/extensions/runner.d.ts +13 -11
  86. package/dist/core/extensions/runner.d.ts.map +1 -1
  87. package/dist/core/extensions/runner.js +139 -64
  88. package/dist/core/extensions/runner.js.map +1 -1
  89. package/dist/core/extensions/types.d.ts +174 -34
  90. package/dist/core/extensions/types.d.ts.map +1 -1
  91. package/dist/core/extensions/types.js +10 -0
  92. package/dist/core/extensions/types.js.map +1 -1
  93. package/dist/core/extensions/wrapper.d.ts +4 -11
  94. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  95. package/dist/core/extensions/wrapper.js +6 -86
  96. package/dist/core/extensions/wrapper.js.map +1 -1
  97. package/dist/core/footer-data-provider.d.ts +18 -2
  98. package/dist/core/footer-data-provider.d.ts.map +1 -1
  99. package/dist/core/footer-data-provider.js +220 -40
  100. package/dist/core/footer-data-provider.js.map +1 -1
  101. package/dist/core/index.d.ts +4 -1
  102. package/dist/core/index.d.ts.map +1 -1
  103. package/dist/core/index.js +4 -1
  104. package/dist/core/index.js.map +1 -1
  105. package/dist/core/keybindings.d.ts +283 -50
  106. package/dist/core/keybindings.d.ts.map +1 -1
  107. package/dist/core/keybindings.js +221 -134
  108. package/dist/core/keybindings.js.map +1 -1
  109. package/dist/core/model-registry.d.ts +33 -3
  110. package/dist/core/model-registry.d.ts.map +1 -1
  111. package/dist/core/model-registry.js +165 -97
  112. package/dist/core/model-registry.js.map +1 -1
  113. package/dist/core/model-resolver.d.ts +35 -1
  114. package/dist/core/model-resolver.d.ts.map +1 -1
  115. package/dist/core/model-resolver.js +205 -32
  116. package/dist/core/model-resolver.js.map +1 -1
  117. package/dist/core/output-guard.d.ts +6 -0
  118. package/dist/core/output-guard.d.ts.map +1 -0
  119. package/dist/core/output-guard.js +59 -0
  120. package/dist/core/output-guard.js.map +1 -0
  121. package/dist/core/package-manager.d.ts +43 -2
  122. package/dist/core/package-manager.d.ts.map +1 -1
  123. package/dist/core/package-manager.js +541 -102
  124. package/dist/core/package-manager.js.map +1 -1
  125. package/dist/core/prompt-templates.d.ts +5 -4
  126. package/dist/core/prompt-templates.d.ts.map +1 -1
  127. package/dist/core/prompt-templates.js +35 -37
  128. package/dist/core/prompt-templates.js.map +1 -1
  129. package/dist/core/resolve-config-value.d.ts +6 -0
  130. package/dist/core/resolve-config-value.d.ts.map +1 -1
  131. package/dist/core/resolve-config-value.js +75 -8
  132. package/dist/core/resolve-config-value.js.map +1 -1
  133. package/dist/core/resource-loader.d.ts +6 -5
  134. package/dist/core/resource-loader.d.ts.map +1 -1
  135. package/dist/core/resource-loader.js +166 -119
  136. package/dist/core/resource-loader.js.map +1 -1
  137. package/dist/core/sdk.d.ts +11 -8
  138. package/dist/core/sdk.d.ts.map +1 -1
  139. package/dist/core/sdk.js +31 -29
  140. package/dist/core/sdk.js.map +1 -1
  141. package/dist/core/session-cwd.d.ts +19 -0
  142. package/dist/core/session-cwd.d.ts.map +1 -0
  143. package/dist/core/session-cwd.js +38 -0
  144. package/dist/core/session-cwd.js.map +1 -0
  145. package/dist/core/session-manager.d.ts +11 -1
  146. package/dist/core/session-manager.d.ts.map +1 -1
  147. package/dist/core/session-manager.js +39 -25
  148. package/dist/core/session-manager.js.map +1 -1
  149. package/dist/core/settings-manager.d.ts +60 -10
  150. package/dist/core/settings-manager.d.ts.map +1 -1
  151. package/dist/core/settings-manager.js +291 -140
  152. package/dist/core/settings-manager.js.map +1 -1
  153. package/dist/core/skills.d.ts +5 -3
  154. package/dist/core/skills.d.ts.map +1 -1
  155. package/dist/core/skills.js +54 -9
  156. package/dist/core/skills.js.map +1 -1
  157. package/dist/core/slash-commands.d.ts +2 -3
  158. package/dist/core/slash-commands.d.ts.map +1 -1
  159. package/dist/core/slash-commands.js +3 -2
  160. package/dist/core/slash-commands.js.map +1 -1
  161. package/dist/core/source-info.d.ts +18 -0
  162. package/dist/core/source-info.d.ts.map +1 -0
  163. package/dist/core/source-info.js +19 -0
  164. package/dist/core/source-info.js.map +1 -0
  165. package/dist/core/system-prompt.d.ts +4 -0
  166. package/dist/core/system-prompt.d.ts.map +1 -1
  167. package/dist/core/system-prompt.js +31 -52
  168. package/dist/core/system-prompt.js.map +1 -1
  169. package/dist/core/timings.d.ts +1 -0
  170. package/dist/core/timings.d.ts.map +1 -1
  171. package/dist/core/timings.js +6 -0
  172. package/dist/core/timings.js.map +1 -1
  173. package/dist/core/tools/bash.d.ts +24 -6
  174. package/dist/core/tools/bash.d.ts.map +1 -1
  175. package/dist/core/tools/bash.js +225 -115
  176. package/dist/core/tools/bash.js.map +1 -1
  177. package/dist/core/tools/edit-diff.d.ts +23 -1
  178. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  179. package/dist/core/tools/edit-diff.js +151 -57
  180. package/dist/core/tools/edit-diff.js.map +1 -1
  181. package/dist/core/tools/edit.d.ts +20 -6
  182. package/dist/core/tools/edit.d.ts.map +1 -1
  183. package/dist/core/tools/edit.js +111 -61
  184. package/dist/core/tools/edit.js.map +1 -1
  185. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  186. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  187. package/dist/core/tools/file-mutation-queue.js +37 -0
  188. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  189. package/dist/core/tools/find.d.ts +11 -4
  190. package/dist/core/tools/find.d.ts.map +1 -1
  191. package/dist/core/tools/find.js +82 -30
  192. package/dist/core/tools/find.js.map +1 -1
  193. package/dist/core/tools/grep.d.ts +15 -4
  194. package/dist/core/tools/grep.d.ts.map +1 -1
  195. package/dist/core/tools/grep.js +83 -29
  196. package/dist/core/tools/grep.js.map +1 -1
  197. package/dist/core/tools/index.d.ts +63 -21
  198. package/dist/core/tools/index.d.ts.map +1 -1
  199. package/dist/core/tools/index.js +51 -26
  200. package/dist/core/tools/index.js.map +1 -1
  201. package/dist/core/tools/ls.d.ts +9 -3
  202. package/dist/core/tools/ls.d.ts.map +1 -1
  203. package/dist/core/tools/ls.js +67 -13
  204. package/dist/core/tools/ls.js.map +1 -1
  205. package/dist/core/tools/read.d.ts +10 -3
  206. package/dist/core/tools/read.d.ts.map +1 -1
  207. package/dist/core/tools/read.js +110 -51
  208. package/dist/core/tools/read.js.map +1 -1
  209. package/dist/core/tools/render-utils.d.ts +21 -0
  210. package/dist/core/tools/render-utils.d.ts.map +1 -0
  211. package/dist/core/tools/render-utils.js +49 -0
  212. package/dist/core/tools/render-utils.js.map +1 -0
  213. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  214. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  215. package/dist/core/tools/tool-definition-wrapper.js +32 -0
  216. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  217. package/dist/core/tools/write.d.ts +9 -3
  218. package/dist/core/tools/write.d.ts.map +1 -1
  219. package/dist/core/tools/write.js +168 -30
  220. package/dist/core/tools/write.js.map +1 -1
  221. package/dist/index.d.ts +7 -6
  222. package/dist/index.d.ts.map +1 -1
  223. package/dist/index.js +7 -6
  224. package/dist/index.js.map +1 -1
  225. package/dist/main.d.ts.map +1 -1
  226. package/dist/main.js +354 -379
  227. package/dist/main.js.map +1 -1
  228. package/dist/migrations.d.ts.map +1 -1
  229. package/dist/migrations.js +31 -11
  230. package/dist/migrations.js.map +1 -1
  231. package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  232. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  233. package/dist/modes/interactive/components/assistant-message.js +14 -3
  234. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  235. package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
  236. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  237. package/dist/modes/interactive/components/bash-execution.js +22 -9
  238. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  239. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  240. package/dist/modes/interactive/components/bordered-loader.js +1 -1
  241. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  242. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  243. package/dist/modes/interactive/components/branch-summary-message.js +2 -2
  244. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  245. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  246. package/dist/modes/interactive/components/compaction-summary-message.js +2 -2
  247. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  248. package/dist/modes/interactive/components/config-selector.d.ts +1 -1
  249. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  250. package/dist/modes/interactive/components/config-selector.js +14 -14
  251. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  252. package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
  253. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  254. package/dist/modes/interactive/components/custom-editor.js +6 -6
  255. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  256. package/dist/modes/interactive/components/extension-editor.d.ts +5 -2
  257. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  258. package/dist/modes/interactive/components/extension-editor.js +18 -9
  259. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  260. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  261. package/dist/modes/interactive/components/extension-input.js +5 -5
  262. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  263. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  264. package/dist/modes/interactive/components/extension-selector.js +8 -8
  265. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  266. package/dist/modes/interactive/components/footer.d.ts +1 -0
  267. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  268. package/dist/modes/interactive/components/footer.js +21 -40
  269. package/dist/modes/interactive/components/footer.js.map +1 -1
  270. package/dist/modes/interactive/components/index.d.ts +1 -1
  271. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  272. package/dist/modes/interactive/components/index.js +1 -1
  273. package/dist/modes/interactive/components/index.js.map +1 -1
  274. package/dist/modes/interactive/components/keybinding-hints.d.ts +3 -36
  275. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  276. package/dist/modes/interactive/components/keybinding-hints.js +5 -44
  277. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  278. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  279. package/dist/modes/interactive/components/login-dialog.js +7 -7
  280. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  281. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  282. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/model-selector.js +13 -9
  284. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  285. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  286. package/dist/modes/interactive/components/oauth-selector.js +7 -7
  287. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  288. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  289. package/dist/modes/interactive/components/scoped-models-selector.js +4 -4
  290. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  291. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  292. package/dist/modes/interactive/components/session-selector.js +33 -36
  293. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  294. package/dist/modes/interactive/components/settings-selector.d.ts +5 -0
  295. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  296. package/dist/modes/interactive/components/settings-selector.js +25 -1
  297. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  298. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  299. package/dist/modes/interactive/components/show-images-selector.js +5 -1
  300. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  301. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  302. package/dist/modes/interactive/components/skill-invocation-message.js +2 -2
  303. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  304. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  305. package/dist/modes/interactive/components/theme-selector.js +5 -1
  306. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  307. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  308. package/dist/modes/interactive/components/thinking-selector.js +5 -1
  309. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  310. package/dist/modes/interactive/components/tool-execution.d.ts +17 -29
  311. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  312. package/dist/modes/interactive/components/tool-execution.js +139 -501
  313. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  314. package/dist/modes/interactive/components/tree-selector.d.ts +25 -4
  315. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  316. package/dist/modes/interactive/components/tree-selector.js +184 -34
  317. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  318. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/user-message-selector.js +6 -6
  320. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  321. package/dist/modes/interactive/components/user-message.d.ts +1 -0
  322. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  323. package/dist/modes/interactive/components/user-message.js +12 -0
  324. package/dist/modes/interactive/components/user-message.js.map +1 -1
  325. package/dist/modes/interactive/interactive-mode.d.ts +25 -17
  326. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  327. package/dist/modes/interactive/interactive-mode.js +669 -385
  328. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  329. package/dist/modes/interactive/theme/theme.d.ts +3 -0
  330. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  331. package/dist/modes/interactive/theme/theme.js +83 -48
  332. package/dist/modes/interactive/theme/theme.js.map +1 -1
  333. package/dist/modes/print-mode.d.ts +2 -2
  334. package/dist/modes/print-mode.d.ts.map +1 -1
  335. package/dist/modes/print-mode.js +90 -79
  336. package/dist/modes/print-mode.js.map +1 -1
  337. package/dist/modes/rpc/jsonl.d.ts +17 -0
  338. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  339. package/dist/modes/rpc/jsonl.js +49 -0
  340. package/dist/modes/rpc/jsonl.js.map +1 -0
  341. package/dist/modes/rpc/rpc-client.d.ts +1 -1
  342. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  343. package/dist/modes/rpc/rpc-client.js +8 -11
  344. package/dist/modes/rpc/rpc-client.js.map +1 -1
  345. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  346. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  347. package/dist/modes/rpc/rpc-mode.js +130 -87
  348. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  349. package/dist/modes/rpc/rpc-types.d.ts +3 -4
  350. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  351. package/dist/modes/rpc/rpc-types.js.map +1 -1
  352. package/dist/package-manager-cli.d.ts +4 -0
  353. package/dist/package-manager-cli.d.ts.map +1 -0
  354. package/dist/package-manager-cli.js +234 -0
  355. package/dist/package-manager-cli.js.map +1 -0
  356. package/dist/utils/child-process.d.ts +11 -0
  357. package/dist/utils/child-process.d.ts.map +1 -0
  358. package/dist/utils/child-process.js +78 -0
  359. package/dist/utils/child-process.js.map +1 -0
  360. package/dist/utils/clipboard-image.d.ts.map +1 -1
  361. package/dist/utils/clipboard-image.js +94 -11
  362. package/dist/utils/clipboard-image.js.map +1 -1
  363. package/dist/utils/clipboard-native.d.ts +1 -0
  364. package/dist/utils/clipboard-native.d.ts.map +1 -1
  365. package/dist/utils/clipboard-native.js.map +1 -1
  366. package/dist/utils/clipboard.d.ts +1 -1
  367. package/dist/utils/clipboard.d.ts.map +1 -1
  368. package/dist/utils/clipboard.js +27 -16
  369. package/dist/utils/clipboard.js.map +1 -1
  370. package/dist/utils/exif-orientation.d.ts +5 -0
  371. package/dist/utils/exif-orientation.d.ts.map +1 -0
  372. package/dist/utils/exif-orientation.js +158 -0
  373. package/dist/utils/exif-orientation.js.map +1 -0
  374. package/dist/utils/git.d.ts +5 -1
  375. package/dist/utils/git.d.ts.map +1 -1
  376. package/dist/utils/git.js +14 -3
  377. package/dist/utils/git.js.map +1 -1
  378. package/dist/utils/image-convert.d.ts.map +1 -1
  379. package/dist/utils/image-convert.js +5 -1
  380. package/dist/utils/image-convert.js.map +1 -1
  381. package/dist/utils/image-resize.d.ts +5 -5
  382. package/dist/utils/image-resize.d.ts.map +1 -1
  383. package/dist/utils/image-resize.js +51 -95
  384. package/dist/utils/image-resize.js.map +1 -1
  385. package/dist/utils/paths.d.ts +7 -0
  386. package/dist/utils/paths.d.ts.map +1 -0
  387. package/dist/utils/paths.js +19 -0
  388. package/dist/utils/paths.js.map +1 -0
  389. package/dist/utils/tools-manager.d.ts.map +1 -1
  390. package/dist/utils/tools-manager.js +67 -22
  391. package/dist/utils/tools-manager.js.map +1 -1
  392. package/docs/compaction.md +6 -2
  393. package/docs/custom-provider.md +57 -9
  394. package/docs/development.md +3 -1
  395. package/docs/extensions.md +437 -67
  396. package/docs/json.md +5 -2
  397. package/docs/keybindings.md +108 -107
  398. package/docs/models.md +50 -2
  399. package/docs/packages.md +17 -10
  400. package/docs/prompt-templates.md +6 -6
  401. package/docs/providers.md +10 -1
  402. package/docs/rpc.md +78 -18
  403. package/docs/sdk.md +261 -96
  404. package/docs/settings.md +28 -3
  405. package/docs/skills.md +9 -4
  406. package/docs/terminal-setup.md +39 -3
  407. package/docs/tmux.md +61 -0
  408. package/docs/tree.md +15 -3
  409. package/docs/tui.md +2 -2
  410. package/examples/extensions/README.md +3 -0
  411. package/examples/extensions/antigravity-image-gen.ts +12 -7
  412. package/examples/extensions/built-in-tool-renderer.ts +246 -0
  413. package/examples/extensions/commands.ts +3 -3
  414. package/examples/extensions/custom-compaction.ts +17 -4
  415. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  416. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  417. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  418. package/examples/extensions/custom-provider-gitlab-duo/test.ts +2 -2
  419. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  420. package/examples/extensions/doom-overlay/doom/build.sh +2 -2
  421. package/examples/extensions/dynamic-tools.ts +74 -0
  422. package/examples/extensions/handoff.ts +5 -2
  423. package/examples/extensions/hello.ts +18 -17
  424. package/examples/extensions/hidden-thinking-label.ts +53 -0
  425. package/examples/extensions/minimal-mode.ts +14 -14
  426. package/examples/extensions/overlay-qa-tests.ts +468 -1
  427. package/examples/extensions/preset.ts +2 -3
  428. package/examples/extensions/provider-payload.ts +14 -0
  429. package/examples/extensions/qna.ts +5 -2
  430. package/examples/extensions/question.ts +2 -2
  431. package/examples/extensions/questionnaire.ts +2 -2
  432. package/examples/extensions/rpc-demo.ts +3 -9
  433. package/examples/extensions/sandbox/index.ts +6 -3
  434. package/examples/extensions/status-line.ts +0 -8
  435. package/examples/extensions/subagent/README.md +4 -4
  436. package/examples/extensions/subagent/agents.ts +2 -3
  437. package/examples/extensions/subagent/index.ts +30 -8
  438. package/examples/extensions/summarize.ts +15 -4
  439. package/examples/extensions/todo.ts +2 -4
  440. package/examples/extensions/tool-override.ts +10 -9
  441. package/examples/extensions/tools.ts +0 -5
  442. package/examples/extensions/trigger-compact.ts +11 -1
  443. package/examples/extensions/truncated-tool.ts +8 -5
  444. package/examples/extensions/widget-placement.ts +4 -12
  445. package/examples/extensions/with-deps/index.ts +1 -5
  446. package/examples/extensions/with-deps/package-lock.json +2 -2
  447. package/examples/extensions/with-deps/package.json +1 -1
  448. package/examples/sdk/02-custom-model.ts +2 -2
  449. package/examples/sdk/04-skills.ts +8 -2
  450. package/examples/sdk/08-prompt-templates.ts +4 -3
  451. package/examples/sdk/09-api-keys-and-oauth.ts +5 -5
  452. package/examples/sdk/10-settings.ts +13 -0
  453. package/examples/sdk/12-full-control.ts +2 -3
  454. package/examples/sdk/13-session-runtime.ts +67 -0
  455. package/examples/sdk/README.md +10 -7
  456. package/package.json +98 -94
  457. /package/examples/extensions/subagent/{commands → prompts}/implement-and-review.md +0 -0
  458. /package/examples/extensions/subagent/{commands → prompts}/implement.md +0 -0
  459. /package/examples/extensions/subagent/{commands → prompts}/scout-and-plan.md +0 -0
@@ -1,3 +1,4 @@
1
+ import type { Transport } from "@mariozechner/pi-ai";
1
2
  export interface CompactionSettings {
2
3
  enabled?: boolean;
3
4
  reserveTokens?: number;
@@ -5,6 +6,7 @@ export interface CompactionSettings {
5
6
  }
6
7
  export interface BranchSummarySettings {
7
8
  reserveTokens?: number;
9
+ skipPrompt?: boolean;
8
10
  }
9
11
  export interface RetrySettings {
10
12
  enabled?: boolean;
@@ -29,6 +31,7 @@ export interface ThinkingBudgetsSettings {
29
31
  export interface MarkdownSettings {
30
32
  codeBlockIndent?: string;
31
33
  }
34
+ export type TransportSetting = Transport;
32
35
  /**
33
36
  * Package source for npm/git packages.
34
37
  * - String form: load all resources from the package
@@ -38,7 +41,7 @@ export type PackageSource = string | {
38
41
  source: string;
39
42
  extensions?: string[];
40
43
  skills?: string[];
41
- commands?: string[];
44
+ prompts?: string[];
42
45
  themes?: string[];
43
46
  };
44
47
  export interface Settings {
@@ -46,6 +49,7 @@ export interface Settings {
46
49
  defaultProvider?: string;
47
50
  defaultModel?: string;
48
51
  defaultThinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
52
+ transport?: TransportSetting;
49
53
  steeringMode?: "all" | "one-at-a-time";
50
54
  followUpMode?: "all" | "one-at-a-time";
51
55
  theme?: string;
@@ -56,53 +60,91 @@ export interface Settings {
56
60
  shellPath?: string;
57
61
  quietStartup?: boolean;
58
62
  shellCommandPrefix?: string;
63
+ npmCommand?: string[];
59
64
  collapseChangelog?: boolean;
60
65
  packages?: PackageSource[];
61
66
  extensions?: string[];
62
67
  skills?: string[];
63
- commands?: string[];
68
+ prompts?: string[];
64
69
  themes?: string[];
65
70
  enableSkillCommands?: boolean;
66
71
  terminal?: TerminalSettings;
67
72
  images?: ImageSettings;
68
73
  enabledModels?: string[];
69
74
  doubleEscapeAction?: "fork" | "tree" | "none";
75
+ treeFilterMode?: "default" | "no-tools" | "user-only" | "labeled-only" | "all";
70
76
  thinkingBudgets?: ThinkingBudgetsSettings;
71
77
  editorPaddingX?: number;
72
78
  autocompleteMaxVisible?: number;
73
79
  showHardwareCursor?: boolean;
74
80
  markdown?: MarkdownSettings;
81
+ sessionDir?: string;
75
82
  }
76
- export declare class SettingsManager {
77
- private settingsPath;
83
+ export type SettingsScope = "global" | "project";
84
+ export interface SettingsStorage {
85
+ withLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void;
86
+ }
87
+ export interface SettingsError {
88
+ scope: SettingsScope;
89
+ error: Error;
90
+ }
91
+ export declare class FileSettingsStorage implements SettingsStorage {
92
+ private globalSettingsPath;
78
93
  private projectSettingsPath;
94
+ constructor(cwd?: string, agentDir?: string);
95
+ private acquireLockSyncWithRetry;
96
+ withLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void;
97
+ }
98
+ export declare class InMemorySettingsStorage implements SettingsStorage {
99
+ private global;
100
+ private project;
101
+ withLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void;
102
+ }
103
+ export declare class SettingsManager {
104
+ private storage;
79
105
  private globalSettings;
80
- private inMemoryProjectSettings;
106
+ private projectSettings;
81
107
  private settings;
82
- private persist;
83
108
  private modifiedFields;
84
109
  private modifiedNestedFields;
110
+ private modifiedProjectFields;
111
+ private modifiedProjectNestedFields;
85
112
  private globalSettingsLoadError;
113
+ private projectSettingsLoadError;
114
+ private writeQueue;
115
+ private errors;
86
116
  private constructor();
87
117
  /** Create a SettingsManager that loads from files */
88
118
  static create(cwd?: string, agentDir?: string): SettingsManager;
119
+ /** Create a SettingsManager from an arbitrary storage backend */
120
+ static fromStorage(storage: SettingsStorage): SettingsManager;
89
121
  /** Create an in-memory SettingsManager (no file I/O) */
90
122
  static inMemory(settings?: Partial<Settings>): SettingsManager;
91
- private static loadFromFile;
123
+ private static loadFromStorage;
124
+ private static tryLoadFromStorage;
92
125
  /** Migrate old settings format to new format */
93
126
  private static migrateSettings;
94
- private loadProjectSettings;
95
127
  getGlobalSettings(): Settings;
96
128
  getProjectSettings(): Settings;
97
- reload(): void;
129
+ reload(): Promise<void>;
98
130
  /** Apply additional overrides on top of current settings */
99
131
  applyOverrides(overrides: Partial<Settings>): void;
100
- /** Mark a field as modified during this session */
132
+ /** Mark a global field as modified during this session */
101
133
  private markModified;
134
+ /** Mark a project field as modified during this session */
135
+ private markProjectModified;
136
+ private recordError;
137
+ private clearModifiedScope;
138
+ private enqueueWrite;
139
+ private cloneModifiedNestedFields;
140
+ private persistScopedSettings;
102
141
  private save;
103
142
  private saveProjectSettings;
143
+ flush(): Promise<void>;
144
+ drainErrors(): SettingsError[];
104
145
  getLastChangelogVersion(): string | undefined;
105
146
  setLastChangelogVersion(version: string): void;
147
+ getSessionDir(): string | undefined;
106
148
  getDefaultProvider(): string | undefined;
107
149
  getDefaultModel(): string | undefined;
108
150
  setDefaultProvider(provider: string): void;
@@ -116,6 +158,8 @@ export declare class SettingsManager {
116
158
  setTheme(theme: string): void;
117
159
  getDefaultThinkingLevel(): "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined;
118
160
  setDefaultThinkingLevel(level: "off" | "minimal" | "low" | "medium" | "high" | "xhigh"): void;
161
+ getTransport(): TransportSetting;
162
+ setTransport(transport: TransportSetting): void;
119
163
  getCompactionEnabled(): boolean;
120
164
  setCompactionEnabled(enabled: boolean): void;
121
165
  getCompactionReserveTokens(): number;
@@ -127,7 +171,9 @@ export declare class SettingsManager {
127
171
  };
128
172
  getBranchSummarySettings(): {
129
173
  reserveTokens: number;
174
+ skipPrompt: boolean;
130
175
  };
176
+ getBranchSummarySkipPrompt(): boolean;
131
177
  getRetryEnabled(): boolean;
132
178
  setRetryEnabled(enabled: boolean): void;
133
179
  getRetrySettings(): {
@@ -144,6 +190,8 @@ export declare class SettingsManager {
144
190
  setQuietStartup(quiet: boolean): void;
145
191
  getShellCommandPrefix(): string | undefined;
146
192
  setShellCommandPrefix(prefix: string | undefined): void;
193
+ getNpmCommand(): string[] | undefined;
194
+ setNpmCommand(command: string[] | undefined): void;
147
195
  getCollapseChangelog(): boolean;
148
196
  setCollapseChangelog(collapse: boolean): void;
149
197
  getPackages(): PackageSource[];
@@ -176,6 +224,8 @@ export declare class SettingsManager {
176
224
  setEnabledModels(patterns: string[] | undefined): void;
177
225
  getDoubleEscapeAction(): "fork" | "tree" | "none";
178
226
  setDoubleEscapeAction(action: "fork" | "tree" | "none"): void;
227
+ getTreeFilterMode(): "default" | "no-tools" | "user-only" | "labeled-only" | "all";
228
+ setTreeFilterMode(mode: "default" | "no-tools" | "user-only" | "labeled-only" | "all"): void;
179
229
  getShowHardwareCursor(): boolean;
180
230
  setShowHardwareCursor(enabled: boolean): void;
181
231
  getEditorPaddingX(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"settings-manager.d.ts","sourceRoot":"","sources":["../../src/core/settings-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { CONFIG_DIR_NAME, getAgentDir } from \"../config.js\";\n\nexport interface CompactionSettings {\n\tenabled?: boolean; // default: true\n\treserveTokens?: number; // default: 16384\n\tkeepRecentTokens?: number; // default: 20000\n}\n\nexport interface BranchSummarySettings {\n\treserveTokens?: number; // default: 16384 (tokens reserved for prompt + LLM response)\n}\n\nexport interface RetrySettings {\n\tenabled?: boolean; // default: true\n\tmaxRetries?: number; // default: 3\n\tbaseDelayMs?: number; // default: 2000 (exponential backoff: 2s, 4s, 8s)\n\tmaxDelayMs?: number; // default: 60000 (max server-requested delay before failing)\n}\n\nexport interface TerminalSettings {\n\tshowImages?: boolean; // default: true (only relevant if terminal supports images)\n\tclearOnShrink?: boolean; // default: false (clear empty rows when content shrinks)\n}\n\nexport interface ImageSettings {\n\tautoResize?: boolean; // default: true (resize images to 2000x2000 max for better model compatibility)\n\tblockImages?: boolean; // default: false - when true, prevents all images from being sent to LLM providers\n}\n\nexport interface ThinkingBudgetsSettings {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\nexport interface MarkdownSettings {\n\tcodeBlockIndent?: string; // default: \" \"\n}\n\n/**\n * Package source for npm/git packages.\n * - String form: load all resources from the package\n * - Object form: filter which resources to load\n */\nexport type PackageSource =\n\t| string\n\t| {\n\t\t\tsource: string;\n\t\t\textensions?: string[];\n\t\t\tskills?: string[];\n\t\t\tcommands?: string[];\n\t\t\tthemes?: string[];\n\t };\n\nexport interface Settings {\n\tlastChangelogVersion?: string;\n\tdefaultProvider?: string;\n\tdefaultModel?: string;\n\tdefaultThinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\tsteeringMode?: \"all\" | \"one-at-a-time\";\n\tfollowUpMode?: \"all\" | \"one-at-a-time\";\n\ttheme?: string;\n\tcompaction?: CompactionSettings;\n\tbranchSummary?: BranchSummarySettings;\n\tretry?: RetrySettings;\n\thideThinkingBlock?: boolean;\n\tshellPath?: string; // Custom shell path (e.g., for Cygwin users on Windows)\n\tquietStartup?: boolean;\n\tshellCommandPrefix?: string; // Prefix prepended to every bash command (e.g., \"shopt -s expand_aliases\" for alias support)\n\tcollapseChangelog?: boolean; // Show condensed changelog after update (use /changelog for full)\n\tpackages?: PackageSource[]; // Array of npm/git package sources (string or object with filtering)\n\textensions?: string[]; // Array of local extension file paths or directories\n\tskills?: string[]; // Array of local skill file paths or directories\n\tcommands?: string[]; // Array of local command template paths or directories\n\tthemes?: string[]; // Array of local theme file paths or directories\n\tenableSkillCommands?: boolean; // default: true - register skills as /skill:name commands\n\tterminal?: TerminalSettings;\n\timages?: ImageSettings;\n\tenabledModels?: string[]; // Model patterns for cycling (same format as --models CLI flag)\n\tdoubleEscapeAction?: \"fork\" | \"tree\" | \"none\"; // Action for double-escape with empty editor (default: \"tree\")\n\tthinkingBudgets?: ThinkingBudgetsSettings; // Custom token budgets for thinking levels\n\teditorPaddingX?: number; // Horizontal padding for input editor (default: 0)\n\tautocompleteMaxVisible?: number; // Max visible items in autocomplete dropdown (default: 5)\n\tshowHardwareCursor?: boolean; // Show terminal cursor while still positioning it for IME\n\tmarkdown?: MarkdownSettings;\n}\n\n/** Deep merge settings: project/overrides take precedence, nested objects merge recursively */\nfunction deepMergeSettings(base: Settings, overrides: Settings): Settings {\n\tconst result: Settings = { ...base };\n\n\tfor (const key of Object.keys(overrides) as (keyof Settings)[]) {\n\t\tconst overrideValue = overrides[key];\n\t\tconst baseValue = base[key];\n\n\t\tif (overrideValue === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// For nested objects, merge recursively\n\t\tif (\n\t\t\ttypeof overrideValue === \"object\" &&\n\t\t\toverrideValue !== null &&\n\t\t\t!Array.isArray(overrideValue) &&\n\t\t\ttypeof baseValue === \"object\" &&\n\t\t\tbaseValue !== null &&\n\t\t\t!Array.isArray(baseValue)\n\t\t) {\n\t\t\t(result as Record<string, unknown>)[key] = { ...baseValue, ...overrideValue };\n\t\t} else {\n\t\t\t// For primitives and arrays, override value wins\n\t\t\t(result as Record<string, unknown>)[key] = overrideValue;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport class SettingsManager {\n\tprivate settingsPath: string | null;\n\tprivate projectSettingsPath: string | null;\n\tprivate globalSettings: Settings;\n\tprivate inMemoryProjectSettings: Settings; // For in-memory mode\n\tprivate settings: Settings;\n\tprivate persist: boolean;\n\tprivate modifiedFields = new Set<keyof Settings>(); // Track fields modified during session\n\tprivate modifiedNestedFields = new Map<keyof Settings, Set<string>>(); // Track nested field modifications\n\tprivate globalSettingsLoadError: Error | null = null; // Track if settings file had parse errors\n\n\tprivate constructor(\n\t\tsettingsPath: string | null,\n\t\tprojectSettingsPath: string | null,\n\t\tinitialSettings: Settings,\n\t\tpersist: boolean,\n\t\tloadError: Error | null = null,\n\t) {\n\t\tthis.settingsPath = settingsPath;\n\t\tthis.projectSettingsPath = projectSettingsPath;\n\t\tthis.persist = persist;\n\t\tthis.globalSettings = initialSettings;\n\t\tthis.inMemoryProjectSettings = {};\n\t\tthis.globalSettingsLoadError = loadError;\n\t\tconst projectSettings = this.loadProjectSettings();\n\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t}\n\n\t/** Create a SettingsManager that loads from files */\n\tstatic create(cwd: string = process.cwd(), agentDir: string = getAgentDir()): SettingsManager {\n\t\tconst settingsPath = join(agentDir, \"settings.json\");\n\t\tconst projectSettingsPath = join(cwd, CONFIG_DIR_NAME, \"settings.json\");\n\n\t\tlet globalSettings: Settings = {};\n\t\tlet loadError: Error | null = null;\n\n\t\ttry {\n\t\t\tglobalSettings = SettingsManager.loadFromFile(settingsPath);\n\t\t} catch (error) {\n\t\t\tloadError = error as Error;\n\t\t\tconsole.error(`Warning: Invalid JSON in ${settingsPath}: ${error}`);\n\t\t\tconsole.error(`Fix the syntax error to enable settings persistence.`);\n\t\t}\n\n\t\treturn new SettingsManager(settingsPath, projectSettingsPath, globalSettings, true, loadError);\n\t}\n\n\t/** Create an in-memory SettingsManager (no file I/O) */\n\tstatic inMemory(settings: Partial<Settings> = {}): SettingsManager {\n\t\treturn new SettingsManager(null, null, settings, false);\n\t}\n\n\tprivate static loadFromFile(path: string): Settings {\n\t\tif (!existsSync(path)) {\n\t\t\treturn {};\n\t\t}\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst settings = JSON.parse(content);\n\t\treturn SettingsManager.migrateSettings(settings);\n\t}\n\n\t/** Migrate old settings format to new format */\n\tprivate static migrateSettings(settings: Record<string, unknown>): Settings {\n\t\t// Migrate queueMode -> steeringMode\n\t\tif (\"queueMode\" in settings && !(\"steeringMode\" in settings)) {\n\t\t\tsettings.steeringMode = settings.queueMode;\n\t\t\tdelete settings.queueMode;\n\t\t}\n\n\t\t// Migrate old skills object format to new array format\n\t\tif (\n\t\t\t\"skills\" in settings &&\n\t\t\ttypeof settings.skills === \"object\" &&\n\t\t\tsettings.skills !== null &&\n\t\t\t!Array.isArray(settings.skills)\n\t\t) {\n\t\t\tconst skillsSettings = settings.skills as {\n\t\t\t\tenableSkillCommands?: boolean;\n\t\t\t\tcustomDirectories?: unknown;\n\t\t\t};\n\t\t\tif (skillsSettings.enableSkillCommands !== undefined && settings.enableSkillCommands === undefined) {\n\t\t\t\tsettings.enableSkillCommands = skillsSettings.enableSkillCommands;\n\t\t\t}\n\t\t\tif (Array.isArray(skillsSettings.customDirectories) && skillsSettings.customDirectories.length > 0) {\n\t\t\t\tsettings.skills = skillsSettings.customDirectories;\n\t\t\t} else {\n\t\t\t\tdelete settings.skills;\n\t\t\t}\n\t\t}\n\n\t\treturn settings as Settings;\n\t}\n\n\tprivate loadProjectSettings(): Settings {\n\t\t// In-memory mode: return stored in-memory project settings\n\t\tif (!this.persist) {\n\t\t\treturn structuredClone(this.inMemoryProjectSettings);\n\t\t}\n\n\t\tif (!this.projectSettingsPath || !existsSync(this.projectSettingsPath)) {\n\t\t\treturn {};\n\t\t}\n\n\t\ttry {\n\t\t\tconst content = readFileSync(this.projectSettingsPath, \"utf-8\");\n\t\t\tconst settings = JSON.parse(content);\n\t\t\treturn SettingsManager.migrateSettings(settings);\n\t\t} catch (error) {\n\t\t\tconsole.error(`Warning: Could not read project settings file: ${error}`);\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tgetGlobalSettings(): Settings {\n\t\treturn structuredClone(this.globalSettings);\n\t}\n\n\tgetProjectSettings(): Settings {\n\t\treturn this.loadProjectSettings();\n\t}\n\n\treload(): void {\n\t\tlet nextGlobalSettings: Settings | null = null;\n\n\t\tif (this.persist && this.settingsPath) {\n\t\t\ttry {\n\t\t\t\tnextGlobalSettings = SettingsManager.loadFromFile(this.settingsPath);\n\t\t\t\tthis.globalSettingsLoadError = null;\n\t\t\t} catch (error) {\n\t\t\t\tthis.globalSettingsLoadError = error as Error;\n\t\t\t}\n\t\t}\n\n\t\tif (nextGlobalSettings) {\n\t\t\tthis.globalSettings = nextGlobalSettings;\n\t\t}\n\n\t\tthis.modifiedFields.clear();\n\t\tthis.modifiedNestedFields.clear();\n\n\t\tconst projectSettings = this.loadProjectSettings();\n\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t}\n\n\t/** Apply additional overrides on top of current settings */\n\tapplyOverrides(overrides: Partial<Settings>): void {\n\t\tthis.settings = deepMergeSettings(this.settings, overrides);\n\t}\n\n\t/** Mark a field as modified during this session */\n\tprivate markModified(field: keyof Settings, nestedKey?: string): void {\n\t\tthis.modifiedFields.add(field);\n\t\tif (nestedKey) {\n\t\t\tif (!this.modifiedNestedFields.has(field)) {\n\t\t\t\tthis.modifiedNestedFields.set(field, new Set());\n\t\t\t}\n\t\t\tthis.modifiedNestedFields.get(field)!.add(nestedKey);\n\t\t}\n\t}\n\n\tprivate save(): void {\n\t\tif (this.persist && this.settingsPath) {\n\t\t\t// Don't overwrite if the file had parse errors on initial load\n\t\t\tif (this.globalSettingsLoadError) {\n\t\t\t\t// Re-merge to update active settings even though we can't persist\n\t\t\t\tconst projectSettings = this.loadProjectSettings();\n\t\t\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst dir = dirname(this.settingsPath);\n\t\t\t\tif (!existsSync(dir)) {\n\t\t\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\t\t}\n\n\t\t\t\t// Re-read current file to get latest external changes\n\t\t\t\tconst currentFileSettings = SettingsManager.loadFromFile(this.settingsPath);\n\n\t\t\t\t// Start with file settings as base - preserves external edits\n\t\t\t\tconst mergedSettings: Settings = { ...currentFileSettings };\n\n\t\t\t\t// Only override with in-memory values for fields that were explicitly modified during this session\n\t\t\t\tfor (const field of this.modifiedFields) {\n\t\t\t\t\tconst value = this.globalSettings[field];\n\n\t\t\t\t\t// Handle nested objects specially - merge at nested level to preserve unmodified nested keys\n\t\t\t\t\tif (this.modifiedNestedFields.has(field) && typeof value === \"object\" && value !== null) {\n\t\t\t\t\t\tconst nestedModified = this.modifiedNestedFields.get(field)!;\n\t\t\t\t\t\tconst baseNested = (currentFileSettings[field] as Record<string, unknown>) ?? {};\n\t\t\t\t\t\tconst inMemoryNested = value as Record<string, unknown>;\n\t\t\t\t\t\tconst mergedNested = { ...baseNested };\n\t\t\t\t\t\tfor (const nestedKey of nestedModified) {\n\t\t\t\t\t\t\tmergedNested[nestedKey] = inMemoryNested[nestedKey];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t(mergedSettings as Record<string, unknown>)[field] = mergedNested;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// For top-level primitives and arrays, use the modified value directly\n\t\t\t\t\t\t(mergedSettings as Record<string, unknown>)[field] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.globalSettings = mergedSettings;\n\t\t\t\twriteFileSync(this.settingsPath, JSON.stringify(this.globalSettings, null, 2), \"utf-8\");\n\t\t\t} catch (error) {\n\t\t\t\t// File may have been externally modified with invalid JSON - don't overwrite\n\t\t\t\tconsole.error(`Warning: Could not save settings file: ${error}`);\n\t\t\t}\n\t\t}\n\n\t\t// Always re-merge to update active settings (needed for both file and inMemory modes)\n\t\tconst projectSettings = this.loadProjectSettings();\n\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t}\n\n\tprivate saveProjectSettings(settings: Settings): void {\n\t\t// In-memory mode: store in memory\n\t\tif (!this.persist) {\n\t\t\tthis.inMemoryProjectSettings = structuredClone(settings);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.projectSettingsPath) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst dir = dirname(this.projectSettingsPath);\n\t\t\tif (!existsSync(dir)) {\n\t\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\t}\n\t\t\twriteFileSync(this.projectSettingsPath, JSON.stringify(settings, null, 2), \"utf-8\");\n\t\t} catch (error) {\n\t\t\tconsole.error(`Warning: Could not save project settings file: ${error}`);\n\t\t}\n\t}\n\n\tgetLastChangelogVersion(): string | undefined {\n\t\treturn this.settings.lastChangelogVersion;\n\t}\n\n\tsetLastChangelogVersion(version: string): void {\n\t\tthis.globalSettings.lastChangelogVersion = version;\n\t\tthis.markModified(\"lastChangelogVersion\");\n\t\tthis.save();\n\t}\n\n\tgetDefaultProvider(): string | undefined {\n\t\treturn this.settings.defaultProvider;\n\t}\n\n\tgetDefaultModel(): string | undefined {\n\t\treturn this.settings.defaultModel;\n\t}\n\n\tsetDefaultProvider(provider: string): void {\n\t\tthis.globalSettings.defaultProvider = provider;\n\t\tthis.markModified(\"defaultProvider\");\n\t\tthis.save();\n\t}\n\n\tsetDefaultModel(modelId: string): void {\n\t\tthis.globalSettings.defaultModel = modelId;\n\t\tthis.markModified(\"defaultModel\");\n\t\tthis.save();\n\t}\n\n\tsetDefaultModelAndProvider(provider: string, modelId: string): void {\n\t\tthis.globalSettings.defaultProvider = provider;\n\t\tthis.globalSettings.defaultModel = modelId;\n\t\tthis.markModified(\"defaultProvider\");\n\t\tthis.markModified(\"defaultModel\");\n\t\tthis.save();\n\t}\n\n\tgetSteeringMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.settings.steeringMode || \"one-at-a-time\";\n\t}\n\n\tsetSteeringMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.globalSettings.steeringMode = mode;\n\t\tthis.markModified(\"steeringMode\");\n\t\tthis.save();\n\t}\n\n\tgetFollowUpMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.settings.followUpMode || \"one-at-a-time\";\n\t}\n\n\tsetFollowUpMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.globalSettings.followUpMode = mode;\n\t\tthis.markModified(\"followUpMode\");\n\t\tthis.save();\n\t}\n\n\tgetTheme(): string | undefined {\n\t\treturn this.settings.theme;\n\t}\n\n\tsetTheme(theme: string): void {\n\t\tthis.globalSettings.theme = theme;\n\t\tthis.markModified(\"theme\");\n\t\tthis.save();\n\t}\n\n\tgetDefaultThinkingLevel(): \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | undefined {\n\t\treturn this.settings.defaultThinkingLevel;\n\t}\n\n\tsetDefaultThinkingLevel(level: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\"): void {\n\t\tthis.globalSettings.defaultThinkingLevel = level;\n\t\tthis.markModified(\"defaultThinkingLevel\");\n\t\tthis.save();\n\t}\n\n\tgetCompactionEnabled(): boolean {\n\t\treturn this.settings.compaction?.enabled ?? true;\n\t}\n\n\tsetCompactionEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.compaction) {\n\t\t\tthis.globalSettings.compaction = {};\n\t\t}\n\t\tthis.globalSettings.compaction.enabled = enabled;\n\t\tthis.markModified(\"compaction\", \"enabled\");\n\t\tthis.save();\n\t}\n\n\tgetCompactionReserveTokens(): number {\n\t\treturn this.settings.compaction?.reserveTokens ?? 16384;\n\t}\n\n\tgetCompactionKeepRecentTokens(): number {\n\t\treturn this.settings.compaction?.keepRecentTokens ?? 20000;\n\t}\n\n\tgetCompactionSettings(): { enabled: boolean; reserveTokens: number; keepRecentTokens: number } {\n\t\treturn {\n\t\t\tenabled: this.getCompactionEnabled(),\n\t\t\treserveTokens: this.getCompactionReserveTokens(),\n\t\t\tkeepRecentTokens: this.getCompactionKeepRecentTokens(),\n\t\t};\n\t}\n\n\tgetBranchSummarySettings(): { reserveTokens: number } {\n\t\treturn {\n\t\t\treserveTokens: this.settings.branchSummary?.reserveTokens ?? 16384,\n\t\t};\n\t}\n\n\tgetRetryEnabled(): boolean {\n\t\treturn this.settings.retry?.enabled ?? true;\n\t}\n\n\tsetRetryEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.retry) {\n\t\t\tthis.globalSettings.retry = {};\n\t\t}\n\t\tthis.globalSettings.retry.enabled = enabled;\n\t\tthis.markModified(\"retry\", \"enabled\");\n\t\tthis.save();\n\t}\n\n\tgetRetrySettings(): { enabled: boolean; maxRetries: number; baseDelayMs: number; maxDelayMs: number } {\n\t\treturn {\n\t\t\tenabled: this.getRetryEnabled(),\n\t\t\tmaxRetries: this.settings.retry?.maxRetries ?? 3,\n\t\t\tbaseDelayMs: this.settings.retry?.baseDelayMs ?? 2000,\n\t\t\tmaxDelayMs: this.settings.retry?.maxDelayMs ?? 60000,\n\t\t};\n\t}\n\n\tgetHideThinkingBlock(): boolean {\n\t\treturn this.settings.hideThinkingBlock ?? false;\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.globalSettings.hideThinkingBlock = hide;\n\t\tthis.markModified(\"hideThinkingBlock\");\n\t\tthis.save();\n\t}\n\n\tgetShellPath(): string | undefined {\n\t\treturn this.settings.shellPath;\n\t}\n\n\tsetShellPath(path: string | undefined): void {\n\t\tthis.globalSettings.shellPath = path;\n\t\tthis.markModified(\"shellPath\");\n\t\tthis.save();\n\t}\n\n\tgetQuietStartup(): boolean {\n\t\treturn this.settings.quietStartup ?? false;\n\t}\n\n\tsetQuietStartup(quiet: boolean): void {\n\t\tthis.globalSettings.quietStartup = quiet;\n\t\tthis.markModified(\"quietStartup\");\n\t\tthis.save();\n\t}\n\n\tgetShellCommandPrefix(): string | undefined {\n\t\treturn this.settings.shellCommandPrefix;\n\t}\n\n\tsetShellCommandPrefix(prefix: string | undefined): void {\n\t\tthis.globalSettings.shellCommandPrefix = prefix;\n\t\tthis.markModified(\"shellCommandPrefix\");\n\t\tthis.save();\n\t}\n\n\tgetCollapseChangelog(): boolean {\n\t\treturn this.settings.collapseChangelog ?? false;\n\t}\n\n\tsetCollapseChangelog(collapse: boolean): void {\n\t\tthis.globalSettings.collapseChangelog = collapse;\n\t\tthis.markModified(\"collapseChangelog\");\n\t\tthis.save();\n\t}\n\n\tgetPackages(): PackageSource[] {\n\t\treturn [...(this.settings.packages ?? [])];\n\t}\n\n\tsetPackages(packages: PackageSource[]): void {\n\t\tthis.globalSettings.packages = packages;\n\t\tthis.markModified(\"packages\");\n\t\tthis.save();\n\t}\n\n\tsetProjectPackages(packages: PackageSource[]): void {\n\t\tconst projectSettings = this.loadProjectSettings();\n\t\tprojectSettings.packages = packages;\n\t\tthis.saveProjectSettings(projectSettings);\n\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t}\n\n\tgetExtensionPaths(): string[] {\n\t\treturn [...(this.settings.extensions ?? [])];\n\t}\n\n\tsetExtensionPaths(paths: string[]): void {\n\t\tthis.globalSettings.extensions = paths;\n\t\tthis.markModified(\"extensions\");\n\t\tthis.save();\n\t}\n\n\tsetProjectExtensionPaths(paths: string[]): void {\n\t\tconst projectSettings = this.loadProjectSettings();\n\t\tprojectSettings.extensions = paths;\n\t\tthis.saveProjectSettings(projectSettings);\n\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t}\n\n\tgetSkillPaths(): string[] {\n\t\treturn [...(this.settings.skills ?? [])];\n\t}\n\n\tsetSkillPaths(paths: string[]): void {\n\t\tthis.globalSettings.skills = paths;\n\t\tthis.markModified(\"skills\");\n\t\tthis.save();\n\t}\n\n\tsetProjectSkillPaths(paths: string[]): void {\n\t\tconst projectSettings = this.loadProjectSettings();\n\t\tprojectSettings.skills = paths;\n\t\tthis.saveProjectSettings(projectSettings);\n\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t}\n\n\tgetPromptTemplatePaths(): string[] {\n\t\treturn [...(this.settings.commands ?? [])];\n\t}\n\n\tsetPromptTemplatePaths(paths: string[]): void {\n\t\tthis.globalSettings.commands = paths;\n\t\tthis.markModified(\"commands\");\n\t\tthis.save();\n\t}\n\n\tsetProjectPromptTemplatePaths(paths: string[]): void {\n\t\tconst projectSettings = this.loadProjectSettings();\n\t\tprojectSettings.commands = paths;\n\t\tthis.saveProjectSettings(projectSettings);\n\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t}\n\n\tgetThemePaths(): string[] {\n\t\treturn [...(this.settings.themes ?? [])];\n\t}\n\n\tsetThemePaths(paths: string[]): void {\n\t\tthis.globalSettings.themes = paths;\n\t\tthis.markModified(\"themes\");\n\t\tthis.save();\n\t}\n\n\tsetProjectThemePaths(paths: string[]): void {\n\t\tconst projectSettings = this.loadProjectSettings();\n\t\tprojectSettings.themes = paths;\n\t\tthis.saveProjectSettings(projectSettings);\n\t\tthis.settings = deepMergeSettings(this.globalSettings, projectSettings);\n\t}\n\n\tgetEnableSkillCommands(): boolean {\n\t\treturn this.settings.enableSkillCommands ?? true;\n\t}\n\n\tsetEnableSkillCommands(enabled: boolean): void {\n\t\tthis.globalSettings.enableSkillCommands = enabled;\n\t\tthis.markModified(\"enableSkillCommands\");\n\t\tthis.save();\n\t}\n\n\tgetThinkingBudgets(): ThinkingBudgetsSettings | undefined {\n\t\treturn this.settings.thinkingBudgets;\n\t}\n\n\tgetShowImages(): boolean {\n\t\treturn this.settings.terminal?.showImages ?? true;\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tif (!this.globalSettings.terminal) {\n\t\t\tthis.globalSettings.terminal = {};\n\t\t}\n\t\tthis.globalSettings.terminal.showImages = show;\n\t\tthis.markModified(\"terminal\", \"showImages\");\n\t\tthis.save();\n\t}\n\n\tgetClearOnShrink(): boolean {\n\t\t// Settings takes precedence, then env var, then default false\n\t\tif (this.settings.terminal?.clearOnShrink !== undefined) {\n\t\t\treturn this.settings.terminal.clearOnShrink;\n\t\t}\n\t\treturn process.env.PI_CLEAR_ON_SHRINK === \"1\";\n\t}\n\n\tsetClearOnShrink(enabled: boolean): void {\n\t\tif (!this.globalSettings.terminal) {\n\t\t\tthis.globalSettings.terminal = {};\n\t\t}\n\t\tthis.globalSettings.terminal.clearOnShrink = enabled;\n\t\tthis.markModified(\"terminal\", \"clearOnShrink\");\n\t\tthis.save();\n\t}\n\n\tgetImageAutoResize(): boolean {\n\t\treturn this.settings.images?.autoResize ?? true;\n\t}\n\n\tsetImageAutoResize(enabled: boolean): void {\n\t\tif (!this.globalSettings.images) {\n\t\t\tthis.globalSettings.images = {};\n\t\t}\n\t\tthis.globalSettings.images.autoResize = enabled;\n\t\tthis.markModified(\"images\", \"autoResize\");\n\t\tthis.save();\n\t}\n\n\tgetBlockImages(): boolean {\n\t\treturn this.settings.images?.blockImages ?? false;\n\t}\n\n\tsetBlockImages(blocked: boolean): void {\n\t\tif (!this.globalSettings.images) {\n\t\t\tthis.globalSettings.images = {};\n\t\t}\n\t\tthis.globalSettings.images.blockImages = blocked;\n\t\tthis.markModified(\"images\", \"blockImages\");\n\t\tthis.save();\n\t}\n\n\tgetEnabledModels(): string[] | undefined {\n\t\treturn this.settings.enabledModels;\n\t}\n\n\tsetEnabledModels(patterns: string[] | undefined): void {\n\t\tthis.globalSettings.enabledModels = patterns;\n\t\tthis.markModified(\"enabledModels\");\n\t\tthis.save();\n\t}\n\n\tgetDoubleEscapeAction(): \"fork\" | \"tree\" | \"none\" {\n\t\treturn this.settings.doubleEscapeAction ?? \"tree\";\n\t}\n\n\tsetDoubleEscapeAction(action: \"fork\" | \"tree\" | \"none\"): void {\n\t\tthis.globalSettings.doubleEscapeAction = action;\n\t\tthis.markModified(\"doubleEscapeAction\");\n\t\tthis.save();\n\t}\n\n\tgetShowHardwareCursor(): boolean {\n\t\treturn this.settings.showHardwareCursor ?? process.env.PI_HARDWARE_CURSOR === \"1\";\n\t}\n\n\tsetShowHardwareCursor(enabled: boolean): void {\n\t\tthis.globalSettings.showHardwareCursor = enabled;\n\t\tthis.markModified(\"showHardwareCursor\");\n\t\tthis.save();\n\t}\n\n\tgetEditorPaddingX(): number {\n\t\treturn this.settings.editorPaddingX ?? 0;\n\t}\n\n\tsetEditorPaddingX(padding: number): void {\n\t\tthis.globalSettings.editorPaddingX = Math.max(0, Math.min(3, Math.floor(padding)));\n\t\tthis.markModified(\"editorPaddingX\");\n\t\tthis.save();\n\t}\n\n\tgetAutocompleteMaxVisible(): number {\n\t\treturn this.settings.autocompleteMaxVisible ?? 5;\n\t}\n\n\tsetAutocompleteMaxVisible(maxVisible: number): void {\n\t\tthis.globalSettings.autocompleteMaxVisible = Math.max(3, Math.min(20, Math.floor(maxVisible)));\n\t\tthis.markModified(\"autocompleteMaxVisible\");\n\t\tthis.save();\n\t}\n\n\tgetCodeBlockIndent(): string {\n\t\treturn this.settings.markdown?.codeBlockIndent ?? \" \";\n\t}\n}\n"]}
1
+ {"version":3,"file":"settings-manager.d.ts","sourceRoot":"","sources":["../../src/core/settings-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Transport } from \"@mariozechner/pi-ai\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { CONFIG_DIR_NAME, getAgentDir } from \"../config.js\";\n\nexport interface CompactionSettings {\n\tenabled?: boolean; // default: true\n\treserveTokens?: number; // default: 16384\n\tkeepRecentTokens?: number; // default: 20000\n}\n\nexport interface BranchSummarySettings {\n\treserveTokens?: number; // default: 16384 (tokens reserved for prompt + LLM response)\n\tskipPrompt?: boolean; // default: false - when true, skips \"Summarize branch?\" prompt and defaults to no summary\n}\n\nexport interface RetrySettings {\n\tenabled?: boolean; // default: true\n\tmaxRetries?: number; // default: 3\n\tbaseDelayMs?: number; // default: 2000 (exponential backoff: 2s, 4s, 8s)\n\tmaxDelayMs?: number; // default: 60000 (max server-requested delay before failing)\n}\n\nexport interface TerminalSettings {\n\tshowImages?: boolean; // default: true (only relevant if terminal supports images)\n\tclearOnShrink?: boolean; // default: false (clear empty rows when content shrinks)\n}\n\nexport interface ImageSettings {\n\tautoResize?: boolean; // default: true (resize images to 2000x2000 max for better model compatibility)\n\tblockImages?: boolean; // default: false - when true, prevents all images from being sent to LLM providers\n}\n\nexport interface ThinkingBudgetsSettings {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\nexport interface MarkdownSettings {\n\tcodeBlockIndent?: string; // default: \" \"\n}\n\nexport type TransportSetting = Transport;\n\n/**\n * Package source for npm/git packages.\n * - String form: load all resources from the package\n * - Object form: filter which resources to load\n */\nexport type PackageSource =\n\t| string\n\t| {\n\t\t\tsource: string;\n\t\t\textensions?: string[];\n\t\t\tskills?: string[];\n\t\t\tprompts?: string[];\n\t\t\tthemes?: string[];\n\t };\n\nexport interface Settings {\n\tlastChangelogVersion?: string;\n\tdefaultProvider?: string;\n\tdefaultModel?: string;\n\tdefaultThinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\ttransport?: TransportSetting; // default: \"sse\"\n\tsteeringMode?: \"all\" | \"one-at-a-time\";\n\tfollowUpMode?: \"all\" | \"one-at-a-time\";\n\ttheme?: string;\n\tcompaction?: CompactionSettings;\n\tbranchSummary?: BranchSummarySettings;\n\tretry?: RetrySettings;\n\thideThinkingBlock?: boolean;\n\tshellPath?: string; // Custom shell path (e.g., for Cygwin users on Windows)\n\tquietStartup?: boolean;\n\tshellCommandPrefix?: string; // Prefix prepended to every bash command (e.g., \"shopt -s expand_aliases\" for alias support)\n\tnpmCommand?: string[]; // Command used for npm package lookup/install operations, argv-style (e.g., [\"mise\", \"exec\", \"node@20\", \"--\", \"npm\"])\n\tcollapseChangelog?: boolean; // Show condensed changelog after update (use /changelog for full)\n\tpackages?: PackageSource[]; // Array of npm/git package sources (string or object with filtering)\n\textensions?: string[]; // Array of local extension file paths or directories\n\tskills?: string[]; // Array of local skill file paths or directories\n\tprompts?: string[]; // Array of local prompt template paths or directories\n\tthemes?: string[]; // Array of local theme file paths or directories\n\tenableSkillCommands?: boolean; // default: true - register skills as /skill:name commands\n\tterminal?: TerminalSettings;\n\timages?: ImageSettings;\n\tenabledModels?: string[]; // Model patterns for cycling (same format as --models CLI flag)\n\tdoubleEscapeAction?: \"fork\" | \"tree\" | \"none\"; // Action for double-escape with empty editor (default: \"tree\")\n\ttreeFilterMode?: \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\"; // Default filter when opening /tree\n\tthinkingBudgets?: ThinkingBudgetsSettings; // Custom token budgets for thinking levels\n\teditorPaddingX?: number; // Horizontal padding for input editor (default: 0)\n\tautocompleteMaxVisible?: number; // Max visible items in autocomplete dropdown (default: 5)\n\tshowHardwareCursor?: boolean; // Show terminal cursor while still positioning it for IME\n\tmarkdown?: MarkdownSettings;\n\tsessionDir?: string; // Custom session storage directory (same format as --session-dir CLI flag)\n}\n\n/** Deep merge settings: project/overrides take precedence, nested objects merge recursively */\nfunction deepMergeSettings(base: Settings, overrides: Settings): Settings {\n\tconst result: Settings = { ...base };\n\n\tfor (const key of Object.keys(overrides) as (keyof Settings)[]) {\n\t\tconst overrideValue = overrides[key];\n\t\tconst baseValue = base[key];\n\n\t\tif (overrideValue === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// For nested objects, merge recursively\n\t\tif (\n\t\t\ttypeof overrideValue === \"object\" &&\n\t\t\toverrideValue !== null &&\n\t\t\t!Array.isArray(overrideValue) &&\n\t\t\ttypeof baseValue === \"object\" &&\n\t\t\tbaseValue !== null &&\n\t\t\t!Array.isArray(baseValue)\n\t\t) {\n\t\t\t(result as Record<string, unknown>)[key] = { ...baseValue, ...overrideValue };\n\t\t} else {\n\t\t\t// For primitives and arrays, override value wins\n\t\t\t(result as Record<string, unknown>)[key] = overrideValue;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport type SettingsScope = \"global\" | \"project\";\n\nexport interface SettingsStorage {\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void;\n}\n\nexport interface SettingsError {\n\tscope: SettingsScope;\n\terror: Error;\n}\n\nexport class FileSettingsStorage implements SettingsStorage {\n\tprivate globalSettingsPath: string;\n\tprivate projectSettingsPath: string;\n\n\tconstructor(cwd: string = process.cwd(), agentDir: string = getAgentDir()) {\n\t\tthis.globalSettingsPath = join(agentDir, \"settings.json\");\n\t\tthis.projectSettingsPath = join(cwd, CONFIG_DIR_NAME, \"settings.json\");\n\t}\n\n\tprivate acquireLockSyncWithRetry(path: string): () => void {\n\t\tconst maxAttempts = 10;\n\t\tconst delayMs = 20;\n\t\tlet lastError: unknown;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn lockfile.lockSync(path, { realpath: false });\n\t\t\t} catch (error) {\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tconst start = Date.now();\n\t\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t\t// Sleep synchronously to avoid changing callers to async.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow (lastError as Error) ?? new Error(\"Failed to acquire settings lock\");\n\t}\n\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void {\n\t\tconst path = scope === \"global\" ? this.globalSettingsPath : this.projectSettingsPath;\n\t\tconst dir = dirname(path);\n\n\t\tlet release: (() => void) | undefined;\n\t\ttry {\n\t\t\t// Only create directory and lock if file exists or we need to write\n\t\t\tconst fileExists = existsSync(path);\n\t\t\tif (fileExists) {\n\t\t\t\trelease = this.acquireLockSyncWithRetry(path);\n\t\t\t}\n\t\t\tconst current = fileExists ? readFileSync(path, \"utf-8\") : undefined;\n\t\t\tconst next = fn(current);\n\t\t\tif (next !== undefined) {\n\t\t\t\t// Only create directory when we actually need to write\n\t\t\t\tif (!existsSync(dir)) {\n\t\t\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\t\t}\n\t\t\t\tif (!release) {\n\t\t\t\t\trelease = this.acquireLockSyncWithRetry(path);\n\t\t\t\t}\n\t\t\t\twriteFileSync(path, next, \"utf-8\");\n\t\t\t}\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class InMemorySettingsStorage implements SettingsStorage {\n\tprivate global: string | undefined;\n\tprivate project: string | undefined;\n\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void {\n\t\tconst current = scope === \"global\" ? this.global : this.project;\n\t\tconst next = fn(current);\n\t\tif (next !== undefined) {\n\t\t\tif (scope === \"global\") {\n\t\t\t\tthis.global = next;\n\t\t\t} else {\n\t\t\t\tthis.project = next;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class SettingsManager {\n\tprivate storage: SettingsStorage;\n\tprivate globalSettings: Settings;\n\tprivate projectSettings: Settings;\n\tprivate settings: Settings;\n\tprivate modifiedFields = new Set<keyof Settings>(); // Track global fields modified during session\n\tprivate modifiedNestedFields = new Map<keyof Settings, Set<string>>(); // Track global nested field modifications\n\tprivate modifiedProjectFields = new Set<keyof Settings>(); // Track project fields modified during session\n\tprivate modifiedProjectNestedFields = new Map<keyof Settings, Set<string>>(); // Track project nested field modifications\n\tprivate globalSettingsLoadError: Error | null = null; // Track if global settings file had parse errors\n\tprivate projectSettingsLoadError: Error | null = null; // Track if project settings file had parse errors\n\tprivate writeQueue: Promise<void> = Promise.resolve();\n\tprivate errors: SettingsError[];\n\n\tprivate constructor(\n\t\tstorage: SettingsStorage,\n\t\tinitialGlobal: Settings,\n\t\tinitialProject: Settings,\n\t\tglobalLoadError: Error | null = null,\n\t\tprojectLoadError: Error | null = null,\n\t\tinitialErrors: SettingsError[] = [],\n\t) {\n\t\tthis.storage = storage;\n\t\tthis.globalSettings = initialGlobal;\n\t\tthis.projectSettings = initialProject;\n\t\tthis.globalSettingsLoadError = globalLoadError;\n\t\tthis.projectSettingsLoadError = projectLoadError;\n\t\tthis.errors = [...initialErrors];\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t}\n\n\t/** Create a SettingsManager that loads from files */\n\tstatic create(cwd: string = process.cwd(), agentDir: string = getAgentDir()): SettingsManager {\n\t\tconst storage = new FileSettingsStorage(cwd, agentDir);\n\t\treturn SettingsManager.fromStorage(storage);\n\t}\n\n\t/** Create a SettingsManager from an arbitrary storage backend */\n\tstatic fromStorage(storage: SettingsStorage): SettingsManager {\n\t\tconst globalLoad = SettingsManager.tryLoadFromStorage(storage, \"global\");\n\t\tconst projectLoad = SettingsManager.tryLoadFromStorage(storage, \"project\");\n\t\tconst initialErrors: SettingsError[] = [];\n\t\tif (globalLoad.error) {\n\t\t\tinitialErrors.push({ scope: \"global\", error: globalLoad.error });\n\t\t}\n\t\tif (projectLoad.error) {\n\t\t\tinitialErrors.push({ scope: \"project\", error: projectLoad.error });\n\t\t}\n\n\t\treturn new SettingsManager(\n\t\t\tstorage,\n\t\t\tglobalLoad.settings,\n\t\t\tprojectLoad.settings,\n\t\t\tglobalLoad.error,\n\t\t\tprojectLoad.error,\n\t\t\tinitialErrors,\n\t\t);\n\t}\n\n\t/** Create an in-memory SettingsManager (no file I/O) */\n\tstatic inMemory(settings: Partial<Settings> = {}): SettingsManager {\n\t\tconst storage = new InMemorySettingsStorage();\n\t\treturn new SettingsManager(storage, settings, {});\n\t}\n\n\tprivate static loadFromStorage(storage: SettingsStorage, scope: SettingsScope): Settings {\n\t\tlet content: string | undefined;\n\t\tstorage.withLock(scope, (current) => {\n\t\t\tcontent = current;\n\t\t\treturn undefined;\n\t\t});\n\n\t\tif (!content) {\n\t\t\treturn {};\n\t\t}\n\t\tconst settings = JSON.parse(content);\n\t\treturn SettingsManager.migrateSettings(settings);\n\t}\n\n\tprivate static tryLoadFromStorage(\n\t\tstorage: SettingsStorage,\n\t\tscope: SettingsScope,\n\t): { settings: Settings; error: Error | null } {\n\t\ttry {\n\t\t\treturn { settings: SettingsManager.loadFromStorage(storage, scope), error: null };\n\t\t} catch (error) {\n\t\t\treturn { settings: {}, error: error as Error };\n\t\t}\n\t}\n\n\t/** Migrate old settings format to new format */\n\tprivate static migrateSettings(settings: Record<string, unknown>): Settings {\n\t\t// Migrate queueMode -> steeringMode\n\t\tif (\"queueMode\" in settings && !(\"steeringMode\" in settings)) {\n\t\t\tsettings.steeringMode = settings.queueMode;\n\t\t\tdelete settings.queueMode;\n\t\t}\n\n\t\t// Migrate legacy websockets boolean -> transport enum\n\t\tif (!(\"transport\" in settings) && typeof settings.websockets === \"boolean\") {\n\t\t\tsettings.transport = settings.websockets ? \"websocket\" : \"sse\";\n\t\t\tdelete settings.websockets;\n\t\t}\n\n\t\t// Migrate old skills object format to new array format\n\t\tif (\n\t\t\t\"skills\" in settings &&\n\t\t\ttypeof settings.skills === \"object\" &&\n\t\t\tsettings.skills !== null &&\n\t\t\t!Array.isArray(settings.skills)\n\t\t) {\n\t\t\tconst skillsSettings = settings.skills as {\n\t\t\t\tenableSkillCommands?: boolean;\n\t\t\t\tcustomDirectories?: unknown;\n\t\t\t};\n\t\t\tif (skillsSettings.enableSkillCommands !== undefined && settings.enableSkillCommands === undefined) {\n\t\t\t\tsettings.enableSkillCommands = skillsSettings.enableSkillCommands;\n\t\t\t}\n\t\t\tif (Array.isArray(skillsSettings.customDirectories) && skillsSettings.customDirectories.length > 0) {\n\t\t\t\tsettings.skills = skillsSettings.customDirectories;\n\t\t\t} else {\n\t\t\t\tdelete settings.skills;\n\t\t\t}\n\t\t}\n\n\t\treturn settings as Settings;\n\t}\n\n\tgetGlobalSettings(): Settings {\n\t\treturn structuredClone(this.globalSettings);\n\t}\n\n\tgetProjectSettings(): Settings {\n\t\treturn structuredClone(this.projectSettings);\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tawait this.writeQueue;\n\t\tconst globalLoad = SettingsManager.tryLoadFromStorage(this.storage, \"global\");\n\t\tif (!globalLoad.error) {\n\t\t\tthis.globalSettings = globalLoad.settings;\n\t\t\tthis.globalSettingsLoadError = null;\n\t\t} else {\n\t\t\tthis.globalSettingsLoadError = globalLoad.error;\n\t\t\tthis.recordError(\"global\", globalLoad.error);\n\t\t}\n\n\t\tthis.modifiedFields.clear();\n\t\tthis.modifiedNestedFields.clear();\n\t\tthis.modifiedProjectFields.clear();\n\t\tthis.modifiedProjectNestedFields.clear();\n\n\t\tconst projectLoad = SettingsManager.tryLoadFromStorage(this.storage, \"project\");\n\t\tif (!projectLoad.error) {\n\t\t\tthis.projectSettings = projectLoad.settings;\n\t\t\tthis.projectSettingsLoadError = null;\n\t\t} else {\n\t\t\tthis.projectSettingsLoadError = projectLoad.error;\n\t\t\tthis.recordError(\"project\", projectLoad.error);\n\t\t}\n\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t}\n\n\t/** Apply additional overrides on top of current settings */\n\tapplyOverrides(overrides: Partial<Settings>): void {\n\t\tthis.settings = deepMergeSettings(this.settings, overrides);\n\t}\n\n\t/** Mark a global field as modified during this session */\n\tprivate markModified(field: keyof Settings, nestedKey?: string): void {\n\t\tthis.modifiedFields.add(field);\n\t\tif (nestedKey) {\n\t\t\tif (!this.modifiedNestedFields.has(field)) {\n\t\t\t\tthis.modifiedNestedFields.set(field, new Set());\n\t\t\t}\n\t\t\tthis.modifiedNestedFields.get(field)!.add(nestedKey);\n\t\t}\n\t}\n\n\t/** Mark a project field as modified during this session */\n\tprivate markProjectModified(field: keyof Settings, nestedKey?: string): void {\n\t\tthis.modifiedProjectFields.add(field);\n\t\tif (nestedKey) {\n\t\t\tif (!this.modifiedProjectNestedFields.has(field)) {\n\t\t\t\tthis.modifiedProjectNestedFields.set(field, new Set());\n\t\t\t}\n\t\t\tthis.modifiedProjectNestedFields.get(field)!.add(nestedKey);\n\t\t}\n\t}\n\n\tprivate recordError(scope: SettingsScope, error: unknown): void {\n\t\tconst normalizedError = error instanceof Error ? error : new Error(String(error));\n\t\tthis.errors.push({ scope, error: normalizedError });\n\t}\n\n\tprivate clearModifiedScope(scope: SettingsScope): void {\n\t\tif (scope === \"global\") {\n\t\t\tthis.modifiedFields.clear();\n\t\t\tthis.modifiedNestedFields.clear();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.modifiedProjectFields.clear();\n\t\tthis.modifiedProjectNestedFields.clear();\n\t}\n\n\tprivate enqueueWrite(scope: SettingsScope, task: () => void): void {\n\t\tthis.writeQueue = this.writeQueue\n\t\t\t.then(() => {\n\t\t\t\ttask();\n\t\t\t\tthis.clearModifiedScope(scope);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.recordError(scope, error);\n\t\t\t});\n\t}\n\n\tprivate cloneModifiedNestedFields(source: Map<keyof Settings, Set<string>>): Map<keyof Settings, Set<string>> {\n\t\tconst snapshot = new Map<keyof Settings, Set<string>>();\n\t\tfor (const [key, value] of source.entries()) {\n\t\t\tsnapshot.set(key, new Set(value));\n\t\t}\n\t\treturn snapshot;\n\t}\n\n\tprivate persistScopedSettings(\n\t\tscope: SettingsScope,\n\t\tsnapshotSettings: Settings,\n\t\tmodifiedFields: Set<keyof Settings>,\n\t\tmodifiedNestedFields: Map<keyof Settings, Set<string>>,\n\t): void {\n\t\tthis.storage.withLock(scope, (current) => {\n\t\t\tconst currentFileSettings = current\n\t\t\t\t? SettingsManager.migrateSettings(JSON.parse(current) as Record<string, unknown>)\n\t\t\t\t: {};\n\t\t\tconst mergedSettings: Settings = { ...currentFileSettings };\n\t\t\tfor (const field of modifiedFields) {\n\t\t\t\tconst value = snapshotSettings[field];\n\t\t\t\tif (modifiedNestedFields.has(field) && typeof value === \"object\" && value !== null) {\n\t\t\t\t\tconst nestedModified = modifiedNestedFields.get(field)!;\n\t\t\t\t\tconst baseNested = (currentFileSettings[field] as Record<string, unknown>) ?? {};\n\t\t\t\t\tconst inMemoryNested = value as Record<string, unknown>;\n\t\t\t\t\tconst mergedNested = { ...baseNested };\n\t\t\t\t\tfor (const nestedKey of nestedModified) {\n\t\t\t\t\t\tmergedNested[nestedKey] = inMemoryNested[nestedKey];\n\t\t\t\t\t}\n\t\t\t\t\t(mergedSettings as Record<string, unknown>)[field] = mergedNested;\n\t\t\t\t} else {\n\t\t\t\t\t(mergedSettings as Record<string, unknown>)[field] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn JSON.stringify(mergedSettings, null, 2);\n\t\t});\n\t}\n\n\tprivate save(): void {\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\n\t\tif (this.globalSettingsLoadError) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst snapshotGlobalSettings = structuredClone(this.globalSettings);\n\t\tconst modifiedFields = new Set(this.modifiedFields);\n\t\tconst modifiedNestedFields = this.cloneModifiedNestedFields(this.modifiedNestedFields);\n\n\t\tthis.enqueueWrite(\"global\", () => {\n\t\t\tthis.persistScopedSettings(\"global\", snapshotGlobalSettings, modifiedFields, modifiedNestedFields);\n\t\t});\n\t}\n\n\tprivate saveProjectSettings(settings: Settings): void {\n\t\tthis.projectSettings = structuredClone(settings);\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\n\t\tif (this.projectSettingsLoadError) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst snapshotProjectSettings = structuredClone(this.projectSettings);\n\t\tconst modifiedFields = new Set(this.modifiedProjectFields);\n\t\tconst modifiedNestedFields = this.cloneModifiedNestedFields(this.modifiedProjectNestedFields);\n\t\tthis.enqueueWrite(\"project\", () => {\n\t\t\tthis.persistScopedSettings(\"project\", snapshotProjectSettings, modifiedFields, modifiedNestedFields);\n\t\t});\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tawait this.writeQueue;\n\t}\n\n\tdrainErrors(): SettingsError[] {\n\t\tconst drained = [...this.errors];\n\t\tthis.errors = [];\n\t\treturn drained;\n\t}\n\n\tgetLastChangelogVersion(): string | undefined {\n\t\treturn this.settings.lastChangelogVersion;\n\t}\n\n\tsetLastChangelogVersion(version: string): void {\n\t\tthis.globalSettings.lastChangelogVersion = version;\n\t\tthis.markModified(\"lastChangelogVersion\");\n\t\tthis.save();\n\t}\n\n\tgetSessionDir(): string | undefined {\n\t\treturn this.settings.sessionDir;\n\t}\n\n\tgetDefaultProvider(): string | undefined {\n\t\treturn this.settings.defaultProvider;\n\t}\n\n\tgetDefaultModel(): string | undefined {\n\t\treturn this.settings.defaultModel;\n\t}\n\n\tsetDefaultProvider(provider: string): void {\n\t\tthis.globalSettings.defaultProvider = provider;\n\t\tthis.markModified(\"defaultProvider\");\n\t\tthis.save();\n\t}\n\n\tsetDefaultModel(modelId: string): void {\n\t\tthis.globalSettings.defaultModel = modelId;\n\t\tthis.markModified(\"defaultModel\");\n\t\tthis.save();\n\t}\n\n\tsetDefaultModelAndProvider(provider: string, modelId: string): void {\n\t\tthis.globalSettings.defaultProvider = provider;\n\t\tthis.globalSettings.defaultModel = modelId;\n\t\tthis.markModified(\"defaultProvider\");\n\t\tthis.markModified(\"defaultModel\");\n\t\tthis.save();\n\t}\n\n\tgetSteeringMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.settings.steeringMode || \"one-at-a-time\";\n\t}\n\n\tsetSteeringMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.globalSettings.steeringMode = mode;\n\t\tthis.markModified(\"steeringMode\");\n\t\tthis.save();\n\t}\n\n\tgetFollowUpMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.settings.followUpMode || \"one-at-a-time\";\n\t}\n\n\tsetFollowUpMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.globalSettings.followUpMode = mode;\n\t\tthis.markModified(\"followUpMode\");\n\t\tthis.save();\n\t}\n\n\tgetTheme(): string | undefined {\n\t\treturn this.settings.theme;\n\t}\n\n\tsetTheme(theme: string): void {\n\t\tthis.globalSettings.theme = theme;\n\t\tthis.markModified(\"theme\");\n\t\tthis.save();\n\t}\n\n\tgetDefaultThinkingLevel(): \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | undefined {\n\t\treturn this.settings.defaultThinkingLevel;\n\t}\n\n\tsetDefaultThinkingLevel(level: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\"): void {\n\t\tthis.globalSettings.defaultThinkingLevel = level;\n\t\tthis.markModified(\"defaultThinkingLevel\");\n\t\tthis.save();\n\t}\n\n\tgetTransport(): TransportSetting {\n\t\treturn this.settings.transport ?? \"sse\";\n\t}\n\n\tsetTransport(transport: TransportSetting): void {\n\t\tthis.globalSettings.transport = transport;\n\t\tthis.markModified(\"transport\");\n\t\tthis.save();\n\t}\n\n\tgetCompactionEnabled(): boolean {\n\t\treturn this.settings.compaction?.enabled ?? true;\n\t}\n\n\tsetCompactionEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.compaction) {\n\t\t\tthis.globalSettings.compaction = {};\n\t\t}\n\t\tthis.globalSettings.compaction.enabled = enabled;\n\t\tthis.markModified(\"compaction\", \"enabled\");\n\t\tthis.save();\n\t}\n\n\tgetCompactionReserveTokens(): number {\n\t\treturn this.settings.compaction?.reserveTokens ?? 16384;\n\t}\n\n\tgetCompactionKeepRecentTokens(): number {\n\t\treturn this.settings.compaction?.keepRecentTokens ?? 20000;\n\t}\n\n\tgetCompactionSettings(): { enabled: boolean; reserveTokens: number; keepRecentTokens: number } {\n\t\treturn {\n\t\t\tenabled: this.getCompactionEnabled(),\n\t\t\treserveTokens: this.getCompactionReserveTokens(),\n\t\t\tkeepRecentTokens: this.getCompactionKeepRecentTokens(),\n\t\t};\n\t}\n\n\tgetBranchSummarySettings(): { reserveTokens: number; skipPrompt: boolean } {\n\t\treturn {\n\t\t\treserveTokens: this.settings.branchSummary?.reserveTokens ?? 16384,\n\t\t\tskipPrompt: this.settings.branchSummary?.skipPrompt ?? false,\n\t\t};\n\t}\n\n\tgetBranchSummarySkipPrompt(): boolean {\n\t\treturn this.settings.branchSummary?.skipPrompt ?? false;\n\t}\n\n\tgetRetryEnabled(): boolean {\n\t\treturn this.settings.retry?.enabled ?? true;\n\t}\n\n\tsetRetryEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.retry) {\n\t\t\tthis.globalSettings.retry = {};\n\t\t}\n\t\tthis.globalSettings.retry.enabled = enabled;\n\t\tthis.markModified(\"retry\", \"enabled\");\n\t\tthis.save();\n\t}\n\n\tgetRetrySettings(): { enabled: boolean; maxRetries: number; baseDelayMs: number; maxDelayMs: number } {\n\t\treturn {\n\t\t\tenabled: this.getRetryEnabled(),\n\t\t\tmaxRetries: this.settings.retry?.maxRetries ?? 3,\n\t\t\tbaseDelayMs: this.settings.retry?.baseDelayMs ?? 2000,\n\t\t\tmaxDelayMs: this.settings.retry?.maxDelayMs ?? 60000,\n\t\t};\n\t}\n\n\tgetHideThinkingBlock(): boolean {\n\t\treturn this.settings.hideThinkingBlock ?? false;\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.globalSettings.hideThinkingBlock = hide;\n\t\tthis.markModified(\"hideThinkingBlock\");\n\t\tthis.save();\n\t}\n\n\tgetShellPath(): string | undefined {\n\t\treturn this.settings.shellPath;\n\t}\n\n\tsetShellPath(path: string | undefined): void {\n\t\tthis.globalSettings.shellPath = path;\n\t\tthis.markModified(\"shellPath\");\n\t\tthis.save();\n\t}\n\n\tgetQuietStartup(): boolean {\n\t\treturn this.settings.quietStartup ?? false;\n\t}\n\n\tsetQuietStartup(quiet: boolean): void {\n\t\tthis.globalSettings.quietStartup = quiet;\n\t\tthis.markModified(\"quietStartup\");\n\t\tthis.save();\n\t}\n\n\tgetShellCommandPrefix(): string | undefined {\n\t\treturn this.settings.shellCommandPrefix;\n\t}\n\n\tsetShellCommandPrefix(prefix: string | undefined): void {\n\t\tthis.globalSettings.shellCommandPrefix = prefix;\n\t\tthis.markModified(\"shellCommandPrefix\");\n\t\tthis.save();\n\t}\n\n\tgetNpmCommand(): string[] | undefined {\n\t\treturn this.settings.npmCommand ? [...this.settings.npmCommand] : undefined;\n\t}\n\n\tsetNpmCommand(command: string[] | undefined): void {\n\t\tthis.globalSettings.npmCommand = command ? [...command] : undefined;\n\t\tthis.markModified(\"npmCommand\");\n\t\tthis.save();\n\t}\n\n\tgetCollapseChangelog(): boolean {\n\t\treturn this.settings.collapseChangelog ?? false;\n\t}\n\n\tsetCollapseChangelog(collapse: boolean): void {\n\t\tthis.globalSettings.collapseChangelog = collapse;\n\t\tthis.markModified(\"collapseChangelog\");\n\t\tthis.save();\n\t}\n\n\tgetPackages(): PackageSource[] {\n\t\treturn [...(this.settings.packages ?? [])];\n\t}\n\n\tsetPackages(packages: PackageSource[]): void {\n\t\tthis.globalSettings.packages = packages;\n\t\tthis.markModified(\"packages\");\n\t\tthis.save();\n\t}\n\n\tsetProjectPackages(packages: PackageSource[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.packages = packages;\n\t\tthis.markProjectModified(\"packages\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetExtensionPaths(): string[] {\n\t\treturn [...(this.settings.extensions ?? [])];\n\t}\n\n\tsetExtensionPaths(paths: string[]): void {\n\t\tthis.globalSettings.extensions = paths;\n\t\tthis.markModified(\"extensions\");\n\t\tthis.save();\n\t}\n\n\tsetProjectExtensionPaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.extensions = paths;\n\t\tthis.markProjectModified(\"extensions\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetSkillPaths(): string[] {\n\t\treturn [...(this.settings.skills ?? [])];\n\t}\n\n\tsetSkillPaths(paths: string[]): void {\n\t\tthis.globalSettings.skills = paths;\n\t\tthis.markModified(\"skills\");\n\t\tthis.save();\n\t}\n\n\tsetProjectSkillPaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.skills = paths;\n\t\tthis.markProjectModified(\"skills\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetPromptTemplatePaths(): string[] {\n\t\treturn [...(this.settings.prompts ?? [])];\n\t}\n\n\tsetPromptTemplatePaths(paths: string[]): void {\n\t\tthis.globalSettings.prompts = paths;\n\t\tthis.markModified(\"prompts\");\n\t\tthis.save();\n\t}\n\n\tsetProjectPromptTemplatePaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.prompts = paths;\n\t\tthis.markProjectModified(\"prompts\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetThemePaths(): string[] {\n\t\treturn [...(this.settings.themes ?? [])];\n\t}\n\n\tsetThemePaths(paths: string[]): void {\n\t\tthis.globalSettings.themes = paths;\n\t\tthis.markModified(\"themes\");\n\t\tthis.save();\n\t}\n\n\tsetProjectThemePaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.themes = paths;\n\t\tthis.markProjectModified(\"themes\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetEnableSkillCommands(): boolean {\n\t\treturn this.settings.enableSkillCommands ?? true;\n\t}\n\n\tsetEnableSkillCommands(enabled: boolean): void {\n\t\tthis.globalSettings.enableSkillCommands = enabled;\n\t\tthis.markModified(\"enableSkillCommands\");\n\t\tthis.save();\n\t}\n\n\tgetThinkingBudgets(): ThinkingBudgetsSettings | undefined {\n\t\treturn this.settings.thinkingBudgets;\n\t}\n\n\tgetShowImages(): boolean {\n\t\treturn this.settings.terminal?.showImages ?? true;\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tif (!this.globalSettings.terminal) {\n\t\t\tthis.globalSettings.terminal = {};\n\t\t}\n\t\tthis.globalSettings.terminal.showImages = show;\n\t\tthis.markModified(\"terminal\", \"showImages\");\n\t\tthis.save();\n\t}\n\n\tgetClearOnShrink(): boolean {\n\t\t// Settings takes precedence, then env var, then default false\n\t\tif (this.settings.terminal?.clearOnShrink !== undefined) {\n\t\t\treturn this.settings.terminal.clearOnShrink;\n\t\t}\n\t\treturn process.env.PI_CLEAR_ON_SHRINK === \"1\";\n\t}\n\n\tsetClearOnShrink(enabled: boolean): void {\n\t\tif (!this.globalSettings.terminal) {\n\t\t\tthis.globalSettings.terminal = {};\n\t\t}\n\t\tthis.globalSettings.terminal.clearOnShrink = enabled;\n\t\tthis.markModified(\"terminal\", \"clearOnShrink\");\n\t\tthis.save();\n\t}\n\n\tgetImageAutoResize(): boolean {\n\t\treturn this.settings.images?.autoResize ?? true;\n\t}\n\n\tsetImageAutoResize(enabled: boolean): void {\n\t\tif (!this.globalSettings.images) {\n\t\t\tthis.globalSettings.images = {};\n\t\t}\n\t\tthis.globalSettings.images.autoResize = enabled;\n\t\tthis.markModified(\"images\", \"autoResize\");\n\t\tthis.save();\n\t}\n\n\tgetBlockImages(): boolean {\n\t\treturn this.settings.images?.blockImages ?? false;\n\t}\n\n\tsetBlockImages(blocked: boolean): void {\n\t\tif (!this.globalSettings.images) {\n\t\t\tthis.globalSettings.images = {};\n\t\t}\n\t\tthis.globalSettings.images.blockImages = blocked;\n\t\tthis.markModified(\"images\", \"blockImages\");\n\t\tthis.save();\n\t}\n\n\tgetEnabledModels(): string[] | undefined {\n\t\treturn this.settings.enabledModels;\n\t}\n\n\tsetEnabledModels(patterns: string[] | undefined): void {\n\t\tthis.globalSettings.enabledModels = patterns;\n\t\tthis.markModified(\"enabledModels\");\n\t\tthis.save();\n\t}\n\n\tgetDoubleEscapeAction(): \"fork\" | \"tree\" | \"none\" {\n\t\treturn this.settings.doubleEscapeAction ?? \"tree\";\n\t}\n\n\tsetDoubleEscapeAction(action: \"fork\" | \"tree\" | \"none\"): void {\n\t\tthis.globalSettings.doubleEscapeAction = action;\n\t\tthis.markModified(\"doubleEscapeAction\");\n\t\tthis.save();\n\t}\n\n\tgetTreeFilterMode(): \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\" {\n\t\tconst mode = this.settings.treeFilterMode;\n\t\tconst valid = [\"default\", \"no-tools\", \"user-only\", \"labeled-only\", \"all\"];\n\t\treturn mode && valid.includes(mode) ? mode : \"default\";\n\t}\n\n\tsetTreeFilterMode(mode: \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\"): void {\n\t\tthis.globalSettings.treeFilterMode = mode;\n\t\tthis.markModified(\"treeFilterMode\");\n\t\tthis.save();\n\t}\n\n\tgetShowHardwareCursor(): boolean {\n\t\treturn this.settings.showHardwareCursor ?? process.env.PI_HARDWARE_CURSOR === \"1\";\n\t}\n\n\tsetShowHardwareCursor(enabled: boolean): void {\n\t\tthis.globalSettings.showHardwareCursor = enabled;\n\t\tthis.markModified(\"showHardwareCursor\");\n\t\tthis.save();\n\t}\n\n\tgetEditorPaddingX(): number {\n\t\treturn this.settings.editorPaddingX ?? 0;\n\t}\n\n\tsetEditorPaddingX(padding: number): void {\n\t\tthis.globalSettings.editorPaddingX = Math.max(0, Math.min(3, Math.floor(padding)));\n\t\tthis.markModified(\"editorPaddingX\");\n\t\tthis.save();\n\t}\n\n\tgetAutocompleteMaxVisible(): number {\n\t\treturn this.settings.autocompleteMaxVisible ?? 5;\n\t}\n\n\tsetAutocompleteMaxVisible(maxVisible: number): void {\n\t\tthis.globalSettings.autocompleteMaxVisible = Math.max(3, Math.min(20, Math.floor(maxVisible)));\n\t\tthis.markModified(\"autocompleteMaxVisible\");\n\t\tthis.save();\n\t}\n\n\tgetCodeBlockIndent(): string {\n\t\treturn this.settings.markdown?.codeBlockIndent ?? \" \";\n\t}\n}\n"]}