cuelo 0.5.0 → 0.5.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 (324) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +13 -13
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/required-server-files.js +5 -5
  6. package/.next/required-server-files.json +5 -5
  7. package/.next/server/app/_global-error/page.js +3 -3
  8. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/_global-error.html +1 -1
  10. package/.next/server/app/_global-error.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  17. package/.next/server/app/_not-found/page.js +2 -2
  18. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  19. package/.next/server/app/_not-found.html +1 -1
  20. package/.next/server/app/_not-found.rsc +3 -3
  21. package/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  22. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  24. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  25. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  26. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  27. package/.next/server/app/api/agent/[id]/account/route.js +1 -1
  28. package/.next/server/app/api/agent/[id]/account/route.js.nft.json +1 -1
  29. package/.next/server/app/api/agent/[id]/account/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/agent/[id]/bash-output/route.js +1 -1
  31. package/.next/server/app/api/agent/[id]/bash-output/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/agent/[id]/events/route.js +2 -2
  33. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  34. package/.next/server/app/api/agent/[id]/events/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/agent/[id]/route.js +1 -1
  36. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  37. package/.next/server/app/api/agent/[id]/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/agent/new/route.js +1 -1
  39. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  40. package/.next/server/app/api/agent/new/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/agent/running/route.js +1 -1
  42. package/.next/server/app/api/agent/running/route.js.nft.json +1 -1
  43. package/.next/server/app/api/agent/running/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/auth/all-providers/route.js +1 -1
  45. package/.next/server/app/api/auth/all-providers/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -1
  47. package/.next/server/app/api/auth/api-key/[provider]/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/auth/login/[provider]/route.js +1 -1
  49. package/.next/server/app/api/auth/login/[provider]/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/auth/logout/[provider]/route.js +1 -1
  51. package/.next/server/app/api/auth/logout/[provider]/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/auth/providers/route.js +1 -1
  53. package/.next/server/app/api/auth/providers/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/cwd/browse/route.js +1 -1
  55. package/.next/server/app/api/cwd/browse/route.js.nft.json +1 -1
  56. package/.next/server/app/api/cwd/browse/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/cwd/validate/route.js +1 -1
  58. package/.next/server/app/api/cwd/validate/route.js.nft.json +1 -1
  59. package/.next/server/app/api/cwd/validate/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/default-cwd/route.js +1 -1
  61. package/.next/server/app/api/default-cwd/route.js.nft.json +1 -1
  62. package/.next/server/app/api/default-cwd/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/display-settings/route.js +1 -1
  64. package/.next/server/app/api/display-settings/route.js.nft.json +1 -1
  65. package/.next/server/app/api/display-settings/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/document-text/route.js +2 -2
  67. package/.next/server/app/api/document-text/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/experiments/route.js +1 -1
  69. package/.next/server/app/api/experiments/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/file-index/route.js +1 -1
  71. package/.next/server/app/api/file-index/route.js.nft.json +1 -1
  72. package/.next/server/app/api/file-index/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/files/[...path]/route.js +2 -2
  74. package/.next/server/app/api/files/[...path]/route.js.nft.json +1 -1
  75. package/.next/server/app/api/files/[...path]/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/git/diff/route.js +2 -2
  77. package/.next/server/app/api/git/diff/route.js.nft.json +1 -1
  78. package/.next/server/app/api/git/diff/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/git/status/route.js +1 -1
  80. package/.next/server/app/api/git/status/route.js.nft.json +1 -1
  81. package/.next/server/app/api/git/status/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/gpt6/handles/route.js +1 -1
  83. package/.next/server/app/api/gpt6/handles/route.js.nft.json +1 -1
  84. package/.next/server/app/api/gpt6/handles/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/gpt6/mcp/route.js +1 -1
  86. package/.next/server/app/api/gpt6/mcp/route.js.nft.json +1 -1
  87. package/.next/server/app/api/gpt6/mcp/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/gpt6/reply/route.js +1 -1
  89. package/.next/server/app/api/gpt6/reply/route.js.nft.json +1 -1
  90. package/.next/server/app/api/gpt6/reply/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/gpt6/token/route.js +1 -1
  92. package/.next/server/app/api/gpt6/token/route.js.nft.json +1 -1
  93. package/.next/server/app/api/gpt6/token/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/gpt6/web6-session/route.js +1 -1
  95. package/.next/server/app/api/gpt6/web6-session/route.js.nft.json +1 -1
  96. package/.next/server/app/api/gpt6/web6-session/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/home/route.js +1 -1
  98. package/.next/server/app/api/home/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/live/call/[callId]/route.js +1 -1
  100. package/.next/server/app/api/live/call/[callId]/route.js.nft.json +1 -1
  101. package/.next/server/app/api/live/call/[callId]/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/live/events/route.js +2 -2
  103. package/.next/server/app/api/live/events/route.js.nft.json +1 -1
  104. package/.next/server/app/api/live/events/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/live/offer/route.js +1 -1
  106. package/.next/server/app/api/live/offer/route.js.nft.json +1 -1
  107. package/.next/server/app/api/live/offer/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/live/voices/route.js +1 -1
  109. package/.next/server/app/api/live/voices/route.js.nft.json +1 -1
  110. package/.next/server/app/api/live/voices/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/mcp/route.js +2 -2
  112. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  113. package/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/model-roles/route.js +1 -1
  115. package/.next/server/app/api/model-roles/route.js.nft.json +1 -1
  116. package/.next/server/app/api/model-roles/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/models/route.js +1 -1
  118. package/.next/server/app/api/models/route.js.nft.json +1 -1
  119. package/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/models-config/catalog/route.js +1 -1
  121. package/.next/server/app/api/models-config/catalog/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/models-config/discover/route.js +1 -1
  123. package/.next/server/app/api/models-config/discover/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/models-config/route.js +3 -3
  125. package/.next/server/app/api/models-config/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/models-config/test/route.js +1 -1
  127. package/.next/server/app/api/models-config/test/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/plugins/route.js +1 -1
  129. package/.next/server/app/api/plugins/route.js.nft.json +1 -1
  130. package/.next/server/app/api/plugins/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/project-trust/route.js +1 -1
  132. package/.next/server/app/api/project-trust/route.js.nft.json +1 -1
  133. package/.next/server/app/api/project-trust/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/projects/route.js +1 -1
  135. package/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/runs/[runId]/route.js +1 -1
  137. package/.next/server/app/api/runs/[runId]/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/runs/route.js +1 -1
  139. package/.next/server/app/api/runs/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/sessions/[id]/auto-name/route.js +1 -1
  141. package/.next/server/app/api/sessions/[id]/auto-name/route.js.nft.json +1 -1
  142. package/.next/server/app/api/sessions/[id]/auto-name/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/sessions/[id]/context/route.js +1 -1
  144. package/.next/server/app/api/sessions/[id]/context/route.js.nft.json +1 -1
  145. package/.next/server/app/api/sessions/[id]/context/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +1 -1
  147. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
  149. package/.next/server/app/api/sessions/[id]/export/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  151. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  152. package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -1
  153. package/.next/server/app/api/sessions/[id]/state/route.js +1 -1
  154. package/.next/server/app/api/sessions/[id]/state/route.js.nft.json +1 -1
  155. package/.next/server/app/api/sessions/[id]/state/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/sessions/route.js +1 -1
  157. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  158. package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/settings/route.js +1 -1
  160. package/.next/server/app/api/settings/route.js.nft.json +1 -1
  161. package/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/sidecars/[service]/[...path]/route.js +1 -1
  163. package/.next/server/app/api/sidecars/[service]/[...path]/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/skills/check/route.js +1 -1
  165. package/.next/server/app/api/skills/check/route.js.nft.json +1 -1
  166. package/.next/server/app/api/skills/check/route_client-reference-manifest.js +1 -1
  167. package/.next/server/app/api/skills/install/route.js +1 -1
  168. package/.next/server/app/api/skills/install/route.js.nft.json +1 -1
  169. package/.next/server/app/api/skills/install/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/skills/route.js +2 -2
  171. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  172. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/skills/search/route.js +1 -1
  174. package/.next/server/app/api/skills/search/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/skills/update/route.js +1 -1
  176. package/.next/server/app/api/skills/update/route.js.nft.json +1 -1
  177. package/.next/server/app/api/skills/update/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/api/theme/route.js +1 -1
  179. package/.next/server/app/api/theme/route.js.nft.json +1 -1
  180. package/.next/server/app/api/theme/route_client-reference-manifest.js +1 -1
  181. package/.next/server/app/api/update-maintenance/route.js +2 -2
  182. package/.next/server/app/api/update-maintenance/route.js.nft.json +1 -1
  183. package/.next/server/app/api/update-maintenance/route_client-reference-manifest.js +1 -1
  184. package/.next/server/app/api/updates/route.js +1 -1
  185. package/.next/server/app/api/updates/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/web-access/recovery/route.js +1 -1
  187. package/.next/server/app/api/web-access/recovery/route.js.nft.json +1 -1
  188. package/.next/server/app/api/web-access/recovery/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/web-access/route.js +1 -1
  190. package/.next/server/app/api/web-access/route.js.nft.json +1 -1
  191. package/.next/server/app/api/web-access/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/web6/consults/route.js +1 -1
  193. package/.next/server/app/api/web6/consults/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/route.js +1 -1
  195. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  196. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/favicon.ico/route.js +1 -1
  198. package/.next/server/app/index.html +1 -1
  199. package/.next/server/app/index.rsc +5 -5
  200. package/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
  201. package/.next/server/app/index.segments/_full.segment.rsc +5 -5
  202. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  203. package/.next/server/app/index.segments/_index.segment.rsc +3 -3
  204. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  205. package/.next/server/app/manifest.webmanifest/route.js +2 -2
  206. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/page.js +9 -9
  208. package/.next/server/app/page_client-reference-manifest.js +1 -1
  209. package/.next/server/app/recover/page.js +2 -2
  210. package/.next/server/app/recover/page_client-reference-manifest.js +1 -1
  211. package/.next/server/app/recover.html +1 -1
  212. package/.next/server/app/recover.rsc +4 -4
  213. package/.next/server/app/recover.segments/_full.segment.rsc +4 -4
  214. package/.next/server/app/recover.segments/_head.segment.rsc +1 -1
  215. package/.next/server/app/recover.segments/_index.segment.rsc +3 -3
  216. package/.next/server/app/recover.segments/_tree.segment.rsc +2 -2
  217. package/.next/server/app/recover.segments/recover/__PAGE__.segment.rsc +2 -2
  218. package/.next/server/app/recover.segments/recover.segment.rsc +1 -1
  219. package/.next/server/app-paths-manifest.json +13 -13
  220. package/.next/server/chunks/319.js +3 -3
  221. package/.next/server/chunks/3379.js +1 -1
  222. package/.next/server/middleware-build-manifest.js +1 -1
  223. package/.next/server/middleware.js +11 -11
  224. package/.next/server/pages/404.html +1 -1
  225. package/.next/server/pages/500.html +1 -1
  226. package/.next/server/server-reference-manifest.json +1 -1
  227. package/.next/static/chunks/app/_not-found/page-9e5295df095e2e41.js +1 -0
  228. package/.next/static/chunks/app/layout-5217e6f9b3d4a4b8.js +1 -0
  229. package/.next/static/chunks/app/page-28b47a94fe58eaba.js +15 -0
  230. package/.next/static/chunks/app/recover/page-c0c40b3c215078a4.js +1 -0
  231. package/.next/static/chunks/{main-app-0dc38ffe862cd588.js → main-app-fbc4aa3c15d48613.js} +1 -1
  232. package/.next/static/chunks/next/dist/client/components/builtin/global-error-50782c8c9c06c8b5.js +1 -0
  233. package/.next/static/css/41958fa4965167ad.css +1 -0
  234. package/.next/trace +104 -8
  235. package/.next/trace-build +1 -1
  236. package/.next/types/app/api/agent/[id]/account/route.ts +1 -1
  237. package/.next/types/app/api/agent/[id]/bash-output/route.ts +1 -1
  238. package/.next/types/app/api/agent/[id]/events/route.ts +1 -1
  239. package/.next/types/app/api/agent/[id]/route.ts +1 -1
  240. package/.next/types/app/api/agent/new/route.ts +1 -1
  241. package/.next/types/app/api/agent/running/route.ts +1 -1
  242. package/.next/types/app/api/auth/all-providers/route.ts +1 -1
  243. package/.next/types/app/api/auth/api-key/[provider]/route.ts +1 -1
  244. package/.next/types/app/api/auth/login/[provider]/route.ts +1 -1
  245. package/.next/types/app/api/auth/logout/[provider]/route.ts +1 -1
  246. package/.next/types/app/api/auth/providers/route.ts +1 -1
  247. package/.next/types/app/api/cwd/browse/route.ts +1 -1
  248. package/.next/types/app/api/cwd/validate/route.ts +1 -1
  249. package/.next/types/app/api/default-cwd/route.ts +1 -1
  250. package/.next/types/app/api/display-settings/route.ts +1 -1
  251. package/.next/types/app/api/document-text/route.ts +1 -1
  252. package/.next/types/app/api/experiments/route.ts +1 -1
  253. package/.next/types/app/api/file-index/route.ts +1 -1
  254. package/.next/types/app/api/files/[...path]/route.ts +1 -1
  255. package/.next/types/app/api/git/diff/route.ts +1 -1
  256. package/.next/types/app/api/git/status/route.ts +1 -1
  257. package/.next/types/app/api/gpt6/handles/route.ts +1 -1
  258. package/.next/types/app/api/gpt6/mcp/route.ts +1 -1
  259. package/.next/types/app/api/gpt6/reply/route.ts +1 -1
  260. package/.next/types/app/api/gpt6/token/route.ts +1 -1
  261. package/.next/types/app/api/gpt6/web6-session/route.ts +1 -1
  262. package/.next/types/app/api/home/route.ts +1 -1
  263. package/.next/types/app/api/live/call/[callId]/route.ts +1 -1
  264. package/.next/types/app/api/live/events/route.ts +1 -1
  265. package/.next/types/app/api/live/offer/route.ts +1 -1
  266. package/.next/types/app/api/live/voices/route.ts +1 -1
  267. package/.next/types/app/api/mcp/route.ts +1 -1
  268. package/.next/types/app/api/model-roles/route.ts +1 -1
  269. package/.next/types/app/api/models/route.ts +1 -1
  270. package/.next/types/app/api/models-config/catalog/route.ts +1 -1
  271. package/.next/types/app/api/models-config/discover/route.ts +1 -1
  272. package/.next/types/app/api/models-config/route.ts +1 -1
  273. package/.next/types/app/api/models-config/test/route.ts +1 -1
  274. package/.next/types/app/api/plugins/route.ts +1 -1
  275. package/.next/types/app/api/project-trust/route.ts +1 -1
  276. package/.next/types/app/api/projects/route.ts +1 -1
  277. package/.next/types/app/api/runs/[runId]/route.ts +1 -1
  278. package/.next/types/app/api/runs/route.ts +1 -1
  279. package/.next/types/app/api/sessions/[id]/auto-name/route.ts +1 -1
  280. package/.next/types/app/api/sessions/[id]/context/route.ts +1 -1
  281. package/.next/types/app/api/sessions/[id]/entries/[entryId]/thinking/route.ts +1 -1
  282. package/.next/types/app/api/sessions/[id]/export/route.ts +1 -1
  283. package/.next/types/app/api/sessions/[id]/route.ts +1 -1
  284. package/.next/types/app/api/sessions/[id]/state/route.ts +1 -1
  285. package/.next/types/app/api/sessions/route.ts +1 -1
  286. package/.next/types/app/api/settings/route.ts +1 -1
  287. package/.next/types/app/api/sidecars/[service]/[...path]/route.ts +1 -1
  288. package/.next/types/app/api/skills/check/route.ts +1 -1
  289. package/.next/types/app/api/skills/install/route.ts +1 -1
  290. package/.next/types/app/api/skills/route.ts +1 -1
  291. package/.next/types/app/api/skills/search/route.ts +1 -1
  292. package/.next/types/app/api/skills/update/route.ts +1 -1
  293. package/.next/types/app/api/theme/route.ts +1 -1
  294. package/.next/types/app/api/update-maintenance/route.ts +1 -1
  295. package/.next/types/app/api/updates/route.ts +1 -1
  296. package/.next/types/app/api/web-access/recovery/route.ts +1 -1
  297. package/.next/types/app/api/web-access/route.ts +1 -1
  298. package/.next/types/app/api/web6/consults/route.ts +1 -1
  299. package/.next/types/app/api/worktrees/route.ts +1 -1
  300. package/.next/types/app/layout.ts +1 -1
  301. package/.next/types/app/page.ts +1 -1
  302. package/.next/types/app/recover/page.ts +1 -1
  303. package/README.md +174 -174
  304. package/Tools/CUELO_Setup/files/native-runtime-patch.js +349 -349
  305. package/Tools/OMP_Global_Config/agent/AGENTS.md +1 -1
  306. package/Tools/OMP_Global_Config/agent/agents/maker.md +390 -390
  307. package/Tools/OMP_Global_Config/agent/extensions/command-guard/matcher.ts +3 -1
  308. package/Tools/OMP_Global_Config/agent/extensions/jev-runtime.ts +63 -28
  309. package/Tools/OMP_Global_Config/agent/extensions/todo-nudge.ts +56 -56
  310. package/Tools/OMP_Global_Config/agent/prompt-copies/AGENTS.en.md +2 -2
  311. package/Tools/OMP_Global_Config/patches/apply-core-patch.mjs +5101 -5005
  312. package/bin/prepare-runtime.js +81 -81
  313. package/install.mjs +393 -393
  314. package/package.json +1 -1
  315. package/public/audio/completion/voices.json +1195 -1195
  316. package/public/offline.html +145 -145
  317. package/.next/static/chunks/app/_not-found/page-d3f2ac234e6fd3b6.js +0 -1
  318. package/.next/static/chunks/app/layout-95725ad1abf3cb75.js +0 -1
  319. package/.next/static/chunks/app/page-26a4df181c1d562c.js +0 -15
  320. package/.next/static/chunks/app/recover/page-770a1de1ff4ded56.js +0 -1
  321. package/.next/static/chunks/next/dist/client/components/builtin/global-error-070571d2fa580e7d.js +0 -1
  322. package/.next/static/css/bc8f2da9192ea16d.css +0 -1
  323. /package/.next/static/{MvC-CM1U-UMEzpaGIsCuQ → bGz6gPjG3dJqXPXBB1JeP}/_buildManifest.js +0 -0
  324. /package/.next/static/{MvC-CM1U-UMEzpaGIsCuQ → bGz6gPjG3dJqXPXBB1JeP}/_ssgManifest.js +0 -0
