@selesai/code 0.5.13 → 0.5.15

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 (297) hide show
  1. package/README.md +186 -0
  2. package/dist/bun/cli.d.ts.map +1 -1
  3. package/dist/bun/cli.js +2 -0
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +3 -1
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/cli/list-models.d.ts +2 -2
  9. package/dist/cli/list-models.d.ts.map +1 -1
  10. package/dist/cli/list-models.js +3 -3
  11. package/dist/cli/list-models.js.map +1 -1
  12. package/dist/config.d.ts +1 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +2 -2
  15. package/dist/config.js.map +1 -1
  16. package/dist/core/agent-session-auto-handoff.test.d.ts.map +1 -1
  17. package/dist/core/agent-session-auto-handoff.test.js +2 -2
  18. package/dist/core/agent-session-auto-handoff.test.js.map +1 -1
  19. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  20. package/dist/core/agent-session-runtime.js +3 -0
  21. package/dist/core/agent-session-runtime.js.map +1 -1
  22. package/dist/core/agent-session-services.d.ts +3 -6
  23. package/dist/core/agent-session-services.d.ts.map +1 -1
  24. package/dist/core/agent-session-services.js +23 -9
  25. package/dist/core/agent-session-services.js.map +1 -1
  26. package/dist/core/agent-session.d.ts +28 -10
  27. package/dist/core/agent-session.d.ts.map +1 -1
  28. package/dist/core/agent-session.js +136 -90
  29. package/dist/core/agent-session.js.map +1 -1
  30. package/dist/core/auth-storage.d.ts +20 -98
  31. package/dist/core/auth-storage.d.ts.map +1 -1
  32. package/dist/core/auth-storage.js +59 -251
  33. package/dist/core/auth-storage.js.map +1 -1
  34. package/dist/core/built-in-extensions.d.ts +3 -0
  35. package/dist/core/built-in-extensions.d.ts.map +1 -0
  36. package/dist/core/built-in-extensions.js +3 -0
  37. package/dist/core/built-in-extensions.js.map +1 -0
  38. package/dist/core/cache-stats.d.ts +2 -2
  39. package/dist/core/cache-stats.d.ts.map +1 -1
  40. package/dist/core/cache-stats.js +1 -1
  41. package/dist/core/cache-stats.js.map +1 -1
  42. package/dist/core/compaction/branch-summarization.d.ts +8 -2
  43. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  44. package/dist/core/compaction/branch-summarization.js +8 -11
  45. package/dist/core/compaction/branch-summarization.js.map +1 -1
  46. package/dist/core/compaction/compaction.d.ts +19 -3
  47. package/dist/core/compaction/compaction.d.ts.map +1 -1
  48. package/dist/core/compaction/compaction.js +63 -26
  49. package/dist/core/compaction/compaction.js.map +1 -1
  50. package/dist/core/compaction/utils.d.ts +1 -1
  51. package/dist/core/compaction/utils.d.ts.map +1 -1
  52. package/dist/core/compaction/utils.js +6 -17
  53. package/dist/core/compaction/utils.js.map +1 -1
  54. package/dist/core/extensions/loader.d.ts.map +1 -1
  55. package/dist/core/extensions/loader.js +21 -4
  56. package/dist/core/extensions/loader.js.map +1 -1
  57. package/dist/core/extensions/runner.d.ts +4 -1
  58. package/dist/core/extensions/runner.d.ts.map +1 -1
  59. package/dist/core/extensions/runner.js +39 -0
  60. package/dist/core/extensions/runner.js.map +1 -1
  61. package/dist/core/extensions/types.d.ts +24 -3
  62. package/dist/core/extensions/types.d.ts.map +1 -1
  63. package/dist/core/extensions/types.js.map +1 -1
  64. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  65. package/dist/core/extensions/wrapper.js +22 -3
  66. package/dist/core/extensions/wrapper.js.map +1 -1
  67. package/dist/core/keybindings.d.ts +8 -3
  68. package/dist/core/keybindings.d.ts.map +1 -1
  69. package/dist/core/keybindings.js +7 -3
  70. package/dist/core/keybindings.js.map +1 -1
  71. package/dist/core/llama/client.d.ts +61 -0
  72. package/dist/core/llama/client.d.ts.map +1 -0
  73. package/dist/core/llama/client.js +302 -0
  74. package/dist/core/llama/client.js.map +1 -0
  75. package/dist/core/llama/huggingface.d.ts +23 -0
  76. package/dist/core/llama/huggingface.d.ts.map +1 -0
  77. package/dist/core/llama/huggingface.js +141 -0
  78. package/dist/core/llama/huggingface.js.map +1 -0
  79. package/dist/core/llama/index.d.ts +3 -0
  80. package/dist/core/llama/index.d.ts.map +1 -0
  81. package/dist/core/llama/index.js +208 -0
  82. package/dist/core/llama/index.js.map +1 -0
  83. package/dist/core/llama/provider.d.ts +10 -0
  84. package/dist/core/llama/provider.d.ts.map +1 -0
  85. package/dist/core/llama/provider.js +102 -0
  86. package/dist/core/llama/provider.js.map +1 -0
  87. package/dist/core/llama/ui.d.ts +42 -0
  88. package/dist/core/llama/ui.d.ts.map +1 -0
  89. package/dist/core/llama/ui.js +416 -0
  90. package/dist/core/llama/ui.js.map +1 -0
  91. package/dist/core/model-config.d.ts +513 -0
  92. package/dist/core/model-config.d.ts.map +1 -0
  93. package/dist/core/model-config.js +272 -0
  94. package/dist/core/model-config.js.map +1 -0
  95. package/dist/core/model-registry.d.ts +20 -126
  96. package/dist/core/model-registry.d.ts.map +1 -1
  97. package/dist/core/model-registry.js +62 -780
  98. package/dist/core/model-registry.js.map +1 -1
  99. package/dist/core/model-resolver.d.ts +6 -6
  100. package/dist/core/model-resolver.d.ts.map +1 -1
  101. package/dist/core/model-resolver.js +21 -18
  102. package/dist/core/model-resolver.js.map +1 -1
  103. package/dist/core/model-runtime.d.ts +83 -0
  104. package/dist/core/model-runtime.d.ts.map +1 -0
  105. package/dist/core/model-runtime.js +451 -0
  106. package/dist/core/model-runtime.js.map +1 -0
  107. package/dist/core/models-store.d.ts +17 -0
  108. package/dist/core/models-store.d.ts.map +1 -0
  109. package/dist/core/models-store.js +45 -0
  110. package/dist/core/models-store.js.map +1 -0
  111. package/dist/core/package-manager.d.ts.map +1 -1
  112. package/dist/core/package-manager.js +7 -2
  113. package/dist/core/package-manager.js.map +1 -1
  114. package/dist/core/prompt-templates.d.ts +1 -0
  115. package/dist/core/prompt-templates.d.ts.map +1 -1
  116. package/dist/core/prompt-templates.js +4 -4
  117. package/dist/core/prompt-templates.js.map +1 -1
  118. package/dist/core/provider-composer.d.ts +55 -0
  119. package/dist/core/provider-composer.d.ts.map +1 -0
  120. package/dist/core/provider-composer.js +375 -0
  121. package/dist/core/provider-composer.js.map +1 -0
  122. package/dist/core/radius.d.ts +2 -0
  123. package/dist/core/radius.d.ts.map +1 -0
  124. package/dist/core/radius.js +2 -0
  125. package/dist/core/radius.js.map +1 -0
  126. package/dist/core/remote-catalog-provider.d.ts +5 -0
  127. package/dist/core/remote-catalog-provider.d.ts.map +1 -0
  128. package/dist/core/remote-catalog-provider.js +102 -0
  129. package/dist/core/remote-catalog-provider.js.map +1 -0
  130. package/dist/core/resource-loader.d.ts.map +1 -1
  131. package/dist/core/resource-loader.js +1 -0
  132. package/dist/core/resource-loader.js.map +1 -1
  133. package/dist/core/runtime-credentials.d.ts +17 -0
  134. package/dist/core/runtime-credentials.d.ts.map +1 -0
  135. package/dist/core/runtime-credentials.js +42 -0
  136. package/dist/core/runtime-credentials.js.map +1 -0
  137. package/dist/core/sdk.d.ts +4 -7
  138. package/dist/core/sdk.d.ts.map +1 -1
  139. package/dist/core/sdk.js +18 -25
  140. package/dist/core/sdk.js.map +1 -1
  141. package/dist/core/session-manager.d.ts +12 -7
  142. package/dist/core/session-manager.d.ts.map +1 -1
  143. package/dist/core/session-manager.js +103 -27
  144. package/dist/core/session-manager.js.map +1 -1
  145. package/dist/core/system-prompt.d.ts.map +1 -1
  146. package/dist/core/system-prompt.js +2 -12
  147. package/dist/core/system-prompt.js.map +1 -1
  148. package/dist/core/tools/read.d.ts.map +1 -1
  149. package/dist/core/tools/read.js +1 -1
  150. package/dist/core/tools/read.js.map +1 -1
  151. package/dist/core/usage-totals.d.ts +19 -0
  152. package/dist/core/usage-totals.d.ts.map +1 -0
  153. package/dist/core/usage-totals.js +52 -0
  154. package/dist/core/usage-totals.js.map +1 -0
  155. package/dist/extensions/index.d.ts +3 -0
  156. package/dist/extensions/index.d.ts.map +1 -0
  157. package/dist/extensions/index.js +9 -0
  158. package/dist/extensions/index.js.map +1 -0
  159. package/dist/extensions/llama/client.d.ts +61 -0
  160. package/dist/extensions/llama/client.d.ts.map +1 -0
  161. package/dist/extensions/llama/client.js +309 -0
  162. package/dist/extensions/llama/client.js.map +1 -0
  163. package/dist/extensions/llama/huggingface.d.ts +23 -0
  164. package/dist/extensions/llama/huggingface.d.ts.map +1 -0
  165. package/dist/extensions/llama/huggingface.js +146 -0
  166. package/dist/extensions/llama/huggingface.js.map +1 -0
  167. package/dist/extensions/llama/index.d.ts +3 -0
  168. package/dist/extensions/llama/index.d.ts.map +1 -0
  169. package/dist/extensions/llama/index.js +211 -0
  170. package/dist/extensions/llama/index.js.map +1 -0
  171. package/dist/extensions/llama/provider.d.ts +10 -0
  172. package/dist/extensions/llama/provider.d.ts.map +1 -0
  173. package/dist/extensions/llama/provider.js +106 -0
  174. package/dist/extensions/llama/provider.js.map +1 -0
  175. package/dist/extensions/llama/ui.d.ts +42 -0
  176. package/dist/extensions/llama/ui.d.ts.map +1 -0
  177. package/dist/extensions/llama/ui.js +420 -0
  178. package/dist/extensions/llama/ui.js.map +1 -0
  179. package/dist/extensions/package.json +4 -3
  180. package/dist/extensions/pi-powerline-footer/README.md +1 -1
  181. package/dist/extensions/pi-powerline-footer/guide.ts +227 -0
  182. package/dist/extensions/pi-powerline-footer/index.ts +88 -55
  183. package/dist/extensions/pi-powerline-footer/tests/editor-responsiveness.test.ts +0 -78
  184. package/dist/extensions/pi-powerline-footer/tests/guide.test.ts +102 -0
  185. package/dist/extensions/pi-powerline-footer/welcome.ts +65 -30
  186. package/dist/extensions/tokenin-onboarding.ts +3 -3
  187. package/dist/index.d.ts +4 -3
  188. package/dist/index.d.ts.map +1 -1
  189. package/dist/index.js +3 -3
  190. package/dist/index.js.map +1 -1
  191. package/dist/main.d.ts.map +1 -1
  192. package/dist/main.js +21 -19
  193. package/dist/main.js.map +1 -1
  194. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  195. package/dist/modes/interactive/components/assistant-message.js +22 -10
  196. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  197. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  198. package/dist/modes/interactive/components/custom-editor.js +1 -1
  199. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  200. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  201. package/dist/modes/interactive/components/footer.js +24 -23
  202. package/dist/modes/interactive/components/footer.js.map +1 -1
  203. package/dist/modes/interactive/components/login-dialog.d.ts +5 -5
  204. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  205. package/dist/modes/interactive/components/login-dialog.js +17 -8
  206. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  207. package/dist/modes/interactive/components/model-selector.d.ts +11 -4
  208. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  209. package/dist/modes/interactive/components/model-selector.js +72 -41
  210. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  211. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
  212. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  213. package/dist/modes/interactive/components/oauth-selector.js +14 -27
  214. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  215. package/dist/modes/interactive/components/tree-selector.d.ts +5 -0
  216. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  217. package/dist/modes/interactive/components/tree-selector.js +49 -12
  218. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  219. package/dist/modes/interactive/interactive-mode.d.ts +8 -5
  220. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  221. package/dist/modes/interactive/interactive-mode.js +253 -225
  222. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  223. package/dist/modes/rpc/rpc-client.d.ts +4 -0
  224. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  225. package/dist/modes/rpc/rpc-client.js +7 -0
  226. package/dist/modes/rpc/rpc-client.js.map +1 -1
  227. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  228. package/dist/modes/rpc/rpc-mode.js +6 -2
  229. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  230. package/dist/modes/rpc/rpc-types.d.ts +11 -0
  231. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  232. package/dist/modes/rpc/rpc-types.js.map +1 -1
  233. package/dist/package-manager-cli.d.ts.map +1 -1
  234. package/dist/package-manager-cli.js +67 -5
  235. package/dist/package-manager-cli.js.map +1 -1
  236. package/dist/skills/caveman/SKILL.md +1 -0
  237. package/dist/skills/handoff/SKILL.md +1 -0
  238. package/dist/skills/handoff-text/SKILL.md +1 -0
  239. package/dist/skills/implanger/SKILL.md +1 -0
  240. package/dist/skills/improve-codebase/SKILL.md +1 -0
  241. package/dist/skills/planger/SKILL.md +1 -0
  242. package/dist/skills/ponytail/SKILL.md +1 -0
  243. package/dist/skills/ponytail-audit/SKILL.md +1 -0
  244. package/dist/skills/ponytail-debt/SKILL.md +1 -0
  245. package/dist/skills/ponytail-gain/SKILL.md +1 -0
  246. package/dist/skills/ponytail-help/SKILL.md +1 -0
  247. package/dist/skills/ponytail-review/SKILL.md +1 -0
  248. package/dist/skills/workflow-creation/SKILL.md +1 -0
  249. package/dist/utils/clipboard-native.d.ts +1 -0
  250. package/dist/utils/clipboard-native.d.ts.map +1 -1
  251. package/dist/utils/clipboard-native.js.map +1 -1
  252. package/dist/utils/clipboard.d.ts +2 -0
  253. package/dist/utils/clipboard.d.ts.map +1 -1
  254. package/dist/utils/clipboard.js +13 -0
  255. package/dist/utils/clipboard.js.map +1 -1
  256. package/package.json +26 -5
  257. package/dist/agents/architect.md +0 -217
  258. package/dist/agents/builder.md +0 -120
  259. package/dist/agents/commentator.md +0 -130
  260. package/dist/agents/explorer.md +0 -51
  261. package/dist/agents/recapper.md +0 -26
  262. package/dist/extensions/gitignore-guard.ts +0 -132
  263. package/dist/extensions/hooks/claude-codex-hooks.json +0 -44
  264. package/dist/extensions/hooks/copilot-hooks.json +0 -21
  265. package/dist/extensions/hooks/ponytail-activate.js +0 -91
  266. package/dist/extensions/hooks/ponytail-config.js +0 -122
  267. package/dist/extensions/hooks/ponytail-instructions.js +0 -94
  268. package/dist/extensions/hooks/ponytail-mode-tracker.js +0 -55
  269. package/dist/extensions/hooks/ponytail-runtime.js +0 -68
  270. package/dist/extensions/hooks/ponytail-statusline.ps1 +0 -21
  271. package/dist/extensions/hooks/ponytail-statusline.sh +0 -12
  272. package/dist/extensions/hooks/ponytail-subagent.js +0 -22
  273. package/dist/extensions/pi-extension/index.js +0 -189
  274. package/dist/extensions/pi-extension/package.json +0 -8
  275. package/dist/extensions/pi-extension/test/extension.test.js +0 -167
  276. package/dist/extensions/pi-extension/test/helpers.test.js +0 -92
  277. package/dist/extensions/pi-powerline-footer/welcome-dismiss.ts +0 -34
  278. package/dist/extensions/pi-subagents/agents/context-builder.md +0 -46
  279. package/dist/extensions/pi-subagents/agents/delegate.md +0 -12
  280. package/dist/extensions/pi-subagents/agents/oracle.md +0 -73
  281. package/dist/extensions/pi-subagents/agents/planner.md +0 -55
  282. package/dist/extensions/pi-subagents/agents/reviewer.md +0 -79
  283. package/dist/extensions/pi-subagents/agents/scout.md +0 -50
  284. package/dist/extensions/pi-subagents/agents/worker.md +0 -55
  285. package/dist/extensions/pi-subagents/src/runs/shared/spawn-timing.ts +0 -46
  286. package/dist/extensions/pi-subagents/test/unit/spawn-timing.test.ts +0 -45
  287. package/dist/extensions/pi-subagents/tsconfig.runner.json +0 -17
  288. package/dist/extensions/ponytail-pi-extension/index.js +0 -189
  289. package/dist/extensions/ponytail-pi-extension/package.json +0 -8
  290. package/dist/extensions/ponytail-pi-extension/test/extension.test.js +0 -167
  291. package/dist/extensions/ponytail-pi-extension/test/helpers.test.js +0 -92
  292. package/dist/extensions/prototype.ts +0 -713
  293. package/dist/extensions/question.ts +0 -350
  294. package/dist/extensions/quick.ts +0 -630
  295. package/dist/extensions/tps-tracker.ts +0 -280
  296. package/dist/extensions/workflow/task-validators.ts +0 -69
  297. package/dist/skills/selesai-default/SKILL.md +0 -16
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\taccessSync,\n\tchmodSync,\n\tconstants,\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"source\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nexport type SelfUpdatePackageTarget = string | { packageName: string; installSpec?: string };\n\nfunction normalizeSelfUpdatePackageTarget(target: SelfUpdatePackageTarget): {\n\tpackageName: string;\n\tinstallSpec: string;\n} {\n\tif (typeof target === \"string\") {\n\t\treturn { packageName: target, installSpec: target };\n\t}\n\treturn { packageName: target.packageName, installSpec: target.installSpec ?? target.packageName };\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tif (existsSync(join(getPackageDir(), \".git\"))) {\n\t\treturn \"source\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageTarget: SelfUpdatePackageTarget = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"source\": {\n\t\t\tif (target.packageName !== installedPackageName) return undefined;\n\t\t\tconst packageDir = getPackageDir();\n\t\t\tconst steps = [\n\t\t\t\tmakeSelfUpdateCommandStep(\"git\", [\"-C\", packageDir, \"pull\", \"--ff-only\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"install\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"run\", \"build\"]),\n\t\t\t];\n\t\t\treturn { ...steps[0], display: steps.map((step) => step.display).join(\" && \"), steps };\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst match = readCommandOutput(\"pnpm\", [\"root\", \"-g\"])\n\t\t\t\t? undefined\n\t\t\t\t: /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\tconst binDirArgs = match\n\t\t\t\t? [`--config.global-bin-dir=${process.env.PNPM_HOME || dirname(dirname(match[1]))}`]\n\t\t\t\t: [];\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\t...binDirArgs,\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", ...binDirArgs, installedPackageName]),\n\t\t\t);\n\t\t}\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", target.installSpec]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\ttarget.installSpec,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\tif (root) return [root, dirname(root)];\n\t\t\tconst match = /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\treturn match ? [match[1]] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"source\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageTarget, npmCommand);\n\tif (!command || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\tif (method !== \"source\" && !isManagedByGlobalPackageManager(method, packageName, npmCommand)) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/earendil-works/pi-mono/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);\n\tif (command) {\n\t\tif (method === \"source\") {\n\t\t\treturn isSelfUpdatePathWritable()\n\t\t\t\t? `Update the source checkout yourself with: ${command.display}`\n\t\t\t\t: `This source checkout is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.PI_PACKAGE_DIR;\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/**\n * Resolve a bundled subdirectory shipped with the package (defaults/extensions/themes).\n * - For Bun binary: <dir>/ next to executable\n * - For Node.js (dist/): dist/<dir>/\n * - For tsx (src/): src/<dir>/\n */\nfunction getBundledSubdir(name: string): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), name);\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, name);\n}\n\n/**\n * Get path to bundled default config directory (shipped with package).\n * Holds bundled defaults. settings.json is copied on first run; models.json is loaded directly.\n */\nexport function getBundledDefaultsDir(): string {\n\treturn getBundledSubdir(\"defaults\");\n}\n\n/**\n * Get path to bundled built-in extensions directory (shipped with package).\n * Loaded directly via additionalExtensionPaths at boot (not copied into the\n * user agent dir) — same hook as CLI --extension. .ts ships as-is (jiti loads it).\n * - For Bun binary: extensions/ next to executable\n * - For Node.js (dist/): dist/extensions/\n * - For tsx (src/): src/extensions/\n */\nexport function getBundledExtensionsDir(): string {\n\treturn getBundledSubdir(\"extensions\");\n}\n\n/**\n * Get path to bundled built-in themes directory (shipped with package).\n * Loaded directly via additionalThemePaths at boot.\n */\nexport function getBundledThemesDir(): string {\n\treturn getBundledSubdir(\"themes\");\n}\n\n/**\n * Get path to bundled built-in skills directory (shipped with package).\n * Loaded directly via additionalSkillPaths at boot.\n */\nexport function getBundledSkillsDir(): string {\n\treturn getBundledSubdir(\"skills\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@earendil-works/pi-coding-agent\";\nexport const APP_NAME: string = piConfigName || \"pi\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".pi\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://pi.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.PI_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.pi/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.pi/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n\n/**\n * Marker file written once first-time onboarding completes. Decouples the\n * first-run dialog gate from settings.json existence so that bootstrapping a\n * bundled default settings.json does not suppress the dialog.\n */\nexport function getFirstRunMarkerPath(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \".firstRunComplete\");\n}\n\n/**\n * Mark first-run onboarding as complete. Safe to call repeatedly.\n */\nexport function markFirstRunComplete(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\twriteFileSync(getFirstRunMarkerPath(agentDir), \"1\", { mode: 0o600 });\n}\n\n// =============================================================================\n// Agent Dir Bootstrap (first-run seeding)\n// =============================================================================\n\n/** Subdirectories created under the agent dir on first run. */\nconst AGENT_SUBDIRS = [\n\t\"themes\",\n\t\"tools\",\n\t\"bin\",\n\t\"prompts\",\n\t\"sessions\",\n\t\"extensions\",\n\t\"skills\",\n] as const;\n\n/**\n * Ensure the agent dir and standard subdirs exist (mode 0o700 for privacy).\n * Safe to call on every startup; no-op when dirs already exist.\n */\nexport function ensureAgentDir(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\tfor (const sub of AGENT_SUBDIRS) {\n\t\tmkdirSync(join(agentDir, sub), { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Seed a default config file from the bundled defaults dir if it does not yet\n * exist. Never overwrites an existing user file. Returns the destination path\n * when a seed was written, undefined when the file already existed or the\n * bundled source is missing.\n */\nexport function seedDefaultConfigFile(\n\tdestPath: string,\n\tbundledName: string,\n\tbundledDefaultsDir: string = getBundledDefaultsDir(),\n): string | undefined {\n\tif (existsSync(destPath)) return undefined;\n\tconst source = join(bundledDefaultsDir, bundledName);\n\tif (!existsSync(source)) return undefined;\n\tmkdirSync(dirname(destPath), { recursive: true, mode: 0o700 });\n\tcopyFileSync(source, destPath);\n\ttry {\n\t\tchmodSync(destPath, 0o600);\n\t} catch {\n\t\t// chmod is best-effort (no-op on platforms that don't support it).\n\t}\n\treturn destPath;\n}\n\n/**\n * Recursively copy a bundled directory tree into the user's agent dir, skipping\n * any file that already exists (user edits survive). Never overwrites. Used to\n * seed bundled skills/themes so the user can inspect and edit them.\n * Returns the list of destination paths that were written.\n */\nfunction seedBundledDir(\n\tdestDir: string,\n\tbundledDir: string,\n): string[] {\n\tif (!existsSync(bundledDir)) return [];\n\tmkdirSync(destDir, { recursive: true, mode: 0o700 });\n\tconst written: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tmkdirSync(dst, { recursive: true, mode: 0o700 });\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tif (!existsSync(dstPath)) mkdirSync(dstPath, { recursive: true, mode: 0o700 });\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (entry.isFile() || entry.isSymbolicLink()) {\n\t\t\t\tif (existsSync(dstPath)) continue;\n\t\t\t\tcopyFileSync(srcPath, dstPath);\n\t\t\t\ttry {\n\t\t\t\t\tchmodSync(dstPath, 0o600);\n\t\t\t\t} catch {\n\t\t\t\t\t// best-effort\n\t\t\t\t}\n\t\t\t\twritten.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn written;\n}\n\nfunction removeIdenticalBundledFiles(destDir: string, bundledDir: string): string[] {\n\tif (!existsSync(destDir) || !existsSync(bundledDir)) return [];\n\tconst removed: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tif (!existsSync(dst)) continue;\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (existsSync(dstPath) && readFileSync(srcPath).equals(readFileSync(dstPath))) {\n\t\t\t\tunlinkSync(dstPath);\n\t\t\t\tremoved.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn removed;\n}\n\n/**\n * Bundled extensions load directly from the installed package. Do not copy them\n * into the user's agent dir, otherwise startup discovers both copies and tool\n * registration conflicts with itself.\n * Remove files copied by older releases only when they are byte-identical to\n * bundled files, so user-edited extensions survive.\n */\nexport function seedDefaultExtensions(\n\tagentDir: string,\n\tbundledExtensionsDir: string = getBundledExtensionsDir(),\n): string[] {\n\tremoveIdenticalBundledFiles(join(agentDir, \"extensions\"), bundledExtensionsDir);\n\treturn [];\n}\n\n/**\n * Seed bundled built-in skills into the user's agent dir/skills.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultSkills(\n\tagentDir: string,\n\tbundledSkillsDir: string = getBundledSkillsDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"skills\"), bundledSkillsDir);\n}\n\n/**\n * Seed bundled built-in themes into the user's agent dir/themes.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultThemes(\n\tagentDir: string,\n\tbundledThemesDir: string = getBundledThemesDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"themes\"), bundledThemesDir);\n}\n\n/**\n * Run full first-run bootstrap for the agent dir: ensure directories and seed\n * settings.json from bundled defaults. Idempotent — safe on every startup.\n * Bundled models load package-locally; copying them would expose internal\n * providers as user config. Bundled extensions also stay package-local.\n */\nexport function bootstrapAgentDir(agentDir: string = getAgentDir()): void {\n\tensureAgentDir(agentDir);\n\tseedDefaultConfigFile(join(agentDir, \"settings.json\"), \"settings.json\");\n\tseedDefaultExtensions(agentDir);\n\tseedDefaultSkills(agentDir);\n\tseedDefaultThemes(agentDir);\n}\n"]}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\taccessSync,\n\tchmodSync,\n\tconstants,\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"source\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nexport type SelfUpdatePackageTarget = string | { packageName: string; installSpec?: string };\n\nfunction normalizeSelfUpdatePackageTarget(target: SelfUpdatePackageTarget): {\n\tpackageName: string;\n\tinstallSpec: string;\n} {\n\tif (typeof target === \"string\") {\n\t\treturn { packageName: target, installSpec: target };\n\t}\n\treturn { packageName: target.packageName, installSpec: target.installSpec ?? target.packageName };\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tif (existsSync(join(getPackageDir(), \".git\"))) {\n\t\treturn \"source\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageTarget: SelfUpdatePackageTarget = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"source\": {\n\t\t\tif (target.packageName !== installedPackageName) return undefined;\n\t\t\tconst packageDir = getPackageDir();\n\t\t\tconst steps = [\n\t\t\t\tmakeSelfUpdateCommandStep(\"git\", [\"-C\", packageDir, \"pull\", \"--ff-only\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"install\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"run\", \"build\"]),\n\t\t\t];\n\t\t\treturn { ...steps[0], display: steps.map((step) => step.display).join(\" && \"), steps };\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst match = readCommandOutput(\"pnpm\", [\"root\", \"-g\"])\n\t\t\t\t? undefined\n\t\t\t\t: /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\tconst binDirArgs = match\n\t\t\t\t? [`--config.global-bin-dir=${process.env.PNPM_HOME || dirname(dirname(match[1]))}`]\n\t\t\t\t: [];\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\t...binDirArgs,\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", ...binDirArgs, installedPackageName]),\n\t\t\t);\n\t\t}\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", target.installSpec]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\ttarget.installSpec,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\tif (root) return [root, dirname(root)];\n\t\t\tconst match = /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\treturn match ? [match[1]] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"source\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageTarget, npmCommand);\n\tif (!command || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\tif (method !== \"source\" && !isManagedByGlobalPackageManager(method, packageName, npmCommand)) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/earendil-works/pi-mono/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);\n\tif (command) {\n\t\tif (method === \"source\") {\n\t\t\treturn isSelfUpdatePathWritable()\n\t\t\t\t? `Update the source checkout yourself with: ${command.display}`\n\t\t\t\t: `This source checkout is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.PI_PACKAGE_DIR;\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/**\n * Resolve a bundled subdirectory shipped with the package (defaults/extensions/themes).\n * - For Bun binary: <dir>/ next to executable\n * - For Node.js (dist/): dist/<dir>/\n * - For tsx (src/): src/<dir>/\n */\nfunction getBundledSubdir(name: string): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), name);\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, name);\n}\n\n/**\n * Get path to bundled default config directory (shipped with package).\n * Holds bundled defaults. settings.json is copied on first run; models.json is loaded directly.\n */\nexport function getBundledDefaultsDir(): string {\n\treturn getBundledSubdir(\"defaults\");\n}\n\n/**\n * Get path to bundled built-in extensions directory (shipped with package).\n * Loaded directly via additionalExtensionPaths at boot (not copied into the\n * user agent dir) — same hook as CLI --extension. .ts ships as-is (jiti loads it).\n * - For Bun binary: extensions/ next to executable\n * - For Node.js (dist/): dist/extensions/\n * - For tsx (src/): src/extensions/\n */\nexport function getBundledExtensionsDir(): string {\n\treturn getBundledSubdir(\"extensions\");\n}\n\n/**\n * Get path to bundled built-in themes directory (shipped with package).\n * Loaded directly via additionalThemePaths at boot.\n */\nexport function getBundledThemesDir(): string {\n\treturn getBundledSubdir(\"themes\");\n}\n\n/**\n * Get path to bundled built-in skills directory (shipped with package).\n * Loaded directly via additionalSkillPaths at boot.\n */\nexport function getBundledSkillsDir(): string {\n\treturn getBundledSubdir(\"skills\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@earendil-works/pi-coding-agent\";\nexport const APP_NAME: string = piConfigName || \"pi\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".pi\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://pi.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.PI_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/<configured-dir>/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.selesai/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n\n/**\n * Marker file written once first-time onboarding completes. Decouples the\n * first-run dialog gate from settings.json existence so that bootstrapping a\n * bundled default settings.json does not suppress the dialog.\n */\nexport function getFirstRunMarkerPath(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \".firstRunComplete\");\n}\n\n/**\n * Mark first-run onboarding as complete. Safe to call repeatedly.\n */\nexport function markFirstRunComplete(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\twriteFileSync(getFirstRunMarkerPath(agentDir), \"1\", { mode: 0o600 });\n}\n\n// =============================================================================\n// Agent Dir Bootstrap (first-run seeding)\n// =============================================================================\n\n/** Subdirectories created under the agent dir on first run. */\nconst AGENT_SUBDIRS = [\n\t\"themes\",\n\t\"tools\",\n\t\"bin\",\n\t\"prompts\",\n\t\"sessions\",\n\t\"extensions\",\n\t\"skills\",\n] as const;\n\n/**\n * Ensure the agent dir and standard subdirs exist (mode 0o700 for privacy).\n * Safe to call on every startup; no-op when dirs already exist.\n */\nexport function ensureAgentDir(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\tfor (const sub of AGENT_SUBDIRS) {\n\t\tmkdirSync(join(agentDir, sub), { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Seed a default config file from the bundled defaults dir if it does not yet\n * exist. Never overwrites an existing user file. Returns the destination path\n * when a seed was written, undefined when the file already existed or the\n * bundled source is missing.\n */\nexport function seedDefaultConfigFile(\n\tdestPath: string,\n\tbundledName: string,\n\tbundledDefaultsDir: string = getBundledDefaultsDir(),\n): string | undefined {\n\tif (existsSync(destPath)) return undefined;\n\tconst source = join(bundledDefaultsDir, bundledName);\n\tif (!existsSync(source)) return undefined;\n\tmkdirSync(dirname(destPath), { recursive: true, mode: 0o700 });\n\tcopyFileSync(source, destPath);\n\ttry {\n\t\tchmodSync(destPath, 0o600);\n\t} catch {\n\t\t// chmod is best-effort (no-op on platforms that don't support it).\n\t}\n\treturn destPath;\n}\n\n/**\n * Recursively copy a bundled directory tree into the user's agent dir, skipping\n * any file that already exists (user edits survive). Never overwrites. Used to\n * seed bundled skills/themes so the user can inspect and edit them.\n * Returns the list of destination paths that were written.\n */\nfunction seedBundledDir(\n\tdestDir: string,\n\tbundledDir: string,\n): string[] {\n\tif (!existsSync(bundledDir)) return [];\n\tmkdirSync(destDir, { recursive: true, mode: 0o700 });\n\tconst written: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tmkdirSync(dst, { recursive: true, mode: 0o700 });\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tif (!existsSync(dstPath)) mkdirSync(dstPath, { recursive: true, mode: 0o700 });\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (entry.isFile() || entry.isSymbolicLink()) {\n\t\t\t\tif (existsSync(dstPath)) continue;\n\t\t\t\tcopyFileSync(srcPath, dstPath);\n\t\t\t\ttry {\n\t\t\t\t\tchmodSync(dstPath, 0o600);\n\t\t\t\t} catch {\n\t\t\t\t\t// best-effort\n\t\t\t\t}\n\t\t\t\twritten.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn written;\n}\n\nfunction removeIdenticalBundledFiles(destDir: string, bundledDir: string): string[] {\n\tif (!existsSync(destDir) || !existsSync(bundledDir)) return [];\n\tconst removed: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tif (!existsSync(dst)) continue;\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (existsSync(dstPath) && readFileSync(srcPath).equals(readFileSync(dstPath))) {\n\t\t\t\tunlinkSync(dstPath);\n\t\t\t\tremoved.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn removed;\n}\n\n/**\n * Bundled extensions load directly from the installed package. Do not copy them\n * into the user's agent dir, otherwise startup discovers both copies and tool\n * registration conflicts with itself.\n * Remove files copied by older releases only when they are byte-identical to\n * bundled files, so user-edited extensions survive.\n */\nexport function seedDefaultExtensions(\n\tagentDir: string,\n\tbundledExtensionsDir: string = getBundledExtensionsDir(),\n): string[] {\n\tremoveIdenticalBundledFiles(join(agentDir, \"extensions\"), bundledExtensionsDir);\n\treturn [];\n}\n\n/**\n * Seed bundled built-in skills into the user's agent dir/skills.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultSkills(\n\tagentDir: string,\n\tbundledSkillsDir: string = getBundledSkillsDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"skills\"), bundledSkillsDir);\n}\n\n/**\n * Seed bundled built-in themes into the user's agent dir/themes.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultThemes(\n\tagentDir: string,\n\tbundledThemesDir: string = getBundledThemesDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"themes\"), bundledThemesDir);\n}\n\n/**\n * Run full first-run bootstrap for the agent dir: ensure directories and seed\n * settings.json from bundled defaults. Idempotent — safe on every startup.\n * Bundled models load package-locally; copying them would expose internal\n * providers as user config. Bundled extensions also stay package-local.\n */\nexport function bootstrapAgentDir(agentDir: string = getAgentDir()): void {\n\tensureAgentDir(agentDir);\n\tseedDefaultConfigFile(join(agentDir, \"settings.json\"), \"settings.json\");\n\tseedDefaultExtensions(agentDir);\n\tseedDefaultSkills(agentDir);\n\tseedDefaultThemes(agentDir);\n}\n"]}
package/dist/config.js CHANGED
@@ -475,9 +475,9 @@ export function getShareViewerUrl(gistId) {
475
475
  return `${baseUrl}#${gistId}`;
476
476
  }
477
477
  // =============================================================================
478
- // User Config Paths (~/.pi/agent/*)
478
+ // User Config Paths (~/<configured-dir>/agent/*)
479
479
  // =============================================================================
480
- /** Get the agent config directory (e.g., ~/.pi/agent/) */
480
+ /** Get the agent config directory (e.g., ~/.selesai/agent/) */
481
481
  export function getAgentDir() {
482
482
  const envDir = process.env[ENV_AGENT_DIR];
483
483
  if (envDir) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\taccessSync,\n\tchmodSync,\n\tconstants,\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"source\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nexport type SelfUpdatePackageTarget = string | { packageName: string; installSpec?: string };\n\nfunction normalizeSelfUpdatePackageTarget(target: SelfUpdatePackageTarget): {\n\tpackageName: string;\n\tinstallSpec: string;\n} {\n\tif (typeof target === \"string\") {\n\t\treturn { packageName: target, installSpec: target };\n\t}\n\treturn { packageName: target.packageName, installSpec: target.installSpec ?? target.packageName };\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tif (existsSync(join(getPackageDir(), \".git\"))) {\n\t\treturn \"source\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageTarget: SelfUpdatePackageTarget = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"source\": {\n\t\t\tif (target.packageName !== installedPackageName) return undefined;\n\t\t\tconst packageDir = getPackageDir();\n\t\t\tconst steps = [\n\t\t\t\tmakeSelfUpdateCommandStep(\"git\", [\"-C\", packageDir, \"pull\", \"--ff-only\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"install\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"run\", \"build\"]),\n\t\t\t];\n\t\t\treturn { ...steps[0], display: steps.map((step) => step.display).join(\" && \"), steps };\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst match = readCommandOutput(\"pnpm\", [\"root\", \"-g\"])\n\t\t\t\t? undefined\n\t\t\t\t: /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\tconst binDirArgs = match\n\t\t\t\t? [`--config.global-bin-dir=${process.env.PNPM_HOME || dirname(dirname(match[1]))}`]\n\t\t\t\t: [];\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\t...binDirArgs,\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", ...binDirArgs, installedPackageName]),\n\t\t\t);\n\t\t}\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", target.installSpec]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\ttarget.installSpec,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\tif (root) return [root, dirname(root)];\n\t\t\tconst match = /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\treturn match ? [match[1]] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"source\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageTarget, npmCommand);\n\tif (!command || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\tif (method !== \"source\" && !isManagedByGlobalPackageManager(method, packageName, npmCommand)) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/earendil-works/pi-mono/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);\n\tif (command) {\n\t\tif (method === \"source\") {\n\t\t\treturn isSelfUpdatePathWritable()\n\t\t\t\t? `Update the source checkout yourself with: ${command.display}`\n\t\t\t\t: `This source checkout is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.PI_PACKAGE_DIR;\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/**\n * Resolve a bundled subdirectory shipped with the package (defaults/extensions/themes).\n * - For Bun binary: <dir>/ next to executable\n * - For Node.js (dist/): dist/<dir>/\n * - For tsx (src/): src/<dir>/\n */\nfunction getBundledSubdir(name: string): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), name);\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, name);\n}\n\n/**\n * Get path to bundled default config directory (shipped with package).\n * Holds bundled defaults. settings.json is copied on first run; models.json is loaded directly.\n */\nexport function getBundledDefaultsDir(): string {\n\treturn getBundledSubdir(\"defaults\");\n}\n\n/**\n * Get path to bundled built-in extensions directory (shipped with package).\n * Loaded directly via additionalExtensionPaths at boot (not copied into the\n * user agent dir) — same hook as CLI --extension. .ts ships as-is (jiti loads it).\n * - For Bun binary: extensions/ next to executable\n * - For Node.js (dist/): dist/extensions/\n * - For tsx (src/): src/extensions/\n */\nexport function getBundledExtensionsDir(): string {\n\treturn getBundledSubdir(\"extensions\");\n}\n\n/**\n * Get path to bundled built-in themes directory (shipped with package).\n * Loaded directly via additionalThemePaths at boot.\n */\nexport function getBundledThemesDir(): string {\n\treturn getBundledSubdir(\"themes\");\n}\n\n/**\n * Get path to bundled built-in skills directory (shipped with package).\n * Loaded directly via additionalSkillPaths at boot.\n */\nexport function getBundledSkillsDir(): string {\n\treturn getBundledSubdir(\"skills\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@earendil-works/pi-coding-agent\";\nexport const APP_NAME: string = piConfigName || \"pi\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".pi\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://pi.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.PI_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.pi/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.pi/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n\n/**\n * Marker file written once first-time onboarding completes. Decouples the\n * first-run dialog gate from settings.json existence so that bootstrapping a\n * bundled default settings.json does not suppress the dialog.\n */\nexport function getFirstRunMarkerPath(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \".firstRunComplete\");\n}\n\n/**\n * Mark first-run onboarding as complete. Safe to call repeatedly.\n */\nexport function markFirstRunComplete(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\twriteFileSync(getFirstRunMarkerPath(agentDir), \"1\", { mode: 0o600 });\n}\n\n// =============================================================================\n// Agent Dir Bootstrap (first-run seeding)\n// =============================================================================\n\n/** Subdirectories created under the agent dir on first run. */\nconst AGENT_SUBDIRS = [\n\t\"themes\",\n\t\"tools\",\n\t\"bin\",\n\t\"prompts\",\n\t\"sessions\",\n\t\"extensions\",\n\t\"skills\",\n] as const;\n\n/**\n * Ensure the agent dir and standard subdirs exist (mode 0o700 for privacy).\n * Safe to call on every startup; no-op when dirs already exist.\n */\nexport function ensureAgentDir(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\tfor (const sub of AGENT_SUBDIRS) {\n\t\tmkdirSync(join(agentDir, sub), { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Seed a default config file from the bundled defaults dir if it does not yet\n * exist. Never overwrites an existing user file. Returns the destination path\n * when a seed was written, undefined when the file already existed or the\n * bundled source is missing.\n */\nexport function seedDefaultConfigFile(\n\tdestPath: string,\n\tbundledName: string,\n\tbundledDefaultsDir: string = getBundledDefaultsDir(),\n): string | undefined {\n\tif (existsSync(destPath)) return undefined;\n\tconst source = join(bundledDefaultsDir, bundledName);\n\tif (!existsSync(source)) return undefined;\n\tmkdirSync(dirname(destPath), { recursive: true, mode: 0o700 });\n\tcopyFileSync(source, destPath);\n\ttry {\n\t\tchmodSync(destPath, 0o600);\n\t} catch {\n\t\t// chmod is best-effort (no-op on platforms that don't support it).\n\t}\n\treturn destPath;\n}\n\n/**\n * Recursively copy a bundled directory tree into the user's agent dir, skipping\n * any file that already exists (user edits survive). Never overwrites. Used to\n * seed bundled skills/themes so the user can inspect and edit them.\n * Returns the list of destination paths that were written.\n */\nfunction seedBundledDir(\n\tdestDir: string,\n\tbundledDir: string,\n): string[] {\n\tif (!existsSync(bundledDir)) return [];\n\tmkdirSync(destDir, { recursive: true, mode: 0o700 });\n\tconst written: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tmkdirSync(dst, { recursive: true, mode: 0o700 });\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tif (!existsSync(dstPath)) mkdirSync(dstPath, { recursive: true, mode: 0o700 });\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (entry.isFile() || entry.isSymbolicLink()) {\n\t\t\t\tif (existsSync(dstPath)) continue;\n\t\t\t\tcopyFileSync(srcPath, dstPath);\n\t\t\t\ttry {\n\t\t\t\t\tchmodSync(dstPath, 0o600);\n\t\t\t\t} catch {\n\t\t\t\t\t// best-effort\n\t\t\t\t}\n\t\t\t\twritten.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn written;\n}\n\nfunction removeIdenticalBundledFiles(destDir: string, bundledDir: string): string[] {\n\tif (!existsSync(destDir) || !existsSync(bundledDir)) return [];\n\tconst removed: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tif (!existsSync(dst)) continue;\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (existsSync(dstPath) && readFileSync(srcPath).equals(readFileSync(dstPath))) {\n\t\t\t\tunlinkSync(dstPath);\n\t\t\t\tremoved.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn removed;\n}\n\n/**\n * Bundled extensions load directly from the installed package. Do not copy them\n * into the user's agent dir, otherwise startup discovers both copies and tool\n * registration conflicts with itself.\n * Remove files copied by older releases only when they are byte-identical to\n * bundled files, so user-edited extensions survive.\n */\nexport function seedDefaultExtensions(\n\tagentDir: string,\n\tbundledExtensionsDir: string = getBundledExtensionsDir(),\n): string[] {\n\tremoveIdenticalBundledFiles(join(agentDir, \"extensions\"), bundledExtensionsDir);\n\treturn [];\n}\n\n/**\n * Seed bundled built-in skills into the user's agent dir/skills.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultSkills(\n\tagentDir: string,\n\tbundledSkillsDir: string = getBundledSkillsDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"skills\"), bundledSkillsDir);\n}\n\n/**\n * Seed bundled built-in themes into the user's agent dir/themes.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultThemes(\n\tagentDir: string,\n\tbundledThemesDir: string = getBundledThemesDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"themes\"), bundledThemesDir);\n}\n\n/**\n * Run full first-run bootstrap for the agent dir: ensure directories and seed\n * settings.json from bundled defaults. Idempotent — safe on every startup.\n * Bundled models load package-locally; copying them would expose internal\n * providers as user config. Bundled extensions also stay package-local.\n */\nexport function bootstrapAgentDir(agentDir: string = getAgentDir()): void {\n\tensureAgentDir(agentDir);\n\tseedDefaultConfigFile(join(agentDir, \"settings.json\"), \"settings.json\");\n\tseedDefaultExtensions(agentDir);\n\tseedDefaultSkills(agentDir);\n\tseedDefaultThemes(agentDir);\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\taccessSync,\n\tchmodSync,\n\tconstants,\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"source\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nexport type SelfUpdatePackageTarget = string | { packageName: string; installSpec?: string };\n\nfunction normalizeSelfUpdatePackageTarget(target: SelfUpdatePackageTarget): {\n\tpackageName: string;\n\tinstallSpec: string;\n} {\n\tif (typeof target === \"string\") {\n\t\treturn { packageName: target, installSpec: target };\n\t}\n\treturn { packageName: target.packageName, installSpec: target.installSpec ?? target.packageName };\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tif (existsSync(join(getPackageDir(), \".git\"))) {\n\t\treturn \"source\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageTarget: SelfUpdatePackageTarget = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"source\": {\n\t\t\tif (target.packageName !== installedPackageName) return undefined;\n\t\t\tconst packageDir = getPackageDir();\n\t\t\tconst steps = [\n\t\t\t\tmakeSelfUpdateCommandStep(\"git\", [\"-C\", packageDir, \"pull\", \"--ff-only\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"install\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"run\", \"build\"]),\n\t\t\t];\n\t\t\treturn { ...steps[0], display: steps.map((step) => step.display).join(\" && \"), steps };\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst match = readCommandOutput(\"pnpm\", [\"root\", \"-g\"])\n\t\t\t\t? undefined\n\t\t\t\t: /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\tconst binDirArgs = match\n\t\t\t\t? [`--config.global-bin-dir=${process.env.PNPM_HOME || dirname(dirname(match[1]))}`]\n\t\t\t\t: [];\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\t...binDirArgs,\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", ...binDirArgs, installedPackageName]),\n\t\t\t);\n\t\t}\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", target.installSpec]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\ttarget.installSpec,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\tif (root) return [root, dirname(root)];\n\t\t\tconst match = /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\treturn match ? [match[1]] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"source\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageTarget, npmCommand);\n\tif (!command || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\tif (method !== \"source\" && !isManagedByGlobalPackageManager(method, packageName, npmCommand)) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/earendil-works/pi-mono/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);\n\tif (command) {\n\t\tif (method === \"source\") {\n\t\t\treturn isSelfUpdatePathWritable()\n\t\t\t\t? `Update the source checkout yourself with: ${command.display}`\n\t\t\t\t: `This source checkout is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.PI_PACKAGE_DIR;\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/**\n * Resolve a bundled subdirectory shipped with the package (defaults/extensions/themes).\n * - For Bun binary: <dir>/ next to executable\n * - For Node.js (dist/): dist/<dir>/\n * - For tsx (src/): src/<dir>/\n */\nfunction getBundledSubdir(name: string): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), name);\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, name);\n}\n\n/**\n * Get path to bundled default config directory (shipped with package).\n * Holds bundled defaults. settings.json is copied on first run; models.json is loaded directly.\n */\nexport function getBundledDefaultsDir(): string {\n\treturn getBundledSubdir(\"defaults\");\n}\n\n/**\n * Get path to bundled built-in extensions directory (shipped with package).\n * Loaded directly via additionalExtensionPaths at boot (not copied into the\n * user agent dir) — same hook as CLI --extension. .ts ships as-is (jiti loads it).\n * - For Bun binary: extensions/ next to executable\n * - For Node.js (dist/): dist/extensions/\n * - For tsx (src/): src/extensions/\n */\nexport function getBundledExtensionsDir(): string {\n\treturn getBundledSubdir(\"extensions\");\n}\n\n/**\n * Get path to bundled built-in themes directory (shipped with package).\n * Loaded directly via additionalThemePaths at boot.\n */\nexport function getBundledThemesDir(): string {\n\treturn getBundledSubdir(\"themes\");\n}\n\n/**\n * Get path to bundled built-in skills directory (shipped with package).\n * Loaded directly via additionalSkillPaths at boot.\n */\nexport function getBundledSkillsDir(): string {\n\treturn getBundledSubdir(\"skills\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@earendil-works/pi-coding-agent\";\nexport const APP_NAME: string = piConfigName || \"pi\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".pi\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://pi.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.PI_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/<configured-dir>/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.selesai/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n\n/**\n * Marker file written once first-time onboarding completes. Decouples the\n * first-run dialog gate from settings.json existence so that bootstrapping a\n * bundled default settings.json does not suppress the dialog.\n */\nexport function getFirstRunMarkerPath(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \".firstRunComplete\");\n}\n\n/**\n * Mark first-run onboarding as complete. Safe to call repeatedly.\n */\nexport function markFirstRunComplete(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\twriteFileSync(getFirstRunMarkerPath(agentDir), \"1\", { mode: 0o600 });\n}\n\n// =============================================================================\n// Agent Dir Bootstrap (first-run seeding)\n// =============================================================================\n\n/** Subdirectories created under the agent dir on first run. */\nconst AGENT_SUBDIRS = [\n\t\"themes\",\n\t\"tools\",\n\t\"bin\",\n\t\"prompts\",\n\t\"sessions\",\n\t\"extensions\",\n\t\"skills\",\n] as const;\n\n/**\n * Ensure the agent dir and standard subdirs exist (mode 0o700 for privacy).\n * Safe to call on every startup; no-op when dirs already exist.\n */\nexport function ensureAgentDir(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\tfor (const sub of AGENT_SUBDIRS) {\n\t\tmkdirSync(join(agentDir, sub), { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Seed a default config file from the bundled defaults dir if it does not yet\n * exist. Never overwrites an existing user file. Returns the destination path\n * when a seed was written, undefined when the file already existed or the\n * bundled source is missing.\n */\nexport function seedDefaultConfigFile(\n\tdestPath: string,\n\tbundledName: string,\n\tbundledDefaultsDir: string = getBundledDefaultsDir(),\n): string | undefined {\n\tif (existsSync(destPath)) return undefined;\n\tconst source = join(bundledDefaultsDir, bundledName);\n\tif (!existsSync(source)) return undefined;\n\tmkdirSync(dirname(destPath), { recursive: true, mode: 0o700 });\n\tcopyFileSync(source, destPath);\n\ttry {\n\t\tchmodSync(destPath, 0o600);\n\t} catch {\n\t\t// chmod is best-effort (no-op on platforms that don't support it).\n\t}\n\treturn destPath;\n}\n\n/**\n * Recursively copy a bundled directory tree into the user's agent dir, skipping\n * any file that already exists (user edits survive). Never overwrites. Used to\n * seed bundled skills/themes so the user can inspect and edit them.\n * Returns the list of destination paths that were written.\n */\nfunction seedBundledDir(\n\tdestDir: string,\n\tbundledDir: string,\n): string[] {\n\tif (!existsSync(bundledDir)) return [];\n\tmkdirSync(destDir, { recursive: true, mode: 0o700 });\n\tconst written: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tmkdirSync(dst, { recursive: true, mode: 0o700 });\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tif (!existsSync(dstPath)) mkdirSync(dstPath, { recursive: true, mode: 0o700 });\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (entry.isFile() || entry.isSymbolicLink()) {\n\t\t\t\tif (existsSync(dstPath)) continue;\n\t\t\t\tcopyFileSync(srcPath, dstPath);\n\t\t\t\ttry {\n\t\t\t\t\tchmodSync(dstPath, 0o600);\n\t\t\t\t} catch {\n\t\t\t\t\t// best-effort\n\t\t\t\t}\n\t\t\t\twritten.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn written;\n}\n\nfunction removeIdenticalBundledFiles(destDir: string, bundledDir: string): string[] {\n\tif (!existsSync(destDir) || !existsSync(bundledDir)) return [];\n\tconst removed: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tif (!existsSync(dst)) continue;\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (existsSync(dstPath) && readFileSync(srcPath).equals(readFileSync(dstPath))) {\n\t\t\t\tunlinkSync(dstPath);\n\t\t\t\tremoved.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn removed;\n}\n\n/**\n * Bundled extensions load directly from the installed package. Do not copy them\n * into the user's agent dir, otherwise startup discovers both copies and tool\n * registration conflicts with itself.\n * Remove files copied by older releases only when they are byte-identical to\n * bundled files, so user-edited extensions survive.\n */\nexport function seedDefaultExtensions(\n\tagentDir: string,\n\tbundledExtensionsDir: string = getBundledExtensionsDir(),\n): string[] {\n\tremoveIdenticalBundledFiles(join(agentDir, \"extensions\"), bundledExtensionsDir);\n\treturn [];\n}\n\n/**\n * Seed bundled built-in skills into the user's agent dir/skills.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultSkills(\n\tagentDir: string,\n\tbundledSkillsDir: string = getBundledSkillsDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"skills\"), bundledSkillsDir);\n}\n\n/**\n * Seed bundled built-in themes into the user's agent dir/themes.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultThemes(\n\tagentDir: string,\n\tbundledThemesDir: string = getBundledThemesDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"themes\"), bundledThemesDir);\n}\n\n/**\n * Run full first-run bootstrap for the agent dir: ensure directories and seed\n * settings.json from bundled defaults. Idempotent — safe on every startup.\n * Bundled models load package-locally; copying them would expose internal\n * providers as user config. Bundled extensions also stay package-local.\n */\nexport function bootstrapAgentDir(agentDir: string = getAgentDir()): void {\n\tensureAgentDir(agentDir);\n\tseedDefaultConfigFile(join(agentDir, \"settings.json\"), \"settings.json\");\n\tseedDefaultExtensions(agentDir);\n\tseedDefaultSkills(agentDir);\n\tseedDefaultThemes(agentDir);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-session-auto-handoff.test.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-auto-handoff.test.ts"],"names":[],"mappings":"","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { ResolvedCommand } from \"./extensions/types.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\nfunction createMockSession({\n\tenabled,\n\tthreshold = 128_000,\n\ttokens,\n\tmode = \"tui\",\n\tcommand,\n}: {\n\tenabled: boolean;\n\tthreshold?: number;\n\ttokens: number | null;\n\tmode?: \"tui\" | \"print\" | \"rpc\";\n\tcommand?: ResolvedCommand | undefined;\n}) {\n\tconst settings = SettingsManager.inMemory({\n\t\tautoHandoff: { enabled, thresholdTokens: threshold },\n\t});\n\n\tconst getCommand = vi.fn(() => command);\n\tconst handler = command?.handler ?? vi.fn();\n\tconst createCommandContext = vi.fn(() => ({ mock: \"ctx\" }) as unknown as never);\n\tconst emitError = vi.fn();\n\n\tconst extensionRunner = {\n\t\tgetCommand,\n\t\tcreateCommandContext,\n\t\temitError,\n\t\temit: vi.fn(),\n\t} as unknown as ExtensionRunner;\n\n\tconst resourceLoader = {\n\t\tgetExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], assertActive: () => {} } }),\n\t\tgetSkills: () => ({ skills: [], diagnostics: [] }),\n\t\tgetPrompts: () => ({ prompts: [], diagnostics: [] }),\n\t\tgetThemes: () => ({ themes: [], diagnostics: [] }),\n\t\tgetAgents: () => ({ agents: [], diagnostics: [] }),\n\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\tgetSystemPrompt: () => undefined,\n\t\tgetAppendSystemPrompt: () => [],\n\t\tgetExtensionDiagnostics: () => [],\n\t\textendResources: () => {},\n\t\treload: vi.fn(),\n\t};\n\n\tconst modelRegistry = {\n\t\tregisterProvider: vi.fn(),\n\t\tunregisterProvider: vi.fn(),\n\t\tgetProvider: vi.fn(),\n\t\tgetProviders: vi.fn(() => []),\n\t\tgetModels: vi.fn(() => []),\n\t};\n\n\tconst agent = {\n\t\tstate: { messages: [], tools: [] },\n\t\tsubscribe: vi.fn(() => () => {}),\n\t};\n\n\tconst session = new AgentSession({\n\t\tagent: agent as unknown as never,\n\t\tsessionManager: { getBranch: () => [] } as unknown as never,\n\t\tsettingsManager: settings,\n\t\tcwd: \"/tmp\",\n\t\tresourceLoader: resourceLoader as unknown as never,\n\t\tmodelRegistry: modelRegistry as unknown as never,\n\t});\n\n\t(session as any)._extensionRunner = extensionRunner;\n\t(session as any)._extensionMode = mode;\n\t(session as any).getContextUsage = () =>\n\t\ttokens === null ? null : { tokens, contextWindow: 200_000, percent: tokens / 200_000 };\n\n\treturn { session, getCommand, createCommandContext, handler, emitError, settings };\n}\n\ndescribe(\"AgentSession auto handoff\", () => {\n\tit(\"invokes handoff-new once when enabled and threshold reached in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand, createCommandContext, emitError } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 128_000,\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t\texpect(createCommandContext).toHaveBeenCalled();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t\texpect(command.handler).toHaveBeenCalledWith(\"\", expect.anything());\n\t\texpect(emitError).not.toHaveBeenCalled();\n\t});\n\n\tit(\"dispatches auto handoff via _emitAgentSettled in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({ enabled: true, tokens: 200_000, command });\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"_emitAgentSettled does not auto-handoff in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"print\",\n\t\t\tcommand,\n\t\t});\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when disabled\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: false, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 127_999, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are null\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: null, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"rpc\",\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when handoff-new command is not registered\", async () => {\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command: undefined });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t});\n\n\tit(\"emits error when handoff-new throws but does not rethrow\", async () => {\n\t\tconst command = {\n\t\t\thandler: vi.fn(() => Promise.reject(new Error(\"boom\"))),\n\t\t} as unknown as ResolvedCommand;\n\t\tconst { session, emitError } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait expect((session as any)._checkAutoHandoff()).resolves.toBeUndefined();\n\n\t\texpect(emitError).toHaveBeenCalledWith({\n\t\t\textensionPath: \"command:handoff-new\",\n\t\t\tevent: \"auto-handoff\",\n\t\t\terror: \"boom\",\n\t\t});\n\t});\n\n\tit(\"resets triggered flag when tokens drop below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\n\t\t// Simulate tokens dropping below threshold (e.g. compaction/new session)\n\t\t(session as any).getContextUsage = () => ({ tokens: 1000, contextWindow: 200_000, percent: 0.5 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1); // still once\n\n\t\t// Tokens rise above threshold again\n\t\t(session as any).getContextUsage = () => ({ tokens: 200_000, contextWindow: 200_000, percent: 100 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(2);\n\t});\n});\n"]}
1
+ {"version":3,"file":"agent-session-auto-handoff.test.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-auto-handoff.test.ts"],"names":[],"mappings":"","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { ResolvedCommand } from \"./extensions/types.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\nfunction createMockSession({\n\tenabled,\n\tthreshold = 128_000,\n\ttokens,\n\tmode = \"tui\",\n\tcommand,\n}: {\n\tenabled: boolean;\n\tthreshold?: number;\n\ttokens: number | null;\n\tmode?: \"tui\" | \"print\" | \"rpc\";\n\tcommand?: ResolvedCommand | undefined;\n}) {\n\tconst settings = SettingsManager.inMemory({\n\t\tautoHandoff: { enabled, thresholdTokens: threshold },\n\t});\n\n\tconst getCommand = vi.fn(() => command);\n\tconst handler = command?.handler ?? vi.fn();\n\tconst createCommandContext = vi.fn(() => ({ mock: \"ctx\" }) as unknown as never);\n\tconst emitError = vi.fn();\n\n\tconst extensionRunner = {\n\t\tgetCommand,\n\t\tcreateCommandContext,\n\t\temitError,\n\t\temit: vi.fn(),\n\t} as unknown as ExtensionRunner;\n\n\tconst resourceLoader = {\n\t\tgetExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], pendingNativeProviderRegistrations: [], assertActive: () => {} } }),\n\t\tgetSkills: () => ({ skills: [], diagnostics: [] }),\n\t\tgetPrompts: () => ({ prompts: [], diagnostics: [] }),\n\t\tgetThemes: () => ({ themes: [], diagnostics: [] }),\n\t\tgetAgents: () => ({ agents: [], diagnostics: [] }),\n\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\tgetSystemPrompt: () => undefined,\n\t\tgetAppendSystemPrompt: () => [],\n\t\tgetExtensionDiagnostics: () => [],\n\t\textendResources: () => {},\n\t\treload: vi.fn(),\n\t};\n\n\tconst modelRegistry = {\n\t\tregisterProvider: vi.fn(),\n\t\tunregisterProvider: vi.fn(),\n\t\tgetProvider: vi.fn(),\n\t\tgetProviders: vi.fn(() => []),\n\t\tgetModels: vi.fn(() => []),\n\t};\n\n\tconst agent = {\n\t\tstate: { messages: [], tools: [] },\n\t\tsubscribe: vi.fn(() => () => {}),\n\t};\n\n\tconst session = new AgentSession({\n\t\tagent: agent as unknown as never,\n\t\tsessionManager: { getBranch: () => [] } as unknown as never,\n\t\tsettingsManager: settings,\n\t\tcwd: \"/tmp\",\n\t\tresourceLoader: resourceLoader as unknown as never,\n\t\tmodelRuntime: modelRegistry as unknown as never,\n\t});\n\n\t(session as any)._extensionRunner = extensionRunner;\n\t(session as any)._extensionMode = mode;\n\t(session as any).getContextUsage = () =>\n\t\ttokens === null ? null : { tokens, contextWindow: 200_000, percent: tokens / 200_000 };\n\n\treturn { session, getCommand, createCommandContext, handler, emitError, settings };\n}\n\ndescribe(\"AgentSession auto handoff\", () => {\n\tit(\"invokes handoff-new once when enabled and threshold reached in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand, createCommandContext, emitError } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 128_000,\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t\texpect(createCommandContext).toHaveBeenCalled();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t\texpect(command.handler).toHaveBeenCalledWith(\"\", expect.anything());\n\t\texpect(emitError).not.toHaveBeenCalled();\n\t});\n\n\tit(\"dispatches auto handoff via _emitAgentSettled in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({ enabled: true, tokens: 200_000, command });\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"_emitAgentSettled does not auto-handoff in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"print\",\n\t\t\tcommand,\n\t\t});\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when disabled\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: false, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 127_999, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are null\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: null, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"rpc\",\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when handoff-new command is not registered\", async () => {\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command: undefined });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t});\n\n\tit(\"emits error when handoff-new throws but does not rethrow\", async () => {\n\t\tconst command = {\n\t\t\thandler: vi.fn(() => Promise.reject(new Error(\"boom\"))),\n\t\t} as unknown as ResolvedCommand;\n\t\tconst { session, emitError } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait expect((session as any)._checkAutoHandoff()).resolves.toBeUndefined();\n\n\t\texpect(emitError).toHaveBeenCalledWith({\n\t\t\textensionPath: \"command:handoff-new\",\n\t\t\tevent: \"auto-handoff\",\n\t\t\terror: \"boom\",\n\t\t});\n\t});\n\n\tit(\"resets triggered flag when tokens drop below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\n\t\t// Simulate tokens dropping below threshold (e.g. compaction/new session)\n\t\t(session as any).getContextUsage = () => ({ tokens: 1000, contextWindow: 200_000, percent: 0.5 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1); // still once\n\n\t\t// Tokens rise above threshold again\n\t\t(session as any).getContextUsage = () => ({ tokens: 200_000, contextWindow: 200_000, percent: 100 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(2);\n\t});\n});\n"]}
@@ -16,7 +16,7 @@ function createMockSession({ enabled, threshold = 128_000, tokens, mode = "tui",
16
16
  emit: vi.fn(),
17
17
  };
18
18
  const resourceLoader = {
19
- getExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], assertActive: () => { } } }),
19
+ getExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], pendingNativeProviderRegistrations: [], assertActive: () => { } } }),
20
20
  getSkills: () => ({ skills: [], diagnostics: [] }),
