@selesai/code 0.2.1 → 0.3.1

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 (284) hide show
  1. package/dist/config.d.ts +4 -15
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +5 -45
  4. package/dist/config.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +1 -0
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +8 -0
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/diagnostics.d.ts +1 -0
  10. package/dist/core/diagnostics.d.ts.map +1 -1
  11. package/dist/core/diagnostics.js.map +1 -1
  12. package/dist/core/model-registry.d.ts +4 -1
  13. package/dist/core/model-registry.d.ts.map +1 -1
  14. package/dist/core/model-registry.js +101 -51
  15. package/dist/core/model-registry.js.map +1 -1
  16. package/dist/core/package-manager.d.ts +10 -0
  17. package/dist/core/package-manager.d.ts.map +1 -1
  18. package/dist/core/package-manager.js +93 -8
  19. package/dist/core/package-manager.js.map +1 -1
  20. package/dist/core/package-manager.test.d.ts +2 -0
  21. package/dist/core/package-manager.test.d.ts.map +1 -0
  22. package/dist/core/package-manager.test.js +20 -0
  23. package/dist/core/package-manager.test.js.map +1 -0
  24. package/dist/core/resource-loader.d.ts +3 -0
  25. package/dist/core/resource-loader.d.ts.map +1 -1
  26. package/dist/core/resource-loader.js +10 -0
  27. package/dist/core/resource-loader.js.map +1 -1
  28. package/dist/core/settings-manager.d.ts +1 -0
  29. package/dist/core/settings-manager.d.ts.map +1 -1
  30. package/dist/core/settings-manager.js.map +1 -1
  31. package/dist/defaults/models.json +64 -113
  32. package/dist/extensions/caveman/caveman-instructions.cjs +39 -0
  33. package/dist/extensions/caveman/index.js +116 -0
  34. package/dist/extensions/caveman/package.json +8 -0
  35. package/dist/extensions/caveman/test/extension.test.js +185 -0
  36. package/dist/extensions/caveman/test/helpers.test.js +67 -0
  37. package/dist/extensions/copy-turn.ts +2 -2
  38. package/dist/extensions/pi-intercom/broker/broker.ts +2 -3
  39. package/dist/extensions/pi-intercom/broker/paths.ts +10 -5
  40. package/dist/extensions/pi-intercom/broker/spawn.ts +2 -3
  41. package/dist/extensions/pi-intercom/config.ts +2 -2
  42. package/dist/extensions/pi-intercom/index.ts +2 -2
  43. package/dist/extensions/pi-intercom/package.json +2 -2
  44. package/dist/extensions/pi-intercom/ui/compose.ts +3 -3
  45. package/dist/extensions/pi-intercom/ui/inline-message.ts +3 -3
  46. package/dist/extensions/pi-intercom/ui/session-list.ts +3 -3
  47. package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +2 -2
  48. package/dist/extensions/pi-powerline-footer/bash-mode/history.ts +2 -1
  49. package/dist/extensions/pi-powerline-footer/index.ts +40 -47
  50. package/dist/extensions/pi-powerline-footer/package.json +2 -2
  51. package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +10 -10
  52. package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +1 -1
  53. package/dist/extensions/pi-powerline-footer/tests/working-vibes.test.ts +2 -2
  54. package/dist/extensions/pi-powerline-footer/theme.ts +6 -6
  55. package/dist/extensions/pi-powerline-footer/tps.ts +1 -1
  56. package/dist/extensions/pi-powerline-footer/types.ts +7 -7
  57. package/dist/extensions/pi-powerline-footer/welcome.ts +23 -16
  58. package/dist/extensions/pi-powerline-footer/working-vibes.ts +52 -59
  59. package/dist/extensions/pi-rewind-hook/index.ts +1 -1
  60. package/dist/extensions/pi-rewind-hook/package.json +1 -1
  61. package/dist/extensions/pi-subagents/README.md +224 -52
  62. package/dist/extensions/pi-subagents/agents/architect.md +188 -0
  63. package/dist/extensions/pi-subagents/agents/builder.md +120 -0
  64. package/dist/extensions/pi-subagents/agents/commentator.md +131 -0
  65. package/dist/extensions/pi-subagents/agents/explorer.md +51 -0
  66. package/dist/extensions/pi-subagents/agents/recapper.md +21 -0
  67. package/dist/extensions/pi-subagents/install.mjs +93 -0
  68. package/dist/extensions/pi-subagents/package.json +4 -5
  69. package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +1 -1
  70. package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +1 -1
  71. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +76 -13
  72. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +179 -2
  73. package/dist/extensions/pi-subagents/src/agents/agent-memory.ts +254 -0
  74. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +11 -0
  75. package/dist/extensions/pi-subagents/src/agents/agents.ts +193 -19
  76. package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +27 -2
  77. package/dist/extensions/pi-subagents/src/extension/config.ts +27 -4
  78. package/dist/extensions/pi-subagents/src/extension/doctor.ts +1 -7
  79. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +3 -2
  80. package/dist/extensions/pi-subagents/src/extension/index.ts +73 -71
  81. package/dist/extensions/pi-subagents/src/extension/rpc.ts +369 -0
  82. package/dist/extensions/pi-subagents/src/extension/schemas.ts +54 -10
  83. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +200 -0
  84. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +21 -253
  85. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +519 -0
  86. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +1 -1
  87. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +195 -105
  88. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +88 -2
  89. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +67 -10
  90. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +34 -4
  91. package/dist/extensions/pi-subagents/src/runs/background/completion-batcher.ts +166 -0
  92. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +156 -1
  93. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +515 -0
  94. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +161 -44
  95. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +1 -2
  96. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +3 -2
  97. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +167 -6
  98. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +514 -0
  99. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +28 -1
  100. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +873 -204
  101. package/dist/extensions/pi-subagents/src/runs/background/wait.ts +353 -0
  102. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +123 -27
  103. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +174 -70
  104. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +569 -81
  105. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +45 -22
  106. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +3 -1
  107. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +2 -2
  108. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +172 -21
  109. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +128 -0
  110. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +89 -0
  111. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +50 -1
  112. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +35 -4
  113. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +63 -45
  114. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +2 -0
  115. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +125 -5
  116. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +74 -0
  117. package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +52 -0
  118. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +28 -5
  119. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +16 -1
  120. package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +15 -2
  121. package/dist/extensions/pi-subagents/src/shared/child-transcript.ts +212 -0
  122. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +133 -22
  123. package/dist/extensions/pi-subagents/src/shared/settings.ts +3 -1
  124. package/dist/extensions/pi-subagents/src/shared/types.ts +197 -4
  125. package/dist/extensions/pi-subagents/src/shared/utils.ts +108 -17
  126. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +330 -0
  127. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +135 -4
  128. package/dist/extensions/pi-subagents/src/tui/render.ts +32 -12
  129. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +94 -0
  130. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +2772 -0
  131. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +1107 -0
  132. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +463 -0
  133. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +274 -0
  134. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +1535 -0
  135. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +242 -0
  136. package/dist/extensions/pi-subagents/test/integration/doctor-executor.test.ts +128 -0
  137. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +252 -0
  138. package/dist/extensions/pi-subagents/test/integration/foreground-result-size.test.ts +188 -0
  139. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +1306 -0
  140. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +1033 -0
  141. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +397 -0
  142. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +583 -0
  143. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +691 -0
  144. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +892 -0
  145. package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +62 -0
  146. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1824 -0
  147. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1284 -0
  148. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +127 -0
  149. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +299 -0
  150. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +37 -0
  151. package/dist/extensions/pi-subagents/test/support/helpers.ts +189 -0
  152. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +335 -0
  153. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +129 -0
  154. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +184 -0
  155. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +285 -0
  156. package/dist/extensions/pi-subagents/test/support/register-loader.mjs +15 -0
  157. package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +108 -0
  158. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +421 -0
  159. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +213 -0
  160. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +343 -0
  161. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +1199 -0
  162. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +556 -0
  163. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +420 -0
  164. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +579 -0
  165. package/dist/extensions/pi-subagents/test/unit/agent-scope.test.ts +20 -0
  166. package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +88 -0
  167. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +24 -0
  168. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +86 -0
  169. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +221 -0
  170. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +98 -0
  171. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +285 -0
  172. package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +112 -0
  173. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +206 -0
  174. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +159 -0
  175. package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +229 -0
  176. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +225 -0
  177. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +101 -0
  178. package/dist/extensions/pi-subagents/test/unit/completion-batcher.test.ts +228 -0
  179. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +36 -0
  180. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +152 -0
  181. package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +72 -0
  182. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +327 -0
  183. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +161 -0
  184. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +159 -0
  185. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +217 -0
  186. package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +88 -0
  187. package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +68 -0
  188. package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +78 -0
  189. package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +415 -0
  190. package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +126 -0
  191. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +271 -0
  192. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +173 -0
  193. package/dist/extensions/pi-subagents/test/unit/jsonl-writer.test.ts +119 -0
  194. package/dist/extensions/pi-subagents/test/unit/live-async-resume.test.ts +170 -0
  195. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +346 -0
  196. package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +62 -0
  197. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +87 -0
  198. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +145 -0
  199. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +162 -0
  200. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +470 -0
  201. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +329 -0
  202. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +319 -0
  203. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +70 -0
  204. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +247 -0
  205. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +113 -0
  206. package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +94 -0
  207. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +803 -0
  208. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +209 -0
  209. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +238 -0
  210. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +118 -0
  211. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +299 -0
  212. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +408 -0
  213. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +134 -0
  214. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +257 -0
  215. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +209 -0
  216. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +226 -0
  217. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +294 -0
  218. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +147 -0
  219. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +997 -0
  220. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +478 -0
  221. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +562 -0
  222. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +213 -0
  223. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +438 -0
  224. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +54 -0
  225. package/dist/extensions/pi-subagents/test/unit/slash-chain-groups.test.ts +464 -0
  226. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +255 -0
  227. package/dist/extensions/pi-subagents/test/unit/status-format.test.ts +19 -0
  228. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +245 -0
  229. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +517 -0
  230. package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +72 -0
  231. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +52 -0
  232. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +237 -0
  233. package/dist/extensions/pi-subagents/test/unit/total-cost.test.ts +60 -0
  234. package/dist/extensions/pi-subagents/test/unit/ts-loader.test.ts +33 -0
  235. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +202 -0
  236. package/dist/extensions/pi-subagents/test/unit/types-fork-preamble.test.ts +23 -0
  237. package/dist/extensions/pi-subagents/test/unit/wait.test.ts +398 -0
  238. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +88 -0
  239. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +26 -0
  240. package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +134 -0
  241. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +479 -0
  242. package/dist/extensions/pi-web-agent/package.json +2 -2
  243. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +2 -2
  244. package/dist/extensions/pi-web-agent/src/changelog-notice.ts +5 -2
  245. package/dist/extensions/pi-web-agent/src/commands/web-agent-config.ts +1 -1
  246. package/dist/extensions/pi-web-agent/src/extension.ts +1 -1
  247. package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +6 -4
  248. package/dist/extensions/question/helpers.ts +3 -3
  249. package/dist/extensions/question/index.ts +2 -2
  250. package/dist/extensions/question/navigation.ts +2 -2
  251. package/dist/extensions/question/package.json +2 -2
  252. package/dist/extensions/question/question-list.ts +2 -2
  253. package/dist/extensions/question/tests/question-list.test.ts +2 -2
  254. package/dist/extensions/question/tui-adapter.ts +2 -2
  255. package/dist/extensions/question/types.ts +2 -2
  256. package/dist/extensions/question/ui-protocol.ts +2 -2
  257. package/dist/extensions/rtk.ts +2 -2
  258. package/dist/extensions/tokenin-onboarding.ts +2 -2
  259. package/dist/extensions/undo.ts +1 -1
  260. package/dist/extensions/web-agent-onboarding.ts +3 -3
  261. package/dist/extensions/workflow/adapter.ts +16 -8
  262. package/dist/extensions/workflow/extension.ts +1 -1
  263. package/dist/extensions/workflow/package.json +1 -1
  264. package/dist/main.d.ts.map +1 -1
  265. package/dist/main.js +4 -0
  266. package/dist/main.js.map +1 -1
  267. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  268. package/dist/modes/interactive/components/assistant-message.js +2 -0
  269. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  270. package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
  271. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  272. package/dist/modes/interactive/components/first-time-setup.js +19 -5
  273. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  274. package/dist/skills/caveman/SKILL.md +49 -0
  275. package/dist/skills/handoff-text/SKILL.md +13 -0
  276. package/dist/utils/thinking-tags.d.ts +7 -0
  277. package/dist/utils/thinking-tags.d.ts.map +1 -0
  278. package/dist/utils/thinking-tags.js +63 -0
  279. package/dist/utils/thinking-tags.js.map +1 -0
  280. package/docs/docs.json +4 -0
  281. package/docs/extensions.md +2 -0
  282. package/docs/settings.md +15 -0
  283. package/docs/shared-host-extensions.md +109 -0
  284. package/package.json +2 -2
