ompgui 0.6.5 → 0.7.2

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 (334) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +10 -4
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +31 -3
  5. package/.next/react-loadable-manifest.json +16 -9
  6. package/.next/required-server-files.js +2 -2
  7. package/.next/required-server-files.json +2 -2
  8. package/.next/routes-manifest.json +40 -2
  9. package/.next/server/app/_global-error/page.js +1 -1
  10. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/.next/server/app/_global-error.html +1 -1
  12. package/.next/server/app/_global-error.rsc +2 -2
  13. package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  14. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +2 -2
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found/page.js +1 -1
  17. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/server/app/_not-found.html +1 -1
  19. package/.next/server/app/_not-found.rsc +3 -3
  20. package/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +3 -3
  22. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/server/app/api/agent/[id]/bash-output/route.js +1 -1
  24. package/.next/server/app/api/agent/[id]/events/route.js +2 -2
  25. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  26. package/.next/server/app/api/agent/[id]/route.js +1 -1
  27. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  28. package/.next/server/app/api/agent/new/route.js +1 -1
  29. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  30. package/.next/server/app/api/agent/running/events/route.js +2 -2
  31. package/.next/server/app/api/agent/running/events/route.js.nft.json +1 -1
  32. package/.next/server/app/api/agents/[name]/route.js +1 -1
  33. package/.next/server/app/api/agents/route.js +1 -1
  34. package/.next/server/app/api/agents/unpack/route.js +1 -1
  35. package/.next/server/app/api/app-update/route.js +1 -1
  36. package/.next/server/app/api/auth/all-providers/route.js +1 -1
  37. package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -1
  38. package/.next/server/app/api/auth/login/[provider]/route.js +1 -1
  39. package/.next/server/app/api/auth/logout/[provider]/route.js +1 -1
  40. package/.next/server/app/api/auth/providers/route.js +1 -1
  41. package/.next/server/app/api/cwd/browse/route.js +1 -1
  42. package/.next/server/app/api/cwd/validate/route.js +2 -1
  43. package/.next/server/app/api/daemon/route.js +1 -0
  44. package/.next/server/app/api/daemon/route.js.nft.json +1 -0
  45. package/.next/server/app/api/daemon/route_client-reference-manifest.js +1 -0
  46. package/.next/server/app/api/default-cwd/route.js +1 -1
  47. package/.next/server/app/api/file-index/route.js +1 -1
  48. package/.next/server/app/api/files/[...path]/route.js +5 -5
  49. package/.next/server/app/api/files/[...path]/route.js.nft.json +1 -1
  50. package/.next/server/app/api/git/diff/route.js +2 -2
  51. package/.next/server/app/api/git/status/route.js +2 -2
  52. package/.next/server/app/api/home/route.js +1 -1
  53. package/.next/server/app/api/mcp/route.js +3 -3
  54. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  55. package/.next/server/app/api/model-roles/route.js +1 -1
  56. package/.next/server/app/api/models/route.js +1 -1
  57. package/.next/server/app/api/models-config/catalog/route.js +1 -1
  58. package/.next/server/app/api/models-config/route.js +1 -1
  59. package/.next/server/app/api/models-config/test/route.js +1 -1
  60. package/.next/server/app/api/omp-settings/route.js +1 -1
  61. package/.next/server/app/api/omp-update/route.js +2 -2
  62. package/.next/server/app/api/omp-update/route.js.nft.json +1 -1
  63. package/.next/server/app/api/omp-version/route.js +1 -1
  64. package/.next/server/app/api/plugins/route.js +1 -1
  65. package/.next/server/app/api/projects/route.js +2 -2
  66. package/.next/server/app/api/providers/enable/route.js +1 -1
  67. package/.next/server/app/api/relay/devices/[id]/route.js +1 -0
  68. package/.next/server/app/api/relay/devices/[id]/route.js.nft.json +1 -0
  69. package/.next/server/app/api/relay/devices/[id]/route_client-reference-manifest.js +1 -0
  70. package/.next/server/app/api/relay/devices/route.js +1 -0
  71. package/.next/server/app/api/relay/devices/route.js.nft.json +1 -0
  72. package/.next/server/app/api/relay/devices/route_client-reference-manifest.js +1 -0
  73. package/.next/server/app/api/relay/pair/route.js +1 -0
  74. package/.next/server/app/api/relay/pair/route.js.nft.json +1 -0
  75. package/.next/server/app/api/relay/pair/route_client-reference-manifest.js +1 -0
  76. package/.next/server/app/api/sessions/[id]/archive/route.js +1 -1
  77. package/.next/server/app/api/sessions/[id]/archive/route.js.nft.json +1 -1
  78. package/.next/server/app/api/sessions/[id]/auto-name/route.js +1 -1
  79. package/.next/server/app/api/sessions/[id]/auto-name/route.js.nft.json +1 -1
  80. package/.next/server/app/api/sessions/[id]/context/route.js +1 -1
  81. package/.next/server/app/api/sessions/[id]/entries/[entryId]/media/route.js +1 -1
  82. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +1 -1
  83. package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
  84. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  85. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  86. package/.next/server/app/api/sessions/[id]/state/route.js +1 -1
  87. package/.next/server/app/api/sessions/[id]/state/route.js.nft.json +1 -1
  88. package/.next/server/app/api/sessions/[id]/subagents/[subagentId]/route.js +1 -1
  89. package/.next/server/app/api/sessions/[id]/subagents/route.js +1 -1
  90. package/.next/server/app/api/sessions/[id]/subagents/route.js.nft.json +1 -1
  91. package/.next/server/app/api/sessions/archive/route.js +1 -1
  92. package/.next/server/app/api/sessions/import/route.js +1 -1
  93. package/.next/server/app/api/sessions/route.js +1 -1
  94. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  95. package/.next/server/app/api/skills/check/route.js +1 -1
  96. package/.next/server/app/api/skills/check/route.js.nft.json +1 -1
  97. package/.next/server/app/api/skills/install/route.js +1 -1
  98. package/.next/server/app/api/skills/route.js +2 -2
  99. package/.next/server/app/api/skills/search/route.js +1 -1
  100. package/.next/server/app/api/skills/update/route.js +1 -1
  101. package/.next/server/app/api/skills/update/route.js.nft.json +1 -1
  102. package/.next/server/app/api/usage/route.js +1 -1
  103. package/.next/server/app/api/web-auth/session/route.js +1 -1
  104. package/.next/server/app/api/worktrees/route.js +1 -1
  105. package/.next/server/app/apple-icon.png/route.js +1 -1
  106. package/.next/server/app/favicon.ico/route.js +1 -1
  107. package/.next/server/app/icon.svg/route.js +1 -1
  108. package/.next/server/app/index.html +1 -1
  109. package/.next/server/app/index.rsc +4 -4
  110. package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  111. package/.next/server/app/index.segments/_full.segment.rsc +4 -4
  112. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  113. package/.next/server/app/login/page.js +1 -1
  114. package/.next/server/app/login/page.js.nft.json +1 -1
  115. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  116. package/.next/server/app/login.html +1 -1
  117. package/.next/server/app/login.rsc +3 -3
  118. package/.next/server/app/login.segments/_full.segment.rsc +3 -3
  119. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  120. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +3 -3
  121. package/.next/server/app/manifest.webmanifest/route.js +2 -2
  122. package/.next/server/app/page.js +2 -2
  123. package/.next/server/app/page.js.nft.json +1 -1
  124. package/.next/server/app/page_client-reference-manifest.js +1 -1
  125. package/.next/server/app/pair/page.js +1 -0
  126. package/.next/server/app/pair/page.js.nft.json +1 -0
  127. package/.next/server/app/pair/page_client-reference-manifest.js +1 -0
  128. package/.next/server/app/pair.html +1 -0
  129. package/.next/server/app/pair.meta +26 -0
  130. package/.next/server/app/pair.rsc +23 -0
  131. package/.next/server/app/pair.segments/_full.segment.rsc +23 -0
  132. package/.next/server/app/pair.segments/_tree.segment.rsc +4 -0
  133. package/.next/server/app/pair.segments/pair/__PAGE__.segment.rsc +25 -0
  134. package/.next/server/app/relay/route.js +1 -0
  135. package/.next/server/app/relay/route.js.nft.json +1 -0
  136. package/.next/server/app/relay/route_client-reference-manifest.js +1 -0
  137. package/.next/server/app-paths-manifest.json +10 -4
  138. package/.next/server/chunks/1448.js +1 -1
  139. package/.next/server/chunks/1671.js +1 -1
  140. package/.next/server/chunks/2043.js +12 -0
  141. package/.next/server/chunks/2676.js +4 -0
  142. package/.next/server/chunks/2865.js +1 -1
  143. package/.next/server/chunks/3100.js +2 -2
  144. package/.next/server/chunks/3798.js +4 -5
  145. package/.next/server/chunks/5318.js +1 -1
  146. package/.next/server/chunks/6209.js +4 -4
  147. package/.next/server/chunks/{8353.js → 6332.js} +2 -2
  148. package/.next/server/chunks/7077.js +1 -0
  149. package/.next/server/chunks/714.js +1 -1
  150. package/.next/server/chunks/7779.js +1 -0
  151. package/.next/server/chunks/795.js +105 -0
  152. package/.next/server/chunks/8501.js +1 -1
  153. package/.next/server/chunks/8672.js +1 -0
  154. package/.next/server/chunks/8834.js +18 -0
  155. package/.next/server/chunks/9145.js +2 -0
  156. package/.next/server/chunks/933.js +1 -1
  157. package/.next/server/functions-config-manifest.json +1 -0
  158. package/.next/server/instrumentation.js +1 -1
  159. package/.next/server/instrumentation.js.nft.json +1 -1
  160. package/.next/server/middleware-build-manifest.js +1 -1
  161. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  162. package/.next/server/middleware.js +2 -2
  163. package/.next/server/pages/404.html +1 -1
  164. package/.next/server/pages/500.html +1 -1
  165. package/.next/server/prefetch-hints.json +14 -0
  166. package/.next/server/server-reference-manifest.json +1 -1
  167. package/.next/static/Na7qed083WBP3X-plluRO/_buildManifest.js +1 -0
  168. package/.next/static/chunks/1012.477e42e5184b6aaa.js +17 -0
  169. package/.next/static/chunks/1941.66c3a0942c0c3e5d.js +1 -0
  170. package/.next/static/chunks/3944.6215b78f025077b3.js +1 -0
  171. package/.next/static/chunks/4315-142781649334beb2.js +1 -0
  172. package/.next/static/chunks/484.761e1ff01f663fb2.js +1 -0
  173. package/.next/static/chunks/5658.0fe2642c815aea9a.js +1 -0
  174. package/.next/static/chunks/587-c973123b3c9a5b80.js +1 -0
  175. package/.next/static/chunks/9448.b6c5eb8f1356d5fd.js +2 -0
  176. package/.next/static/chunks/9668.b62ea9e45077f781.js +1 -0
  177. package/.next/static/chunks/app/_global-error/page-710453b8adcf7d31.js +1 -0
  178. package/.next/static/chunks/app/api/agent/[id]/bash-output/route-710453b8adcf7d31.js +1 -0
  179. package/.next/static/chunks/app/api/agent/[id]/events/route-710453b8adcf7d31.js +1 -0
  180. package/.next/static/chunks/app/api/agent/[id]/route-710453b8adcf7d31.js +1 -0
  181. package/.next/static/chunks/app/api/agent/new/route-710453b8adcf7d31.js +1 -0
  182. package/.next/static/chunks/app/api/agent/running/events/route-710453b8adcf7d31.js +1 -0
  183. package/.next/static/chunks/app/api/agents/[name]/route-710453b8adcf7d31.js +1 -0
  184. package/.next/static/chunks/app/api/agents/route-710453b8adcf7d31.js +1 -0
  185. package/.next/static/chunks/app/api/agents/unpack/route-710453b8adcf7d31.js +1 -0
  186. package/.next/static/chunks/app/api/app-update/route-710453b8adcf7d31.js +1 -0
  187. package/.next/static/chunks/app/api/auth/all-providers/route-710453b8adcf7d31.js +1 -0
  188. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-710453b8adcf7d31.js +1 -0
  189. package/.next/static/chunks/app/api/auth/login/[provider]/route-710453b8adcf7d31.js +1 -0
  190. package/.next/static/chunks/app/api/auth/logout/[provider]/route-710453b8adcf7d31.js +1 -0
  191. package/.next/static/chunks/app/api/auth/providers/route-710453b8adcf7d31.js +1 -0
  192. package/.next/static/chunks/app/api/cwd/browse/route-710453b8adcf7d31.js +1 -0
  193. package/.next/static/chunks/app/api/cwd/validate/route-710453b8adcf7d31.js +1 -0
  194. package/.next/static/chunks/app/api/daemon/route-710453b8adcf7d31.js +1 -0
  195. package/.next/static/chunks/app/api/default-cwd/route-710453b8adcf7d31.js +1 -0
  196. package/.next/static/chunks/app/api/file-index/route-710453b8adcf7d31.js +1 -0
  197. package/.next/static/chunks/app/api/files/[...path]/route-710453b8adcf7d31.js +1 -0
  198. package/.next/static/chunks/app/api/git/diff/route-710453b8adcf7d31.js +1 -0
  199. package/.next/static/chunks/app/api/git/status/route-710453b8adcf7d31.js +1 -0
  200. package/.next/static/chunks/app/api/home/route-710453b8adcf7d31.js +1 -0
  201. package/.next/static/chunks/app/api/mcp/route-710453b8adcf7d31.js +1 -0
  202. package/.next/static/chunks/app/api/model-roles/route-710453b8adcf7d31.js +1 -0
  203. package/.next/static/chunks/app/api/models/route-710453b8adcf7d31.js +1 -0
  204. package/.next/static/chunks/app/api/models-config/catalog/route-710453b8adcf7d31.js +1 -0
  205. package/.next/static/chunks/app/api/models-config/route-710453b8adcf7d31.js +1 -0
  206. package/.next/static/chunks/app/api/models-config/test/route-710453b8adcf7d31.js +1 -0
  207. package/.next/static/chunks/app/api/omp-settings/route-710453b8adcf7d31.js +1 -0
  208. package/.next/static/chunks/app/api/omp-update/route-710453b8adcf7d31.js +1 -0
  209. package/.next/static/chunks/app/api/omp-version/route-710453b8adcf7d31.js +1 -0
  210. package/.next/static/chunks/app/api/plugins/route-710453b8adcf7d31.js +1 -0
  211. package/.next/static/chunks/app/api/projects/route-710453b8adcf7d31.js +1 -0
  212. package/.next/static/chunks/app/api/providers/enable/route-710453b8adcf7d31.js +1 -0
  213. package/.next/static/chunks/app/api/relay/devices/[id]/route-710453b8adcf7d31.js +1 -0
  214. package/.next/static/chunks/app/api/relay/devices/route-710453b8adcf7d31.js +1 -0
  215. package/.next/static/chunks/app/api/relay/pair/route-710453b8adcf7d31.js +1 -0
  216. package/.next/static/chunks/app/api/sessions/[id]/archive/route-710453b8adcf7d31.js +1 -0
  217. package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-710453b8adcf7d31.js +1 -0
  218. package/.next/static/chunks/app/api/sessions/[id]/context/route-710453b8adcf7d31.js +1 -0
  219. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/media/route-710453b8adcf7d31.js +1 -0
  220. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-710453b8adcf7d31.js +1 -0
  221. package/.next/static/chunks/app/api/sessions/[id]/export/route-710453b8adcf7d31.js +1 -0
  222. package/.next/static/chunks/app/api/sessions/[id]/route-710453b8adcf7d31.js +1 -0
  223. package/.next/static/chunks/app/api/sessions/[id]/state/route-710453b8adcf7d31.js +1 -0
  224. package/.next/static/chunks/app/api/sessions/[id]/subagents/[subagentId]/route-710453b8adcf7d31.js +1 -0
  225. package/.next/static/chunks/app/api/sessions/[id]/subagents/route-710453b8adcf7d31.js +1 -0
  226. package/.next/static/chunks/app/api/sessions/archive/route-710453b8adcf7d31.js +1 -0
  227. package/.next/static/chunks/app/api/sessions/import/route-710453b8adcf7d31.js +1 -0
  228. package/.next/static/chunks/app/api/sessions/route-710453b8adcf7d31.js +1 -0
  229. package/.next/static/chunks/app/api/skills/check/route-710453b8adcf7d31.js +1 -0
  230. package/.next/static/chunks/app/api/skills/install/route-710453b8adcf7d31.js +1 -0
  231. package/.next/static/chunks/app/api/skills/route-710453b8adcf7d31.js +1 -0
  232. package/.next/static/chunks/app/api/skills/search/route-710453b8adcf7d31.js +1 -0
  233. package/.next/static/chunks/app/api/skills/update/route-710453b8adcf7d31.js +1 -0
  234. package/.next/static/chunks/app/api/usage/route-710453b8adcf7d31.js +1 -0
  235. package/.next/static/chunks/app/api/web-auth/session/route-710453b8adcf7d31.js +1 -0
  236. package/.next/static/chunks/app/api/worktrees/route-710453b8adcf7d31.js +1 -0
  237. package/.next/static/chunks/app/manifest.webmanifest/route-710453b8adcf7d31.js +1 -0
  238. package/.next/static/chunks/app/{page-2845a463e3b265c2.js → page-f53564bcb292e1e5.js} +2 -2
  239. package/.next/static/chunks/app/pair/page-d72423ffc5654e29.js +1 -0
  240. package/.next/static/chunks/app/relay/route-710453b8adcf7d31.js +1 -0
  241. package/.next/static/chunks/next/dist/client/components/builtin/app-error-710453b8adcf7d31.js +1 -0
  242. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-710453b8adcf7d31.js +1 -0
  243. package/.next/static/chunks/next/dist/client/components/builtin/not-found-710453b8adcf7d31.js +1 -0
  244. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-710453b8adcf7d31.js +1 -0
  245. package/.next/static/chunks/webpack-4e02c722bd171663.js +1 -0
  246. package/.next/static/css/63b622301ba107de.css +3 -0
  247. package/README.ja.md +32 -1
  248. package/README.ko.md +34 -1
  249. package/README.md +35 -2
  250. package/README.zh-CN.md +32 -1
  251. package/bin/ompgui-options.js +18 -3
  252. package/bin/ompgui-pair.js +108 -0
  253. package/bin/ompgui-service.js +223 -0
  254. package/bin/ompgui-update.js +85 -22
  255. package/bin/ompgui.js +30 -11
  256. package/next.config.ts +3 -1
  257. package/package.json +9 -5
  258. package/.next/server/chunks/2118.js +0 -1
  259. package/.next/server/chunks/3379.js +0 -1
  260. package/.next/server/chunks/6777.js +0 -1
  261. package/.next/server/chunks/7834.js +0 -5
  262. package/.next/server/chunks/8816.js +0 -18
  263. package/.next/static/chunks/4315-6b59cc5d91fe9083.js +0 -1
  264. package/.next/static/chunks/484.3215a9f03ff865da.js +0 -1
  265. package/.next/static/chunks/5658.eb16997c19c2372b.js +0 -1
  266. package/.next/static/chunks/6139.8971a8cbb6c07ac8.js +0 -17
  267. package/.next/static/chunks/7194.651566324b8fac6f.js +0 -1
  268. package/.next/static/chunks/9448.3ded6700334581bd.js +0 -2
  269. package/.next/static/chunks/9668.5e681bc0055ed4d0.js +0 -1
  270. package/.next/static/chunks/app/_global-error/page-129e1f8238bd66db.js +0 -1
  271. package/.next/static/chunks/app/api/agent/[id]/bash-output/route-129e1f8238bd66db.js +0 -1
  272. package/.next/static/chunks/app/api/agent/[id]/events/route-129e1f8238bd66db.js +0 -1
  273. package/.next/static/chunks/app/api/agent/[id]/route-129e1f8238bd66db.js +0 -1
  274. package/.next/static/chunks/app/api/agent/new/route-129e1f8238bd66db.js +0 -1
  275. package/.next/static/chunks/app/api/agent/running/events/route-129e1f8238bd66db.js +0 -1
  276. package/.next/static/chunks/app/api/agents/[name]/route-129e1f8238bd66db.js +0 -1
  277. package/.next/static/chunks/app/api/agents/route-129e1f8238bd66db.js +0 -1
  278. package/.next/static/chunks/app/api/agents/unpack/route-129e1f8238bd66db.js +0 -1
  279. package/.next/static/chunks/app/api/app-update/route-129e1f8238bd66db.js +0 -1
  280. package/.next/static/chunks/app/api/auth/all-providers/route-129e1f8238bd66db.js +0 -1
  281. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-129e1f8238bd66db.js +0 -1
  282. package/.next/static/chunks/app/api/auth/login/[provider]/route-129e1f8238bd66db.js +0 -1
  283. package/.next/static/chunks/app/api/auth/logout/[provider]/route-129e1f8238bd66db.js +0 -1
  284. package/.next/static/chunks/app/api/auth/providers/route-129e1f8238bd66db.js +0 -1
  285. package/.next/static/chunks/app/api/cwd/browse/route-129e1f8238bd66db.js +0 -1
  286. package/.next/static/chunks/app/api/cwd/validate/route-129e1f8238bd66db.js +0 -1
  287. package/.next/static/chunks/app/api/default-cwd/route-129e1f8238bd66db.js +0 -1
  288. package/.next/static/chunks/app/api/file-index/route-129e1f8238bd66db.js +0 -1
  289. package/.next/static/chunks/app/api/files/[...path]/route-129e1f8238bd66db.js +0 -1
  290. package/.next/static/chunks/app/api/git/diff/route-129e1f8238bd66db.js +0 -1
  291. package/.next/static/chunks/app/api/git/status/route-129e1f8238bd66db.js +0 -1
  292. package/.next/static/chunks/app/api/home/route-129e1f8238bd66db.js +0 -1
  293. package/.next/static/chunks/app/api/mcp/route-129e1f8238bd66db.js +0 -1
  294. package/.next/static/chunks/app/api/model-roles/route-129e1f8238bd66db.js +0 -1
  295. package/.next/static/chunks/app/api/models/route-129e1f8238bd66db.js +0 -1
  296. package/.next/static/chunks/app/api/models-config/catalog/route-129e1f8238bd66db.js +0 -1
  297. package/.next/static/chunks/app/api/models-config/route-129e1f8238bd66db.js +0 -1
  298. package/.next/static/chunks/app/api/models-config/test/route-129e1f8238bd66db.js +0 -1
  299. package/.next/static/chunks/app/api/omp-settings/route-129e1f8238bd66db.js +0 -1
  300. package/.next/static/chunks/app/api/omp-update/route-129e1f8238bd66db.js +0 -1
  301. package/.next/static/chunks/app/api/omp-version/route-129e1f8238bd66db.js +0 -1
  302. package/.next/static/chunks/app/api/plugins/route-129e1f8238bd66db.js +0 -1
  303. package/.next/static/chunks/app/api/projects/route-129e1f8238bd66db.js +0 -1
  304. package/.next/static/chunks/app/api/providers/enable/route-129e1f8238bd66db.js +0 -1
  305. package/.next/static/chunks/app/api/sessions/[id]/archive/route-129e1f8238bd66db.js +0 -1
  306. package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-129e1f8238bd66db.js +0 -1
  307. package/.next/static/chunks/app/api/sessions/[id]/context/route-129e1f8238bd66db.js +0 -1
  308. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/media/route-129e1f8238bd66db.js +0 -1
  309. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-129e1f8238bd66db.js +0 -1
  310. package/.next/static/chunks/app/api/sessions/[id]/export/route-129e1f8238bd66db.js +0 -1
  311. package/.next/static/chunks/app/api/sessions/[id]/route-129e1f8238bd66db.js +0 -1
  312. package/.next/static/chunks/app/api/sessions/[id]/state/route-129e1f8238bd66db.js +0 -1
  313. package/.next/static/chunks/app/api/sessions/[id]/subagents/[subagentId]/route-129e1f8238bd66db.js +0 -1
  314. package/.next/static/chunks/app/api/sessions/[id]/subagents/route-129e1f8238bd66db.js +0 -1
  315. package/.next/static/chunks/app/api/sessions/archive/route-129e1f8238bd66db.js +0 -1
  316. package/.next/static/chunks/app/api/sessions/import/route-129e1f8238bd66db.js +0 -1
  317. package/.next/static/chunks/app/api/sessions/route-129e1f8238bd66db.js +0 -1
  318. package/.next/static/chunks/app/api/skills/check/route-129e1f8238bd66db.js +0 -1
  319. package/.next/static/chunks/app/api/skills/install/route-129e1f8238bd66db.js +0 -1
  320. package/.next/static/chunks/app/api/skills/route-129e1f8238bd66db.js +0 -1
  321. package/.next/static/chunks/app/api/skills/search/route-129e1f8238bd66db.js +0 -1
  322. package/.next/static/chunks/app/api/skills/update/route-129e1f8238bd66db.js +0 -1
  323. package/.next/static/chunks/app/api/usage/route-129e1f8238bd66db.js +0 -1
  324. package/.next/static/chunks/app/api/web-auth/session/route-129e1f8238bd66db.js +0 -1
  325. package/.next/static/chunks/app/api/worktrees/route-129e1f8238bd66db.js +0 -1
  326. package/.next/static/chunks/app/manifest.webmanifest/route-129e1f8238bd66db.js +0 -1
  327. package/.next/static/chunks/next/dist/client/components/builtin/app-error-129e1f8238bd66db.js +0 -1
  328. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-129e1f8238bd66db.js +0 -1
  329. package/.next/static/chunks/next/dist/client/components/builtin/not-found-129e1f8238bd66db.js +0 -1
  330. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-129e1f8238bd66db.js +0 -1
  331. package/.next/static/chunks/webpack-9c013878cb300763.js +0 -1
  332. package/.next/static/css/dd19cac539e3e218.css +0 -3
  333. package/.next/static/wMrrM4WHr4pqT7Bavv79j/_buildManifest.js +0 -1
  334. /package/.next/static/{wMrrM4WHr4pqT7Bavv79j → Na7qed083WBP3X-plluRO}/_ssgManifest.js +0 -0
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+
3
+ const { spawn } = require("child_process");
4
+ const { isPortAvailable } = require("./port-availability");
5
+
6
+ function cookieHeader(response) {
7
+ if (typeof response.headers.getSetCookie === "function") {
8
+ const cookies = response.headers.getSetCookie();
9
+ if (cookies.length) return cookies.map((value) => value.split(";")[0]).join("; ");
10
+ }
11
+ const single = response.headers.get("set-cookie");
12
+ return single ? single.split(";")[0] : "";
13
+ }
14
+
15
+ async function ensureLocalSession(base, password, headers) {
16
+ if (!password) return;
17
+ const login = await fetch(`${base}/api/web-auth/session`, {
18
+ method: "POST",
19
+ headers: { "content-type": "application/json" },
20
+ body: JSON.stringify({ password }),
21
+ });
22
+ if (!login.ok) {
23
+ throw new Error("Could not sign in with the configured password. Pass --password or open /pair in the browser.");
24
+ }
25
+ const cookie = cookieHeader(login);
26
+ if (cookie) headers.cookie = cookie;
27
+ }
28
+
29
+ async function requestJson(url, init) {
30
+ const response = await fetch(url, init);
31
+ const text = await response.text();
32
+ let body = {};
33
+ try { body = text ? JSON.parse(text) : {}; } catch { body = { error: text }; }
34
+ if (!response.ok) {
35
+ throw new Error(body.error || `Request failed (${response.status})`);
36
+ }
37
+ return body;
38
+ }
39
+
40
+ function openPairPage(target) {
41
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd.exe" : "xdg-open";
42
+ const args = process.platform === "win32" ? ["/c", "start", "", target] : [target];
43
+ try {
44
+ const child = spawn(cmd, args, { stdio: "ignore", detached: true });
45
+ child.on("error", () => {});
46
+ child.unref();
47
+ } catch {
48
+ // printed URL is enough
49
+ }
50
+ }
51
+
52
+ async function runPair(options) {
53
+ const { port, hostname, password, relayUrl, openBrowser } = options;
54
+ if (await isPortAvailable(port, hostname)) {
55
+ throw new Error(`ompgui is not running on ${hostname}:${port}. Start it, then run ompgui pair.`);
56
+ }
57
+ const base = options.baseUrl;
58
+ const headers = { "content-type": "application/json" };
59
+ await ensureLocalSession(base, password, headers);
60
+ const body = {};
61
+ if (relayUrl) body.url = relayUrl;
62
+ const offer = await requestJson(`${base}/api/relay/pair`, {
63
+ method: "POST",
64
+ headers,
65
+ body: JSON.stringify(body),
66
+ });
67
+ console.log(offer.uri);
68
+ console.log(`Relay: ${offer.relayUrl}`);
69
+ console.log(`Expires: ${new Date(offer.expiresAt).toISOString()}`);
70
+ if (openBrowser) openPairPage(`${base}/pair`);
71
+ }
72
+
73
+ async function runDevices(options) {
74
+ const { port, hostname, password, extraPositionals } = options;
75
+ if (await isPortAvailable(port, hostname)) {
76
+ throw new Error(`ompgui is not running on ${hostname}:${port}. Start it, then run ompgui devices.`);
77
+ }
78
+ const base = options.baseUrl;
79
+ const headers = { "content-type": "application/json" };
80
+ await ensureLocalSession(base, password, headers);
81
+
82
+ if (extraPositionals[0] === "revoke") {
83
+ const id = extraPositionals[1];
84
+ if (!id) throw new Error("Usage: ompgui devices revoke <id>");
85
+ await requestJson(`${base}/api/relay/devices/${encodeURIComponent(id)}`, { method: "DELETE", headers });
86
+ console.log(`Revoked ${id}`);
87
+ return;
88
+ }
89
+ if (extraPositionals.length) {
90
+ throw new Error(`Unknown ompgui devices command: ${extraPositionals.join(" ")}`);
91
+ }
92
+ const listed = await requestJson(`${base}/api/relay/devices`, { headers });
93
+ const devices = listed.devices ?? [];
94
+ if (devices.length === 0) {
95
+ console.log("No paired devices.");
96
+ return;
97
+ }
98
+ for (const device of devices) {
99
+ console.log(`${device.id}\t${device.label || ""}\tlastSeen ${device.lastSeenAt}`);
100
+ }
101
+ }
102
+
103
+ async function runRelayCli(options) {
104
+ if (options.command === "pair") return runPair(options);
105
+ return runDevices(options);
106
+ }
107
+
108
+ module.exports = { runRelayCli, runPair, runDevices };
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs");
4
+ const os = require("node:os");
5
+ const path = require("node:path");
6
+ const { spawn, spawnSync } = require("node:child_process");
7
+ const LABEL = "com.hanbinnoh.ompgui";
8
+ const POLL_WAIT = new Int32Array(new SharedArrayBuffer(4));
9
+ const ACTIONS = new Set(["install", "repair", "start", "stop", "restart", "status", "uninstall", "remove", "enable", "disable"]);
10
+ const escapeXml = (value) => String(value).replace(/[<>&"']/g, (char) => ({ "<": "&lt;", ">": "&gt;", "&": "&amp;", '"': "&quot;", "'": "&apos;" })[char]);
11
+ function plistValue(value) {
12
+ if (typeof value === "boolean") return value ? "<true/>" : "<false/>";
13
+ if (Array.isArray(value)) return `<array>${value.map(plistValue).join("")}</array>`;
14
+ if (value && typeof value === "object") return `<dict>${Object.entries(value).map(([key, entry]) => `<key>${escapeXml(key)}</key>${plistValue(entry)}`).join("")}</dict>`;
15
+ return `<string>${escapeXml(value)}</string>`;
16
+ }
17
+ function createServiceManager({ processAlive = (pid) => {
18
+ try { process.kill(pid, 0); return true; } catch (error) { if (error.code === "ESRCH") return false; throw error; }
19
+ }, now = Date.now, pause = (milliseconds) => Atomics.wait(POLL_WAIT, 0, 0, milliseconds), label = LABEL, platform = process.platform, home = os.homedir(), uid = process.getuid?.(), env = process.env, execPath = process.execPath, cliPath = path.join(__dirname, "ompgui.js"), portAvailable = (port, hostname) => {
20
+ const probe = spawnSync(process.execPath, [__filename, "--check-port", String(port), hostname], { encoding: "utf8", timeout: 5000 });
21
+ if (probe.status === 0) return true;
22
+ if (probe.status === 2) return false;
23
+ throw new Error("Could not check service port availability");
24
+ }, run = (command, args) => spawnSync(command, args, { encoding: "utf8", timeout: 10000 }) } = {}) {
25
+ // Internal dependency-injection seam only; CLI and HTTP never accept a label override.
26
+ if (typeof label !== "string" || !/^com\.hanbinnoh\.ompgui(?:\.verify[A-Za-z0-9-]+)?$/.test(label)) throw new Error("Invalid ompgui service label");
27
+ const plistPath = path.join(home, "Library", "LaunchAgents", `${label}.plist`);
28
+ const logPath = path.join(home, "Library", "Logs", "ompgui", "service.log");
29
+ const domain = `gui/${uid}`;
30
+ const target = `${domain}/${label}`;
31
+ function command(args, allowMissing = false) {
32
+ const result = run("/bin/launchctl", args);
33
+ if (result.error || result.status !== 0) {
34
+ // launchctl's missing-service exit status is 113; never hide permission/domain errors.
35
+ if (allowMissing && result.status === 113) return null;
36
+ throw new Error(`launchctl ${args[0]} failed${result.error ? `: ${result.error.code || "execution error"}` : ` (exit ${result.status})`}`);
37
+ }
38
+ return result.stdout || "";
39
+ }
40
+ function ownedExecutable(args) {
41
+ if (!Array.isArray(args) || args.length < 2 || typeof args[0] !== "string" || typeof args[1] !== "string" || !path.isAbsolute(args[0]) || !path.isAbsolute(args[1]) || path.basename(args[0]) !== "node") return false;
42
+ try {
43
+ const resolved = fs.realpathSync(args[1]);
44
+ if (path.basename(resolved) !== "ompgui.js" || path.basename(path.dirname(resolved)) !== "bin") return false;
45
+ return JSON.parse(fs.readFileSync(path.join(path.dirname(resolved), "..", "package.json"), "utf8")).name === "ompgui";
46
+ } catch { return false; }
47
+ }
48
+ function readInstalled() {
49
+ let stat;
50
+ try { stat = fs.lstatSync(plistPath); } catch (error) { if (error.code === "ENOENT") return null; throw error; }
51
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.uid !== uid || (stat.mode & 0o022) !== 0) throw new Error("Refusing unmanaged or foreign-owned LaunchAgent");
52
+ const result = run("/usr/bin/plutil", ["-convert", "json", "-o", "-", plistPath]);
53
+ if (result.error || result.status !== 0) throw new Error("Cannot read LaunchAgent configuration");
54
+ let config;
55
+ try { config = JSON.parse(result.stdout); } catch { throw new Error("Invalid LaunchAgent configuration"); }
56
+ if (config.Label !== label || !ownedExecutable(config.ProgramArguments) || config.Program) throw new Error("Refusing LaunchAgent not owned by ompgui");
57
+ return config;
58
+ }
59
+ function inspect() {
60
+ const state = { supported: platform === "darwin", installed: false, running: false, autoStart: false, label, pid: null, logPath: null };
61
+ if (!state.supported) return { ...state, error: "Service management is supported only on macOS." };
62
+ const config = readInstalled();
63
+ state.installed = Boolean(config);
64
+ state.logPath = typeof config?.StandardOutPath === "string" ? config.StandardOutPath : null;
65
+ const printed = command(["print", target], true);
66
+ if (printed !== null) {
67
+ const source = printed.match(/^\s*path = (.+)$/m)?.[1]?.trim();
68
+ if (!config || source !== plistPath) throw new Error("Refusing loaded service with unverified ownership");
69
+ const pid = printed.match(/^\s*pid = (\d+)\s*$/m);
70
+ state.pid = pid ? Number(pid[1]) : null;
71
+ state.running = /\bstate = running\b/.test(printed) && state.pid !== null;
72
+ if (!state.running) state.pid = null;
73
+ }
74
+ const disabled = command(["print-disabled", domain]);
75
+ const explicitlyDisabled = new RegExp(`"${label.replaceAll(".", "\\.")}"\\s*=>\\s*(?:true|disabled)\\b`).test(disabled);
76
+ state.autoStart = Boolean(config && config.RunAtLoad !== false && !explicitlyDisabled);
77
+ return { ...state, loaded: printed !== null, explicitlyDisabled };
78
+ }
79
+ function status() {
80
+ try { const state = inspect(); delete state.loaded; delete state.explicitlyDisabled; return state; }
81
+ catch (error) { return { supported: platform === "darwin", installed: fs.existsSync(plistPath), running: false, autoStart: false, label, pid: null, logPath: null, error: error.message }; }
82
+ }
83
+ function validate(action) {
84
+ if (!ACTIONS.has(action)) throw new Error(`Unknown service action: ${action}`);
85
+ if (platform !== "darwin") throw new Error("Service management is supported only on macOS.");
86
+ const state = inspect();
87
+ if (["start", "restart", "enable", "disable"].includes(action) && !state.installed) throw new Error("Service is not installed. Run ompgui service install first.");
88
+ return state;
89
+ }
90
+ function execute(action, options = {}) {
91
+ if (action === "status") return status();
92
+ const before = validate(action);
93
+ if (action === "remove") action = "uninstall";
94
+ if (action === "repair") action = before.installed ? "restart" : "install";
95
+ if (["install", "start", "restart"].includes(action) && !before.running) {
96
+ const installed = before.installed ? readInstalled() : null;
97
+ const launch = installed ? require("./ompgui-options").parseLaunchOptions(installed.ProgramArguments.slice(2), installed.EnvironmentVariables || {}) : options;
98
+ const port = launch.port || "30177";
99
+ const hostname = launch.hostname || "127.0.0.1";
100
+ if (!portAvailable(port, hostname)) throw new Error(`Port ${port} on ${hostname} is already in use. Stop the foreground server or other listener, then run ompgui service ${before.installed ? "start" : "install"}. No service configuration was changed.`);
101
+ }
102
+ if (action === "install" && !before.installed) {
103
+ const realCli = fs.realpathSync(cliPath);
104
+ const packageDir = path.resolve(path.dirname(realCli), "..");
105
+ if (!ownedExecutable([execPath, realCli]) || fs.existsSync(path.join(packageDir, ".git")) || !fs.existsSync(path.join(packageDir, ".next", "BUILD_ID"))) throw new Error("Install the published ompgui package before installing its service; development checkouts are not supported.");
106
+ const persistentEnv = {};
107
+ for (const [key, value] of Object.entries(env)) {
108
+ if ((/^(OMP_|OMPGUI_|OMP_WEB_)/.test(key) || ["PATH", "HOME", "SHELL", "LANG", "LC_ALL", "PI_CODING_AGENT_DIR", "PI_PROFILE"].includes(key)) && typeof value === "string" && !/(?:PACKAGE_DIR|LAUNCHER_PID)$/.test(key)) persistentEnv[key] = value;
109
+ }
110
+ persistentEnv.OMPGUI_NO_OPEN = "1";
111
+ if (options.password) { persistentEnv.OMPGUI_PASSWORD = options.password; persistentEnv.OMP_WEB_PASSWORD = options.password; }
112
+ if (options.relayUrl) persistentEnv.OMPGUI_RELAY_URL = options.relayUrl;
113
+ const config = { Label: label, ProgramArguments: [execPath, realCli, "--port", String(options.port || "30177"), "--hostname", options.hostname || "127.0.0.1", "--no-open"], WorkingDirectory: home, EnvironmentVariables: persistentEnv, RunAtLoad: true, KeepAlive: true, StandardOutPath: logPath, StandardErrorPath: logPath };
114
+ fs.mkdirSync(path.dirname(plistPath), { recursive: true, mode: 0o700 });
115
+ fs.mkdirSync(path.dirname(logPath), { recursive: true, mode: 0o700 });
116
+ const temporary = `${plistPath}.${process.pid}.${require("node:crypto").randomUUID()}.tmp`;
117
+ try {
118
+ fs.writeFileSync(temporary, `<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">${plistValue(config)}</plist>\n`, { mode: 0o600, flag: "wx" });
119
+ fs.renameSync(temporary, plistPath);
120
+ } finally { fs.rmSync(temporary, { force: true }); }
121
+ }
122
+ if (["enable", "disable"].includes(action)) {
123
+ if (!before.installed) throw new Error("Service is not installed. Run ompgui service install first.");
124
+ command([action, target]);
125
+ return status();
126
+ }
127
+ if (["stop", "uninstall"].includes(action)) {
128
+ if (before.loaded) {
129
+ command(["bootout", target]);
130
+ // The launcher allows 5 seconds before forcing its Next child to exit.
131
+ const deadline = now() + 10000;
132
+ while (command(["print", target], true) !== null) {
133
+ if (now() >= deadline) throw new Error("Service is still stopping. Configuration was preserved; wait, check ompgui status, and retry the action.");
134
+ pause(100);
135
+ }
136
+ while (before.pid !== null && processAlive(before.pid)) {
137
+ if (now() >= deadline) throw new Error("Service process is still exiting. Configuration was preserved; wait, check ompgui status, and retry the action.");
138
+ pause(100);
139
+ }
140
+ }
141
+ if (action === "uninstall" && before.installed) fs.unlinkSync(plistPath);
142
+ } else {
143
+ if (!before.installed && action !== "install") throw new Error("Service is not installed. Run ompgui service install first.");
144
+ if (action === "install") command(["enable", target]);
145
+ if (!before.loaded) {
146
+ const restoreDisabled = action !== "install" && before.explicitlyDisabled;
147
+ if (restoreDisabled) command(["enable", target]);
148
+ try {
149
+ command(["bootstrap", domain, plistPath]);
150
+ command(["kickstart", target]);
151
+ }
152
+ finally { if (restoreDisabled) command(["disable", target]); }
153
+ } else if (action === "restart") command(["kickstart", "-k", target]);
154
+ else if (!before.running) command(["kickstart", target]);
155
+ }
156
+ return status();
157
+ }
158
+ function updateSnapshot(packageDir) {
159
+ if (platform !== "darwin") return null;
160
+ const before = inspect();
161
+ if (!before.installed || !before.running) return null;
162
+ const config = readInstalled();
163
+ const packagePath = path.resolve(path.dirname(fs.realpathSync(config.ProgramArguments[1])), "..");
164
+ if (packagePath !== fs.realpathSync(packageDir)) throw new Error("Running ompgui service belongs to another installation; update that installation instead.");
165
+ const contents = fs.readFileSync(plistPath);
166
+ const launch = require("./ompgui-options").parseLaunchOptions(config.ProgramArguments.slice(2), config.EnvironmentVariables || {});
167
+ return {
168
+ packagePath, port: launch.port, hostname: launch.hostname,
169
+ verify() {
170
+ const current = inspect();
171
+ if (!current.installed || !fs.readFileSync(plistPath).equals(contents) || current.explicitlyDisabled !== before.explicitlyDisabled) throw new Error("Service configuration changed during update; refusing automatic restart.");
172
+ },
173
+ };
174
+ }
175
+ return { status, execute, validate, updateSnapshot, plistPath };
176
+ }
177
+ async function runServiceCli(options) {
178
+ const action = options.command === "service" ? options.extraPositionals[0] || "repair" : options.command;
179
+ if (options.extraPositionals.length > (options.command === "service" ? 1 : 0)) throw new Error("Unexpected service arguments");
180
+ const manager = createServiceManager();
181
+ let result;
182
+ try {
183
+ if (options.defer) {
184
+ if (!["stop", "restart", "uninstall"].includes(action)) throw new Error("Only stop, restart, and uninstall can be deferred");
185
+ manager.validate(action);
186
+ const child = spawn(process.execPath, [__filename, action], { detached: true, stdio: "ignore", env: process.env });
187
+ const spawned = Promise.withResolvers();
188
+ child.once("spawn", spawned.resolve);
189
+ child.once("error", spawned.reject);
190
+ await spawned.promise;
191
+ child.unref();
192
+ result = { ...manager.status(), accepted: true };
193
+ } else result = manager.execute(action, options);
194
+ } catch (error) { result = { ...manager.status(), error: error.message }; }
195
+ if (options.json) console.log(JSON.stringify(result));
196
+ else {
197
+ console.log(`ompgui service: ${result.running ? `running (PID ${result.pid})` : "stopped"}; ${result.installed ? "installed" : "not installed"}; login auto-start ${result.autoStart ? "enabled" : "disabled"}`);
198
+ if (result.logPath) console.log(`Logs: ${result.logPath}`);
199
+ if (result.error) console.error(result.error);
200
+ }
201
+ if (result.error) process.exitCode = 1;
202
+ return result;
203
+ }
204
+ if (require.main === module) {
205
+ const action = process.argv[2];
206
+ if (["stop", "restart", "uninstall"].includes(action) && process.argv.length === 3) setTimeout(() => {
207
+ const manager = createServiceManager();
208
+ const before = manager.status();
209
+ try {
210
+ const result = manager.execute(action);
211
+ if (result.error) throw new Error(result.error);
212
+ } catch (error) {
213
+ process.exitCode = 1;
214
+ if (before.logPath) {
215
+ try { fs.appendFileSync(before.logPath, `${new Date().toISOString()} Deferred service ${action} failed: ${error.message}\n`, { mode: 0o600 }); } catch { /* No alternate secret-bearing output destination. */ }
216
+ }
217
+ }
218
+ }, 1200);
219
+ else if (action === "--check-port" && process.argv.length === 5) {
220
+ require("./port-availability").isPortAvailable(process.argv[3], process.argv[4]).then((available) => { process.exitCode = available ? 0 : 2; }).catch(() => { process.exitCode = 1; });
221
+ } else process.exitCode = 1;
222
+ }
223
+ module.exports = { LABEL, createServiceManager, runServiceCli };
@@ -4,6 +4,18 @@ const { spawn } = require("child_process");
4
4
  const fs = require("fs");
5
5
  const os = require("os");
6
6
  const path = require("path");
7
+ const { createServiceManager } = require("./ompgui-service");
8
+ const { setTimeout: sleep } = require("node:timers/promises");
9
+
10
+ async function checkReady({ hostname, port }) {
11
+ const host = hostname === "0.0.0.0" ? "127.0.0.1" : hostname === "::" ? "::1" : hostname;
12
+ const authority = host.includes(":") ? `[${host}]` : host;
13
+ try {
14
+ const response = await fetch(`http://${authority}:${port}/`, { signal: AbortSignal.timeout(1000), redirect: "manual" });
15
+ await response.body?.cancel();
16
+ return response.ok || response.status === 307 || response.status === 308;
17
+ } catch { return false; }
18
+ }
7
19
 
8
20
  function normalizePath(value, platform) {
9
21
  const normalized = path.normalize(value).replaceAll("\\", path.sep);
@@ -35,39 +47,46 @@ function findNpmCli(nodePath = process.execPath, exists = fs.existsSync) {
35
47
  }) ?? null;
36
48
  }
