@code-yeongyu/senpi 2026.7.25 → 2026.7.26

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 (575) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +1 -1
  3. package/dist/beta/omo-local-update.d.ts +207 -0
  4. package/dist/beta/omo-local-update.d.ts.map +1 -0
  5. package/dist/beta/omo-local-update.js +708 -0
  6. package/dist/beta/omo-local-update.js.map +1 -0
  7. package/dist/cli/args.d.ts +4 -16
  8. package/dist/cli/args.d.ts.map +1 -1
  9. package/dist/cli/args.js +9 -25
  10. package/dist/cli/args.js.map +1 -1
  11. package/dist/cli/grok-neo-gate.d.ts +12 -0
  12. package/dist/cli/grok-neo-gate.d.ts.map +1 -0
  13. package/dist/cli/grok-neo-gate.js +18 -0
  14. package/dist/cli/grok-neo-gate.js.map +1 -0
  15. package/dist/cli-main.js +4 -0
  16. package/dist/cli-main.js.map +1 -1
  17. package/dist/cli.js +2 -0
  18. package/dist/cli.js.map +1 -1
  19. package/dist/core/agent-session-runtime.d.ts +2 -0
  20. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  21. package/dist/core/agent-session-runtime.js +33 -8
  22. package/dist/core/agent-session-runtime.js.map +1 -1
  23. package/dist/core/agent-session.d.ts +22 -3
  24. package/dist/core/agent-session.d.ts.map +1 -1
  25. package/dist/core/agent-session.js +202 -58
  26. package/dist/core/agent-session.js.map +1 -1
  27. package/dist/core/auth-providers.d.ts +2 -2
  28. package/dist/core/auth-providers.js +2 -2
  29. package/dist/core/auth-providers.js.map +1 -1
  30. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
  31. package/dist/core/extensions/builtin/bash-timeout/timeout.js +3 -2
  32. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  33. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/compaction/index.js +30 -2
  35. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  36. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/compaction/speculative.js +28 -0
  38. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  39. package/dist/core/extensions/builtin/config-reload/index.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/config-reload/index.js +20 -17
  41. package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
  42. package/dist/core/extensions/builtin/config-reload/log.d.ts +4 -1
  43. package/dist/core/extensions/builtin/config-reload/log.d.ts.map +1 -1
  44. package/dist/core/extensions/builtin/config-reload/log.js +3 -0
  45. package/dist/core/extensions/builtin/config-reload/log.js.map +1 -1
  46. package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts +15 -0
  47. package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts.map +1 -0
  48. package/dist/core/extensions/builtin/config-reload/routine-settings.js +102 -0
  49. package/dist/core/extensions/builtin/config-reload/routine-settings.js.map +1 -0
  50. package/dist/core/extensions/builtin/goal/command-registration.js +2 -2
  51. package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
  52. package/dist/core/extensions/builtin/goal/format.d.ts +1 -1
  53. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/goal/format.js +9 -2
  55. package/dist/core/extensions/builtin/goal/format.js.map +1 -1
  56. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/goal/index.js +38 -23
  58. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  59. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +6 -0
  60. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -0
  61. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +19 -0
  62. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -0
  63. package/dist/core/extensions/builtin/goal/persistence.d.ts +6 -0
  64. package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -0
  65. package/dist/core/extensions/builtin/goal/persistence.js +141 -0
  66. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -0
  67. package/dist/core/extensions/builtin/goal/store.d.ts +7 -3
  68. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/goal/store.js +66 -181
  70. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  71. package/dist/core/extensions/builtin/goal/tool-registration.d.ts +1 -0
  72. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/goal/tool-registration.js +26 -15
  74. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  75. package/dist/core/extensions/builtin/goal/transitions.d.ts +3 -0
  76. package/dist/core/extensions/builtin/goal/transitions.d.ts.map +1 -0
  77. package/dist/core/extensions/builtin/goal/transitions.js +45 -0
  78. package/dist/core/extensions/builtin/goal/transitions.js.map +1 -0
  79. package/dist/core/extensions/builtin/goal/types.d.ts +10 -4
  80. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
  81. package/dist/core/extensions/builtin/goal/types.js +2 -2
  82. package/dist/core/extensions/builtin/goal/types.js.map +1 -1
  83. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
  84. package/dist/core/extensions/builtin/goal/ui.js +2 -0
  85. package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
  86. package/dist/core/extensions/builtin/goal/validation.d.ts +8 -1
  87. package/dist/core/extensions/builtin/goal/validation.d.ts.map +1 -1
  88. package/dist/core/extensions/builtin/goal/validation.js +24 -12
  89. package/dist/core/extensions/builtin/goal/validation.js.map +1 -1
  90. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  91. package/dist/core/extensions/builtin/index.js +0 -2
  92. package/dist/core/extensions/builtin/index.js.map +1 -1
  93. package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
  94. package/dist/core/extensions/builtin/mcp/index.js +8 -5
  95. package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
  96. package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
  97. package/dist/core/extensions/builtin/permission-system/parsers.js +1 -0
  98. package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
  99. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +48 -0
  100. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
  101. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +88 -64
  102. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  103. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  104. package/dist/core/extensions/builtin/terminal/extension.js +32 -0
  105. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  106. package/dist/core/extensions/builtin/terminal/index.d.ts +1 -1
  107. package/dist/core/extensions/builtin/terminal/index.d.ts.map +1 -1
  108. package/dist/core/extensions/builtin/terminal/index.js +1 -1
  109. package/dist/core/extensions/builtin/terminal/index.js.map +1 -1
  110. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +29 -0
  111. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -0
  112. package/dist/core/extensions/builtin/terminal/monitor-notify.js +185 -0
  113. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -0
  114. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +35 -0
  115. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -0
  116. package/dist/core/extensions/builtin/terminal/monitor-registry.js +98 -0
  117. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -0
  118. package/dist/core/extensions/builtin/terminal/notify.d.ts +9 -0
  119. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  120. package/dist/core/extensions/builtin/terminal/notify.js +30 -14
  121. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  122. package/dist/core/extensions/builtin/terminal/prompt.d.ts +1 -1
  123. package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
  124. package/dist/core/extensions/builtin/terminal/prompt.js +13 -5
  125. package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
  126. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +3 -12
  127. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  128. package/dist/core/extensions/builtin/terminal/runtime-session.js +4 -59
  129. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  130. package/dist/core/extensions/builtin/terminal/settings.d.ts +8 -0
  131. package/dist/core/extensions/builtin/terminal/settings.d.ts.map +1 -1
  132. package/dist/core/extensions/builtin/terminal/settings.js +16 -2
  133. package/dist/core/extensions/builtin/terminal/settings.js.map +1 -1
  134. package/dist/core/extensions/builtin/terminal/shared.d.ts +2 -2
  135. package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
  136. package/dist/core/extensions/builtin/terminal/shared.js +2 -1
  137. package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
  138. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts +10 -4
  139. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  140. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +17 -96
  141. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  142. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +7 -0
  143. package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
  144. package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
  145. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +41 -0
  146. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -0
  147. package/dist/core/extensions/builtin/terminal/tools/monitor.js +97 -0
  148. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -0
  149. package/dist/core/extensions/builtin/terminal/tools/render.d.ts +3 -0
  150. package/dist/core/extensions/builtin/terminal/tools/render.d.ts.map +1 -1
  151. package/dist/core/extensions/builtin/terminal/tools/render.js +5 -2
  152. package/dist/core/extensions/builtin/terminal/tools/render.js.map +1 -1
  153. package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts +19 -0
  154. package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts.map +1 -0
  155. package/dist/core/extensions/builtin/todotools/fuzzy-match.js +70 -0
  156. package/dist/core/extensions/builtin/todotools/fuzzy-match.js.map +1 -0
  157. package/dist/core/extensions/builtin/todotools/normalize.d.ts +8 -0
  158. package/dist/core/extensions/builtin/todotools/normalize.d.ts.map +1 -0
  159. package/dist/core/extensions/builtin/todotools/normalize.js +174 -0
  160. package/dist/core/extensions/builtin/todotools/normalize.js.map +1 -0
  161. package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
  162. package/dist/core/extensions/builtin/todotools/prompt.d.ts.map +1 -1
  163. package/dist/core/extensions/builtin/todotools/prompt.js +4 -2
  164. package/dist/core/extensions/builtin/todotools/prompt.js.map +1 -1
  165. package/dist/core/extensions/builtin/todotools/state.d.ts +9 -8
  166. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  167. package/dist/core/extensions/builtin/todotools/state.js +99 -48
  168. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  169. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +1 -1
  170. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  171. package/dist/core/extensions/builtin/todotools/tools/todo.js +65 -38
  172. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  173. package/dist/core/extensions/builtin/websearch/index.d.ts.map +1 -1
  174. package/dist/core/extensions/builtin/websearch/index.js +2 -4
  175. package/dist/core/extensions/builtin/websearch/index.js.map +1 -1
  176. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -1
  177. package/dist/core/extensions/builtin/websearch/websearch/config.js +4 -1
  178. package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -1
  179. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -1
  180. package/dist/core/extensions/builtin/websearch/websearch/native.js +2 -4
  181. package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -1
  182. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -1
  183. package/dist/core/extensions/builtin/websearch/websearch/renderers.js +20 -8
  184. package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -1
  185. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts +6 -1
  186. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -1
  187. package/dist/core/extensions/builtin/websearch/websearch/search.js +15 -11
  188. package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -1
  189. package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts.map +1 -1
  190. package/dist/core/extensions/builtin/websearch/websearch/tool.js +5 -10
  191. package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -1
  192. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +1 -0
  193. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
  194. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
  195. package/dist/core/extensions/loader.d.ts.map +1 -1
  196. package/dist/core/extensions/loader.js +12 -0
  197. package/dist/core/extensions/loader.js.map +1 -1
  198. package/dist/core/extensions/runner.d.ts +5 -0
  199. package/dist/core/extensions/runner.d.ts.map +1 -1
  200. package/dist/core/extensions/runner.js +12 -1
  201. package/dist/core/extensions/runner.js.map +1 -1
  202. package/dist/core/extensions/types.d.ts +25 -1
  203. package/dist/core/extensions/types.d.ts.map +1 -1
  204. package/dist/core/extensions/types.js.map +1 -1
  205. package/dist/core/keybindings.d.ts +0 -5
  206. package/dist/core/keybindings.d.ts.map +1 -1
  207. package/dist/core/keybindings.js +0 -2
  208. package/dist/core/keybindings.js.map +1 -1
  209. package/dist/core/messages.d.ts +32 -0
  210. package/dist/core/messages.d.ts.map +1 -1
  211. package/dist/core/messages.js +91 -0
  212. package/dist/core/messages.js.map +1 -1
  213. package/dist/core/model-resolver.d.ts +10 -1
  214. package/dist/core/model-resolver.d.ts.map +1 -1
  215. package/dist/core/model-resolver.js +13 -3
  216. package/dist/core/model-resolver.js.map +1 -1
  217. package/dist/core/model-runtime.d.ts +2 -0
  218. package/dist/core/model-runtime.d.ts.map +1 -1
  219. package/dist/core/model-runtime.js +4 -3
  220. package/dist/core/model-runtime.js.map +1 -1
  221. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  222. package/dist/core/remote-catalog-provider.js +19 -1
  223. package/dist/core/remote-catalog-provider.js.map +1 -1
  224. package/dist/core/resource-loader.d.ts +9 -0
  225. package/dist/core/resource-loader.d.ts.map +1 -1
  226. package/dist/core/resource-loader.js +13 -2
  227. package/dist/core/resource-loader.js.map +1 -1
  228. package/dist/core/retry-fallback/controller.d.ts +7 -0
  229. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  230. package/dist/core/retry-fallback/controller.js +13 -0
  231. package/dist/core/retry-fallback/controller.js.map +1 -1
  232. package/dist/core/retry-fallback/cooldown.d.ts.map +1 -1
  233. package/dist/core/retry-fallback/cooldown.js +5 -0
  234. package/dist/core/retry-fallback/cooldown.js.map +1 -1
  235. package/dist/core/sdk.d.ts.map +1 -1
  236. package/dist/core/sdk.js +11 -35
  237. package/dist/core/sdk.js.map +1 -1
  238. package/dist/core/settings-manager.d.ts +12 -16
  239. package/dist/core/settings-manager.d.ts.map +1 -1
  240. package/dist/core/settings-manager.js +10 -13
  241. package/dist/core/settings-manager.js.map +1 -1
  242. package/dist/core/slash-commands.d.ts.map +1 -1
  243. package/dist/core/slash-commands.js +1 -0
  244. package/dist/core/slash-commands.js.map +1 -1
  245. package/dist/core/thinking-levels.d.ts.map +1 -1
  246. package/dist/core/thinking-levels.js +9 -2
  247. package/dist/core/thinking-levels.js.map +1 -1
  248. package/dist/core/timings.d.ts +7 -2
  249. package/dist/core/timings.d.ts.map +1 -1
  250. package/dist/core/timings.js +11 -0
  251. package/dist/core/timings.js.map +1 -1
  252. package/dist/extensions/llama/provider.d.ts.map +1 -1
  253. package/dist/extensions/llama/provider.js +6 -0
  254. package/dist/extensions/llama/provider.js.map +1 -1
  255. package/dist/inspector-policy.d.ts +22 -0
  256. package/dist/inspector-policy.d.ts.map +1 -0
  257. package/dist/inspector-policy.js +84 -0
  258. package/dist/inspector-policy.js.map +1 -0
  259. package/dist/main.d.ts +6 -0
  260. package/dist/main.d.ts.map +1 -1
  261. package/dist/main.js +20 -23
  262. package/dist/main.js.map +1 -1
  263. package/dist/modes/app-server/runtime.d.ts.map +1 -1
  264. package/dist/modes/app-server/runtime.js +1 -0
  265. package/dist/modes/app-server/runtime.js.map +1 -1
  266. package/dist/modes/app-server/threads/goal-handlers.js +4 -2
  267. package/dist/modes/app-server/threads/goal-handlers.js.map +1 -1
  268. package/dist/modes/app-server/threads/goal-wire.d.ts.map +1 -1
  269. package/dist/modes/app-server/threads/goal-wire.js +1 -0
  270. package/dist/modes/app-server/threads/goal-wire.js.map +1 -1
  271. package/dist/modes/app-server/threads/handlers.d.ts +1 -0
  272. package/dist/modes/app-server/threads/handlers.d.ts.map +1 -1
  273. package/dist/modes/app-server/threads/handlers.js +2 -0
  274. package/dist/modes/app-server/threads/handlers.js.map +1 -1
  275. package/dist/modes/app-server/threads/turn-runtime.d.ts +1 -0
  276. package/dist/modes/app-server/threads/turn-runtime.d.ts.map +1 -1
  277. package/dist/modes/app-server/threads/turn-runtime.js.map +1 -1
  278. package/dist/modes/app-server/threads/turns.d.ts.map +1 -1
  279. package/dist/modes/app-server/threads/turns.js +47 -3
  280. package/dist/modes/app-server/threads/turns.js.map +1 -1
  281. package/dist/modes/interactive/components/custom-message.d.ts +3 -1
  282. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/custom-message.js +9 -2
  284. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  285. package/dist/modes/interactive/components/status-indicator.d.ts +1 -0
  286. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  287. package/dist/modes/interactive/components/status-indicator.js +29 -4
  288. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  289. package/dist/modes/interactive/components/tool-execution.d.ts +5 -1
  290. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  291. package/dist/modes/interactive/components/tool-execution.js +43 -17
  292. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  293. package/dist/modes/interactive/grok/chrome-tokens.d.ts +22 -0
  294. package/dist/modes/interactive/grok/chrome-tokens.d.ts.map +1 -0
  295. package/dist/modes/interactive/grok/chrome-tokens.js +27 -0
  296. package/dist/modes/interactive/grok/chrome-tokens.js.map +1 -0
  297. package/dist/modes/interactive/grok/chrome.d.ts +51 -0
  298. package/dist/modes/interactive/grok/chrome.d.ts.map +1 -0
  299. package/dist/modes/interactive/grok/chrome.js +105 -0
  300. package/dist/modes/interactive/grok/chrome.js.map +1 -0
  301. package/dist/modes/interactive/grok/footer.d.ts +14 -0
  302. package/dist/modes/interactive/grok/footer.d.ts.map +1 -0
  303. package/dist/modes/interactive/grok/footer.js +27 -0
  304. package/dist/modes/interactive/grok/footer.js.map +1 -0
  305. package/dist/modes/interactive/grok/input-card.d.ts +9 -0
  306. package/dist/modes/interactive/grok/input-card.d.ts.map +1 -0
  307. package/dist/modes/interactive/grok/input-card.js +30 -0
  308. package/dist/modes/interactive/grok/input-card.js.map +1 -0
  309. package/dist/modes/interactive/grok/palette.d.ts +145 -0
  310. package/dist/modes/interactive/grok/palette.d.ts.map +1 -0
  311. package/dist/modes/interactive/grok/palette.js +92 -0
  312. package/dist/modes/interactive/grok/palette.js.map +1 -0
  313. package/dist/modes/interactive/grok/tool-row.d.ts +17 -0
  314. package/dist/modes/interactive/grok/tool-row.d.ts.map +1 -0
  315. package/dist/modes/interactive/grok/tool-row.js +26 -0
  316. package/dist/modes/interactive/grok/tool-row.js.map +1 -0
  317. package/dist/modes/interactive/grok/welcome-card.d.ts +10 -0
  318. package/dist/modes/interactive/grok/welcome-card.d.ts.map +1 -0
  319. package/dist/modes/interactive/grok/welcome-card.js +30 -0
  320. package/dist/modes/interactive/grok/welcome-card.js.map +1 -0
  321. package/dist/modes/interactive/interactive-mode.d.ts +5 -0
  322. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  323. package/dist/modes/interactive/interactive-mode.js +117 -54
  324. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  325. package/dist/modes/interactive/theme/grok-day.json +77 -0
  326. package/dist/modes/interactive/theme/grok-night.json +93 -0
  327. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  328. package/dist/modes/interactive/theme/theme.js +4 -0
  329. package/dist/modes/interactive/theme/theme.js.map +1 -1
  330. package/dist/modes/rpc/connection-handler.d.ts +3 -3
  331. package/dist/modes/rpc/connection-handler.js +6 -6
  332. package/dist/modes/rpc/connection-handler.js.map +1 -1
  333. package/dist/modes/rpc/custom-capability.d.ts +6 -7
  334. package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
  335. package/dist/modes/rpc/custom-capability.js +6 -7
  336. package/dist/modes/rpc/custom-capability.js.map +1 -1
  337. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  338. package/dist/modes/rpc/rpc-mode.js +5 -5
  339. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  340. package/dist/package-manager-cli.d.ts.map +1 -1
  341. package/dist/package-manager-cli.js +11 -0
  342. package/dist/package-manager-cli.js.map +1 -1
  343. package/dist/senpi +2 -0
  344. package/docs/docs.json +4 -0
  345. package/docs/environment-variables.md +1 -0
  346. package/docs/extensions.md +2 -2
  347. package/docs/grok-neo.md +77 -0
  348. package/docs/keybindings.md +0 -1
  349. package/docs/settings.md +14 -3
  350. package/docs/terminal-tools.md +6 -3
  351. package/docs/usage.md +1 -1
  352. package/examples/extensions/message-renderer.ts +2 -2
  353. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +47 -0
  354. package/node_modules/@code-yeongyu/senpi-codemode/README.md +39 -19
  355. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  356. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +6 -1
  357. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/output-bridge.ts +0 -1
  358. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-notifier.ts +40 -0
  359. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +46 -66
  360. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +5 -2
  361. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +2 -0
  362. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +19 -4
  363. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +7 -0
  364. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +8 -5
  365. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +23 -5
  366. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +322 -0
  367. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +253 -18
  368. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/interrupt-note.ts +58 -0
  369. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +28 -6
  370. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/status-events.ts +20 -0
  371. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +65 -22
  372. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  373. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +4 -41
  374. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  375. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +6 -0
  376. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  377. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +4 -0
  378. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  379. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +10 -0
  380. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -0
  381. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +38 -0
  382. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -0
  383. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +5 -0
  384. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  385. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  386. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  387. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  388. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +210 -26
  389. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  390. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts.map +1 -1
  391. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +16 -8
  392. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  393. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  394. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +39 -20
  395. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  396. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.d.ts.map +1 -1
  397. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js +9 -2
  398. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js.map +1 -1
  399. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
  400. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +4 -3
  401. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
  402. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.d.ts.map +1 -1
  403. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js +12 -2
  404. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js.map +1 -1
  405. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  406. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +19 -11
  407. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  408. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  409. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +121 -23
  410. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  411. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +1 -0
  412. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  413. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +67 -31
  414. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  415. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  416. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +13 -8
  417. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  418. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.d.ts.map +1 -1
  419. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js +1 -0
  420. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js.map +1 -1
  421. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.d.ts +3 -2
  422. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.d.ts.map +1 -1
  423. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.js +37 -35
  424. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.js.map +1 -1
  425. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  426. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +11 -1
  427. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  428. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
  429. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  430. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  431. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  432. package/node_modules/@earendil-works/pi-ai/dist/models-store.d.ts +5 -0
  433. package/node_modules/@earendil-works/pi-ai/dist/models-store.d.ts.map +1 -1
  434. package/node_modules/@earendil-works/pi-ai/dist/models-store.js.map +1 -1
  435. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  436. package/node_modules/@earendil-works/pi-ai/dist/models.js +5 -1
  437. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  438. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  439. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  440. package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  442. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  443. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  444. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  445. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  446. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +9 -0
  447. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  448. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  449. package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.d.ts.map +1 -1
  450. package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.js +8 -3
  451. package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.js.map +1 -1
  452. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  453. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +10 -0
  454. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  455. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts +30 -0
  456. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts.map +1 -0
  457. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js +70 -0
  458. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js.map +1 -0
  459. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts +1 -1
  460. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts.map +1 -1
  461. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js +7 -3
  462. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js.map +1 -1
  463. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts +9 -0
  464. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts.map +1 -0
  465. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js +16 -0
  466. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js.map +1 -0
  467. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  468. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  469. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +1 -0
  470. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
  471. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +35 -3
  472. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
  473. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +6 -0
  474. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  475. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  476. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +32 -0
  477. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +1 -1
  478. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +15 -7
  479. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +1 -1
  480. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  481. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  482. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  483. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  484. package/package.json +8 -8
  485. package/dist/cli/neo/build-argv.d.ts +0 -19
  486. package/dist/cli/neo/build-argv.d.ts.map +0 -1
  487. package/dist/cli/neo/build-argv.js +0 -84
  488. package/dist/cli/neo/build-argv.js.map +0 -1
  489. package/dist/cli/neo/daemon-launch.d.ts +0 -25
  490. package/dist/cli/neo/daemon-launch.d.ts.map +0 -1
  491. package/dist/cli/neo/daemon-launch.js +0 -97
  492. package/dist/cli/neo/daemon-launch.js.map +0 -1
  493. package/dist/cli/neo/gate.d.ts +0 -15
  494. package/dist/cli/neo/gate.d.ts.map +0 -1
  495. package/dist/cli/neo/gate.js +0 -21
  496. package/dist/cli/neo/gate.js.map +0 -1
  497. package/dist/cli/neo/launch.d.ts +0 -24
  498. package/dist/cli/neo/launch.d.ts.map +0 -1
  499. package/dist/cli/neo/launch.js +0 -66
  500. package/dist/cli/neo/launch.js.map +0 -1
  501. package/dist/cli/neo/platform.d.ts +0 -38
  502. package/dist/cli/neo/platform.d.ts.map +0 -1
  503. package/dist/cli/neo/platform.js +0 -54
  504. package/dist/cli/neo/platform.js.map +0 -1
  505. package/dist/cli/neo/resolve-binary.d.ts +0 -39
  506. package/dist/cli/neo/resolve-binary.d.ts.map +0 -1
  507. package/dist/cli/neo/resolve-binary.js +0 -66
  508. package/dist/cli/neo/resolve-binary.js.map +0 -1
  509. package/dist/core/extensions/builtin/session-observer/index.d.ts +0 -5
  510. package/dist/core/extensions/builtin/session-observer/index.d.ts.map +0 -1
  511. package/dist/core/extensions/builtin/session-observer/index.js +0 -36
  512. package/dist/core/extensions/builtin/session-observer/index.js.map +0 -1
  513. package/dist/core/extensions/builtin/session-observer/loader.d.ts +0 -3
  514. package/dist/core/extensions/builtin/session-observer/loader.d.ts.map +0 -1
  515. package/dist/core/extensions/builtin/session-observer/loader.js +0 -20
  516. package/dist/core/extensions/builtin/session-observer/loader.js.map +0 -1
  517. package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts +0 -7
  518. package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts.map +0 -1
  519. package/dist/core/extensions/builtin/session-observer/overlay-format.js +0 -30
  520. package/dist/core/extensions/builtin/session-observer/overlay-format.js.map +0 -1
  521. package/dist/core/extensions/builtin/session-observer/overlay.d.ts +0 -51
  522. package/dist/core/extensions/builtin/session-observer/overlay.d.ts.map +0 -1
  523. package/dist/core/extensions/builtin/session-observer/overlay.js +0 -229
  524. package/dist/core/extensions/builtin/session-observer/overlay.js.map +0 -1
  525. package/dist/core/extensions/builtin/session-observer/scanner.d.ts +0 -10
  526. package/dist/core/extensions/builtin/session-observer/scanner.d.ts.map +0 -1
  527. package/dist/core/extensions/builtin/session-observer/scanner.js +0 -142
  528. package/dist/core/extensions/builtin/session-observer/scanner.js.map +0 -1
  529. package/dist/core/extensions/builtin/session-observer/text.d.ts +0 -7
  530. package/dist/core/extensions/builtin/session-observer/text.d.ts.map +0 -1
  531. package/dist/core/extensions/builtin/session-observer/text.js +0 -37
  532. package/dist/core/extensions/builtin/session-observer/text.js.map +0 -1
  533. package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts +0 -7
  534. package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts.map +0 -1
  535. package/dist/core/extensions/builtin/session-observer/transcript-entries.js +0 -71
  536. package/dist/core/extensions/builtin/session-observer/transcript-entries.js.map +0 -1
  537. package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts +0 -11
  538. package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts.map +0 -1
  539. package/dist/core/extensions/builtin/session-observer/transcript-format.js +0 -65
  540. package/dist/core/extensions/builtin/session-observer/transcript-format.js.map +0 -1
  541. package/dist/core/extensions/builtin/session-observer/transcript.d.ts +0 -4
  542. package/dist/core/extensions/builtin/session-observer/transcript.d.ts.map +0 -1
  543. package/dist/core/extensions/builtin/session-observer/transcript.js +0 -81
  544. package/dist/core/extensions/builtin/session-observer/transcript.js.map +0 -1
  545. package/dist/core/extensions/builtin/session-observer/types.d.ts +0 -33
  546. package/dist/core/extensions/builtin/session-observer/types.d.ts.map +0 -1
  547. package/dist/core/extensions/builtin/session-observer/types.js +0 -2
  548. package/dist/core/extensions/builtin/session-observer/types.js.map +0 -1
  549. package/dist/modes/rpc/neo-daemon-child-worker.d.ts +0 -29
  550. package/dist/modes/rpc/neo-daemon-child-worker.d.ts.map +0 -1
  551. package/dist/modes/rpc/neo-daemon-child-worker.js +0 -95
  552. package/dist/modes/rpc/neo-daemon-child-worker.js.map +0 -1
  553. package/dist/modes/rpc/neo-daemon-mode.d.ts +0 -110
  554. package/dist/modes/rpc/neo-daemon-mode.d.ts.map +0 -1
  555. package/dist/modes/rpc/neo-daemon-mode.js +0 -267
  556. package/dist/modes/rpc/neo-daemon-mode.js.map +0 -1
  557. package/dist/modes/rpc/neo-daemon-protocol.d.ts +0 -50
  558. package/dist/modes/rpc/neo-daemon-protocol.d.ts.map +0 -1
  559. package/dist/modes/rpc/neo-daemon-protocol.js +0 -66
  560. package/dist/modes/rpc/neo-daemon-protocol.js.map +0 -1
  561. package/dist/modes/rpc/neo-daemon-registry.d.ts +0 -98
  562. package/dist/modes/rpc/neo-daemon-registry.d.ts.map +0 -1
  563. package/dist/modes/rpc/neo-daemon-registry.js +0 -209
  564. package/dist/modes/rpc/neo-daemon-registry.js.map +0 -1
  565. package/dist/modes/rpc/neo-runtime-options-argv.d.ts +0 -17
  566. package/dist/modes/rpc/neo-runtime-options-argv.d.ts.map +0 -1
  567. package/dist/modes/rpc/neo-runtime-options-argv.js +0 -79
  568. package/dist/modes/rpc/neo-runtime-options-argv.js.map +0 -1
  569. package/dist/modes/rpc/neo-runtime-options.d.ts +0 -84
  570. package/dist/modes/rpc/neo-runtime-options.d.ts.map +0 -1
  571. package/dist/modes/rpc/neo-runtime-options.js +0 -92
  572. package/dist/modes/rpc/neo-runtime-options.js.map +0 -1
  573. package/docs/neo.md +0 -111
  574. package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/runtime.ts +0 -258
  575. package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/tools.ts +0 -106