@@ -0,0 +1,116 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ const require = createRequire(import.meta.url);
4
+ const { getCavemanInstructions } = require("./caveman-instructions.cjs");
5
+
6
+ export { getCavemanInstructions };
7
+
8
+ export function resolveSessionActive(entries, fallback = true) {
9
+ if (!Array.isArray(entries)) return fallback;
10
+
11
+ for (let i = entries.length - 1; i >= 0; i -= 1) {
12
+ const entry = entries[i];
13
+ if (entry?.type !== "custom" || entry?.customType !== "caveman-mode") continue;
14
+
15
+ const active = entry?.data?.active;
16
+ if (typeof active === "boolean") return active;
17
+ }
18
+
19
+ return fallback;
20
+ }
21
+
22
+ export function parseCavemanCommand(text) {
23
+ const normalizedText = String(text || "").trim().toLowerCase();
24
+ if (!normalizedText) return { type: "toggle" };
25
+
26
+ const [primary] = normalizedText.split(/\s+/);
27
+ if (primary === "status") return { type: "status" };
28
+ if (primary === "on" || primary === "enable") return { type: "set", active: true };
29
+ if (primary === "off" || primary === "disable") return { type: "set", active: false };
30
+ return { type: "invalid", reason: "unknown-subcommand", arg: primary };
31
+ }
32
+
33
+ export function isDeactivationCommand(text) {
34
+ const t = String(text || "").trim().toLowerCase().replace(/[.!?\s]+$/, "");
35
+ return t === "stop caveman" || t === "normal mode";
36
+ }
37
+
38
+ export default function cavemanExtension(pi) {
39
+ let active = true;
40
+ let isActive = false;
41
+ let lastCtx = null;
42
+
43
+ function syncStatus(ctx) {
44
+ if (ctx) lastCtx = ctx;
45
+ const c = ctx || lastCtx;
46
+ if (!c?.ui?.setStatus || !c.ui.theme?.fg) return;
47
+ const theme = c.ui.theme;
48
+ if (!active) {
49
+ c.ui.setStatus("caveman", "");
50
+ return;
51
+ }
52
+ const indicator = isActive ? theme.fg("accent", "●") : theme.fg("dim", "○");
53
+ c.ui.setStatus("caveman", indicator + " 🦴 " + theme.fg("muted", "caveman: ") + theme.fg("text", active ? "ON" : "OFF"));
54
+ }
55
+
56
+ const setActive = (value, ctx) => {
57
+ active = Boolean(value);
58
+ pi.appendEntry("caveman-mode", { active });
59
+ syncStatus(ctx);
60
+ ctx?.ui?.notify?.(`Caveman mode ${active ? "enabled" : "disabled"}.`, "info");
61
+ };
62
+
63
+ pi.registerCommand("caveman", {
64
+ description: "Toggle or report Caveman mode",
65
+ handler: async (args, ctx) => {
66
+ const parsed = parseCavemanCommand(args);
67
+
68
+ if (parsed.type === "status") {
69
+ ctx?.ui?.notify?.(`Caveman: ${active ? "ON" : "OFF"}`, "info");
70
+ return;
71
+ }
72
+
73
+ if (parsed.type === "toggle") {
74
+ setActive(!active, ctx);
75
+ return;
76
+ }
77
+
78
+ if (parsed.type === "set") {
79
+ setActive(parsed.active, ctx);
80
+ return;
81
+ }
82
+
83
+ ctx?.ui?.notify?.("Unknown /caveman subcommand. Use: on, off, status.", "warning");
84
+ },
85
+ });
86
+
87
+ pi.on("input", async (event) => {
88
+ if (event?.source === "extension") return;
89
+ const text = String(event?.text || "");
90
+ if (active && isDeactivationCommand(text)) {
91
+ setActive(false);
92
+ }
93
+ });
94
+
95
+ pi.on("session_start", async (_event, ctx) => {
96
+ const entries = ctx?.sessionManager?.getBranch?.() || ctx?.sessionManager?.getEntries?.() || [];
97
+ active = resolveSessionActive(entries, true);
98
+ syncStatus(ctx);
99
+ ctx?.ui?.notify?.(`Caveman loaded: ${active ? "ON" : "OFF"}`, "info");
100
+ });
101
+
102
+ pi.on("agent_start", async (_event, ctx) => {
103
+ isActive = true;
104
+ syncStatus(ctx);
105
+ });
106
+
107
+ pi.on("agent_end", async (_event, ctx) => {
108
+ isActive = false;
109
+ syncStatus(ctx);
110
+ });
111
+
112
+ pi.on("before_agent_start", async (event) => {
113
+ if (!active) return;
114
+ return { systemPrompt: `${event.systemPrompt}\n\n${getCavemanInstructions()}` };
115
+ });
116
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "caveman",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "test": "node --test ./test/*.test.js"
7
+ }
8
+ }
@@ -0,0 +1,185 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import cavemanExtension from "../index.js";
5
+
6
+ function createPiHarness() {
7
+ const events = new Map();
8
+ const commands = new Map();
9
+ const appendedEntries = [];
10
+ const sentUserMessages = [];
11
+
12
+ const pi = {
13
+ on(eventName, handler) { events.set(eventName, handler); },
14
+ registerCommand(name, options) { commands.set(name, options); },
15
+ appendEntry(customType, data) { appendedEntries.push({ customType, data }); },
16
+ sendUserMessage(text, options) { sentUserMessages.push({ text, options }); },
17
+ };
18
+
19
+ cavemanExtension(pi);
20
+ return { events, commands, appendedEntries, sentUserMessages };
21
+ }
22
+
23
+ function createCommandContext(overrides = {}) {
24
+ return {
25
+ isIdle: () => true,
26
+ sessionManager: { getEntries: () => [] },
27
+ ui: { notify() {} },
28
+ ...overrides,
29
+ };
30
+ }
31
+
32
+ test("extension registers the /caveman command", () => {
33
+ const { commands } = createPiHarness();
34
+ assert.deepEqual([...commands.keys()], ["caveman"]);
35
+ });
36
+
37
+ test("/caveman on/off appends a caveman-mode entry", async () => {
38
+ const { commands, events, appendedEntries } = createPiHarness();
39
+ const ctx = createCommandContext();
40
+
41
+ await events.get("session_start")({ reason: "startup" }, ctx);
42
+ await commands.get("caveman").handler("off", ctx);
43
+
44
+ assert.deepEqual(appendedEntries.at(-1), { customType: "caveman-mode", data: { active: false } });
45
+
46
+ await commands.get("caveman").handler("on", ctx);
47
+ assert.deepEqual(appendedEntries.at(-1), { customType: "caveman-mode", data: { active: true } });
48
+ });
49
+
50
+ test("bare /caveman toggles off then back on", async () => {
51
+ const { commands, events, appendedEntries } = createPiHarness();
52
+ const ctx = createCommandContext();
53
+
54
+ await events.get("session_start")({ reason: "startup" }, ctx); // starts on
55
+ await commands.get("caveman").handler("", ctx);
56
+ assert.equal(appendedEntries.at(-1).data.active, false);
57
+ await commands.get("caveman").handler("", ctx);
58
+ assert.equal(appendedEntries.at(-1).data.active, true);
59
+ });
60
+
61
+ test("before_agent_start injects instructions while active", async () => {
62
+ const { events } = createPiHarness();
63
+ const ctx = createCommandContext();
64
+
65
+ await events.get("session_start")({ reason: "startup" }, ctx);
66
+ const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
67
+
68
+ assert.ok(result.systemPrompt.startsWith("BASE"));
69
+ assert.ok(result.systemPrompt.includes("CAVEMAN MODE ACTIVE"));
70
+ });
71
+
72
+ test("disabled caveman skips instruction injection", async () => {
73
+ const { commands, events } = createPiHarness();
74
+ const ctx = createCommandContext();
75
+
76
+ await events.get("session_start")({ reason: "startup" }, ctx);
77
+ await commands.get("caveman").handler("off", ctx);
78
+ const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
79
+
80
+ assert.equal(result, undefined);
81
+ });
82
+
83
+ test("session_start restores latest persisted active flag", async () => {
84
+ const { events } = createPiHarness();
85
+ const ctx = createCommandContext({
86
+ sessionManager: {
87
+ getEntries: () => [
88
+ { type: "custom", customType: "caveman-mode", data: { active: false } },
89
+ ],
90
+ },
91
+ });
92
+
93
+ await events.get("session_start")({ reason: "resume" }, ctx);
94
+ const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
95
+
96
+ assert.equal(result, undefined); // persisted false -> no injection
97
+ });
98
+
99
+ test("'stop caveman' as a whole message deactivates mid-session", async () => {
100
+ const { events } = createPiHarness();
101
+ const ctx = createCommandContext();
102
+
103
+ await events.get("session_start")({ reason: "startup" }, ctx);
104
+ await events.get("input")({ text: "stop caveman", source: "interactive" }, ctx);
105
+
106
+ const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
107
+ assert.equal(result, undefined);
108
+ });
109
+
110
+ test("a request merely mentioning 'stop caveman' stays active", async () => {
111
+ const { events } = createPiHarness();
112
+ const ctx = createCommandContext();
113
+
114
+ await events.get("session_start")({ reason: "startup" }, ctx);
115
+ await events.get("input")({ text: "how do I stop caveman re-rendering?", source: "interactive" }, ctx);
116
+
117
+ const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
118
+ assert.ok(result.systemPrompt.includes("CAVEMAN MODE ACTIVE"));
119
+ });
120
+
121
+ test("status bar renders ON and flips active on agent_start", async () => {
122
+ const { events } = createPiHarness();
123
+ const statusWrites = [];
124
+ const ctx = createCommandContext({
125
+ sessionManager: { getEntries: () => [] },
126
+ ui: { notify() {}, setStatus: (key, text) => statusWrites.push({ key, text }), theme: { fg: (_c, t) => t } },
127
+ });
128
+
129
+ await events.get("session_start")({ reason: "startup" }, ctx);
130
+ await events.get("agent_start")({}, ctx);
131
+
132
+ assert.equal(statusWrites.at(-2).key, "caveman");
133
+ assert.match(statusWrites.at(-2).text, /○.*ON/);
134
+ assert.match(statusWrites.at(-1).text, /●.*ON/);
135
+ });
136
+
137
+ test("status bar clears when disabled", async () => {
138
+ const { events, commands } = createPiHarness();
139
+ const statusWrites = [];
140
+ const ctx = createCommandContext({
141
+ ui: { notify() {}, setStatus: (key, text) => statusWrites.push({ key, text }), theme: { fg: (_c, t) => t } },
142
+ });
143
+
144
+ await events.get("session_start")({ reason: "startup" }, ctx);
145
+ await commands.get("caveman").handler("off", ctx);
146
+
147
+ assert.deepEqual(statusWrites.at(-1), { key: "caveman", text: "" });
148
+ });
149
+
150
+ test("status bar stays silent when ui lacks a theme", async () => {
151
+ const { events } = createPiHarness();
152
+ const calls = [];
153
+ const ctx = createCommandContext({
154
+ sessionManager: { getEntries: () => [] },
155
+ ui: { notify() {}, setStatus: (_key, text) => calls.push(text) }, // no theme
156
+ });
157
+
158
+ await events.get("session_start")({ reason: "startup" }, ctx);
159
+ await events.get("agent_start")({}, ctx);
160
+
161
+ assert.deepEqual(calls, []);
162
+ });
163
+
164
+ test("invalid subcommand notifies warning and does not append", async () => {
165
+ const { commands, appendedEntries } = createPiHarness();
166
+ let notified = null;
167
+ const ctx = createCommandContext({ ui: { notify: (_m, kind) => { notified = kind; } } });
168
+
169
+ await commands.get("caveman").handler("banana", ctx);
170
+
171
+ assert.equal(notified, "warning");
172
+ assert.equal(appendedEntries.length, 0);
173
+ });
174
+
175
+ test("status subcommand reports without changing state", async () => {
176
+ const { commands, events, appendedEntries } = createPiHarness();
177
+ let reported = null;
178
+ const ctx = createCommandContext({ ui: { notify: (m) => { reported = m; } } });
179
+
180
+ await events.get("session_start")({ reason: "startup" }, ctx); // starts on
181
+ await commands.get("caveman").handler("status", ctx);
182
+
183
+ assert.match(reported, /ON/);
184
+ assert.equal(appendedEntries.length, 0);
185
+ });
@@ -0,0 +1,67 @@
1
+ import assert from "node:assert/strict";
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import test from "node:test";
5
+
6
+ import {
7
+ getCavemanInstructions,
8
+ isDeactivationCommand,
9
+ parseCavemanCommand,
10
+ resolveSessionActive,
11
+ } from "../index.js";
12
+
13
+ test("parseCavemanCommand: bare toggles", () => {
14
+ assert.deepEqual(parseCavemanCommand(""), { type: "toggle" });
15
+ assert.deepEqual(parseCavemanCommand(" "), { type: "toggle" });
16
+ });
17
+
18
+ test("parseCavemanCommand: on/off/status", () => {
19
+ assert.deepEqual(parseCavemanCommand("on"), { type: "set", active: true });
20
+ assert.deepEqual(parseCavemanCommand("ENABLE"), { type: "set", active: true });
21
+ assert.deepEqual(parseCavemanCommand("off"), { type: "set", active: false });
22
+ assert.deepEqual(parseCavemanCommand("disable"), { type: "set", active: false });
23
+ assert.deepEqual(parseCavemanCommand("status"), { type: "status" });
24
+ });
25
+
26
+ test("parseCavemanCommand: unknown arg is invalid", () => {
27
+ assert.deepEqual(parseCavemanCommand("banana"), { type: "invalid", reason: "unknown-subcommand", arg: "banana" });
28
+ });
29
+
30
+ test("resolveSessionActive: latest persisted entry wins", () => {
31
+ const entries = [
32
+ { type: "custom", customType: "caveman-mode", data: { active: false } },
33
+ { type: "custom", customType: "caveman-mode", data: { active: true } },
34
+ ];
35
+ assert.equal(resolveSessionActive(entries, true), true);
36
+ });
37
+
38
+ test("resolveSessionActive: non-array entries fall back", () => {
39
+ assert.equal(resolveSessionActive(null, true), true);
40
+ assert.equal(resolveSessionActive(undefined, false), false);
41
+ assert.equal(resolveSessionActive({}, true), true);
42
+ assert.equal(resolveSessionActive("nope"), true); // DEFAULT fallback
43
+ });
44
+
45
+ test("isDeactivationCommand: only the whole message, case-insensitive, trailing punct ok", () => {
46
+ assert.equal(isDeactivationCommand("stop caveman"), true);
47
+ assert.equal(isDeactivationCommand("STOP CAVEMAN!"), true);
48
+ assert.equal(isDeactivationCommand("normal mode"), true);
49
+ assert.equal(isDeactivationCommand("Normal Mode."), true);
50
+ assert.equal(isDeactivationCommand("add a normal mode toggle"), false);
51
+ assert.equal(isDeactivationCommand("how do I stop caveman re-rendering"), false);
52
+ });
53
+
54
+ test("getCavemanInstructions reads SKILL.md and strips frontmatter", () => {
55
+ const instructions = getCavemanInstructions();
56
+ assert.ok(instructions.startsWith("CAVEMAN MODE ACTIVE"));
57
+ assert.ok(!instructions.includes("name: caveman")); // frontmatter gone
58
+ assert.ok(instructions.includes("Respond terse like smart caveman"));
59
+ });
60
+
61
+ test("getCavemanInstructions matches src/skills/caveman/SKILL.md body", () => {
62
+ const skillPath = fileURLToPath(new URL("../../../skills/caveman/SKILL.md", import.meta.url));
63
+ const raw = readFileSync(skillPath, "utf8");
64
+ const body = raw.replace(/^---[\s\S]*?---\s*/, "");
65
+
66
+ assert.ok(getCavemanInstructions().endsWith(body));
67
+ });
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
- import { copyToClipboard } from "@earendil-works/pi-coding-agent";
2
+ import type { ExtensionAPI } from "@selesai/code";
3
+ import { copyToClipboard } from "@selesai/code";
4
4
  import { Text } from "@earendil-works/pi-tui";