37
49
 
38
- function getInstallCommand(method, platform = process.platform, nodePath = process.execPath, resolveNpmCli = findNpmCli) {
50
+ function getInstallCommand(method, platform = process.platform, nodePath = process.execPath, resolveNpmCli = findNpmCli, packageDir) {
51
+ const paths = platform === "win32" ? path.win32 : path;
52
+ const modules = packageDir && paths.dirname(packageDir);
53
+ if (packageDir && (paths.basename(packageDir) !== "ompgui" || paths.basename(modules) !== "node_modules")) {
54
+ throw new Error("Cannot safely update this installation layout. Reinstall ompgui with npm or Bun first.");
55
+ }
39
56
  if (method === "bun") {
40
- return { command: platform === "win32" ? "bun.exe" : "bun", args: ["add", "--global", "ompgui@latest"] };
57
+ const target = packageDir ? ["--global-dir", paths.dirname(modules), "--global-bin-dir", platform === "win32" ? paths.join(paths.dirname(modules), ".bin") : paths.resolve(modules, "../../../bin")] : [];
58
+ return { command: platform === "win32" ? "bun.exe" : "bun", args: ["add", "--global", ...target, "ompgui@latest"] };
41
59
  }
60
+ const parent = packageDir && paths.dirname(modules);
61
+ const global = !packageDir || platform === "win32" || paths.basename(parent) === "lib";
62
+ const target = packageDir ? ["--prefix", global && platform !== "win32" ? paths.dirname(parent) : parent] : [];
63
+ const args = ["install", ...(global ? ["--global"] : ["--no-save"]), ...target, "ompgui@latest"];
42
64
  if (platform === "win32") {
43
65
  const npmCli = resolveNpmCli(nodePath);
44
66
  if (!npmCli) throw new Error("Could not locate npm-cli.js beside the active Node.js installation.");
45
- return { command: nodePath, args: [npmCli, "install", "--global", "ompgui@latest"] };
67
+ return { command: nodePath, args: [npmCli, ...args] };
46
68
  }
47
- return { command: "npm", args: ["install", "--global", "ompgui@latest"] };
69
+ return { command: "npm", args };
48
70
  }
49
71
 
50
72
  function readInstalledVersion(packageDir) {
51
73
  try {
52
74
  const packageJson = JSON.parse(fs.readFileSync(path.join(packageDir, "package.json"), "utf8"));
53
- return typeof packageJson.version === "string" ? packageJson.version : null;
75
+ return packageJson.name === "ompgui" && typeof packageJson.version === "string" && /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(packageJson.version) ? packageJson.version : null;
54
76
  } catch {
55
77
  return null;
56
78
  }
57
79
  }
58
80
 
59
81
  function runInstaller(command, args, env = process.env) {
60
- return new Promise((resolve, reject) => {
61
- const child = spawn(command, args, { env, stdio: "inherit", windowsHide: true });
62
- child.once("error", reject);
63
- child.once("exit", (code, signal) => {
64
- if (code === 0) {
65
- resolve();
66
- return;
67
- }
68
- reject(new Error(signal ? `${command} was terminated by ${signal}` : `${command} exited with code ${code ?? "unknown"}`));
69
- });
82
+ const { promise, resolve, reject } = Promise.withResolvers();
83
+ const child = spawn(command, args, { env, stdio: "inherit", windowsHide: true });
84
+ child.once("error", reject);
85
+ child.once("exit", (code, signal) => {
86
+ if (code === 0) resolve();
87
+ else reject(new Error(signal ? `${command} was terminated by ${signal}` : `${command} exited with code ${code ?? "unknown"}`));
70
88
  });
89
+ return promise;
71
90
  }
72
91
 
73
92
  async function updateOmpGui({
@@ -77,18 +96,62 @@ async function updateOmpGui({
77
96
  homeDir = os.homedir(),
78
97
  install = runInstaller,
79
98
  stdout = process.stdout,
99
+ serviceManager = createServiceManager({ platform, home: homeDir, env }),
100
+ ready = checkReady,
101
+ pause = sleep,
102
+ now = Date.now,
103
+ readinessTimeout = 30000,
80
104
  } = {}) {
81
105
  if (!packageDir) throw new Error("The ompgui package directory is unavailable.");
82
106
 
83
107
  const beforeVersion = readInstalledVersion(packageDir);
84
108
  const method = detectInstallMethod(packageDir, env, homeDir, platform);
85
- const { command, args } = getInstallCommand(method, platform);
86
- stdout.write(`Updating ompgui${beforeVersion ? ` v${beforeVersion}` : ""} with ${method}...\n`);
87
- await install(command, args, env);
88
-
89
- const afterVersion = readInstalledVersion(packageDir);
90
- if (!afterVersion) {
91
- throw new Error("The package manager finished, but the installed ompgui version could not be verified.");
109
+ const { command, args } = getInstallCommand(method, platform, process.execPath, findNpmCli, packageDir);
110
+ const snapshot = platform === "darwin" ? serviceManager.updateSnapshot(packageDir) : null;
111
+ async function startAndWait() {
112
+ snapshot.verify();
113
+ const started = await serviceManager.execute("start");
114
+ if (started.error) throw new Error(started.error);
115
+ const deadline = now() + readinessTimeout;
116
+ while (now() < deadline) {
117
+ const state = serviceManager.status();
118
+ if (state.error) throw new Error(state.error);
119
+ if (state.running && await ready(snapshot)) {
120
+ snapshot.verify();
121
+ return;
122
+ }
123
+ await pause(Math.min(100, Math.max(0, deadline - now())));
124
+ }
125
+ throw new Error("Service did not become ready before the deadline. Check ompgui status and service logs.");
126
+ }
127
+ if (snapshot) {
128
+ stdout.write("Stopping the running ompgui service before updating...\n");
129
+ const stopped = await serviceManager.execute("stop");
130
+ if (stopped.error) throw new Error(stopped.error);
131
+ snapshot.verify();
132
+ }
133
+ let afterVersion;
134
+ try {
135
+ stdout.write(`Updating ompgui${beforeVersion ? ` v${beforeVersion}` : ""} with ${method}...\n`);
136
+ await install(command, args, env);
137
+ afterVersion = readInstalledVersion(packageDir);
138
+ if (!afterVersion) throw new Error("The package manager finished, but the installed ompgui version could not be verified.");
139
+ } catch (error) {
140
+ if (snapshot) {
141
+ stdout.write("Update failed; attempting to start the available ompgui installation (no rollback was performed)...\n");
142
+ try {
143
+ await startAndWait();
144
+ stdout.write("The available ompgui service is running again.\n");
145
+ } catch (recoveryError) {
146
+ throw new AggregateError([error, recoveryError], `${error.message} Recovery start also failed: ${recoveryError.message}`);
147
+ }
148
+ }
149
+ throw error;
150
+ }
151
+ if (snapshot) {
152
+ stdout.write("Starting the updated ompgui service...\n");
153
+ await startAndWait();
154
+ stdout.write("The ompgui service is ready.\n");
92
155
  }
93
156
  if (beforeVersion && afterVersion && beforeVersion === afterVersion) {
94
157
  stdout.write(`ompgui v${afterVersion} is already up to date.\n`);
package/bin/ompgui.js CHANGED
@@ -10,16 +10,35 @@ const pkgDir = path.join(__dirname, "..");
10
10
  const options = parseLaunchOptions();
11
11
  if (options.help || options.version) process.exit(0);
12
12
  if (options.command) {
13
- if (options.command !== "update" || options.extraPositionals.length) {
14
- console.error(`Unknown ompgui command: ${[options.command, ...options.extraPositionals].join(" ")}`);
15
- process.exit(1);
13
+ if (["service", "start", "stop", "restart", "status"].includes(options.command)) {
14
+ require("./ompgui-service").runServiceCli(options).catch((error) => {
15
+ console.error(error.message);
16
+ process.exitCode = 1;
17
+ });
18
+ return;
16
19
  }
17
- const { updateOmpGui } = require("./ompgui-update");
18
- updateOmpGui({ packageDir: pkgDir }).catch((error) => {
19
- console.error(`Could not update ompgui: ${error.message}`);
20
- process.exitCode = 1;
21
- });
22
- return;
20
+ if (options.command === "update") {
21
+ if (options.extraPositionals.length) {
22
+ console.error(`Unknown ompgui command: ${[options.command, ...options.extraPositionals].join(" ")}`);
23
+ process.exit(1);
24
+ }
25
+ const { updateOmpGui } = require("./ompgui-update");
26
+ updateOmpGui({ packageDir: pkgDir }).catch((error) => {
27
+ console.error(`Could not update ompgui: ${error.message}`);
28
+ process.exitCode = 1;
29
+ });
30
+ return;
31
+ }
32
+ if (options.command === "pair" || options.command === "devices") {
33
+ const { runRelayCli } = require("./ompgui-pair");
34
+ runRelayCli(options).catch((error) => {
35
+ console.error(error instanceof Error ? error.message : String(error));
36
+ process.exitCode = 1;
37
+ });
38
+ return;
39
+ }
40
+ console.error(`Unknown ompgui command: ${[options.command, ...options.extraPositionals].join(" ")}`);
41
+ process.exit(1);
23
42
  }
24
43
  const { isPortAvailable } = require("./port-availability");
25
44
  const { wireChildProcessLifecycle } = require("./process-lifecycle");
@@ -28,10 +47,10 @@ let nextBin;
28
47
  try { nextBin = require.resolve("next/dist/bin/next", { paths:[pkgDir] }); } catch { try { nextBin = path.join(path.dirname(require.resolve("next/package.json", {paths:[pkgDir]})), "dist", "bin", "next"); } catch { nextBin = path.join(pkgDir,"node_modules/next/dist/bin/next"); } }
29
48
  const { port, hostname, password, openBrowser } = options;
30
49
  if (password) { process.env.OMPGUI_PASSWORD = password; process.env.OMP_WEB_PASSWORD = password; }
31
- const loopback = new Set(["127.0.0.1","localhost","::1","[::1]"]);
50
+ const loopback = new Set(["127.0.0.1","localhost","::1"]);
32
51
  if (!loopback.has(hostname) && !(typeof password === "string" && password.length)) { console.error(`Refusing to listen on ${hostname} without OMPGUI_PASSWORD (or --password). Set a strong password or bind to 127.0.0.1.`); process.exit(1); }
33
52
  if (!fs.existsSync(nextDir)) { console.error("Build artifacts not found. Please report this issue."); process.exit(1); }
34
- const url = `http://${hostname}:${port}`;
53
+ const url = options.baseUrl;
35
54
  function openBrowserWindow(target) { const cmd = process.platform === "win32" ? "cmd.exe" : process.platform === "darwin" ? "open" : process.platform === "linux" && (process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP) ? "wslview" : "xdg-open"; const args = process.platform === "win32" ? ["/c","start","",target] : [target]; try { const p=spawn(cmd,args,{stdio:"ignore",detached:true}); p.on("error",e=>console.warn(`Could not open browser automatically: ${e.message}`)); p.unref(); } catch(e) { console.warn(`Could not open browser automatically: ${e.message}`); } }
36
55
  async function main() {
37
56
  if (!await isPortAvailable(port, hostname)) { console.log(`ompgui is already running on ${hostname}:${port}.`); if (openBrowser) openBrowserWindow(url); return; }
package/next.config.ts CHANGED
@@ -54,7 +54,9 @@ const nextConfig = (phase: string): NextConfig => {
54
54
  ];
55
55
  const headers = [
56
56
  {
57
- source: "/:path*",
57
+ // File routes supply their own document policy. Applying the app's
58
+ // script-enabled CSP here overrides their inert SVG/DOCX responses.
59
+ source: "/:path((?!api/files(?:/|$)).*)",
58
60
  headers: securityHeaders,
59
61
  },
60
62
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ompgui",
3
- "version": "0.6.5",
3
+ "version": "0.7.2",
4
4
  "description": "Web UI & Browser GUI for the oh-my-pi (omp) coding agent",
5
5
  "homepage": "https://github.com/dbc-hbin/ompgui#readme",
6
6
  "repository": {
@@ -22,6 +22,8 @@
22
22
  "files": [
23
23
  "bin/ompgui.js",
24
24
  "bin/ompgui-update.js",
25
+ "bin/ompgui-service.js",
26
+ "bin/ompgui-pair.js",
25
27
  "bin/omp-web.js",
26
28
  "bin/ompgui-options.js",
27
29
  "bin/omp-web-options.js",
@@ -43,7 +45,7 @@
43
45
  "dev": "next dev -H 127.0.0.1 -p 30178",
44
46
  "build": "next build --webpack",
45
47
  "start": "next start -H 127.0.0.1 -p 30177",
46
- "test": "node --experimental-strip-types --test lib/*.test.mjs lib/omp/*.test.mjs components/*.test.mjs components/ui/*.test.mjs hooks/*.test.mjs bin/*.test.mjs",
48
+ "test": "node --experimental-strip-types --test lib/*.test.mjs lib/omp/*.test.mjs lib/relay/*.test.mjs components/*.test.mjs components/ui/*.test.mjs hooks/*.test.mjs bin/*.test.mjs",
47
49
  "typecheck": "tsc --noEmit",
48
50
  "lint": "eslint .",
49
51
  "prepack": "npm run build",
@@ -65,17 +67,18 @@
65
67
  "rehype-katex": "^7.0.1",
66
68
  "rehype-raw": "^7.0.0",
67
69
  "rehype-sanitize": "^6.0.0",
70
+ "rehype-stringify": "^10.0.1",
68
71
  "remark-gfm": "^4.0.1",
69
72
  "remark-math": "^6.0.0",
70
73
  "undici": "8.10.0",
74
+ "unified": "^11.0.5",
75
+ "uqr": "^0.1.3",
71
76
  "yaml": "^2"
72
77
  },
73
78
  "devDependencies": {
74
- "@capacitor/android": "^8.5.0",
75
- "@capacitor/cli": "^8.5.0",
76
- "@capacitor/core": "^8.5.0",
77
79
  "@lobehub/icons": "^5.6.0",
78
80
  "@tailwindcss/postcss": "^4.2.2",
81
+ "@types/hast": "^3.0.4",
79
82
  "@types/node": "^25",
80
83
  "@types/react": "^19",
81
84
  "@types/react-dom": "^19",
@@ -84,6 +87,7 @@
84
87
  "eslint-config-next": "16.2.9",
85
88
  "jiti": "^2.7.0",
86
89
  "postcss": "^8",
90
+ "prismjs": "^1.30.0",
87
91
  "typescript": "^5"
88
92
  }
89
93
  }