@@ -0,0 +1,708 @@
1
+ // BETA(omo-local-update): removable beta module - delete this file, all test/omo-local-update*
2
+ // files to drop the feature.
3
+ //
4
+ // Beta: on bare `senpi update`, compare a locally-installed OMO plugin (omo-senpi +
5
+ // senpi-task) against origin/dev of its source checkout and replace the LOCAL PLUGIN
6
+ // INSTALL only when different. The user's checkout receives ZERO git mutations: this module
7
+ // never runs checkout/branch/commit/merge/reset/clean/stash/push against the user's repo.
8
+ // Its only git writes are `git fetch origin dev` (remote-tracking ref update) plus
9
+ // worktree add/remove/prune registering the FEATURE-OWNED persistent build worktree under
10
+ // <agentDir>/omo-local-update/. `checkout --detach --force` is used exactly once and only
11
+ // inside that feature-owned worktree, which this module creates and owns exclusively.
12
+ // Builds run there; the install target (pluginPath) is swapped atomically by rename.
13
+ //
14
+ // Export policy: `runOmoLocalUpdateBeta` is the ONLY production API and the only symbol the
15
+ // CLI may import. Every other export in this module is /** exported for tests only */ so the
16
+ // single test file (test/omo-local-update.test.ts) can exercise helpers directly - no
17
+ // CLI-side helper imports, no logic duplication.
18
+ import { randomUUID } from "node:crypto";
19
+ import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync, } from "node:fs";
20
+ import { homedir } from "node:os";
21
+ import { dirname, join, relative, resolve, sep } from "node:path";
22
+ import chalk from "chalk";
23
+ import { spawnProcess, waitForChildProcess } from "../utils/child-process.js";
24
+ import { canonicalizePath, isLocalPath, resolvePath } from "../utils/paths.js";
25
+ import { killProcessTree } from "../utils/shell.js";
26
+ /**
27
+ * exported for tests only
28
+ *
29
+ * Shared process seam for the whole module. spawnProcess/waitForChildProcess neither capture
30
+ * output nor enforce timeouts; this adds both. The child is spawned detached on POSIX so it
31
+ * owns a process group, and the timeout kill goes through killProcessTree (SIGKILL to the
32
+ * whole group) - without that, bun/git descendants would keep mutating the build worktree
33
+ * after the direct child died.
34
+ */
35
+ export async function defaultRun(command, args, options) {
36
+ const child = spawnProcess(command, args, {
37
+ cwd: options.cwd,
38
+ stdio: ["ignore", "pipe", "pipe"],
39
+ env: { ...process.env, ...options.env },
40
+ detached: process.platform !== "win32",
41
+ windowsHide: true,
42
+ });
43
+ let stdout = "";
44
+ let stderr = "";
45
+ child.stdout.on("data", (chunk) => {
46
+ stdout += chunk.toString();
47
+ });
48
+ child.stderr.on("data", (chunk) => {
49
+ stderr += chunk.toString();
50
+ });
51
+ const abort = new AbortController();
52
+ let timedOut = false;
53
+ const pid = child.pid;
54
+ const timer = options.timeoutMs === undefined
55
+ ? undefined
56
+ : setTimeout(() => {
57
+ timedOut = true;
58
+ if (pid !== undefined) {
59
+ killProcessTree(pid);
60
+ }
61
+ abort.abort();
62
+ }, options.timeoutMs);
63
+ try {
64
+ const code = await waitForChildProcess(child, { signal: abort.signal });
65
+ return { code, stdout, stderr, timedOut };
66
+ }
67
+ finally {
68
+ if (timer !== undefined) {
69
+ clearTimeout(timer);
70
+ }
71
+ }
72
+ }
73
+ /** exported for tests only */
74
+ export function isKillSwitched(env) {
75
+ return env.SENPI_OMO_LOCAL_UPDATE === "0";
76
+ }
77
+ function defaultReadJson(path) {
78
+ try {
79
+ return JSON.parse(readFileSync(path, "utf-8"));
80
+ }
81
+ catch {
82
+ return undefined;
83
+ }
84
+ }
85
+ function packageNameOf(json) {
86
+ if (typeof json !== "object" || json === null) {
87
+ return undefined;
88
+ }
89
+ const name = json.name;
90
+ return typeof name === "string" ? name : undefined;
91
+ }
92
+ /** Same semantics as package-manager.ts's private getHomeDir (HOME env wins over os.homedir). */
93
+ function homeDir() {
94
+ return process.env.HOME || homedir();
95
+ }
96
+ /**
97
+ * exported for tests only
98
+ *
99
+ * Three-part detection gate (ALL must hold, else silent no-op):
100
+ * 1. A global settings `packages` entry (string or object form) is a local path whose resolved
101
+ * dir's package.json name is `@code-yeongyu/omo-senpi`.
102
+ * 2. The derived repo root (pluginPath/../../..) contains both workspace packages
103
+ * `@oh-my-opencode/omo-senpi` and `@oh-my-opencode/senpi-task`.
104
+ * 3. `git -C <repoRoot> rev-parse --show-toplevel` succeeds AND its canonicalized output equals
105
+ * the canonicalized repo root - a mismatched toplevel would mean the derived root is not
106
+ * the checkout it claims to be.
107
+ */
108
+ export async function detectOmoLocalInstall(options) {
109
+ const readJson = options.readJson ?? defaultReadJson;
110
+ const exists = options.exists ?? existsSync;
111
+ if (!options.packages) {
112
+ return undefined;
113
+ }
114
+ for (const entry of options.packages) {
115
+ const source = typeof entry === "string" ? entry : entry.source;
116
+ if (!isLocalPath(source)) {
117
+ continue;
118
+ }
119
+ const pluginPath = resolvePath(source, options.agentDir, { homeDir: homeDir(), trim: true });
120
+ if (packageNameOf(readJson(join(pluginPath, "package.json"))) !== "@code-yeongyu/omo-senpi") {
121
+ continue;
122
+ }
123
+ const repoRoot = resolve(pluginPath, "..", "..", "..");
124
+ const omoSenpiPkgPath = join(repoRoot, "packages", "omo-senpi", "package.json");
125
+ const senpiTaskPkgPath = join(repoRoot, "packages", "senpi-task", "package.json");
126
+ if (!exists(omoSenpiPkgPath) || packageNameOf(readJson(omoSenpiPkgPath)) !== "@oh-my-opencode/omo-senpi") {
127
+ continue;
128
+ }
129
+ if (!exists(senpiTaskPkgPath) || packageNameOf(readJson(senpiTaskPkgPath)) !== "@oh-my-opencode/senpi-task") {
130
+ continue;
131
+ }
132
+ let topLevel;
133
+ try {
134
+ const result = await options.run("git", ["-C", repoRoot, "rev-parse", "--show-toplevel"], {});
135
+ if (result.code !== 0) {
136
+ continue;
137
+ }
138
+ topLevel = result.stdout.trim();
139
+ }
140
+ catch {
141
+ continue;
142
+ }
143
+ if (topLevel === "" || canonicalizePath(topLevel) !== canonicalizePath(repoRoot)) {
144
+ continue;
145
+ }
146
+ return { pluginPath, repoRoot };
147
+ }
148
+ return undefined;
149
+ }
150
+ /** exported for tests only */
151
+ export function omoLocalUpdateStampPath(agentDir) {
152
+ return join(agentDir, "omo-local-update-state.json");
153
+ }
154
+ /** exported for tests only */
155
+ export function readStamp(agentDir) {
156
+ const json = defaultReadJson(omoLocalUpdateStampPath(agentDir));
157
+ if (typeof json !== "object" || json === null) {
158
+ return undefined;
159
+ }
160
+ const candidate = json;
161
+ if (typeof candidate.repoRoot !== "string" ||
162
+ typeof candidate.sha !== "string" ||
163
+ typeof candidate.omoSenpiTree !== "string" ||
164
+ typeof candidate.senpiTaskTree !== "string" ||
165
+ typeof candidate.installedAt !== "string" ||
166
+ !Array.isArray(candidate.artifacts)) {
167
+ return undefined;
168
+ }
169
+ const artifacts = [];
170
+ for (const artifact of candidate.artifacts) {
171
+ if (typeof artifact !== "string") {
172
+ return undefined;
173
+ }
174
+ artifacts.push(artifact);
175
+ }
176
+ return {
177
+ repoRoot: candidate.repoRoot,
178
+ sha: candidate.sha,
179
+ omoSenpiTree: candidate.omoSenpiTree,
180
+ senpiTaskTree: candidate.senpiTaskTree,
181
+ installedAt: candidate.installedAt,
182
+ artifacts,
183
+ };
184
+ }
185
+ /** exported for tests only */
186
+ export function writeStamp(agentDir, stamp) {
187
+ mkdirSync(agentDir, { recursive: true });
188
+ writeFileSync(omoLocalUpdateStampPath(agentDir), `${JSON.stringify(stamp, null, 2)}\n`, "utf-8");
189
+ }
190
+ /**
191
+ * exported for tests only
192
+ *
193
+ * Skip decision (taken BEFORE any worktree op, install, or write): skip only when the stamp
194
+ * belongs to this repo root, was installed at the frozen remote sha, recorded a non-empty
195
+ * artifact inventory, and every inventoried path still exists. A repoRoot mismatch always
196
+ * updates; an empty/absent inventory never skips; force always updates.
197
+ */
198
+ export function shouldSkipUpdate(options) {
199
+ if (options.force) {
200
+ return false;
201
+ }
202
+ const stamp = options.stamp;
203
+ if (!stamp) {
204
+ return false;
205
+ }
206
+ if (stamp.repoRoot !== options.repoRoot) {
207
+ return false;
208
+ }
209
+ if (stamp.sha !== options.remoteSha) {
210
+ return false;
211
+ }
212
+ if (stamp.artifacts.length === 0) {
213
+ return false;
214
+ }
215
+ return options.stampArtifactsExist;
216
+ }
217
+ /**
218
+ * exported for tests only
219
+ *
220
+ * Failure of one orchestrator-owned step (fetch/worktree/install/build/artifacts/swap/stamp).
221
+ * The stage feeds `OMO local plugin update failed (<stage>): ...`; `output` (combined
222
+ * stdout+stderr of the failed step) is echoed dim, last 40 lines.
223
+ */
224
+ export class OmoLocalStepError extends Error {
225
+ constructor(stage, message, output) {
226
+ super(message);
227
+ this.name = "OmoLocalStepError";
228
+ this.stage = stage;
229
+ this.output = output;
230
+ }
231
+ }
232
+ function firstErrorLine(result) {
233
+ for (const text of [result.stderr, result.stdout]) {
234
+ for (const line of text.split("\n")) {
235
+ const trimmed = line.trim();
236
+ if (trimmed !== "") {
237
+ return trimmed;
238
+ }
239
+ }
240
+ }
241
+ return "unknown error";
242
+ }
243
+ /**
244
+ * exported for tests only
245
+ *
246
+ * Inspect the two packages' state ON ORIGIN/DEV: ONE `git fetch origin dev` (120s, read-only
247
+ * - the ONLY network/ref operation in the module), then rev-parse/log reads against the
248
+ * frozen `origin/dev` ref. A fetch failure throws an OmoLocalStepError with stage "fetch"
249
+ * before anything else is touched.
250
+ */
251
+ export async function computeRemoteState(options) {
252
+ const { repoRoot, run } = options;
253
+ const git = (args, timeoutMs) => run("git", args, { cwd: repoRoot, timeoutMs });
254
+ const requireOk = async (args, timeoutMs) => {
255
+ const result = await git(args, timeoutMs);
256
+ if (result.timedOut) {
257
+ throw new OmoLocalStepError("fetch", `git ${args.join(" ")} timed out`);
258
+ }
259
+ if (result.code !== 0) {
260
+ throw new OmoLocalStepError("fetch", `git ${args.join(" ")}: ${firstErrorLine(result)}`, `${result.stdout}${result.stderr}`);
261
+ }
262
+ return result.stdout.trim();
263
+ };
264
+ await requireOk(["fetch", "origin", "dev"], 120_000);
265
+ const sha = await requireOk(["rev-parse", "origin/dev"]);
266
+ if (sha === "") {
267
+ throw new OmoLocalStepError("fetch", "git rev-parse origin/dev: empty output");
268
+ }
269
+ const subject = await requireOk(["log", "-1", "--format=%s", "origin/dev"]);
270
+ const omoSenpiTree = await requireOk(["rev-parse", "origin/dev:packages/omo-senpi"]);
271
+ const senpiTaskTree = await requireOk(["rev-parse", "origin/dev:packages/senpi-task"]);
272
+ return { sha, subject, omoSenpiTree, senpiTaskTree };
273
+ }
274
+ /** exported for tests only */
275
+ export function omoLocalUpdateLockPath(agentDir) {
276
+ return join(agentDir, "omo-local-update.lock");
277
+ }
278
+ /** exported for tests only */
279
+ export function omoLocalUpdateBuildWorktreePath(agentDir) {
280
+ return join(agentDir, "omo-local-update", "build-worktree");
281
+ }
282
+ function readLockFile(path) {
283
+ try {
284
+ const json = JSON.parse(readFileSync(path, "utf-8"));
285
+ if (typeof json.pid !== "number" || typeof json.nonce !== "string") {
286
+ return undefined;
287
+ }
288
+ return { pid: json.pid, nonce: json.nonce };
289
+ }
290
+ catch {
291
+ return undefined;
292
+ }
293
+ }
294
+ function pidIsAlive(pid) {
295
+ try {
296
+ process.kill(pid, 0);
297
+ return true;
298
+ }
299
+ catch (error) {
300
+ // EPERM: the process exists but belongs to another user.
301
+ return error.code === "EPERM";
302
+ }
303
+ }
304
+ /**
305
+ * Atomic lock acquisition (concurrency guard): `wx` create writing {pid, nonce, startedAt}.
306
+ * On EEXIST: a LIVE pid wins unconditionally - dim line, NEVER take over regardless of age.
307
+ * A dead pid (or an unreadable lock) is unlinked and the `wx` create retried ONCE; a
308
+ * concurrent winner's fresh lock then loses us the retry, which is correct. Synchronous
309
+ * throughout, so in-process contenders cannot interleave mid-check.
310
+ */
311
+ function acquireOmoLocalLock(agentDir, log) {
312
+ mkdirSync(agentDir, { recursive: true });
313
+ const path = omoLocalUpdateLockPath(agentDir);
314
+ const lock = { path, pid: process.pid, nonce: randomUUID() };
315
+ const payload = JSON.stringify({ pid: lock.pid, nonce: lock.nonce, startedAt: new Date().toISOString() });
316
+ const tryCreate = () => {
317
+ try {
318
+ writeFileSync(path, payload, { flag: "wx" });
319
+ return true;
320
+ }
321
+ catch (error) {
322
+ if (error.code === "EEXIST") {
323
+ return false;
324
+ }
325
+ throw error;
326
+ }
327
+ };
328
+ const reportBusy = () => {
329
+ const existing = readLockFile(path);
330
+ log(chalk.dim(`OMO local plugin update already running (pid ${existing?.pid ?? "unknown"}); skipping.`));
331
+ return undefined;
332
+ };
333
+ if (tryCreate()) {
334
+ return lock;
335
+ }
336
+ const existing = readLockFile(path);
337
+ if (existing !== undefined && pidIsAlive(existing.pid)) {
338
+ return reportBusy();
339
+ }
340
+ try {
341
+ rmSync(path);
342
+ }
343
+ catch {
344
+ // Another process reclaimed first; the single retry below loses correctly.
345
+ }
346
+ if (tryCreate()) {
347
+ return lock;
348
+ }
349
+ return reportBusy();
350
+ }
351
+ /** Owner-checked unlink: re-read and match our own pid+nonce before deleting. */
352
+ function releaseOmoLocalLock(lock) {
353
+ try {
354
+ const existing = readLockFile(lock.path);
355
+ if (existing !== undefined && existing.pid === lock.pid && existing.nonce === lock.nonce) {
356
+ rmSync(lock.path);
357
+ }
358
+ }
359
+ catch {
360
+ // Lock release must never throw.
361
+ }
362
+ }
363
+ /** Post-build completeness set: five files plus a non-empty skills glob. */
364
+ const REQUIRED_BUILD_ARTIFACTS = [
365
+ "extensions/omo.js",
366
+ "runtime/lsp-daemon/dist/cli.js",
367
+ "runtime/lsp-daemon/dist/index.js",
368
+ "runtime/lsp-daemon/dist/.omo-runtime-manifest.json",
369
+ "scripts/install.mjs",
370
+ ];
371
+ function walkFiles(rootDir) {
372
+ const files = [];
373
+ const pending = [rootDir];
374
+ while (pending.length > 0) {
375
+ const dir = pending.pop();
376
+ if (dir === undefined) {
377
+ continue;
378
+ }
379
+ let entries;
380
+ try {
381
+ entries = readdirSync(dir, { withFileTypes: true });
382
+ }
383
+ catch {
384
+ continue;
385
+ }
386
+ for (const entry of entries) {
387
+ const full = join(dir, entry.name);
388
+ if (entry.isDirectory()) {
389
+ pending.push(full);
390
+ }
391
+ else if (entry.isFile()) {
392
+ files.push(full);
393
+ }
394
+ }
395
+ }
396
+ return files;
397
+ }
398
+ /**
399
+ * Post-install inventory for the stamp: every file under plugin/extensions/ and
400
+ * plugin/runtime/lsp-daemon/dist/, every SKILL.md under plugin/skills/, plus
401
+ * plugin/scripts/install.mjs - paths relative to the plugin dir, posix-separated, sorted.
402
+ */
403
+ function collectArtifactInventory(pluginPath) {
404
+ const inventory = [];
405
+ const collectUnder = (relativeDir, filter) => {
406
+ for (const filePath of walkFiles(join(pluginPath, relativeDir))) {
407
+ const posixPath = relative(pluginPath, filePath).split(sep).join("/");
408
+ if (filter === undefined || filter(posixPath)) {
409
+ inventory.push(posixPath);
410
+ }
411
+ }
412
+ };
413
+ collectUnder("extensions");
414
+ collectUnder(join("runtime", "lsp-daemon", "dist"));
415
+ collectUnder("skills", (posixPath) => posixPath.endsWith("/SKILL.md"));
416
+ if (existsSync(join(pluginPath, "scripts", "install.mjs"))) {
417
+ inventory.push("scripts/install.mjs");
418
+ }
419
+ inventory.sort();
420
+ return inventory;
421
+ }
422
+ /** Post-build completeness check: the five required files + >=1 skills/<name>/SKILL.md. */
423
+ function findMissingBuildArtifacts(pluginPath) {
424
+ const missing = [];
425
+ for (const required of REQUIRED_BUILD_ARTIFACTS) {
426
+ if (!existsSync(join(pluginPath, required))) {
427
+ missing.push(required);
428
+ }
429
+ }
430
+ let skillCount = 0;
431
+ try {
432
+ for (const entry of readdirSync(join(pluginPath, "skills"), { withFileTypes: true })) {
433
+ if (entry.isDirectory() && existsSync(join(pluginPath, "skills", entry.name, "SKILL.md"))) {
434
+ skillCount++;
435
+ }
436
+ }
437
+ }
438
+ catch {
439
+ // A missing skills dir counts as zero skills.
440
+ }
441
+ if (skillCount === 0) {
442
+ missing.push("skills/*/SKILL.md");
443
+ }
444
+ return missing;
445
+ }
446
+ /** Marker error: the bun binary is missing from PATH (spawn ENOENT). */
447
+ class OmoLocalBunMissingError extends Error {
448
+ constructor() {
449
+ super("bun not found on PATH");
450
+ this.name = "OmoLocalBunMissingError";
451
+ }
452
+ }
453
+ /**
454
+ * One bun step through the shared run seam, run INSIDE the build worktree (never the user's
455
+ * checkout). A missing binary (spawn ENOENT) gets the dedicated marker so the orchestrator
456
+ * can render the single yellow bun warning; any other failed start, non-zero exit, or
457
+ * timeout becomes an OmoLocalStepError carrying the combined output for the dim dump.
458
+ */
459
+ async function runBunStep(stage, args, worktree, run, timeoutMs) {
460
+ let result;
461
+ try {
462
+ result = await run("bun", args, { cwd: worktree, timeoutMs });
463
+ }
464
+ catch (error) {
465
+ if (error.code === "ENOENT") {
466
+ throw new OmoLocalBunMissingError();
467
+ }
468
+ throw new OmoLocalStepError(stage, `bun ${args.join(" ")} failed to start: ${error instanceof Error ? error.message : String(error)}`);
469
+ }
470
+ const output = `${result.stdout}${result.stderr}`;
471
+ if (result.timedOut) {
472
+ throw new OmoLocalStepError(stage, `bun ${args.join(" ")} timed out after ${Math.round(timeoutMs / 1000)}s`, output);
473
+ }
474
+ if (result.code !== 0) {
475
+ throw new OmoLocalStepError(stage, `bun ${args.join(" ")} exited with code ${result.code ?? "unknown"}`, output);
476
+ }
477
+ }
478
+ /**
479
+ * exported for tests only
480
+ *
481
+ * Validate/reuse the FEATURE-OWNED persistent build worktree:
482
+ * - present AND owned by this repo (`git -C <wt> rev-parse --git-common-dir` realpath-equals
483
+ * realpath(repoRoot/.git)) -> reuse: `git -C <wt> checkout --detach --force <sha>`. The
484
+ * --force is SAFE here: this worktree is exclusively feature-owned, so it only discards
485
+ * our own previous build outputs, and untracked node_modules survives for incremental
486
+ * installs.
487
+ * - present but foreign/invalid -> `git -C repoRoot worktree remove --force <wt>` (fs rm
488
+ * fallback), then re-add.
489
+ * - absent -> `git -C repoRoot worktree add --detach <wt> <sha>`.
490
+ * These are the ONLY git mutations in the module besides `git fetch`, and they touch only
491
+ * the feature-owned worktree registration - never the user's checkout state.
492
+ */
493
+ export async function ensureBuildWorktree(options) {
494
+ const { worktree, repoRoot, sha, run } = options;
495
+ if (existsSync(worktree)) {
496
+ const commonDir = await run("git", ["-C", worktree, "rev-parse", "--git-common-dir"], {});
497
+ const owned = commonDir.code === 0 &&
498
+ commonDir.stdout.trim() !== "" &&
499
+ canonicalizePath(resolve(worktree, commonDir.stdout.trim())) === canonicalizePath(join(repoRoot, ".git"));
500
+ if (owned) {
501
+ const checkout = await run("git", ["-C", worktree, "checkout", "--detach", "--force", sha], {});
502
+ if (checkout.code !== 0) {
503
+ throw new OmoLocalStepError("worktree", `git checkout --detach --force: ${firstErrorLine(checkout)}`, `${checkout.stdout}${checkout.stderr}`);
504
+ }
505
+ return;
506
+ }
507
+ // Foreign or invalid directory at the feature-owned path: remove it (registered
508
+ // worktree or not) and fall through to a fresh add.
509
+ const remove = await run("git", ["-C", repoRoot, "worktree", "remove", "--force", worktree], {});
510
+ if (remove.code !== 0 || existsSync(worktree)) {
511
+ rmSync(worktree, { recursive: true, force: true });
512
+ }
513
+ }
514
+ mkdirSync(dirname(worktree), { recursive: true });
515
+ const add = await run("git", ["-C", repoRoot, "worktree", "add", "--detach", worktree, sha], {});
516
+ if (add.code === 0) {
517
+ return;
518
+ }
519
+ // A stale registration whose directory vanished blocks the add; prune metadata and retry once.
520
+ await run("git", ["-C", repoRoot, "worktree", "prune"], {});
521
+ const retry = await run("git", ["-C", repoRoot, "worktree", "add", "--detach", worktree, sha], {});
522
+ if (retry.code !== 0) {
523
+ throw new OmoLocalStepError("worktree", `git worktree add: ${firstErrorLine(retry)}`, `${add.stdout}${add.stderr}${retry.stdout}${retry.stderr}`);
524
+ }
525
+ }
526
+ const defaultFsSeam = {
527
+ cpSync: (source, destination) => {
528
+ cpSync(source, destination, { recursive: true });
529
+ },
530
+ renameSync: (oldPath, newPath) => {
531
+ renameSync(oldPath, newPath);
532
+ },
533
+ rmSync: (path) => {
534
+ rmSync(path, { recursive: true, force: true });
535
+ },
536
+ };
537
+ let swapCounter = 0;
538
+ /**
539
+ * exported for tests only
540
+ *
541
+ * ATOMIC SWAP of the install target. staging/prev are siblings of pluginPath (same parent
542
+ * => same filesystem => atomic renames): copy the built tree to staging, move pluginPath
543
+ * aside to prev, move staging into place. If the staging rename fails, prev is restored
544
+ * and staging removed before the error propagates - the local install is never left
545
+ * half-swapped. On success prev is removed.
546
+ */
547
+ export function swapPluginDir(options) {
548
+ const seam = options.fs ?? defaultFsSeam;
549
+ swapCounter += 1;
550
+ const tag = `${Date.now()}-${process.pid}-${swapCounter}`;
551
+ const staging = `${options.pluginPath}.staging-${tag}`;
552
+ const prev = `${options.pluginPath}.prev-${tag}`;
553
+ seam.cpSync(options.sourceDir, staging);
554
+ seam.renameSync(options.pluginPath, prev);
555
+ try {
556
+ seam.renameSync(staging, options.pluginPath);
557
+ }
558
+ catch (error) {
559
+ seam.renameSync(prev, options.pluginPath);
560
+ seam.rmSync(staging);
561
+ throw error;
562
+ }
563
+ seam.rmSync(prev);
564
+ }
565
+ function firstLine(text) {
566
+ for (const line of text.split("\n")) {
567
+ const trimmed = line.trim();
568
+ if (trimmed !== "") {
569
+ return trimmed;
570
+ }
571
+ }
572
+ return "unknown error";
573
+ }
574
+ function lastNonEmptyLines(text, count) {
575
+ const lines = [];
576
+ for (const line of text.split("\n")) {
577
+ if (line.trim() !== "") {
578
+ lines.push(line);
579
+ }
580
+ }
581
+ return lines.slice(-count);
582
+ }
583
+ /**
584
+ * Beta hook entry point, called from bare `senpi update` before the self-update.
585
+ *
586
+ * SINGLE owner of the ORDERED state machine: gate chain (kill-switch -> detection) ->
587
+ * atomic lock acquisition (held through fetch, worktree, build, swap, stamp AND notify;
588
+ * owner-checked unlink in `finally`) -> computeRemoteState (ONE read-only fetch + frozen
589
+ * rev-parse reads of origin/dev) -> skip decision BEFORE any worktree op, install, or
590
+ * write -> ensureBuildWorktree (feature-owned persistent worktree, reuse-or-recreate) ->
591
+ * `bun install` (600s, cwd = build worktree) -> `bun run build:senpi-plugin` (900s, cwd =
592
+ * build worktree) -> completeness check in the WORKTREE plugin dir -> atomic swap of the
593
+ * install target -> writeStamp (inventory from the NEW plugin dir) -> notify (green line
594
+ * + dim per-package tree comparison when an old stamp existed).
595
+ *
596
+ * HARD GUARANTEES: the user's checkout receives ZERO git mutations (no
597
+ * checkout/branch/commit/merge/reset/clean/stash/push anywhere; only `git fetch` and
598
+ * feature-owned worktree add/remove). Only pluginPath content is replaced. This hook NEVER
599
+ * throws and NEVER sets process.exitCode: every failure downgrades to a yellow warning +
600
+ * dim manual hint so the senpi self-update continues untouched.
601
+ */
602
+ export async function runOmoLocalUpdateBeta(options) {
603
+ const log = options.log ??
604
+ ((message) => {
605
+ console.log(message);
606
+ });
607
+ const run = options.run ?? defaultRun;
608
+ let repoRoot;
609
+ try {
610
+ if (isKillSwitched(options.env)) {
611
+ return;
612
+ }
613
+ const install = await detectOmoLocalInstall({
614
+ packages: options.settings?.packages,
615
+ agentDir: options.agentDir,
616
+ run,
617
+ });
618
+ if (!install) {
619
+ return;
620
+ }
621
+ repoRoot = install.repoRoot;
622
+ const { pluginPath } = install;
623
+ const lock = acquireOmoLocalLock(options.agentDir, log);
624
+ if (lock === undefined) {
625
+ return;
626
+ }
627
+ try {
628
+ log(chalk.dim("Updating OMO local plugins: fetching origin/dev..."));
629
+ const remoteState = await computeRemoteState({ repoRoot, run });
630
+ // Skip decision FIRST: a skip touches NOTHING (no worktree ops, no install, no writes).
631
+ const stamp = readStamp(options.agentDir);
632
+ const stampArtifactsExist = stamp?.artifacts.every((artifact) => existsSync(join(pluginPath, artifact))) ?? false;
633
+ if (shouldSkipUpdate({
634
+ stamp,
635
+ repoRoot,
636
+ remoteSha: remoteState.sha,
637
+ stampArtifactsExist,
638
+ force: options.force ?? false,
639
+ })) {
640
+ log(chalk.dim(`OMO local plugins already at origin/dev @${remoteState.sha.slice(0, 7)}; skipping rebuild.`));
641
+ return;
642
+ }
643
+ // Build in the feature-owned persistent worktree - never in the user's checkout.
644
+ const worktree = omoLocalUpdateBuildWorktreePath(options.agentDir);
645
+ await ensureBuildWorktree({ worktree, repoRoot, sha: remoteState.sha, run });
646
+ try {
647
+ log(chalk.dim("Updating OMO local plugins: installing deps..."));
648
+ await runBunStep("install", ["install"], worktree, run, 600_000);
649
+ log(chalk.dim("Updating OMO local plugins: building plugin..."));
650
+ await runBunStep("build", ["run", "build:senpi-plugin"], worktree, run, 900_000);
651
+ }
652
+ catch (stepError) {
653
+ if (stepError instanceof OmoLocalBunMissingError) {
654
+ log(chalk.yellow("OMO local plugin update skipped: bun is required to install and build the plugin but was not found on PATH. Install bun and re-run `senpi update`."));
655
+ return;
656
+ }
657
+ throw stepError;
658
+ }
659
+ const worktreePluginDir = join(worktree, relative(repoRoot, pluginPath));
660
+ const missing = findMissingBuildArtifacts(worktreePluginDir);
661
+ if (missing.length > 0) {
662
+ throw new OmoLocalStepError("artifacts", `build incomplete - missing: ${missing.join(", ")}`);
663
+ }
664
+ // Atomic swap of the install target, then stamp from the NEW plugin dir inventory.
665
+ try {
666
+ swapPluginDir({ pluginPath, sourceDir: worktreePluginDir });
667
+ }
668
+ catch (swapError) {
669
+ throw new OmoLocalStepError("swap", `atomic swap failed: ${swapError instanceof Error ? swapError.message : String(swapError)}`);
670
+ }
671
+ writeStamp(options.agentDir, {
672
+ repoRoot,
673
+ sha: remoteState.sha,
674
+ omoSenpiTree: remoteState.omoSenpiTree,
675
+ senpiTaskTree: remoteState.senpiTaskTree,
676
+ installedAt: new Date().toISOString(),
677
+ artifacts: collectArtifactInventory(pluginPath),
678
+ });
679
+ const short = remoteState.sha.slice(0, 7);
680
+ log(chalk.green(`Updated OMO local plugins (omo-senpi + senpi-task) to origin/dev @${short} - ${remoteState.subject}`));
681
+ if (stamp !== undefined) {
682
+ const omoLine = stamp.omoSenpiTree === remoteState.omoSenpiTree ? "unchanged" : "updated";
683
+ const taskLine = stamp.senpiTaskTree === remoteState.senpiTaskTree ? "unchanged" : "updated";
684
+ log(chalk.dim(`omo-senpi: ${omoLine}, senpi-task: ${taskLine}`));
685
+ }
686
+ }
687
+ finally {
688
+ releaseOmoLocalLock(lock);
689
+ }
690
+ }
691
+ catch (error) {
692
+ // The hook NEVER throws and NEVER sets process.exitCode: render the yellow failure
693
+ // line (+ dim failed-step output tail + dim manual hint) and let the senpi
694
+ // self-update continue.
695
+ const stage = error instanceof OmoLocalStepError ? error.stage : "unknown";
696
+ const message = error instanceof Error ? error.message : String(error);
697
+ log(chalk.yellow(`OMO local plugin update failed (${stage}): ${firstLine(message)}`));
698
+ if (error instanceof OmoLocalStepError && error.output !== undefined) {
699
+ for (const line of lastNonEmptyLines(error.output, 40)) {
700
+ log(chalk.dim(line));
701
+ }
702
+ }
703
+ if (repoRoot !== undefined) {
704
+ log(chalk.dim(`To update manually: git -C ${repoRoot} pull origin dev && bun install && bun run build:senpi-plugin`));
705
+ }
706
+ }
707
+ }
708
+ //# sourceMappingURL=omo-local-update.js.map