5
5
 
6
6
  type AnyMessage = any;
@@ -1,13 +1,12 @@
1
1
  import net from "net";
2
2
  import { writeFileSync, unlinkSync, mkdirSync } from "fs";
3
3
  import { join } from "path";
4
- import { homedir } from "os";
5
4
  import { randomUUID } from "crypto";
6
5
  import { writeMessage, createMessageReader } from "./framing.js";
7
- import { getBrokerSocketPath } from "./paths.js";
6
+ import { getBrokerSocketPath, getIntercomDir } from "./paths.js";
8
7
  import type { SessionInfo, Message, Attachment, BrokerMessage } from "../types.js";
9
8
 
10
- const INTERCOM_DIR = join(homedir(), ".pi/agent/intercom");
9
+ const INTERCOM_DIR = getIntercomDir();
11
10
  const SOCKET_PATH = getBrokerSocketPath();
12
11
  const PID_PATH = join(INTERCOM_DIR, "broker.pid");
13
12
 
@@ -1,5 +1,5 @@
1
1
  import { join } from "path";
2
- import { homedir } from "os";
2
+ import { getAgentDir } from "@selesai/code";
3
3
 
4
4
  function sanitizePipeSegment(value: string): string {
5
5
  return value
@@ -8,13 +8,18 @@ function sanitizePipeSegment(value: string): string {
8
8
  .toLowerCase() || "default";
9
9
  }
10
10
 
11
+ /** selesai config dir (~/.selesai/agent on the selesai fork, ~/.pi/agent upstream). */
12
+ export function getIntercomDir(): string {
13
+ return join(getAgentDir(), "intercom");
14
+ }
15
+
11
16
  export function getBrokerSocketPath(
12
17
  platform: NodeJS.Platform = process.platform,
13
- homeDir: string = homedir(),
18
+ intercomDir: string = getIntercomDir(),
14
19
  ): string {
15
20
  if (platform === "win32") {
16
- return `\\\\.\\pipe\\pi-intercom-${sanitizePipeSegment(homeDir)}`;
21
+ return `\\\\.\\pipe\\pi-intercom-${sanitizePipeSegment(intercomDir)}`;
17
22
  }
18
23
 
19
- return join(homeDir, ".pi/agent/intercom/broker.sock");
20
- }
24
+ return join(intercomDir, "broker.sock");
25
+ }
@@ -2,11 +2,10 @@ import { spawn } from "child_process";
2
2
  import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