package/install.mjs CHANGED
@@ -1,393 +1,393 @@
1
- #!/usr/bin/env node
2
- // CUELO public installer. Run it explicitly; no npm lifecycle script calls it.
3
- //
4
- // node install.mjs [setup] [--home <dir>] [--model <provider/model>] [--role <name>=<provider/model[:effort]>]...
5
- // node install.mjs start [--home <dir>] [--port-base <n>]
6
- // node install.mjs health [--port-base <n>]
7
- //
8
- // setup: in a source checkout installs dependencies, builds, applies and checks
9
- // the SDK patches (same steps as ci.yml and bin/prepare-runtime.js); in an
10
- // installed npm package it only checks the prepared runtime. Then it copies the
11
- // public harness into the omp profile without replacing anything already there.
12
- // start: runs the app and the three local sidecars in the foreground.
13
- // health: asks the four local services whether they answer, without calling a provider.
14
-
15
- import { spawn, spawnSync } from "node:child_process";
16
- import fs from "node:fs";
17
- import { createRequire } from "node:module";
18
- import os from "node:os";
19
- import path from "node:path";
20
- import { fileURLToPath } from "node:url";
21
-
22
- const ROOT = path.dirname(fileURLToPath(import.meta.url));
23
- const require = createRequire(path.join(ROOT, "package.json"));
24
-
25
- /** The model slots the public harness routes Makers to; `--model` sets omp's core `default` separately. */
26
- export const HARNESS_ROLES = [
27
- "implSol",
28
- "implOpus",
29
- "implDeepSeek",
30
- "makerHardUiOpus",
31
- "makerHardCodeOpus",
32
- "makerHardCodeAstra",
33
- ];
34
- const SELECTOR = /^[^/\s:]+\/[^\s:]+(?::[a-z]+)?$/;
35
-
36
- // The public harness is exactly what package.json `files` ships under this folder, so a
37
- // source checkout and an installed package copy the same set. Personal config, models and
38
- // skills are not listed there.
39
- const HARNESS_PREFIX = "Tools/OMP_Global_Config/agent/";
40
-
41
- export const SERVICES = [
42
- // The app answers its own maintenance status without a session or a provider.
43
- { name: "web", env: "PORT", port: 30141, method: "GET", path: "/api/update-maintenance", expect: 200 },
44
- // usage-server has no health route; its CORS preflight answers without reading credentials.
45
- { name: "usage", env: "OMP_USAGE_PORT", port: 30142, method: "OPTIONS", path: "/usage", expect: 204 },
46
- { name: "btw", env: "OMP_BTW_PORT", port: 30143, method: "GET", path: "/health", expect: 200 },
47
- { name: "subagent", env: "OMP_SUBAGENT_PORT", port: 30144, method: "GET", path: "/health", expect: 200 },
48
- ];
49
-
50
- const MAX_PORT_BASE = 65535 - (SERVICES.length - 1);
51
-
52
- function parsePort(value, max) {
53
- if (typeof value !== "string" || !/^\d{1,5}$/.test(value.trim())) return null;
54
- const port = Number(value.trim());
55
- return port >= 1 && port <= max ? port : null;
56
- }
57
-
58
- /**
59
- * The ports of one CUELO set. `--port-base n` puts the four services on n..n+3; without it each
60
- * service keeps its own variable (the ones the app and sidecars read) or its default. Nothing is
61
- * probed or guessed.
62
- */
63
- export function servicePorts(portBase = null, env = process.env) {
64
- return SERVICES.map((service, index) => ({
65
- ...service,
66
- port: portBase !== null ? portBase + index : parsePort(env[service.env], 65535) ?? service.port,
67
- }));
68
- }
69
-
70
- /** The variables that point the app, its sidecar proxy and every sidecar at the same port set. */
71
- export function portEnv(services) {
72
- return Object.fromEntries(services.map((service) => [service.env, String(service.port)]));
73
- }
74
-
75
- class UsageError extends Error {}
76
-
77
- export function parseArgs(argv) {
78
- const args = [...argv];
79
- const command = args[0] && !args[0].startsWith("--") ? args.shift() : "setup";
80
- if (!["setup", "start", "health"].includes(command)) throw new UsageError(`unknown command: ${command}`);
81
- const options = { command, home: null, roles: {}, portBase: null };
82
- while (args.length > 0) {
83
- const flag = args.shift();
84
- const value = args.shift();
85
- if (value === undefined || value.startsWith("--")) throw new UsageError(`${flag} needs a value`);
86
- if (flag === "--home" && command !== "health") {
87
- options.home = path.resolve(value);
88
- } else if (flag === "--port-base" && command !== "setup") {
89
- options.portBase = parsePort(value, MAX_PORT_BASE);
90
- if (options.portBase === null) throw new UsageError(`--port-base takes a number from 1 to ${MAX_PORT_BASE}`);
91
- } else if (flag === "--model" && command === "setup") {
92
- options.roles.default = value;
93
- } else if (flag === "--role" && command === "setup") {
94
- const at = value.indexOf("=");
95
- const name = value.slice(0, at);
96
- if (at <= 0 || !HARNESS_ROLES.includes(name)) {
97
- throw new UsageError(`--role takes <name>=<provider/model>, name one of ${HARNESS_ROLES.join(", ")}`);
98
- }
99
- options.roles[name] = value.slice(at + 1);
100
- } else {
101
- throw new UsageError(`unknown option for ${command}: ${flag}`);
102
- }
103
- }
104
- for (const [name, selector] of Object.entries(options.roles)) {
105
- if (!SELECTOR.test(selector)) throw new UsageError(`${name}: "${selector}" is not <provider>/<model>[:effort]`);
106
- }
107
- return options;
108
- }
109
-
110
- /**
111
- * The omp profile a command targets. `--home` points the whole process tree at
112
- * another home, so the SDK, the sidecars and this installer read the same profile.
113
- */
114
- export function resolveProfile(home, env = process.env) {
115
- if (home) {
116
- const agentDir = path.join(home, ".omp", "agent");
117
- return { agentDir, env: { ...env, HOME: home, USERPROFILE: home, PI_CODING_AGENT_DIR: agentDir } };
118
- }
119
- return { agentDir: env.PI_CODING_AGENT_DIR || path.join(os.homedir(), ".omp", "agent"), env: { ...env } };
120
- }
121
-
122
- /** The harness entries (files or folders, relative to the agent folder) named by package.json `files`. */
123
- export function harnessEntries(packageFiles) {
124
- return packageFiles.filter((entry) => typeof entry === "string" && entry.startsWith(HARNESS_PREFIX))
125
- .map((entry) => entry.slice(HARNESS_PREFIX.length));
126
- }
127
-
128
- /** Copies the public harness file by file; an existing profile file is always kept as it is. */
129
- export function copyHarness(sourceDir, agentDir, entries) {
130
- const report = { created: [], kept: [] };
131
- const copy = (rel) => {
132
- const name = path.basename(rel);
133
- // Same exclusions as the `!…/**/tests` and `!…/**/*.test.*` entries of `files`; npm
134
- // never packs a nested node_modules either.
135
- if (name === "tests" || name === "node_modules" || /\.test\./.test(name)) return;
136
- const source = path.join(sourceDir, rel);
137
- if (fs.statSync(source).isDirectory()) {
138
- for (const child of fs.readdirSync(source)) copy(path.join(rel, child));
139
- return;
140
- }
141
- const target = path.join(agentDir, rel);
142
- fs.mkdirSync(path.dirname(target), { recursive: true });
143
- try {
144
- fs.copyFileSync(source, target, fs.constants.COPYFILE_EXCL);
145
- report.created.push(rel);
146
- } catch (error) {
147
- if (error.code !== "EEXIST") throw error;
148
- report.kept.push(rel);
149
- }
150
- };
151
- for (const entry of entries) copy(entry);
152
- return report;
153
- }
154
-
155
- /**
156
- * What a new profile's `config.yml` starts with, so the public harness runs the way it is used:
157
- * local learning and project-scoped memory, the harness's Maker routing (isolated task runs,
158
- * its roles instead of the bundled agents) and request budget, and nothing that spends
159
- * provider requests on its own (`autoContinue`, `autoRetain` stay off). Values equal to the
160
- * omp defaults are left out.
161
- */
162
- export const PROFILE_DEFAULTS = {
163
- defaultThinkingLevel: "auto",
164
- autolearn: { enabled: true, autoContinue: false },
165
- memory: { backend: "mnemopi" },
166
- mnemopi: { scoping: "per-project-tagged", embeddingVariant: "multilingual", autoRetain: false },
167
- task: {
168
- softRequestBudget: 400,
169
- maxConcurrency: 8,
170
- eager: "preferred",
171
- maxEffort: "xhigh",
172
- isolation: { enabled: true },
173
- disabledAgents: ["scout", "sonic", "task", "reviewer", "security-reviewer"],
174
- },
175
- };
176
-
177
- /**
178
- * Creates `config.yml` for a profile that has none: the defaults above plus exactly the model
179
- * roles the user named. An existing file is never edited; the report lists the roles it lacks.
180
- */
181
- export function createProfileConfig(agentDir, roles) {
182
- const YAML = require("yaml");
183
- const configPath = path.join(agentDir, "config.yml");
184
- if (fs.existsSync(configPath)) {
185
- const assigned = YAML.parse(fs.readFileSync(configPath, "utf8"))?.modelRoles ?? {};
186
- return {
187
- configPath,
188
- written: false,
189
- ignored: Object.keys(roles),
190
- missing: ["default", ...HARNESS_ROLES].filter((name) => typeof assigned[name] !== "string"),
191
- };
192
- }
193
- fs.mkdirSync(agentDir, { recursive: true });
194
- const config = Object.keys(roles).length > 0 ? { ...PROFILE_DEFAULTS, modelRoles: roles } : PROFILE_DEFAULTS;
195
- const body = [
196
- "# Written by CUELO install.mjs for a new profile. Edit freely; setup never rewrites this file.",
197
- YAML.stringify(config),
198
- ].join("\n");
199
- fs.writeFileSync(configPath, body, { flag: "wx" });
200
- return {
201
- configPath,
202
- written: true,
203
- ignored: [],
204
- missing: ["default", ...HARNESS_ROLES].filter((name) => roles[name] === undefined),
205
- };
206
- }
207
-
208
- function run(command, args, options) {
209
- console.log(`> ${[command, ...args].join(" ")}`);
210
- const result = spawnSync(command, args, { stdio: "inherit", ...options });
211
- if (result.error || result.status !== 0) {
212
- throw new Error(`${path.basename(command)} ${args[0] ?? ""} failed: ${result.error?.message ?? `exit ${result.status}`}`);
213
- }
214
- }
215
-
216
- function bunPath() {
217
- const { resolveBunPath, getMissingBunMessage } = require("./bin/runtime.js");
218
- const bun = resolveBunPath();
219
- if (!bun) throw new Error(getMissingBunMessage());
220
- return bun;
221
- }
222
-
223
- function prepareRuntime() {
224
- const node = process.versions.bun ? "node" : process.execPath;
225
- const sourceCheckout = fs.existsSync(path.join(ROOT, "bun.lock")) && fs.existsSync(path.join(ROOT, "app", "layout.tsx"));
226
- if (!sourceCheckout) {
227
- // An installed package ships its production build and patched SDK; only confirm them.
228
- run(node, [path.join(ROOT, "bin", "prepare-runtime.js"), "--check"], { cwd: ROOT });
229
- return;
230
- }
231
- // Same isolated home as ci.yml and the setup runner: the build otherwise walks the real
232
- // profile (protected folders fail with EPERM) and could read the user's omp settings.
233
- // `--home` names where the harness goes, never what the build sees.
234
- const buildHome = path.join(ROOT, ".runtime-patch-home");
235
- fs.mkdirSync(buildHome, { recursive: true });
236
- const buildRoot = path.parse(buildHome).root;
237
- const { PI_CODING_AGENT_DIR: _profile, ...inherited } = process.env;
238
- const buildEnv = {
239
- ...inherited,
240
- HOME: buildHome,
241
- USERPROFILE: buildHome,
242
- HOMEDRIVE: buildRoot.replace(/[\\/]+$/, ""),
243
- HOMEPATH: buildHome.slice(buildRoot.length - 1),
244
- NEXT_TELEMETRY_DISABLED: "1",
245
- };
246
- const bun = bunPath();
247
- run(bun, ["install", "--frozen-lockfile"], { cwd: ROOT, env: buildEnv });
248
- // The native runtime patch edits the production server chunks, so it runs after the build.
249
- run(bun, ["run", "build"], { cwd: ROOT, env: buildEnv });
250
- const env = {
251
- ...buildEnv,
252
- OMP_CORE_PATCH_TARGET: path.join(ROOT, "node_modules", "@oh-my-pi", "pi-coding-agent"),
253
- };
254
- const patches = [
255
- [path.join(ROOT, "Tools", "CUELO_Setup", "files", "native-runtime-patch.js"), ["--target", ROOT]],
256
- [path.join(ROOT, "Tools", "OMP_Global_Config", "patches", "apply-core-patch.mjs"), []],
257
- [path.join(ROOT, "Tools", "OMP_Global_Config", "patches", "apply-notices.mjs"), []],
258
- ];
259
- for (const [script, args] of patches) run(node, [script, ...args], { cwd: ROOT, env });
260
- for (const [script, args] of patches) run(node, [script, ...args, "--check"], { cwd: ROOT, env });
261
- }
262
-
263
- function setup(options) {
264
- prepareRuntime();
265
- const { agentDir } = resolveProfile(options.home);
266
- const packageFiles = JSON.parse(fs.readFileSync(path.join(ROOT, "package.json"), "utf8")).files ?? [];
267
- const harness = copyHarness(path.join(ROOT, "Tools", "OMP_Global_Config", "agent"), agentDir, harnessEntries(packageFiles));
268
- console.log(`Harness: ${harness.created.length} files added to ${agentDir}, ${harness.kept.length} existing files kept unchanged.`);
269
- const roles = createProfileConfig(agentDir, options.roles);
270
- if (roles.written) console.log(`Profile config: wrote ${roles.configPath}.`);
271
- if (roles.ignored.length > 0) console.log(`Profile config: ${roles.configPath} already exists and was not changed; ignored ${roles.ignored.join(", ")}.`);
272
- if (roles.missing.length > 0) {
273
- console.log(`Model roles not set: ${roles.missing.join(", ")}. Choose your own models in CUELO Settings > Model roles.`);
274
- }
275
- console.log("Next: run `node install.mjs start`, open the address it prints, and sign in to your providers under Settings > Models.");
276
- }
277
-
278
- async function portAnswers(port) {
279
- try {
280
- await fetch(`http://127.0.0.1:${port}/`, { method: "HEAD", signal: AbortSignal.timeout(1500) });
281
- return true;
282
- } catch {
283
- return false;
284
- }
285
- }
286
-
287
- async function start(options) {
288
- if (!fs.existsSync(path.join(ROOT, ".next", "BUILD_ID"))) throw new Error("No production build found. Run `node install.mjs setup` first.");
289
- const { env } = resolveProfile(options.home);
290
- const services = servicePorts(options.portBase, env);
291
- const busy = [];
292
- for (const service of services) if (await portAnswers(service.port)) busy.push(`${service.name}:${service.port}`);
293
- if (busy.length > 0) throw new Error(`Already in use: ${busy.join(", ")}. Stop the running CUELO first or pick another --port-base.`);
294
-
295
- const bun = bunPath();
296
- const node = process.versions.bun ? "node" : process.execPath;
297
- const files = path.join(ROOT, "Tools", "CUELO_Setup", "files");
298
- const childEnv = { ...env, ...portEnv(services), CUELO_DIR: ROOT };
299
- const commands = [
300
- // The app-only launcher; `--no-open` leaves the browser to the user, and the explicit loopback
301
- // host wins over an inherited CUELO_HOSTNAME so this never listens beyond the machine.
302
- ["web", bun, [path.join(ROOT, "bin", "cuelo.js"), "--no-open", "--hostname", "127.0.0.1"]],
303
- ["usage", bun, [path.join(files, "usage-server.js")]],
304
- ["btw", bun, [path.join(files, "btw-server.js")]],
305
- ["subagent", node, [path.join(files, "subagent-server.js")]],
306
- ];
307
- const children = commands.map(([name, command, args]) => {
308
- const child = spawn(command, args, { cwd: ROOT, env: childEnv, stdio: ["ignore", "pipe", "pipe"] });
309
- for (const stream of [child.stdout, child.stderr]) {
310
- let pending = "";
311
- stream.setEncoding("utf8");
312
- stream.on("data", (chunk) => {
313
- const lines = (pending + chunk).split(/\r?\n/);
314
- pending = lines.pop() ?? "";
315
- for (const line of lines) console.log(`[${name}] ${line}`);
316
- });
317
- }
318
- return { name, child };
319
- });
320
- const web = services.find((service) => service.name === "web");
321
- console.log(`CUELO is starting at http://127.0.0.1:${web.port} . Press Ctrl+C to stop all four services.`);
322
-
323
- let stopping = false;
324
- const stopAll = () => {
325
- stopping = true;
326
- for (const { child } of children) if (child.exitCode === null) child.kill();
327
- };
328
- process.on("SIGINT", stopAll);
329
- process.on("SIGTERM", stopAll);
330
- const exits = await Promise.all(children.map(({ name, child }) => new Promise((resolve) => {
331
- child.on("exit", (code, signal) => {
332
- if (!stopping) {
333
- console.error(`[${name}] exited (${signal ?? `code ${code}`}); stopping the other services.`);
334
- stopAll();
335
- resolve(1);
336
- return;
337
- }
338
- resolve(0);
339
- });
340
- child.on("error", (error) => {
341
- console.error(`[${name}] could not start: ${error.message}`);
342
- stopAll();
343
- resolve(1);
344
- });
345
- })));
346
- return exits.some((code) => code !== 0) ? 1 : 0;
347
- }
348
-
349
- /** One request per service; nothing here authenticates or reaches a model provider. */
350
- export async function checkHealth(services = servicePorts(), timeoutMs = 3000) {
351
- return Promise.all(services.map(async (service) => {
352
- try {
353
- const response = await fetch(`http://127.0.0.1:${service.port}${service.path}`, {
354
- method: service.method,
355
- signal: AbortSignal.timeout(timeoutMs),
356
- });
357
- return { ...service, ok: response.status === service.expect, status: response.status };
358
- } catch (error) {
359
- return { ...service, ok: false, status: null, error: error.message };
360
- }
361
- }));
362
- }
363
-
364
- async function main(argv) {
365
- let options;
366
- try {
367
- options = parseArgs(argv);
368
- } catch (error) {
369
- if (!(error instanceof UsageError)) throw error;
370
- console.error(error.message);
371
- console.error("Usage: node install.mjs [setup|start|health] [--home <dir>] [--model <provider/model>] [--role <name>=<provider/model[:effort]>] [--port-base <n>]");
372
- return 2;
373
- }
374
- try {
375
- if (options.command === "setup") {
376
- setup(options);
377
- return 0;
378
- }
379
- if (options.command === "start") return await start(options);
380
- const results = await checkHealth(servicePorts(options.portBase));
381
- for (const result of results) {
382
- console.log(`${result.ok ? "OK " : "FAIL"} ${result.name} 127.0.0.1:${result.port} ${result.method} ${result.path} -> ${result.status ?? result.error}`);
383
- }
384
- return results.every((result) => result.ok) ? 0 : 1;
385
- } catch (error) {
386
- console.error(error.message);
387
- return 1;
388
- }
389
- }
390
-
391
- if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
392
- process.exitCode = await main(process.argv.slice(2));
393
- }
1
+ #!/usr/bin/env node
2
+ // CUELO public installer. Run it explicitly; no npm lifecycle script calls it.
3
+ //
4
+ // node install.mjs [setup] [--home <dir>] [--model <provider/model>] [--role <name>=<provider/model[:effort]>]...
5
+ // node install.mjs start [--home <dir>] [--port-base <n>]
6
+ // node install.mjs health [--port-base <n>]
7
+ //
8
+ // setup: in a source checkout installs dependencies, builds, applies and checks
9
+ // the SDK patches (same steps as ci.yml and bin/prepare-runtime.js); in an
10
+ // installed npm package it only checks the prepared runtime. Then it copies the
11
+ // public harness into the omp profile without replacing anything already there.
12
+ // start: runs the app and the three local sidecars in the foreground.
13
+ // health: asks the four local services whether they answer, without calling a provider.
14
+
15
+ import { spawn, spawnSync } from "node:child_process";
16
+ import fs from "node:fs";
17
+ import { createRequire } from "node:module";
18
+ import os from "node:os";
19
+ import path from "node:path";
20
+ import { fileURLToPath } from "node:url";
21
+
22
+ const ROOT = path.dirname(fileURLToPath(import.meta.url));
23
+ const require = createRequire(path.join(ROOT, "package.json"));
24
+
25
+ /** The model slots the public harness routes Makers to; `--model` sets omp's core `default` separately. */
26
+ export const HARNESS_ROLES = [
27
+ "implSol",
28
+ "implOpus",
29
+ "implDeepSeek",
30
+ "makerHardUiOpus",
31
+ "makerHardCodeOpus",
32
+ "makerHardCodeAstra",
33
+ ];
34
+ const SELECTOR = /^[^/\s:]+\/[^\s:]+(?::[a-z]+)?$/;
35
+
36
+ // The public harness is exactly what package.json `files` ships under this folder, so a
37
+ // source checkout and an installed package copy the same set. Personal config, models and
38
+ // skills are not listed there.
39
+ const HARNESS_PREFIX = "Tools/OMP_Global_Config/agent/";
40
+
41
+ export const SERVICES = [
42
+ // The app answers its own maintenance status without a session or a provider.
43
+ { name: "web", env: "PORT", port: 30141, method: "GET", path: "/api/update-maintenance", expect: 200 },
44
+ // usage-server has no health route; its CORS preflight answers without reading credentials.
45
+ { name: "usage", env: "OMP_USAGE_PORT", port: 30142, method: "OPTIONS", path: "/usage", expect: 204 },
46
+ { name: "btw", env: "OMP_BTW_PORT", port: 30143, method: "GET", path: "/health", expect: 200 },
47
+ { name: "subagent", env: "OMP_SUBAGENT_PORT", port: 30144, method: "GET", path: "/health", expect: 200 },
48
+ ];
49
+
50
+ const MAX_PORT_BASE = 65535 - (SERVICES.length - 1);
51
+
52
+ function parsePort(value, max) {
53
+ if (typeof value !== "string" || !/^\d{1,5}$/.test(value.trim())) return null;
54
+ const port = Number(value.trim());
55
+ return port >= 1 && port <= max ? port : null;
56
+ }
57
+
58
+ /**
59
+ * The ports of one CUELO set. `--port-base n` puts the four services on n..n+3; without it each
60
+ * service keeps its own variable (the ones the app and sidecars read) or its default. Nothing is
61
+ * probed or guessed.
62
+ */
63
+ export function servicePorts(portBase = null, env = process.env) {
64
+ return SERVICES.map((service, index) => ({
65
+ ...service,
66
+ port: portBase !== null ? portBase + index : parsePort(env[service.env], 65535) ?? service.port,
67
+ }));
68
+ }
69
+
70
+ /** The variables that point the app, its sidecar proxy and every sidecar at the same port set. */
71
+ export function portEnv(services) {
72
+ return Object.fromEntries(services.map((service) => [service.env, String(service.port)]));
73
+ }
74
+
75
+ class UsageError extends Error {}
76
+
77
+ export function parseArgs(argv) {
78
+ const args = [...argv];
79
+ const command = args[0] && !args[0].startsWith("--") ? args.shift() : "setup";
80
+ if (!["setup", "start", "health"].includes(command)) throw new UsageError(`unknown command: ${command}`);
81
+ const options = { command, home: null, roles: {}, portBase: null };
82
+ while (args.length > 0) {
83
+ const flag = args.shift();
84
+ const value = args.shift();
85
+ if (value === undefined || value.startsWith("--")) throw new UsageError(`${flag} needs a value`);
86
+ if (flag === "--home" && command !== "health") {
87
+ options.home = path.resolve(value);
88
+ } else if (flag === "--port-base" && command !== "setup") {
89
+ options.portBase = parsePort(value, MAX_PORT_BASE);
90
+ if (options.portBase === null) throw new UsageError(`--port-base takes a number from 1 to ${MAX_PORT_BASE}`);
91
+ } else if (flag === "--model" && command === "setup") {
92
+ options.roles.default = value;
93
+ } else if (flag === "--role" && command === "setup") {
94
+ const at = value.indexOf("=");
95
+ const name = value.slice(0, at);
96
+ if (at <= 0 || !HARNESS_ROLES.includes(name)) {
97
+ throw new UsageError(`--role takes <name>=<provider/model>, name one of ${HARNESS_ROLES.join(", ")}`);
98
+ }
99
+ options.roles[name] = value.slice(at + 1);
100
+ } else {
101
+ throw new UsageError(`unknown option for ${command}: ${flag}`);
102
+ }
103
+ }
104
+ for (const [name, selector] of Object.entries(options.roles)) {
105
+ if (!SELECTOR.test(selector)) throw new UsageError(`${name}: "${selector}" is not <provider>/<model>[:effort]`);
106
+ }
107
+ return options;
108
+ }
109
+
110
+ /**
111
+ * The omp profile a command targets. `--home` points the whole process tree at
112
+ * another home, so the SDK, the sidecars and this installer read the same profile.
113
+ */
114
+ export function resolveProfile(home, env = process.env) {
115
+ if (home) {
116
+ const agentDir = path.join(home, ".omp", "agent");
117
+ return { agentDir, env: { ...env, HOME: home, USERPROFILE: home, PI_CODING_AGENT_DIR: agentDir } };
118
+ }
119
+ return { agentDir: env.PI_CODING_AGENT_DIR || path.join(os.homedir(), ".omp", "agent"), env: { ...env } };
120
+ }
121
+
122
+ /** The harness entries (files or folders, relative to the agent folder) named by package.json `files`. */
123
+ export function harnessEntries(packageFiles) {
124
+ return packageFiles.filter((entry) => typeof entry === "string" && entry.startsWith(HARNESS_PREFIX))
125
+ .map((entry) => entry.slice(HARNESS_PREFIX.length));
126
+ }
127
+
128
+ /** Copies the public harness file by file; an existing profile file is always kept as it is. */
129
+ export function copyHarness(sourceDir, agentDir, entries) {
130
+ const report = { created: [], kept: [] };
131
+ const copy = (rel) => {
132
+ const name = path.basename(rel);
133
+ // Same exclusions as the `!…/**/tests` and `!…/**/*.test.*` entries of `files`; npm
134
+ // never packs a nested node_modules either.
135
+ if (name === "tests" || name === "node_modules" || /\.test\./.test(name)) return;
136
+ const source = path.join(sourceDir, rel);
137
+ if (fs.statSync(source).isDirectory()) {
138
+ for (const child of fs.readdirSync(source)) copy(path.join(rel, child));
139
+ return;
140
+ }
141
+ const target = path.join(agentDir, rel);
142
+ fs.mkdirSync(path.dirname(target), { recursive: true });
143
+ try {
144
+ fs.copyFileSync(source, target, fs.constants.COPYFILE_EXCL);
145
+ report.created.push(rel);
146
+ } catch (error) {
147
+ if (error.code !== "EEXIST") throw error;
148
+ report.kept.push(rel);
149
+ }
150
+ };
151
+ for (const entry of entries) copy(entry);
152
+ return report;
153
+ }
154
+
155
+ /**
156
+ * What a new profile's `config.yml` starts with, so the public harness runs the way it is used:
157
+ * local learning and project-scoped memory, the harness's Maker routing (isolated task runs,
158
+ * its roles instead of the bundled agents) and request budget, and nothing that spends
159
+ * provider requests on its own (`autoContinue`, `autoRetain` stay off). Values equal to the
160
+ * omp defaults are left out.
161
+ */
162
+ export const PROFILE_DEFAULTS = {
163
+ defaultThinkingLevel: "auto",
164
+ autolearn: { enabled: true, autoContinue: false },
165
+ memory: { backend: "mnemopi" },
166
+ mnemopi: { scoping: "per-project-tagged", embeddingVariant: "multilingual", autoRetain: false },
167
+ task: {
168
+ softRequestBudget: 400,
169
+ maxConcurrency: 8,
170
+ eager: "preferred",
171
+ maxEffort: "xhigh",
172
+ isolation: { enabled: true },
173
+ disabledAgents: ["scout", "sonic", "task", "reviewer", "security-reviewer"],
174
+ },
175
+ };
176
+
177
+ /**
178
+ * Creates `config.yml` for a profile that has none: the defaults above plus exactly the model
179
+ * roles the user named. An existing file is never edited; the report lists the roles it lacks.
180
+ */
181
+ export function createProfileConfig(agentDir, roles) {
182
+ const YAML = require("yaml");
183
+ const configPath = path.join(agentDir, "config.yml");
184
+ if (fs.existsSync(configPath)) {
185
+ const assigned = YAML.parse(fs.readFileSync(configPath, "utf8"))?.modelRoles ?? {};
186
+ return {
187
+ configPath,
188
+ written: false,
189
+ ignored: Object.keys(roles),
190
+ missing: ["default", ...HARNESS_ROLES].filter((name) => typeof assigned[name] !== "string"),
191
+ };
192
+ }
193
+ fs.mkdirSync(agentDir, { recursive: true });
194
+ const config = Object.keys(roles).length > 0 ? { ...PROFILE_DEFAULTS, modelRoles: roles } : PROFILE_DEFAULTS;
195
+ const body = [
196
+ "# Written by CUELO install.mjs for a new profile. Edit freely; setup never rewrites this file.",
197
+ YAML.stringify(config),
198
+ ].join("\n");
199
+ fs.writeFileSync(configPath, body, { flag: "wx" });
200
+ return {
201
+ configPath,
202
+ written: true,
203
+ ignored: [],
204
+ missing: ["default", ...HARNESS_ROLES].filter((name) => roles[name] === undefined),
205
+ };
206
+ }
207
+
208
+ function run(command, args, options) {
209
+ console.log(`> ${[command, ...args].join(" ")}`);
210
+ const result = spawnSync(command, args, { stdio: "inherit", ...options });
211
+ if (result.error || result.status !== 0) {
212
+ throw new Error(`${path.basename(command)} ${args[0] ?? ""} failed: ${result.error?.message ?? `exit ${result.status}`}`);
213
+ }
214
+ }
215
+
216
+ function bunPath() {
217
+ const { resolveBunPath, getMissingBunMessage } = require("./bin/runtime.js");
218
+ const bun = resolveBunPath();
219
+ if (!bun) throw new Error(getMissingBunMessage());
220
+ return bun;
221
+ }
222
+
223
+ function prepareRuntime() {
224
+ const node = process.versions.bun ? "node" : process.execPath;
225
+ const sourceCheckout = fs.existsSync(path.join(ROOT, "bun.lock")) && fs.existsSync(path.join(ROOT, "app", "layout.tsx"));
226
+ if (!sourceCheckout) {
227
+ // An installed package ships its production build and patched SDK; only confirm them.
228
+ run(node, [path.join(ROOT, "bin", "prepare-runtime.js"), "--check"], { cwd: ROOT });
229
+ return;
230
+ }
231
+ // Same isolated home as ci.yml and the setup runner: the build otherwise walks the real
232
+ // profile (protected folders fail with EPERM) and could read the user's omp settings.
233
+ // `--home` names where the harness goes, never what the build sees.
234
+ const buildHome = path.join(ROOT, ".runtime-patch-home");
235
+ fs.mkdirSync(buildHome, { recursive: true });
236
+ const buildRoot = path.parse(buildHome).root;
237
+ const { PI_CODING_AGENT_DIR: _profile, ...inherited } = process.env;
238
+ const buildEnv = {
239
+ ...inherited,
240
+ HOME: buildHome,
241
+ USERPROFILE: buildHome,
242
+ HOMEDRIVE: buildRoot.replace(/[\\/]+$/, ""),
243
+ HOMEPATH: buildHome.slice(buildRoot.length - 1),
244
+ NEXT_TELEMETRY_DISABLED: "1",
245
+ };
246
+ const bun = bunPath();
247
+ run(bun, ["install", "--frozen-lockfile"], { cwd: ROOT, env: buildEnv });
248
+ // The native runtime patch edits the production server chunks, so it runs after the build.
249
+ run(bun, ["run", "build"], { cwd: ROOT, env: buildEnv });
250
+ const env = {
251
+ ...buildEnv,
252
+ OMP_CORE_PATCH_TARGET: path.join(ROOT, "node_modules", "@oh-my-pi", "pi-coding-agent"),
253
+ };
254
+ const patches = [
255
+ [path.join(ROOT, "Tools", "CUELO_Setup", "files", "native-runtime-patch.js"), ["--target", ROOT]],
256
+ [path.join(ROOT, "Tools", "OMP_Global_Config", "patches", "apply-core-patch.mjs"), []],
257
+ [path.join(ROOT, "Tools", "OMP_Global_Config", "patches", "apply-notices.mjs"), []],
258
+ ];
259
+ for (const [script, args] of patches) run(node, [script, ...args], { cwd: ROOT, env });
260
+ for (const [script, args] of patches) run(node, [script, ...args, "--check"], { cwd: ROOT, env });
261
+ }
262
+
263
+ function setup(options) {
264
+ prepareRuntime();
265
+ const { agentDir } = resolveProfile(options.home);
266
+ const packageFiles = JSON.parse(fs.readFileSync(path.join(ROOT, "package.json"), "utf8")).files ?? [];
267
+ const harness = copyHarness(path.join(ROOT, "Tools", "OMP_Global_Config", "agent"), agentDir, harnessEntries(packageFiles));
268
+ console.log(`Harness: ${harness.created.length} files added to ${agentDir}, ${harness.kept.length} existing files kept unchanged.`);
269
+ const roles = createProfileConfig(agentDir, options.roles);
270
+ if (roles.written) console.log(`Profile config: wrote ${roles.configPath}.`);
271
+ if (roles.ignored.length > 0) console.log(`Profile config: ${roles.configPath} already exists and was not changed; ignored ${roles.ignored.join(", ")}.`);
272
+ if (roles.missing.length > 0) {
273
+ console.log(`Model roles not set: ${roles.missing.join(", ")}. Choose your own models in CUELO Settings > Model roles.`);
274
+ }
275
+ console.log("Next: run `node install.mjs start`, open the address it prints, and sign in to your providers under Settings > Models.");
276
+ }
277
+
278
+ async function portAnswers(port) {
279
+ try {
280
+ await fetch(`http://127.0.0.1:${port}/`, { method: "HEAD", signal: AbortSignal.timeout(1500) });
281
+ return true;
282
+ } catch {
283
+ return false;
284
+ }
285
+ }
286
+
287
+ async function start(options) {
288
+ if (!fs.existsSync(path.join(ROOT, ".next", "BUILD_ID"))) throw new Error("No production build found. Run `node install.mjs setup` first.");
289
+ const { env } = resolveProfile(options.home);
290
+ const services = servicePorts(options.portBase, env);
291
+ const busy = [];
292
+ for (const service of services) if (await portAnswers(service.port)) busy.push(`${service.name}:${service.port}`);
293
+ if (busy.length > 0) throw new Error(`Already in use: ${busy.join(", ")}. Stop the running CUELO first or pick another --port-base.`);
294
+
295
+ const bun = bunPath();
296
+ const node = process.versions.bun ? "node" : process.execPath;
297
+ const files = path.join(ROOT, "Tools", "CUELO_Setup", "files");
298
+ const childEnv = { ...env, ...portEnv(services), CUELO_DIR: ROOT };
299
+ const commands = [
300
+ // The app-only launcher; `--no-open` leaves the browser to the user, and the explicit loopback
301
+ // host wins over an inherited CUELO_HOSTNAME so this never listens beyond the machine.
302
+ ["web", bun, [path.join(ROOT, "bin", "cuelo.js"), "--no-open", "--hostname", "127.0.0.1"]],
303
+ ["usage", bun, [path.join(files, "usage-server.js")]],
304
+ ["btw", bun, [path.join(files, "btw-server.js")]],
305
+ ["subagent", node, [path.join(files, "subagent-server.js")]],
306
+ ];
307
+ const children = commands.map(([name, command, args]) => {
308
+ const child = spawn(command, args, { cwd: ROOT, env: childEnv, stdio: ["ignore", "pipe", "pipe"] });
309
+ for (const stream of [child.stdout, child.stderr]) {
310
+ let pending = "";
311
+ stream.setEncoding("utf8");
312
+ stream.on("data", (chunk) => {
313
+ const lines = (pending + chunk).split(/\r?\n/);
314
+ pending = lines.pop() ?? "";
315
+ for (const line of lines) console.log(`[${name}] ${line}`);
316
+ });
317
+ }
318
+ return { name, child };
319
+ });
320
+ const web = services.find((service) => service.name === "web");
321
+ console.log(`CUELO is starting at http://127.0.0.1:${web.port} . Press Ctrl+C to stop all four services.`);
322
+
323
+ let stopping = false;
324
+ const stopAll = () => {
325
+ stopping = true;
326
+ for (const { child } of children) if (child.exitCode === null) child.kill();
327
+ };
328
+ process.on("SIGINT", stopAll);
329
+ process.on("SIGTERM", stopAll);
330
+ const exits = await Promise.all(children.map(({ name, child }) => new Promise((resolve) => {
331
+ child.on("exit", (code, signal) => {
332
+ if (!stopping) {
333
+ console.error(`[${name}] exited (${signal ?? `code ${code}`}); stopping the other services.`);
334
+ stopAll();
335
+ resolve(1);
336
+ return;
337
+ }
338
+ resolve(0);
339
+ });
340
+ child.on("error", (error) => {
341
+ console.error(`[${name}] could not start: ${error.message}`);
342
+ stopAll();
343
+ resolve(1);
344
+ });
345
+ })));
346
+ return exits.some((code) => code !== 0) ? 1 : 0;
347
+ }
348
+
349
+ /** One request per service; nothing here authenticates or reaches a model provider. */
350
+ export async function checkHealth(services = servicePorts(), timeoutMs = 3000) {
351
+ return Promise.all(services.map(async (service) => {
352
+ try {
353
+ const response = await fetch(`http://127.0.0.1:${service.port}${service.path}`, {
354
+ method: service.method,
355
+ signal: AbortSignal.timeout(timeoutMs),
356
+ });
357
+ return { ...service, ok: response.status === service.expect, status: response.status };
358
+ } catch (error) {
359
+ return { ...service, ok: false, status: null, error: error.message };
360
+ }
361
+ }));
362
+ }
363
+
364
+ async function main(argv) {
365
+ let options;
366
+ try {
367
+ options = parseArgs(argv);
368
+ } catch (error) {
369
+ if (!(error instanceof UsageError)) throw error;
370
+ console.error(error.message);
371
+ console.error("Usage: node install.mjs [setup|start|health] [--home <dir>] [--model <provider/model>] [--role <name>=<provider/model[:effort]>] [--port-base <n>]");
372
+ return 2;
373
+ }
374
+ try {
375
+ if (options.command === "setup") {
376
+ setup(options);
377
+ return 0;
378
+ }
379
+ if (options.command === "start") return await start(options);
380
+ const results = await checkHealth(servicePorts(options.portBase));
381
+ for (const result of results) {
382
+ console.log(`${result.ok ? "OK " : "FAIL"} ${result.name} 127.0.0.1:${result.port} ${result.method} ${result.path} -> ${result.status ?? result.error}`);
383
+ }
384
+ return results.every((result) => result.ok) ? 0 : 1;
385
+ } catch (error) {
386
+ console.error(error.message);
387
+ return 1;
388
+ }
389
+ }
390
+
391
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
392
+ process.exitCode = await main(process.argv.slice(2));
393
+ }