21
21
  getPrompts: () => ({ prompts: [], diagnostics: [] }),
22
22
  getThemes: () => ({ themes: [], diagnostics: [] }),
@@ -45,7 +45,7 @@ function createMockSession({ enabled, threshold = 128_000, tokens, mode = "tui",
45
45
  settingsManager: settings,
46
46
  cwd: "/tmp",
47
47
  resourceLoader: resourceLoader,
48
- modelRegistry: modelRegistry,
48
+ modelRuntime: modelRegistry,
49
49
  });
50
50
  session._extensionRunner = extensionRunner;
51
51
  session._extensionMode = mode;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-session-auto-handoff.test.js","sourceRoot":"","sources":["../../src/core/agent-session-auto-handoff.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { ResolvedCommand } from \"./extensions/types.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\nfunction createMockSession({\n\tenabled,\n\tthreshold = 128_000,\n\ttokens,\n\tmode = \"tui\",\n\tcommand,\n}: {\n\tenabled: boolean;\n\tthreshold?: number;\n\ttokens: number | null;\n\tmode?: \"tui\" | \"print\" | \"rpc\";\n\tcommand?: ResolvedCommand | undefined;\n}) {\n\tconst settings = SettingsManager.inMemory({\n\t\tautoHandoff: { enabled, thresholdTokens: threshold },\n\t});\n\n\tconst getCommand = vi.fn(() => command);\n\tconst handler = command?.handler ?? vi.fn();\n\tconst createCommandContext = vi.fn(() => ({ mock: \"ctx\" }) as unknown as never);\n\tconst emitError = vi.fn();\n\n\tconst extensionRunner = {\n\t\tgetCommand,\n\t\tcreateCommandContext,\n\t\temitError,\n\t\temit: vi.fn(),\n\t} as unknown as ExtensionRunner;\n\n\tconst resourceLoader = {\n\t\tgetExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], assertActive: () => {} } }),\n\t\tgetSkills: () => ({ skills: [], diagnostics: [] }),\n\t\tgetPrompts: () => ({ prompts: [], diagnostics: [] }),\n\t\tgetThemes: () => ({ themes: [], diagnostics: [] }),\n\t\tgetAgents: () => ({ agents: [], diagnostics: [] }),\n\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\tgetSystemPrompt: () => undefined,\n\t\tgetAppendSystemPrompt: () => [],\n\t\tgetExtensionDiagnostics: () => [],\n\t\textendResources: () => {},\n\t\treload: vi.fn(),\n\t};\n\n\tconst modelRegistry = {\n\t\tregisterProvider: vi.fn(),\n\t\tunregisterProvider: vi.fn(),\n\t\tgetProvider: vi.fn(),\n\t\tgetProviders: vi.fn(() => []),\n\t\tgetModels: vi.fn(() => []),\n\t};\n\n\tconst agent = {\n\t\tstate: { messages: [], tools: [] },\n\t\tsubscribe: vi.fn(() => () => {}),\n\t};\n\n\tconst session = new AgentSession({\n\t\tagent: agent as unknown as never,\n\t\tsessionManager: { getBranch: () => [] } as unknown as never,\n\t\tsettingsManager: settings,\n\t\tcwd: \"/tmp\",\n\t\tresourceLoader: resourceLoader as unknown as never,\n\t\tmodelRegistry: modelRegistry as unknown as never,\n\t});\n\n\t(session as any)._extensionRunner = extensionRunner;\n\t(session as any)._extensionMode = mode;\n\t(session as any).getContextUsage = () =>\n\t\ttokens === null ? null : { tokens, contextWindow: 200_000, percent: tokens / 200_000 };\n\n\treturn { session, getCommand, createCommandContext, handler, emitError, settings };\n}\n\ndescribe(\"AgentSession auto handoff\", () => {\n\tit(\"invokes handoff-new once when enabled and threshold reached in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand, createCommandContext, emitError } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 128_000,\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t\texpect(createCommandContext).toHaveBeenCalled();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t\texpect(command.handler).toHaveBeenCalledWith(\"\", expect.anything());\n\t\texpect(emitError).not.toHaveBeenCalled();\n\t});\n\n\tit(\"dispatches auto handoff via _emitAgentSettled in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({ enabled: true, tokens: 200_000, command });\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"_emitAgentSettled does not auto-handoff in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"print\",\n\t\t\tcommand,\n\t\t});\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when disabled\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: false, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 127_999, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are null\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: null, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"rpc\",\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when handoff-new command is not registered\", async () => {\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command: undefined });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t});\n\n\tit(\"emits error when handoff-new throws but does not rethrow\", async () => {\n\t\tconst command = {\n\t\t\thandler: vi.fn(() => Promise.reject(new Error(\"boom\"))),\n\t\t} as unknown as ResolvedCommand;\n\t\tconst { session, emitError } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait expect((session as any)._checkAutoHandoff()).resolves.toBeUndefined();\n\n\t\texpect(emitError).toHaveBeenCalledWith({\n\t\t\textensionPath: \"command:handoff-new\",\n\t\t\tevent: \"auto-handoff\",\n\t\t\terror: \"boom\",\n\t\t});\n\t});\n\n\tit(\"resets triggered flag when tokens drop below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\n\t\t// Simulate tokens dropping below threshold (e.g. compaction/new session)\n\t\t(session as any).getContextUsage = () => ({ tokens: 1000, contextWindow: 200_000, percent: 0.5 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1); // still once\n\n\t\t// Tokens rise above threshold again\n\t\t(session as any).getContextUsage = () => ({ tokens: 200_000, contextWindow: 200_000, percent: 100 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(2);\n\t});\n});\n"]}