3
3
  import { join, dirname } from "path";
4
4
  import { fileURLToPath } from "url";
5
- import { homedir } from "os";
6
5
  import net from "net";
7
- import { getBrokerSocketPath } from "./paths.js";
6
+ import { getBrokerSocketPath, getIntercomDir } from "./paths.js";
8
7
 
9
- const INTERCOM_DIR = join(homedir(), ".pi/agent/intercom");
8
+ const INTERCOM_DIR = getIntercomDir();
10
9
  const EXTENSION_DIR = join(dirname(fileURLToPath(import.meta.url)), "..");
11
10
  const BROKER_SOCKET = getBrokerSocketPath();
12
11
  const BROKER_PID = join(INTERCOM_DIR, "broker.pid");
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readFileSync } from "fs";
2
2
  import { join } from "path";
3
- import { homedir } from "os";
3
+ import { getIntercomDir } from "./broker/paths.js";
4
4
 
5
5
  export interface IntercomConfig {
6
6
  /** Broker command used to spawn the broker process (e.g. "npx" or "bun") */
@@ -22,7 +22,7 @@ export interface IntercomConfig {
22
22
  replyHint: boolean;
23
23
  }
24
24
 
25
- const CONFIG_PATH = join(homedir(), ".pi/agent/intercom/config.json");
25
+ const CONFIG_PATH = join(getIntercomDir(), "config.json");
26
26
 
27
27
  const defaults: IntercomConfig = {
28
28
  brokerCommand: "npx",
@@ -1,7 +1,7 @@
1
- import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
1
+ import type { ExtensionAPI, ExtensionContext } from "@selesai/code";
2
2
  import { randomUUID } from "crypto";
3
3
  import { Type } from "typebox";
4
- import { Text } from "@mariozechner/pi-tui";
4
+ import { Text } from "@earendil-works/pi-tui";
5
5
  import { IntercomClient } from "./broker/client.ts";
6
6
  import { spawnBrokerIfNeeded } from "./broker/spawn.ts";
7
7
  import { SessionListOverlay } from "./ui/session-list.ts";
@@ -28,8 +28,8 @@
28
28
  ]
29
29
  },
30
30
  "peerDependencies": {
31
- "@mariozechner/pi-coding-agent": "*",
32
- "@mariozechner/pi-tui": "*"
31
+ "@selesai/code": "*",
32
+ "@earendil-works/pi-tui": "*"
33
33
  },
34
34
  "dependencies": {
35
35
  "tsx": "^4.20.0",
@@ -1,6 +1,6 @@
1
- import type { Component, TUI } from "@mariozechner/pi-tui";
2
- import { truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
3
- import type { KeybindingsManager, Theme } from "@mariozechner/pi-coding-agent";
1
+ import type { Component, TUI } from "@earendil-works/pi-tui";
2
+ import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
3
+ import type { KeybindingsManager, Theme } from "@selesai/code";
4
4
  import type { IntercomClient } from "../broker/client.js";
5
5
  import type { SessionInfo } from "../types.js";
6
6
 
@@ -1,6 +1,6 @@
1
- import type { Component } from "@mariozechner/pi-tui";
2
- import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@mariozechner/pi-tui";
3
- import type { Theme } from "@mariozechner/pi-coding-agent";
1
+ import type { Component } from "@earendil-works/pi-tui";
2
+ import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
3
+ import type { Theme } from "@selesai/code";
4
4
  import type { SessionInfo, Message } from "../types.js";
5
5
 
6
6
  export class InlineMessageComponent implements Component {
@@ -1,6 +1,6 @@
1
- import type { Component } from "@mariozechner/pi-tui";
2
- import { truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
3
- import type { KeybindingsManager, Theme } from "@mariozechner/pi-coding-agent";
1
+ import type { Component } from "@earendil-works/pi-tui";
2
+ import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
3
+ import type { KeybindingsManager, Theme } from "@selesai/code";
4
4
  import type { SessionInfo } from "../types.js";
5
5
 
6
6
  function middleTruncate(text: string, maxWidth: number): string {
@@ -1,7 +1,7 @@
1
1
  import { fileURLToPath } from "node:url";
2
- import { CustomEditor } from "@earendil-works/pi-coding-agent";
2
+ import { CustomEditor } from "@selesai/code";
3
3
  import { isKeyRelease, matchesKey, visibleWidth, truncateToWidth } from "@earendil-works/pi-tui";
4
- import type { KeybindingsManager } from "@earendil-works/pi-coding-agent/dist/core/keybindings.js";
4
+ import type { KeybindingsManager } from "@selesai/code/dist/core/keybindings.js";
5
5
  import type { AutocompleteProvider } from "@earendil-works/pi-tui";
6
6
  import { matchesConfiguredShortcut } from "../shortcuts.ts";
7
7
  import { getOneOffBashCommandContext } from "./completion.ts";
@@ -1,6 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { homedir } from "node:os";
4
+ import { getAgentDir } from "@selesai/code";
4
5
 
5
6
  interface PersistedHistoryEntry {
6
7
  command: string;
@@ -13,7 +14,7 @@ function getHomeDir(): string {
13
14
  }
14
15
 
15
16
  function getHistoryDir(): string {
16
- return join(getHomeDir(), ".pi", "agent", "powerline-footer", "bash-history");
17
+ return join(getAgentDir(), "powerline-footer", "bash-history");
17
18
  }
18
19
 
19
20
  function projectKey(cwd: string): string {