1
+ {"version":3,"file":"agent-session-auto-handoff.test.js","sourceRoot":"","sources":["../../src/core/agent-session-auto-handoff.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { ResolvedCommand } from \"./extensions/types.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\nfunction createMockSession({\n\tenabled,\n\tthreshold = 128_000,\n\ttokens,\n\tmode = \"tui\",\n\tcommand,\n}: {\n\tenabled: boolean;\n\tthreshold?: number;\n\ttokens: number | null;\n\tmode?: \"tui\" | \"print\" | \"rpc\";\n\tcommand?: ResolvedCommand | undefined;\n}) {\n\tconst settings = SettingsManager.inMemory({\n\t\tautoHandoff: { enabled, thresholdTokens: threshold },\n\t});\n\n\tconst getCommand = vi.fn(() => command);\n\tconst handler = command?.handler ?? vi.fn();\n\tconst createCommandContext = vi.fn(() => ({ mock: \"ctx\" }) as unknown as never);\n\tconst emitError = vi.fn();\n\n\tconst extensionRunner = {\n\t\tgetCommand,\n\t\tcreateCommandContext,\n\t\temitError,\n\t\temit: vi.fn(),\n\t} as unknown as ExtensionRunner;\n\n\tconst resourceLoader = {\n\t\tgetExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], pendingNativeProviderRegistrations: [], assertActive: () => {} } }),\n\t\tgetSkills: () => ({ skills: [], diagnostics: [] }),\n\t\tgetPrompts: () => ({ prompts: [], diagnostics: [] }),\n\t\tgetThemes: () => ({ themes: [], diagnostics: [] }),\n\t\tgetAgents: () => ({ agents: [], diagnostics: [] }),\n\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\tgetSystemPrompt: () => undefined,\n\t\tgetAppendSystemPrompt: () => [],\n\t\tgetExtensionDiagnostics: () => [],\n\t\textendResources: () => {},\n\t\treload: vi.fn(),\n\t};\n\n\tconst modelRegistry = {\n\t\tregisterProvider: vi.fn(),\n\t\tunregisterProvider: vi.fn(),\n\t\tgetProvider: vi.fn(),\n\t\tgetProviders: vi.fn(() => []),\n\t\tgetModels: vi.fn(() => []),\n\t};\n\n\tconst agent = {\n\t\tstate: { messages: [], tools: [] },\n\t\tsubscribe: vi.fn(() => () => {}),\n\t};\n\n\tconst session = new AgentSession({\n\t\tagent: agent as unknown as never,\n\t\tsessionManager: { getBranch: () => [] } as unknown as never,\n\t\tsettingsManager: settings,\n\t\tcwd: \"/tmp\",\n\t\tresourceLoader: resourceLoader as unknown as never,\n\t\tmodelRuntime: modelRegistry as unknown as never,\n\t});\n\n\t(session as any)._extensionRunner = extensionRunner;\n\t(session as any)._extensionMode = mode;\n\t(session as any).getContextUsage = () =>\n\t\ttokens === null ? null : { tokens, contextWindow: 200_000, percent: tokens / 200_000 };\n\n\treturn { session, getCommand, createCommandContext, handler, emitError, settings };\n}\n\ndescribe(\"AgentSession auto handoff\", () => {\n\tit(\"invokes handoff-new once when enabled and threshold reached in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand, createCommandContext, emitError } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 128_000,\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t\texpect(createCommandContext).toHaveBeenCalled();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t\texpect(command.handler).toHaveBeenCalledWith(\"\", expect.anything());\n\t\texpect(emitError).not.toHaveBeenCalled();\n\t});\n\n\tit(\"dispatches auto handoff via _emitAgentSettled in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({ enabled: true, tokens: 200_000, command });\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"_emitAgentSettled does not auto-handoff in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"print\",\n\t\t\tcommand,\n\t\t});\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when disabled\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: false, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 127_999, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are null\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: null, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"rpc\",\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when handoff-new command is not registered\", async () => {\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command: undefined });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t});\n\n\tit(\"emits error when handoff-new throws but does not rethrow\", async () => {\n\t\tconst command = {\n\t\t\thandler: vi.fn(() => Promise.reject(new Error(\"boom\"))),\n\t\t} as unknown as ResolvedCommand;\n\t\tconst { session, emitError } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait expect((session as any)._checkAutoHandoff()).resolves.toBeUndefined();\n\n\t\texpect(emitError).toHaveBeenCalledWith({\n\t\t\textensionPath: \"command:handoff-new\",\n\t\t\tevent: \"auto-handoff\",\n\t\t\terror: \"boom\",\n\t\t});\n\t});\n\n\tit(\"resets triggered flag when tokens drop below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\n\t\t// Simulate tokens dropping below threshold (e.g. compaction/new session)\n\t\t(session as any).getContextUsage = () => ({ tokens: 1000, contextWindow: 200_000, percent: 0.5 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1); // still once\n\n\t\t// Tokens rise above threshold again\n\t\t(session as any).getContextUsage = () => ({ tokens: 200_000, contextWindow: 200_000, percent: 100 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(2);\n\t});\n});\n"]}