cuelo 0.5.0

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 (967) hide show
  1. package/.next/BUILD_ID +1 -0
  2. package/.next/app-path-routes-manifest.json +72 -0
  3. package/.next/build-manifest.json +20 -0
  4. package/.next/diagnostics/build-diagnostics.json +6 -0
  5. package/.next/diagnostics/framework.json +1 -0
  6. package/.next/export-marker.json +6 -0
  7. package/.next/images-manifest.json +68 -0
  8. package/.next/next-minimal-server.js.nft.json +1 -0
  9. package/.next/next-server.js.nft.json +1 -0
  10. package/.next/package.json +1 -0
  11. package/.next/prerender-manifest.json +138 -0
  12. package/.next/react-loadable-manifest.json +2370 -0
  13. package/.next/required-server-files.js +350 -0
  14. package/.next/required-server-files.json +350 -0
  15. package/.next/routes-manifest.json +537 -0
  16. package/.next/server/app/_global-error/page.js +32 -0
  17. package/.next/server/app/_global-error/page.js.nft.json +1 -0
  18. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
  19. package/.next/server/app/_global-error.html +1 -0
  20. package/.next/server/app/_global-error.meta +16 -0
  21. package/.next/server/app/_global-error.rsc +14 -0
  22. package/.next/server/app/_global-error.segments/_full.segment.rsc +14 -0
  23. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +5 -0
  24. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +5 -0
  25. package/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
  26. package/.next/server/app/_global-error.segments/_index.segment.rsc +5 -0
  27. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
  28. package/.next/server/app/_not-found/page.js +2 -0
  29. package/.next/server/app/_not-found/page.js.nft.json +1 -0
  30. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  31. package/.next/server/app/_not-found.html +1 -0
  32. package/.next/server/app/_not-found.meta +16 -0
  33. package/.next/server/app/_not-found.rsc +18 -0
  34. package/.next/server/app/_not-found.segments/_full.segment.rsc +18 -0
  35. package/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
  36. package/.next/server/app/_not-found.segments/_index.segment.rsc +7 -0
  37. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
  38. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +5 -0
  39. package/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -0
  40. package/.next/server/app/api/agent/[id]/account/route.js +1 -0
  41. package/.next/server/app/api/agent/[id]/account/route.js.nft.json +1 -0
  42. package/.next/server/app/api/agent/[id]/account/route_client-reference-manifest.js +1 -0
  43. package/.next/server/app/api/agent/[id]/bash-output/route.js +1 -0
  44. package/.next/server/app/api/agent/[id]/bash-output/route.js.nft.json +1 -0
  45. package/.next/server/app/api/agent/[id]/bash-output/route_client-reference-manifest.js +1 -0
  46. package/.next/server/app/api/agent/[id]/events/route.js +3 -0
  47. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -0
  48. package/.next/server/app/api/agent/[id]/events/route_client-reference-manifest.js +1 -0
  49. package/.next/server/app/api/agent/[id]/route.js +1 -0
  50. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -0
  51. package/.next/server/app/api/agent/[id]/route_client-reference-manifest.js +1 -0
  52. package/.next/server/app/api/agent/new/route.js +1 -0
  53. package/.next/server/app/api/agent/new/route.js.nft.json +1 -0
  54. package/.next/server/app/api/agent/new/route_client-reference-manifest.js +1 -0
  55. package/.next/server/app/api/agent/running/route.js +1 -0
  56. package/.next/server/app/api/agent/running/route.js.nft.json +1 -0
  57. package/.next/server/app/api/agent/running/route_client-reference-manifest.js +1 -0
  58. package/.next/server/app/api/auth/all-providers/route.js +1 -0
  59. package/.next/server/app/api/auth/all-providers/route.js.nft.json +1 -0
  60. package/.next/server/app/api/auth/all-providers/route_client-reference-manifest.js +1 -0
  61. package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -0
  62. package/.next/server/app/api/auth/api-key/[provider]/route.js.nft.json +1 -0
  63. package/.next/server/app/api/auth/api-key/[provider]/route_client-reference-manifest.js +1 -0
  64. package/.next/server/app/api/auth/login/[provider]/route.js +3 -0
  65. package/.next/server/app/api/auth/login/[provider]/route.js.nft.json +1 -0
  66. package/.next/server/app/api/auth/login/[provider]/route_client-reference-manifest.js +1 -0
  67. package/.next/server/app/api/auth/logout/[provider]/route.js +1 -0
  68. package/.next/server/app/api/auth/logout/[provider]/route.js.nft.json +1 -0
  69. package/.next/server/app/api/auth/logout/[provider]/route_client-reference-manifest.js +1 -0
  70. package/.next/server/app/api/auth/providers/route.js +1 -0
  71. package/.next/server/app/api/auth/providers/route.js.nft.json +1 -0
  72. package/.next/server/app/api/auth/providers/route_client-reference-manifest.js +1 -0
  73. package/.next/server/app/api/cwd/browse/route.js +1 -0
  74. package/.next/server/app/api/cwd/browse/route.js.nft.json +1 -0
  75. package/.next/server/app/api/cwd/browse/route_client-reference-manifest.js +1 -0
  76. package/.next/server/app/api/cwd/validate/route.js +1 -0
  77. package/.next/server/app/api/cwd/validate/route.js.nft.json +1 -0
  78. package/.next/server/app/api/cwd/validate/route_client-reference-manifest.js +1 -0
  79. package/.next/server/app/api/default-cwd/route.js +1 -0
  80. package/.next/server/app/api/default-cwd/route.js.nft.json +1 -0
  81. package/.next/server/app/api/default-cwd/route_client-reference-manifest.js +1 -0
  82. package/.next/server/app/api/display-settings/route.js +1 -0
  83. package/.next/server/app/api/display-settings/route.js.nft.json +1 -0
  84. package/.next/server/app/api/display-settings/route_client-reference-manifest.js +1 -0
  85. package/.next/server/app/api/document-text/route.js +4 -0
  86. package/.next/server/app/api/document-text/route.js.nft.json +1 -0
  87. package/.next/server/app/api/document-text/route_client-reference-manifest.js +1 -0
  88. package/.next/server/app/api/experiments/route.js +1 -0
  89. package/.next/server/app/api/experiments/route.js.nft.json +1 -0
  90. package/.next/server/app/api/experiments/route_client-reference-manifest.js +1 -0
  91. package/.next/server/app/api/file-index/route.js +1 -0
  92. package/.next/server/app/api/file-index/route.js.nft.json +1 -0
  93. package/.next/server/app/api/file-index/route_client-reference-manifest.js +1 -0
  94. package/.next/server/app/api/files/[...path]/route.js +49 -0
  95. package/.next/server/app/api/files/[...path]/route.js.nft.json +1 -0
  96. package/.next/server/app/api/files/[...path]/route_client-reference-manifest.js +1 -0
  97. package/.next/server/app/api/git/diff/route.js +6 -0
  98. package/.next/server/app/api/git/diff/route.js.nft.json +1 -0
  99. package/.next/server/app/api/git/diff/route_client-reference-manifest.js +1 -0
  100. package/.next/server/app/api/git/status/route.js +6 -0
  101. package/.next/server/app/api/git/status/route.js.nft.json +1 -0
  102. package/.next/server/app/api/git/status/route_client-reference-manifest.js +1 -0
  103. package/.next/server/app/api/gpt6/handles/route.js +1 -0
  104. package/.next/server/app/api/gpt6/handles/route.js.nft.json +1 -0
  105. package/.next/server/app/api/gpt6/handles/route_client-reference-manifest.js +1 -0
  106. package/.next/server/app/api/gpt6/mcp/route.js +2 -0
  107. package/.next/server/app/api/gpt6/mcp/route.js.nft.json +1 -0
  108. package/.next/server/app/api/gpt6/mcp/route_client-reference-manifest.js +1 -0
  109. package/.next/server/app/api/gpt6/reply/route.js +1 -0
  110. package/.next/server/app/api/gpt6/reply/route.js.nft.json +1 -0
  111. package/.next/server/app/api/gpt6/reply/route_client-reference-manifest.js +1 -0
  112. package/.next/server/app/api/gpt6/token/route.js +1 -0
  113. package/.next/server/app/api/gpt6/token/route.js.nft.json +1 -0
  114. package/.next/server/app/api/gpt6/token/route_client-reference-manifest.js +1 -0
  115. package/.next/server/app/api/gpt6/web6-session/route.js +1 -0
  116. package/.next/server/app/api/gpt6/web6-session/route.js.nft.json +1 -0
  117. package/.next/server/app/api/gpt6/web6-session/route_client-reference-manifest.js +1 -0
  118. package/.next/server/app/api/home/route.js +1 -0
  119. package/.next/server/app/api/home/route.js.nft.json +1 -0
  120. package/.next/server/app/api/home/route_client-reference-manifest.js +1 -0
  121. package/.next/server/app/api/live/call/[callId]/route.js +1 -0
  122. package/.next/server/app/api/live/call/[callId]/route.js.nft.json +1 -0
  123. package/.next/server/app/api/live/call/[callId]/route_client-reference-manifest.js +1 -0
  124. package/.next/server/app/api/live/events/route.js +3 -0
  125. package/.next/server/app/api/live/events/route.js.nft.json +1 -0
  126. package/.next/server/app/api/live/events/route_client-reference-manifest.js +1 -0
  127. package/.next/server/app/api/live/offer/route.js +1 -0
  128. package/.next/server/app/api/live/offer/route.js.nft.json +1 -0
  129. package/.next/server/app/api/live/offer/route_client-reference-manifest.js +1 -0
  130. package/.next/server/app/api/live/voices/route.js +1 -0
  131. package/.next/server/app/api/live/voices/route.js.nft.json +1 -0
  132. package/.next/server/app/api/live/voices/route_client-reference-manifest.js +1 -0
  133. package/.next/server/app/api/mcp/route.js +2 -0
  134. package/.next/server/app/api/mcp/route.js.nft.json +1 -0
  135. package/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -0
  136. package/.next/server/app/api/model-roles/route.js +1 -0
  137. package/.next/server/app/api/model-roles/route.js.nft.json +1 -0
  138. package/.next/server/app/api/model-roles/route_client-reference-manifest.js +1 -0
  139. package/.next/server/app/api/models/route.js +1 -0
  140. package/.next/server/app/api/models/route.js.nft.json +1 -0
  141. package/.next/server/app/api/models/route_client-reference-manifest.js +1 -0
  142. package/.next/server/app/api/models-config/catalog/route.js +1 -0
  143. package/.next/server/app/api/models-config/catalog/route.js.nft.json +1 -0
  144. package/.next/server/app/api/models-config/catalog/route_client-reference-manifest.js +1 -0
  145. package/.next/server/app/api/models-config/discover/route.js +1 -0
  146. package/.next/server/app/api/models-config/discover/route.js.nft.json +1 -0
  147. package/.next/server/app/api/models-config/discover/route_client-reference-manifest.js +1 -0
  148. package/.next/server/app/api/models-config/route.js +25 -0
  149. package/.next/server/app/api/models-config/route.js.nft.json +1 -0
  150. package/.next/server/app/api/models-config/route_client-reference-manifest.js +1 -0
  151. package/.next/server/app/api/models-config/test/route.js +1 -0
  152. package/.next/server/app/api/models-config/test/route.js.nft.json +1 -0
  153. package/.next/server/app/api/models-config/test/route_client-reference-manifest.js +1 -0
  154. package/.next/server/app/api/plugins/route.js +1 -0
  155. package/.next/server/app/api/plugins/route.js.nft.json +1 -0
  156. package/.next/server/app/api/plugins/route_client-reference-manifest.js +1 -0
  157. package/.next/server/app/api/project-trust/route.js +1 -0
  158. package/.next/server/app/api/project-trust/route.js.nft.json +1 -0
  159. package/.next/server/app/api/project-trust/route_client-reference-manifest.js +1 -0
  160. package/.next/server/app/api/projects/route.js +2 -0
  161. package/.next/server/app/api/projects/route.js.nft.json +1 -0
  162. package/.next/server/app/api/projects/route_client-reference-manifest.js +1 -0
  163. package/.next/server/app/api/runs/[runId]/route.js +1 -0
  164. package/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -0
  165. package/.next/server/app/api/runs/[runId]/route_client-reference-manifest.js +1 -0
  166. package/.next/server/app/api/runs/route.js +1 -0
  167. package/.next/server/app/api/runs/route.js.nft.json +1 -0
  168. package/.next/server/app/api/runs/route_client-reference-manifest.js +1 -0
  169. package/.next/server/app/api/sessions/[id]/auto-name/route.js +1 -0
  170. package/.next/server/app/api/sessions/[id]/auto-name/route.js.nft.json +1 -0
  171. package/.next/server/app/api/sessions/[id]/auto-name/route_client-reference-manifest.js +1 -0
  172. package/.next/server/app/api/sessions/[id]/context/route.js +1 -0
  173. package/.next/server/app/api/sessions/[id]/context/route.js.nft.json +1 -0
  174. package/.next/server/app/api/sessions/[id]/context/route_client-reference-manifest.js +1 -0
  175. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +1 -0
  176. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js.nft.json +1 -0
  177. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route_client-reference-manifest.js +1 -0
  178. package/.next/server/app/api/sessions/[id]/export/route.js +1 -0
  179. package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -0
  180. package/.next/server/app/api/sessions/[id]/export/route_client-reference-manifest.js +1 -0
  181. package/.next/server/app/api/sessions/[id]/route.js +1 -0
  182. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -0
  183. package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -0
  184. package/.next/server/app/api/sessions/[id]/state/route.js +1 -0
  185. package/.next/server/app/api/sessions/[id]/state/route.js.nft.json +1 -0
  186. package/.next/server/app/api/sessions/[id]/state/route_client-reference-manifest.js +1 -0
  187. package/.next/server/app/api/sessions/route.js +1 -0
  188. package/.next/server/app/api/sessions/route.js.nft.json +1 -0
  189. package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -0
  190. package/.next/server/app/api/settings/route.js +1 -0
  191. package/.next/server/app/api/settings/route.js.nft.json +1 -0
  192. package/.next/server/app/api/settings/route_client-reference-manifest.js +1 -0
  193. package/.next/server/app/api/sidecars/[service]/[...path]/route.js +1 -0
  194. package/.next/server/app/api/sidecars/[service]/[...path]/route.js.nft.json +1 -0
  195. package/.next/server/app/api/sidecars/[service]/[...path]/route_client-reference-manifest.js +1 -0
  196. package/.next/server/app/api/skills/check/route.js +1 -0
  197. package/.next/server/app/api/skills/check/route.js.nft.json +1 -0
  198. package/.next/server/app/api/skills/check/route_client-reference-manifest.js +1 -0
  199. package/.next/server/app/api/skills/install/route.js +2 -0
  200. package/.next/server/app/api/skills/install/route.js.nft.json +1 -0
  201. package/.next/server/app/api/skills/install/route_client-reference-manifest.js +1 -0
  202. package/.next/server/app/api/skills/route.js +6 -0
  203. package/.next/server/app/api/skills/route.js.nft.json +1 -0
  204. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -0
  205. package/.next/server/app/api/skills/search/route.js +1 -0
  206. package/.next/server/app/api/skills/search/route.js.nft.json +1 -0
  207. package/.next/server/app/api/skills/search/route_client-reference-manifest.js +1 -0
  208. package/.next/server/app/api/skills/update/route.js +1 -0
  209. package/.next/server/app/api/skills/update/route.js.nft.json +1 -0
  210. package/.next/server/app/api/skills/update/route_client-reference-manifest.js +1 -0
  211. package/.next/server/app/api/theme/route.js +1 -0
  212. package/.next/server/app/api/theme/route.js.nft.json +1 -0
  213. package/.next/server/app/api/theme/route_client-reference-manifest.js +1 -0
  214. package/.next/server/app/api/update-maintenance/route.js +556 -0
  215. package/.next/server/app/api/update-maintenance/route.js.nft.json +1 -0
  216. package/.next/server/app/api/update-maintenance/route_client-reference-manifest.js +1 -0
  217. package/.next/server/app/api/updates/route.js +1 -0
  218. package/.next/server/app/api/updates/route.js.nft.json +1 -0
  219. package/.next/server/app/api/updates/route_client-reference-manifest.js +1 -0
  220. package/.next/server/app/api/web-access/recovery/route.js +1 -0
  221. package/.next/server/app/api/web-access/recovery/route.js.nft.json +1 -0
  222. package/.next/server/app/api/web-access/recovery/route_client-reference-manifest.js +1 -0
  223. package/.next/server/app/api/web-access/route.js +1 -0
  224. package/.next/server/app/api/web-access/route.js.nft.json +1 -0
  225. package/.next/server/app/api/web-access/route_client-reference-manifest.js +1 -0
  226. package/.next/server/app/api/web6/consults/route.js +1 -0
  227. package/.next/server/app/api/web6/consults/route.js.nft.json +1 -0
  228. package/.next/server/app/api/web6/consults/route_client-reference-manifest.js +1 -0
  229. package/.next/server/app/api/worktrees/route.js +1 -0
  230. package/.next/server/app/api/worktrees/route.js.nft.json +1 -0
  231. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -0
  232. package/.next/server/app/favicon.ico/route.js +1 -0
  233. package/.next/server/app/favicon.ico/route.js.nft.json +1 -0
  234. package/.next/server/app/favicon.ico.body +0 -0
  235. package/.next/server/app/favicon.ico.meta +1 -0
  236. package/.next/server/app/index.html +1 -0
  237. package/.next/server/app/index.meta +14 -0
  238. package/.next/server/app/index.rsc +20 -0
  239. package/.next/server/app/index.segments/__PAGE__.segment.rsc +9 -0
  240. package/.next/server/app/index.segments/_full.segment.rsc +20 -0
  241. package/.next/server/app/index.segments/_head.segment.rsc +6 -0
  242. package/.next/server/app/index.segments/_index.segment.rsc +7 -0
  243. package/.next/server/app/index.segments/_tree.segment.rsc +5 -0
  244. package/.next/server/app/manifest.webmanifest/route.js +16 -0
  245. package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -0
  246. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -0
  247. package/.next/server/app/page.js +22 -0
  248. package/.next/server/app/page.js.nft.json +1 -0
  249. package/.next/server/app/page_client-reference-manifest.js +1 -0
  250. package/.next/server/app/recover/page.js +2 -0
  251. package/.next/server/app/recover/page.js.nft.json +1 -0
  252. package/.next/server/app/recover/page_client-reference-manifest.js +1 -0
  253. package/.next/server/app/recover.html +1 -0
  254. package/.next/server/app/recover.meta +15 -0
  255. package/.next/server/app/recover.rsc +23 -0
  256. package/.next/server/app/recover.segments/_full.segment.rsc +23 -0
  257. package/.next/server/app/recover.segments/_head.segment.rsc +6 -0
  258. package/.next/server/app/recover.segments/_index.segment.rsc +7 -0
  259. package/.next/server/app/recover.segments/_tree.segment.rsc +4 -0
  260. package/.next/server/app/recover.segments/recover/__PAGE__.segment.rsc +10 -0
  261. package/.next/server/app/recover.segments/recover.segment.rsc +5 -0
  262. package/.next/server/app-paths-manifest.json +72 -0
  263. package/.next/server/chunks/11.js +1 -0
  264. package/.next/server/chunks/1286.js +1 -0
  265. package/.next/server/chunks/1412.js +38 -0
  266. package/.next/server/chunks/1517.js +19 -0
  267. package/.next/server/chunks/1605.js +1 -0
  268. package/.next/server/chunks/169.js +1 -0
  269. package/.next/server/chunks/18.js +86 -0
  270. package/.next/server/chunks/1813.js +1 -0
  271. package/.next/server/chunks/2022.js +1 -0
  272. package/.next/server/chunks/2156.js +1 -0
  273. package/.next/server/chunks/2157.js +1 -0
  274. package/.next/server/chunks/2325.js +82 -0
  275. package/.next/server/chunks/2651.js +2 -0
  276. package/.next/server/chunks/2838.js +1 -0
  277. package/.next/server/chunks/2897.js +79 -0
  278. package/.next/server/chunks/2958.js +90 -0
  279. package/.next/server/chunks/319.js +45 -0
  280. package/.next/server/chunks/3227.js +1 -0
  281. package/.next/server/chunks/3229.js +2 -0
  282. package/.next/server/chunks/3266.js +1 -0
  283. package/.next/server/chunks/3379.js +1 -0
  284. package/.next/server/chunks/3428.js +32 -0
  285. package/.next/server/chunks/3479.js +1 -0
  286. package/.next/server/chunks/367.js +115 -0
  287. package/.next/server/chunks/3698.js +93 -0
  288. package/.next/server/chunks/3709.js +148 -0
  289. package/.next/server/chunks/3759.js +34 -0
  290. package/.next/server/chunks/4107.js +62 -0
  291. package/.next/server/chunks/4741.js +20 -0
  292. package/.next/server/chunks/4755.js +153 -0
  293. package/.next/server/chunks/5002.js +1 -0
  294. package/.next/server/chunks/5112.js +1 -0
  295. package/.next/server/chunks/5289.js +8 -0
  296. package/.next/server/chunks/5318.js +1 -0
  297. package/.next/server/chunks/5452.js +23 -0
  298. package/.next/server/chunks/5453.js +1 -0
  299. package/.next/server/chunks/5582.js +20 -0
  300. package/.next/server/chunks/5749.js +27 -0
  301. package/.next/server/chunks/5782.js +36 -0
  302. package/.next/server/chunks/6163.js +104 -0
  303. package/.next/server/chunks/6169.js +64 -0
  304. package/.next/server/chunks/6208.js +172 -0
  305. package/.next/server/chunks/6399.js +24 -0
  306. package/.next/server/chunks/6429.js +10 -0
  307. package/.next/server/chunks/6496.js +1 -0
  308. package/.next/server/chunks/6775.js +6 -0
  309. package/.next/server/chunks/6823.js +215 -0
  310. package/.next/server/chunks/6888.js +1 -0
  311. package/.next/server/chunks/7245.js +77 -0
  312. package/.next/server/chunks/7307.js +1 -0
  313. package/.next/server/chunks/7372.js +287 -0
  314. package/.next/server/chunks/7384.js +226 -0
  315. package/.next/server/chunks/7516.js +1 -0
  316. package/.next/server/chunks/7531.js +24 -0
  317. package/.next/server/chunks/7591.js +1 -0
  318. package/.next/server/chunks/7755.js +138 -0
  319. package/.next/server/chunks/7916.js +1 -0
  320. package/.next/server/chunks/8078.js +94 -0
  321. package/.next/server/chunks/8253.js +41 -0
  322. package/.next/server/chunks/8635.js +1 -0
  323. package/.next/server/chunks/8688.js +1 -0
  324. package/.next/server/chunks/877.js +1 -0
  325. package/.next/server/chunks/8872.js +1 -0
  326. package/.next/server/chunks/9006.js +1 -0
  327. package/.next/server/chunks/9018.js +1 -0
  328. package/.next/server/chunks/9047.js +1 -0
  329. package/.next/server/chunks/9108.js +1 -0
  330. package/.next/server/chunks/9280.js +256 -0
  331. package/.next/server/chunks/9419.js +1 -0
  332. package/.next/server/chunks/9430.js +1 -0
  333. package/.next/server/chunks/9586.js +1 -0
  334. package/.next/server/chunks/9775.js +1 -0
  335. package/.next/server/chunks/9910.js +1 -0
  336. package/.next/server/chunks/992.js +1 -0
  337. package/.next/server/chunks/9926.js +1 -0
  338. package/.next/server/functions-config-manifest.json +25 -0
  339. package/.next/server/interception-route-rewrite-manifest.js +1 -0
  340. package/.next/server/middleware-build-manifest.js +1 -0
  341. package/.next/server/middleware-manifest.json +6 -0
  342. package/.next/server/middleware-react-loadable-manifest.js +1 -0
  343. package/.next/server/middleware.js +45 -0
  344. package/.next/server/middleware.js.nft.json +1 -0
  345. package/.next/server/next-font-manifest.js +1 -0
  346. package/.next/server/next-font-manifest.json +1 -0
  347. package/.next/server/pages/404.html +1 -0
  348. package/.next/server/pages/500.html +1 -0
  349. package/.next/server/pages-manifest.json +4 -0
  350. package/.next/server/prefetch-hints.json +1 -0
  351. package/.next/server/server-reference-manifest.js +1 -0
  352. package/.next/server/server-reference-manifest.json +1 -0
  353. package/.next/server/webpack-runtime.js +1 -0
  354. package/.next/static/MvC-CM1U-UMEzpaGIsCuQ/_buildManifest.js +1 -0
  355. package/.next/static/MvC-CM1U-UMEzpaGIsCuQ/_ssgManifest.js +1 -0
  356. package/.next/static/chunks/1213.e5c6e70a79b5f7e6.js +24 -0
  357. package/.next/static/chunks/1519.2f596e5f5af9ef57.js +62 -0
  358. package/.next/static/chunks/1966.b8f83f7ba376c962.js +1 -0
  359. package/.next/static/chunks/1974.885c9a133b86d8a4.js +32 -0
  360. package/.next/static/chunks/2280.6a7f540787704698.js +1 -0
  361. package/.next/static/chunks/2521.7f745f50d30076e7.js +77 -0
  362. package/.next/static/chunks/2585.4d6aa847c780c666.js +1 -0
  363. package/.next/static/chunks/2589.1aad68c09021b1ac.js +1 -0
  364. package/.next/static/chunks/2600.45ba17a0f756fc31.js +1 -0
  365. package/.next/static/chunks/2619.9aac8983f30c7c8a.js +1 -0
  366. package/.next/static/chunks/26d302b2.b77b53a34ca944aa.js +122 -0
  367. package/.next/static/chunks/2768.305914f7900745b6.js +1 -0
  368. package/.next/static/chunks/3016.406e568aa95ff867.js +1 -0
  369. package/.next/static/chunks/3022.972047558a20553a.js +172 -0
  370. package/.next/static/chunks/3064.3a2a1e7cd4fdca5f.js +1 -0
  371. package/.next/static/chunks/3174.03fbed7b7d7a8256.js +1 -0
  372. package/.next/static/chunks/3189.b048866768087750.js +1 -0
  373. package/.next/static/chunks/3217.1a053843c58b70b5.js +24 -0
  374. package/.next/static/chunks/3308.34ea31e24088c85f.js +74 -0
  375. package/.next/static/chunks/331.fc5d78e1e91daf43.js +1 -0
  376. package/.next/static/chunks/3510.5d4d1c79533e080c.js +1 -0
  377. package/.next/static/chunks/364.ce5400a9dd70b9dc.js +1 -0
  378. package/.next/static/chunks/370.57cfa27da8567918.js +1 -0
  379. package/.next/static/chunks/3789.c418b69121761983.js +1 -0
  380. package/.next/static/chunks/3794-1b03b52e3112452e.js +32 -0
  381. package/.next/static/chunks/3831.25ae62d10dccc27a.js +1 -0
  382. package/.next/static/chunks/3899.3f761f7e3a944e8c.js +1 -0
  383. package/.next/static/chunks/3a7aa434.93dbd20997cfd24f.js +82 -0
  384. package/.next/static/chunks/4020.3cc19c463c49f969.js +23 -0
  385. package/.next/static/chunks/4035.0acc428926d5c8dd.js +1 -0
  386. package/.next/static/chunks/405.0902e4f6eb7bd9a2.js +215 -0
  387. package/.next/static/chunks/4159.49ae537ff687bdc6.js +138 -0
  388. package/.next/static/chunks/4208.384b381ca2757643.js +287 -0
  389. package/.next/static/chunks/4263.ffa8d9bd8a0faaae.js +1 -0
  390. package/.next/static/chunks/4592.d0f37bc216b9d988.js +93 -0
  391. package/.next/static/chunks/4799.0dc7aa21bff2fd2a.js +1 -0
  392. package/.next/static/chunks/4bd1b696-e356ca5ba0218e27.js +1 -0
  393. package/.next/static/chunks/514.b804c51b26f5e126.js +1 -0
  394. package/.next/static/chunks/5270.28592864d38e881c.js +1 -0
  395. package/.next/static/chunks/52733464.3870f99cc446f9ff.js +1 -0
  396. package/.next/static/chunks/5312.4828d88ccc66f057.js +41 -0
  397. package/.next/static/chunks/5354.b559c717a607dc5c.js +1 -0
  398. package/.next/static/chunks/5413.1f8eeba1c502f3e9.js +34 -0
  399. package/.next/static/chunks/5448.d3972d9fb464b54f.js +38 -0
  400. package/.next/static/chunks/587.d52737d7288c11b4.js +1 -0
  401. package/.next/static/chunks/5909.9e37f7b495b11995.js +115 -0
  402. package/.next/static/chunks/5949.5504b3545fcc3d34.js +104 -0
  403. package/.next/static/chunks/6361.893d04ac34fa1b49.js +148 -0
  404. package/.next/static/chunks/6379-7da431a165ac5d41.js +7 -0
  405. package/.next/static/chunks/6774.8cd53427dbf32cac.js +86 -0
  406. package/.next/static/chunks/6968.b80277c724dbc96e.js +1 -0
  407. package/.next/static/chunks/7113.4b9e7ea870aa300a.js +8 -0
  408. package/.next/static/chunks/7236.55a9728d35f5b8a6.js +1 -0
  409. package/.next/static/chunks/7390.dde9b5bc2f6e24b8.js +1 -0
  410. package/.next/static/chunks/7806.a903780fcfa3a30e.js +1 -0
  411. package/.next/static/chunks/7997.be57e92e583fe635.js +1 -0
  412. package/.next/static/chunks/8216.64a72d4d35ea7be0.js +1 -0
  413. package/.next/static/chunks/830.5d5274d7ad1cb58e.js +1 -0
  414. package/.next/static/chunks/8378.fa91de3406f554c9.js +226 -0
  415. package/.next/static/chunks/8501.cd06aa1b0c7e1c6a.js +79 -0
  416. package/.next/static/chunks/8663.6ec5792fb4952e45.js +27 -0
  417. package/.next/static/chunks/872.96937e758ddce860.js +1 -0
  418. package/.next/static/chunks/8803.75bde095fe3613f5.js +1 -0
  419. package/.next/static/chunks/8863.72f5dbb820a0e4c3.js +1 -0
  420. package/.next/static/chunks/889.ff9934ce4324e448.js +90 -0
  421. package/.next/static/chunks/90542734.b88b1467ff8248c7.js +1 -0
  422. package/.next/static/chunks/9379.5bc9c9343ec5a16c.js +64 -0
  423. package/.next/static/chunks/9389.906fe7aa9cd6a170.js +1 -0
  424. package/.next/static/chunks/9472.8818ee52cfa931a4.js +94 -0
  425. package/.next/static/chunks/966.d6babbf8119162cc.js +1 -0
  426. package/.next/static/chunks/9884.839b23ae397c150e.js +36 -0
  427. package/.next/static/chunks/app/_global-error/page-a9c51a9353807009.js +1 -0
  428. package/.next/static/chunks/app/_not-found/page-d3f2ac234e6fd3b6.js +1 -0
  429. package/.next/static/chunks/app/api/agent/[id]/account/route-a9c51a9353807009.js +1 -0
  430. package/.next/static/chunks/app/api/agent/[id]/bash-output/route-a9c51a9353807009.js +1 -0
  431. package/.next/static/chunks/app/api/agent/[id]/events/route-a9c51a9353807009.js +1 -0
  432. package/.next/static/chunks/app/api/agent/[id]/route-a9c51a9353807009.js +1 -0
  433. package/.next/static/chunks/app/api/agent/new/route-a9c51a9353807009.js +1 -0
  434. package/.next/static/chunks/app/api/agent/running/route-a9c51a9353807009.js +1 -0
  435. package/.next/static/chunks/app/api/auth/all-providers/route-a9c51a9353807009.js +1 -0
  436. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-a9c51a9353807009.js +1 -0
  437. package/.next/static/chunks/app/api/auth/login/[provider]/route-a9c51a9353807009.js +1 -0
  438. package/.next/static/chunks/app/api/auth/logout/[provider]/route-a9c51a9353807009.js +1 -0
  439. package/.next/static/chunks/app/api/auth/providers/route-a9c51a9353807009.js +1 -0
  440. package/.next/static/chunks/app/api/cwd/browse/route-a9c51a9353807009.js +1 -0
  441. package/.next/static/chunks/app/api/cwd/validate/route-a9c51a9353807009.js +1 -0
  442. package/.next/static/chunks/app/api/default-cwd/route-a9c51a9353807009.js +1 -0
  443. package/.next/static/chunks/app/api/display-settings/route-a9c51a9353807009.js +1 -0
  444. package/.next/static/chunks/app/api/document-text/route-a9c51a9353807009.js +1 -0
  445. package/.next/static/chunks/app/api/experiments/route-a9c51a9353807009.js +1 -0
  446. package/.next/static/chunks/app/api/file-index/route-a9c51a9353807009.js +1 -0
  447. package/.next/static/chunks/app/api/files/[...path]/route-a9c51a9353807009.js +1 -0
  448. package/.next/static/chunks/app/api/git/diff/route-a9c51a9353807009.js +1 -0
  449. package/.next/static/chunks/app/api/git/status/route-a9c51a9353807009.js +1 -0
  450. package/.next/static/chunks/app/api/gpt6/handles/route-a9c51a9353807009.js +1 -0
  451. package/.next/static/chunks/app/api/gpt6/mcp/route-a9c51a9353807009.js +1 -0
  452. package/.next/static/chunks/app/api/gpt6/reply/route-a9c51a9353807009.js +1 -0
  453. package/.next/static/chunks/app/api/gpt6/token/route-a9c51a9353807009.js +1 -0
  454. package/.next/static/chunks/app/api/gpt6/web6-session/route-a9c51a9353807009.js +1 -0
  455. package/.next/static/chunks/app/api/home/route-a9c51a9353807009.js +1 -0
  456. package/.next/static/chunks/app/api/live/call/[callId]/route-a9c51a9353807009.js +1 -0
  457. package/.next/static/chunks/app/api/live/events/route-a9c51a9353807009.js +1 -0
  458. package/.next/static/chunks/app/api/live/offer/route-a9c51a9353807009.js +1 -0
  459. package/.next/static/chunks/app/api/live/voices/route-a9c51a9353807009.js +1 -0
  460. package/.next/static/chunks/app/api/mcp/route-a9c51a9353807009.js +1 -0
  461. package/.next/static/chunks/app/api/model-roles/route-a9c51a9353807009.js +1 -0
  462. package/.next/static/chunks/app/api/models/route-a9c51a9353807009.js +1 -0
  463. package/.next/static/chunks/app/api/models-config/catalog/route-a9c51a9353807009.js +1 -0
  464. package/.next/static/chunks/app/api/models-config/discover/route-a9c51a9353807009.js +1 -0
  465. package/.next/static/chunks/app/api/models-config/route-a9c51a9353807009.js +1 -0
  466. package/.next/static/chunks/app/api/models-config/test/route-a9c51a9353807009.js +1 -0
  467. package/.next/static/chunks/app/api/plugins/route-a9c51a9353807009.js +1 -0
  468. package/.next/static/chunks/app/api/project-trust/route-a9c51a9353807009.js +1 -0
  469. package/.next/static/chunks/app/api/projects/route-a9c51a9353807009.js +1 -0
  470. package/.next/static/chunks/app/api/runs/[runId]/route-a9c51a9353807009.js +1 -0
  471. package/.next/static/chunks/app/api/runs/route-a9c51a9353807009.js +1 -0
  472. package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-a9c51a9353807009.js +1 -0
  473. package/.next/static/chunks/app/api/sessions/[id]/context/route-a9c51a9353807009.js +1 -0
  474. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-a9c51a9353807009.js +1 -0
  475. package/.next/static/chunks/app/api/sessions/[id]/export/route-a9c51a9353807009.js +1 -0
  476. package/.next/static/chunks/app/api/sessions/[id]/route-a9c51a9353807009.js +1 -0
  477. package/.next/static/chunks/app/api/sessions/[id]/state/route-a9c51a9353807009.js +1 -0
  478. package/.next/static/chunks/app/api/sessions/route-a9c51a9353807009.js +1 -0
  479. package/.next/static/chunks/app/api/settings/route-a9c51a9353807009.js +1 -0
  480. package/.next/static/chunks/app/api/sidecars/[service]/[...path]/route-a9c51a9353807009.js +1 -0
  481. package/.next/static/chunks/app/api/skills/check/route-a9c51a9353807009.js +1 -0
  482. package/.next/static/chunks/app/api/skills/install/route-a9c51a9353807009.js +1 -0
  483. package/.next/static/chunks/app/api/skills/route-a9c51a9353807009.js +1 -0
  484. package/.next/static/chunks/app/api/skills/search/route-a9c51a9353807009.js +1 -0
  485. package/.next/static/chunks/app/api/skills/update/route-a9c51a9353807009.js +1 -0
  486. package/.next/static/chunks/app/api/theme/route-a9c51a9353807009.js +1 -0
  487. package/.next/static/chunks/app/api/update-maintenance/route-a9c51a9353807009.js +1 -0
  488. package/.next/static/chunks/app/api/updates/route-a9c51a9353807009.js +1 -0
  489. package/.next/static/chunks/app/api/web-access/recovery/route-a9c51a9353807009.js +1 -0
  490. package/.next/static/chunks/app/api/web-access/route-a9c51a9353807009.js +1 -0
  491. package/.next/static/chunks/app/api/web6/consults/route-a9c51a9353807009.js +1 -0
  492. package/.next/static/chunks/app/api/worktrees/route-a9c51a9353807009.js +1 -0
  493. package/.next/static/chunks/app/layout-95725ad1abf3cb75.js +1 -0
  494. package/.next/static/chunks/app/manifest.webmanifest/route-a9c51a9353807009.js +1 -0
  495. package/.next/static/chunks/app/page-26a4df181c1d562c.js +15 -0
  496. package/.next/static/chunks/app/recover/page-770a1de1ff4ded56.js +1 -0
  497. package/.next/static/chunks/c16f53c3-7916593d74747bde.js +1 -0
  498. package/.next/static/chunks/d3ac728e-7964f816a1ca64e5.js +1 -0
  499. package/.next/static/chunks/e413bedd.3a12a8cb02e28fdf.js +153 -0
  500. package/.next/static/chunks/ea233666.f00b64a7d99b4950.js +62 -0
  501. package/.next/static/chunks/framework-32a7466d5cae4a81.js +1 -0
  502. package/.next/static/chunks/main-50999e6ee5708e08.js +5 -0
  503. package/.next/static/chunks/main-app-0dc38ffe862cd588.js +1 -0
  504. package/.next/static/chunks/next/dist/client/components/builtin/app-error-a9c51a9353807009.js +1 -0
  505. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-a9c51a9353807009.js +1 -0
  506. package/.next/static/chunks/next/dist/client/components/builtin/global-error-070571d2fa580e7d.js +1 -0
  507. package/.next/static/chunks/next/dist/client/components/builtin/not-found-a9c51a9353807009.js +1 -0
  508. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-a9c51a9353807009.js +1 -0
  509. package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  510. package/.next/static/chunks/webpack-4094d78ef0b4c382.js +1 -0
  511. package/.next/static/css/2f46e0db0d4a3aed.css +1 -0
  512. package/.next/static/css/792a9d55c2fd2c0c.css +1 -0
  513. package/.next/static/css/92023589aa455863.css +1 -0
  514. package/.next/static/css/bb6b220f400250d8.css +1 -0
  515. package/.next/static/css/bc8f2da9192ea16d.css +1 -0
  516. package/.next/static/media/KaTeX_AMS-Regular.1608a09b.woff +0 -0
  517. package/.next/static/media/KaTeX_AMS-Regular.4aafdb68.ttf +0 -0
  518. package/.next/static/media/KaTeX_AMS-Regular.a79f1c31.woff2 +0 -0
  519. package/.next/static/media/KaTeX_Caligraphic-Bold.b6770918.woff +0 -0
  520. package/.next/static/media/KaTeX_Caligraphic-Bold.cce5b8ec.ttf +0 -0
  521. package/.next/static/media/KaTeX_Caligraphic-Bold.ec17d132.woff2 +0 -0
  522. package/.next/static/media/KaTeX_Caligraphic-Regular.07ef19e7.ttf +0 -0
  523. package/.next/static/media/KaTeX_Caligraphic-Regular.55fac258.woff2 +0 -0
  524. package/.next/static/media/KaTeX_Caligraphic-Regular.dad44a7f.woff +0 -0
  525. package/.next/static/media/KaTeX_Fraktur-Bold.9f256b85.woff +0 -0
  526. package/.next/static/media/KaTeX_Fraktur-Bold.b18f59e1.ttf +0 -0
  527. package/.next/static/media/KaTeX_Fraktur-Bold.d42a5579.woff2 +0 -0
  528. package/.next/static/media/KaTeX_Fraktur-Regular.7c187121.woff +0 -0
  529. package/.next/static/media/KaTeX_Fraktur-Regular.d3c882a6.woff2 +0 -0
  530. package/.next/static/media/KaTeX_Fraktur-Regular.ed38e79f.ttf +0 -0
  531. package/.next/static/media/KaTeX_Main-Bold.b74a1a8b.ttf +0 -0
  532. package/.next/static/media/KaTeX_Main-Bold.c3fb5ac2.woff2 +0 -0
  533. package/.next/static/media/KaTeX_Main-Bold.d181c465.woff +0 -0
  534. package/.next/static/media/KaTeX_Main-BoldItalic.6f2bb1df.woff2 +0 -0
  535. package/.next/static/media/KaTeX_Main-BoldItalic.70d8b0a5.ttf +0 -0
  536. package/.next/static/media/KaTeX_Main-BoldItalic.e3f82f9d.woff +0 -0
  537. package/.next/static/media/KaTeX_Main-Italic.47373d1e.ttf +0 -0
  538. package/.next/static/media/KaTeX_Main-Italic.8916142b.woff2 +0 -0
  539. package/.next/static/media/KaTeX_Main-Italic.9024d815.woff +0 -0
  540. package/.next/static/media/KaTeX_Main-Regular.0462f03b.woff2 +0 -0
  541. package/.next/static/media/KaTeX_Main-Regular.7f51fe03.woff +0 -0
  542. package/.next/static/media/KaTeX_Main-Regular.b7f8fe9b.ttf +0 -0
  543. package/.next/static/media/KaTeX_Math-BoldItalic.572d331f.woff2 +0 -0
  544. package/.next/static/media/KaTeX_Math-BoldItalic.a879cf83.ttf +0 -0
  545. package/.next/static/media/KaTeX_Math-BoldItalic.f1035d8d.woff +0 -0
  546. package/.next/static/media/KaTeX_Math-Italic.5295ba48.woff +0 -0
  547. package/.next/static/media/KaTeX_Math-Italic.939bc644.ttf +0 -0
  548. package/.next/static/media/KaTeX_Math-Italic.f28c23ac.woff2 +0 -0
  549. package/.next/static/media/KaTeX_SansSerif-Bold.8c5b5494.woff2 +0 -0
  550. package/.next/static/media/KaTeX_SansSerif-Bold.94e1e8dc.ttf +0 -0
  551. package/.next/static/media/KaTeX_SansSerif-Bold.bf59d231.woff +0 -0
  552. package/.next/static/media/KaTeX_SansSerif-Italic.3b1e59b3.woff2 +0 -0
  553. package/.next/static/media/KaTeX_SansSerif-Italic.7c9bc82b.woff +0 -0
  554. package/.next/static/media/KaTeX_SansSerif-Italic.b4c20c84.ttf +0 -0
  555. package/.next/static/media/KaTeX_SansSerif-Regular.74048478.woff +0 -0
  556. package/.next/static/media/KaTeX_SansSerif-Regular.ba21ed5f.woff2 +0 -0
  557. package/.next/static/media/KaTeX_SansSerif-Regular.d4d7ba48.ttf +0 -0
  558. package/.next/static/media/KaTeX_Script-Regular.03e9641d.woff2 +0 -0
  559. package/.next/static/media/KaTeX_Script-Regular.07505710.woff +0 -0
  560. package/.next/static/media/KaTeX_Script-Regular.fe9cbbe1.ttf +0 -0
  561. package/.next/static/media/KaTeX_Size1-Regular.e1e279cb.woff +0 -0
  562. package/.next/static/media/KaTeX_Size1-Regular.eae34984.woff2 +0 -0
  563. package/.next/static/media/KaTeX_Size1-Regular.fabc004a.ttf +0 -0
  564. package/.next/static/media/KaTeX_Size2-Regular.57727022.woff +0 -0
  565. package/.next/static/media/KaTeX_Size2-Regular.5916a24f.woff2 +0 -0
  566. package/.next/static/media/KaTeX_Size2-Regular.d6b476ec.ttf +0 -0
  567. package/.next/static/media/KaTeX_Size3-Regular.9acaf01c.woff +0 -0
  568. package/.next/static/media/KaTeX_Size3-Regular.a144ef58.ttf +0 -0
  569. package/.next/static/media/KaTeX_Size3-Regular.b4230e7e.woff2 +0 -0
  570. package/.next/static/media/KaTeX_Size4-Regular.10d95fd3.woff2 +0 -0
  571. package/.next/static/media/KaTeX_Size4-Regular.7a996c9d.woff +0 -0
  572. package/.next/static/media/KaTeX_Size4-Regular.fbccdabe.ttf +0 -0
  573. package/.next/static/media/KaTeX_Typewriter-Regular.6258592b.woff +0 -0
  574. package/.next/static/media/KaTeX_Typewriter-Regular.a8709e36.woff2 +0 -0
  575. package/.next/static/media/KaTeX_Typewriter-Regular.d97aaf4a.ttf +0 -0
  576. package/.next/trace +8 -0
  577. package/.next/trace-build +1 -0
  578. package/.next/types/app/api/agent/[id]/account/route.ts +351 -0
  579. package/.next/types/app/api/agent/[id]/bash-output/route.ts +351 -0
  580. package/.next/types/app/api/agent/[id]/events/route.ts +351 -0
  581. package/.next/types/app/api/agent/[id]/route.ts +351 -0
  582. package/.next/types/app/api/agent/new/route.ts +351 -0
  583. package/.next/types/app/api/agent/running/route.ts +351 -0
  584. package/.next/types/app/api/auth/all-providers/route.ts +351 -0
  585. package/.next/types/app/api/auth/api-key/[provider]/route.ts +351 -0
  586. package/.next/types/app/api/auth/login/[provider]/route.ts +351 -0
  587. package/.next/types/app/api/auth/logout/[provider]/route.ts +351 -0
  588. package/.next/types/app/api/auth/providers/route.ts +351 -0
  589. package/.next/types/app/api/cwd/browse/route.ts +351 -0
  590. package/.next/types/app/api/cwd/validate/route.ts +351 -0
  591. package/.next/types/app/api/default-cwd/route.ts +351 -0
  592. package/.next/types/app/api/display-settings/route.ts +351 -0
  593. package/.next/types/app/api/document-text/route.ts +351 -0
  594. package/.next/types/app/api/experiments/route.ts +351 -0
  595. package/.next/types/app/api/file-index/route.ts +351 -0
  596. package/.next/types/app/api/files/[...path]/route.ts +351 -0
  597. package/.next/types/app/api/git/diff/route.ts +351 -0
  598. package/.next/types/app/api/git/status/route.ts +351 -0
  599. package/.next/types/app/api/gpt6/handles/route.ts +351 -0
  600. package/.next/types/app/api/gpt6/mcp/route.ts +351 -0
  601. package/.next/types/app/api/gpt6/reply/route.ts +351 -0
  602. package/.next/types/app/api/gpt6/token/route.ts +351 -0
  603. package/.next/types/app/api/gpt6/web6-session/route.ts +351 -0
  604. package/.next/types/app/api/home/route.ts +351 -0
  605. package/.next/types/app/api/live/call/[callId]/route.ts +351 -0
  606. package/.next/types/app/api/live/events/route.ts +351 -0
  607. package/.next/types/app/api/live/offer/route.ts +351 -0
  608. package/.next/types/app/api/live/voices/route.ts +351 -0
  609. package/.next/types/app/api/mcp/route.ts +351 -0
  610. package/.next/types/app/api/model-roles/route.ts +351 -0
  611. package/.next/types/app/api/models/route.ts +351 -0
  612. package/.next/types/app/api/models-config/catalog/route.ts +351 -0
  613. package/.next/types/app/api/models-config/discover/route.ts +351 -0
  614. package/.next/types/app/api/models-config/route.ts +351 -0
  615. package/.next/types/app/api/models-config/test/route.ts +351 -0
  616. package/.next/types/app/api/plugins/route.ts +351 -0
  617. package/.next/types/app/api/project-trust/route.ts +351 -0
  618. package/.next/types/app/api/projects/route.ts +351 -0
  619. package/.next/types/app/api/runs/[runId]/route.ts +351 -0
  620. package/.next/types/app/api/runs/route.ts +351 -0
  621. package/.next/types/app/api/sessions/[id]/auto-name/route.ts +351 -0
  622. package/.next/types/app/api/sessions/[id]/context/route.ts +351 -0
  623. package/.next/types/app/api/sessions/[id]/entries/[entryId]/thinking/route.ts +351 -0
  624. package/.next/types/app/api/sessions/[id]/export/route.ts +351 -0
  625. package/.next/types/app/api/sessions/[id]/route.ts +351 -0
  626. package/.next/types/app/api/sessions/[id]/state/route.ts +351 -0
  627. package/.next/types/app/api/sessions/route.ts +351 -0
  628. package/.next/types/app/api/settings/route.ts +351 -0
  629. package/.next/types/app/api/sidecars/[service]/[...path]/route.ts +351 -0
  630. package/.next/types/app/api/skills/check/route.ts +351 -0
  631. package/.next/types/app/api/skills/install/route.ts +351 -0
  632. package/.next/types/app/api/skills/route.ts +351 -0
  633. package/.next/types/app/api/skills/search/route.ts +351 -0
  634. package/.next/types/app/api/skills/update/route.ts +351 -0
  635. package/.next/types/app/api/theme/route.ts +351 -0
  636. package/.next/types/app/api/update-maintenance/route.ts +351 -0
  637. package/.next/types/app/api/updates/route.ts +351 -0
  638. package/.next/types/app/api/web-access/recovery/route.ts +351 -0
  639. package/.next/types/app/api/web-access/route.ts +351 -0
  640. package/.next/types/app/api/web6/consults/route.ts +351 -0
  641. package/.next/types/app/api/worktrees/route.ts +351 -0
  642. package/.next/types/app/layout.ts +87 -0
  643. package/.next/types/app/page.ts +87 -0
  644. package/.next/types/app/recover/page.ts +87 -0
  645. package/.next/types/cache-life.d.ts +145 -0
  646. package/.next/types/package.json +1 -0
  647. package/.next/types/routes.d.ts +137 -0
  648. package/.next/types/validator.ts +655 -0
  649. package/LICENSE +22 -0
  650. package/README.md +174 -0
  651. package/Tools/CUELO_Setup/files/btw-server.js +343 -0
  652. package/Tools/CUELO_Setup/files/native-runtime-patch.js +349 -0
  653. package/Tools/CUELO_Setup/files/subagent-server.js +587 -0
  654. package/Tools/CUELO_Setup/files/usage-server.js +896 -0
  655. package/Tools/OMP_Global_Config/agent/AGENTS.md +122 -0
  656. package/Tools/OMP_Global_Config/agent/RULES.md +75 -0
  657. package/Tools/OMP_Global_Config/agent/WATCHDOG.md +55 -0
  658. package/Tools/OMP_Global_Config/agent/agents/maker.md +390 -0
  659. package/Tools/OMP_Global_Config/agent/extensions/character-voice.ts +718 -0
  660. package/Tools/OMP_Global_Config/agent/extensions/command-guard/index.ts +899 -0
  661. package/Tools/OMP_Global_Config/agent/extensions/command-guard/matcher.ts +1227 -0
  662. package/Tools/OMP_Global_Config/agent/extensions/command-guard/task-guard.ts +890 -0
  663. package/Tools/OMP_Global_Config/agent/extensions/jev-runtime.ts +1567 -0
  664. package/Tools/OMP_Global_Config/agent/extensions/lib/maker-routing.ts +1020 -0
  665. package/Tools/OMP_Global_Config/agent/extensions/lib/prepared-task.ts +204 -0
  666. package/Tools/OMP_Global_Config/agent/extensions/lib/routing-ledger.ts +289 -0
  667. package/Tools/OMP_Global_Config/agent/extensions/lib/task-progress.ts +492 -0
  668. package/Tools/OMP_Global_Config/agent/extensions/prompt-compact.ts +67 -0
  669. package/Tools/OMP_Global_Config/agent/extensions/steering-reply-gate.ts +92 -0
  670. package/Tools/OMP_Global_Config/agent/extensions/todo-nudge.ts +56 -0
  671. package/Tools/OMP_Global_Config/agent/extensions/turn-end-guard.ts +154 -0
  672. package/Tools/OMP_Global_Config/agent/prompt-copies/AGENTS.en.md +125 -0
  673. package/Tools/OMP_Global_Config/agent/prompt-copies/RULES.en.md +28 -0
  674. package/Tools/OMP_Global_Config/agent/rules/docs-handoff.md +36 -0
  675. package/Tools/OMP_Global_Config/agent/rules/frontend.md +63 -0
  676. package/Tools/OMP_Global_Config/agent/rules/harness-policy.json +1080 -0
  677. package/Tools/OMP_Global_Config/agent/rules/legacy-encoding.md +21 -0
  678. package/Tools/OMP_Global_Config/agent/rules/meta-harness.md +45 -0
  679. package/Tools/OMP_Global_Config/agent/rules/omp-harness.md +143 -0
  680. package/Tools/OMP_Global_Config/agent/rules/subagent.md +543 -0
  681. package/Tools/OMP_Global_Config/agent/rules/task-guard.md +54 -0
  682. package/Tools/OMP_Global_Config/agent/rules/verdict.md +183 -0
  683. package/Tools/OMP_Global_Config/agent/rules/web6-consult.md +84 -0
  684. package/Tools/OMP_Global_Config/agent/sop/_common.md +130 -0
  685. package/Tools/OMP_Global_Config/agent/sop/_writer.md +242 -0
  686. package/Tools/OMP_Global_Config/agent/sop/maker.md +9 -0
  687. package/Tools/OMP_Global_Config/agent/tools/git-finalizer/finalizer.ps1 +340 -0
  688. package/Tools/OMP_Global_Config/agent/tools/git-finalizer/index.ts +83 -0
  689. package/Tools/OMP_Global_Config/notices/orchestrate.md +26 -0
  690. package/Tools/OMP_Global_Config/notices/ultrathink.md +9 -0
  691. package/Tools/OMP_Global_Config/notices/workflow.md +16 -0
  692. package/Tools/OMP_Global_Config/patches/apply-core-patch.mjs +5005 -0
  693. package/Tools/OMP_Global_Config/patches/apply-notices.mjs +135 -0
  694. package/bin/cuelo-options.js +38 -0
  695. package/bin/cuelo.js +268 -0
  696. package/bin/password-prompt.js +100 -0
  697. package/bin/prepare-runtime.js +81 -0
  698. package/bin/runtime.js +134 -0
  699. package/bin/web-auth-store.d.ts +104 -0
  700. package/bin/web-auth-store.js +593 -0
  701. package/install.mjs +393 -0
  702. package/next.config.ts +96 -0
  703. package/package.json +134 -0
  704. package/public/audio/completion/isana/01.wav +0 -0
  705. package/public/audio/completion/isana/02.wav +0 -0
  706. package/public/audio/completion/isana/03.wav +0 -0
  707. package/public/audio/completion/isana/04.wav +0 -0
  708. package/public/audio/completion/isana/05.wav +0 -0
  709. package/public/audio/completion/isana/06.wav +0 -0
  710. package/public/audio/completion/isana/approval/01.wav +0 -0
  711. package/public/audio/completion/isana/approval/02.wav +0 -0
  712. package/public/audio/completion/isana/approval/03.wav +0 -0
  713. package/public/audio/completion/isana/choice/01.wav +0 -0
  714. package/public/audio/completion/isana/choice/02.wav +0 -0
  715. package/public/audio/completion/isana/choice/03.wav +0 -0
  716. package/public/audio/completion/isana/failed/01.wav +0 -0
  717. package/public/audio/completion/isana/failed/02.wav +0 -0
  718. package/public/audio/completion/isana/failed/03.wav +0 -0
  719. package/public/audio/completion/isana/working/01.wav +0 -0
  720. package/public/audio/completion/isana/working/02.wav +0 -0
  721. package/public/audio/completion/isana/working/03.wav +0 -0
  722. package/public/audio/completion/mio/01.wav +0 -0
  723. package/public/audio/completion/mio/02.wav +0 -0
  724. package/public/audio/completion/mio/03.wav +0 -0
  725. package/public/audio/completion/mio/04.wav +0 -0
  726. package/public/audio/completion/mio/05.wav +0 -0
  727. package/public/audio/completion/mio/06.wav +0 -0
  728. package/public/audio/completion/mio/approval/01.wav +0 -0
  729. package/public/audio/completion/mio/approval/02.wav +0 -0
  730. package/public/audio/completion/mio/approval/03.wav +0 -0
  731. package/public/audio/completion/mio/choice/01.wav +0 -0
  732. package/public/audio/completion/mio/choice/02.wav +0 -0
  733. package/public/audio/completion/mio/choice/03.wav +0 -0
  734. package/public/audio/completion/mio/failed/01.wav +0 -0
  735. package/public/audio/completion/mio/failed/02.wav +0 -0
  736. package/public/audio/completion/mio/failed/03.wav +0 -0
  737. package/public/audio/completion/mio/working/01.wav +0 -0
  738. package/public/audio/completion/mio/working/02.wav +0 -0
  739. package/public/audio/completion/mio/working/03.wav +0 -0
  740. package/public/audio/completion/nova/01.wav +0 -0
  741. package/public/audio/completion/nova/02.wav +0 -0
  742. package/public/audio/completion/nova/03.wav +0 -0
  743. package/public/audio/completion/nova/04.wav +0 -0
  744. package/public/audio/completion/nova/05.wav +0 -0
  745. package/public/audio/completion/nova/06.wav +0 -0
  746. package/public/audio/completion/nova/approval/01.wav +0 -0
  747. package/public/audio/completion/nova/approval/02.wav +0 -0
  748. package/public/audio/completion/nova/approval/03.wav +0 -0
  749. package/public/audio/completion/nova/choice/01.wav +0 -0
  750. package/public/audio/completion/nova/choice/02.wav +0 -0
  751. package/public/audio/completion/nova/choice/03.wav +0 -0
  752. package/public/audio/completion/nova/failed/01.wav +0 -0
  753. package/public/audio/completion/nova/failed/02.wav +0 -0
  754. package/public/audio/completion/nova/failed/03.wav +0 -0
  755. package/public/audio/completion/nova/working/01.wav +0 -0
  756. package/public/audio/completion/nova/working/02.wav +0 -0
  757. package/public/audio/completion/nova/working/03.wav +0 -0
  758. package/public/audio/completion/rin/01.wav +0 -0
  759. package/public/audio/completion/rin/02.wav +0 -0
  760. package/public/audio/completion/rin/03.wav +0 -0
  761. package/public/audio/completion/rin/04.wav +0 -0
  762. package/public/audio/completion/rin/05.wav +0 -0
  763. package/public/audio/completion/rin/06.wav +0 -0
  764. package/public/audio/completion/rin/approval/01.wav +0 -0
  765. package/public/audio/completion/rin/approval/02.wav +0 -0
  766. package/public/audio/completion/rin/approval/03.wav +0 -0
  767. package/public/audio/completion/rin/choice/01.wav +0 -0
  768. package/public/audio/completion/rin/choice/02.wav +0 -0
  769. package/public/audio/completion/rin/choice/03.wav +0 -0
  770. package/public/audio/completion/rin/failed/01.wav +0 -0
  771. package/public/audio/completion/rin/failed/02.wav +0 -0
  772. package/public/audio/completion/rin/failed/03.wav +0 -0
  773. package/public/audio/completion/rin/working/01.wav +0 -0
  774. package/public/audio/completion/rin/working/02.wav +0 -0
  775. package/public/audio/completion/rin/working/03.wav +0 -0
  776. package/public/audio/completion/shion/01.wav +0 -0
  777. package/public/audio/completion/shion/02.wav +0 -0
  778. package/public/audio/completion/shion/03.wav +0 -0
  779. package/public/audio/completion/shion/04.wav +0 -0
  780. package/public/audio/completion/shion/05.wav +0 -0
  781. package/public/audio/completion/shion/06.wav +0 -0
  782. package/public/audio/completion/shion/approval/01.wav +0 -0
  783. package/public/audio/completion/shion/approval/02.wav +0 -0
  784. package/public/audio/completion/shion/approval/03.wav +0 -0
  785. package/public/audio/completion/shion/choice/01.wav +0 -0
  786. package/public/audio/completion/shion/choice/02.wav +0 -0
  787. package/public/audio/completion/shion/choice/03.wav +0 -0
  788. package/public/audio/completion/shion/failed/01.wav +0 -0
  789. package/public/audio/completion/shion/failed/02.wav +0 -0
  790. package/public/audio/completion/shion/failed/03.wav +0 -0
  791. package/public/audio/completion/shion/working/01.wav +0 -0
  792. package/public/audio/completion/shion/working/02.wav +0 -0
  793. package/public/audio/completion/shion/working/03.wav +0 -0
  794. package/public/audio/completion/voices.json +1195 -0
  795. package/public/audio/completion/yuki/01.wav +0 -0
  796. package/public/audio/completion/yuki/02.wav +0 -0
  797. package/public/audio/completion/yuki/03.wav +0 -0
  798. package/public/audio/completion/yuki/04.wav +0 -0
  799. package/public/audio/completion/yuki/05.wav +0 -0
  800. package/public/audio/completion/yuki/06.wav +0 -0
  801. package/public/audio/completion/yuki/approval/01.wav +0 -0
  802. package/public/audio/completion/yuki/approval/02.wav +0 -0
  803. package/public/audio/completion/yuki/approval/03.wav +0 -0
  804. package/public/audio/completion/yuki/choice/01.wav +0 -0
  805. package/public/audio/completion/yuki/choice/02.wav +0 -0
  806. package/public/audio/completion/yuki/choice/03.wav +0 -0
  807. package/public/audio/completion/yuki/failed/01.wav +0 -0
  808. package/public/audio/completion/yuki/failed/02.wav +0 -0
  809. package/public/audio/completion/yuki/failed/03.wav +0 -0
  810. package/public/audio/completion/yuki/working/01.wav +0 -0
  811. package/public/audio/completion/yuki/working/02.wav +0 -0
  812. package/public/audio/completion/yuki/working/03.wav +0 -0
  813. package/public/avatars/isana.webp +0 -0
  814. package/public/avatars/mio.webp +0 -0
  815. package/public/avatars/nova.webp +0 -0
  816. package/public/avatars/rin.webp +0 -0
  817. package/public/avatars/shion.webp +0 -0
  818. package/public/avatars/yuki.webp +0 -0
  819. package/public/icons/apple-touch-icon.png +0 -0
  820. package/public/icons/catppuccin/LICENSE +22 -0
  821. package/public/icons/catppuccin/README.md +8 -0
  822. package/public/icons/catppuccin/latte/_file.svg +3 -0
  823. package/public/icons/catppuccin/latte/_folder.svg +3 -0
  824. package/public/icons/catppuccin/latte/_folder_open.svg +3 -0
  825. package/public/icons/catppuccin/latte/bash.svg +7 -0
  826. package/public/icons/catppuccin/latte/bun-lock.svg +8 -0
  827. package/public/icons/catppuccin/latte/config.svg +3 -0
  828. package/public/icons/catppuccin/latte/css.svg +6 -0
  829. package/public/icons/catppuccin/latte/database.svg +3 -0
  830. package/public/icons/catppuccin/latte/docker.svg +3 -0
  831. package/public/icons/catppuccin/latte/env.svg +3 -0
  832. package/public/icons/catppuccin/latte/eslint.svg +6 -0
  833. package/public/icons/catppuccin/latte/git.svg +6 -0
  834. package/public/icons/catppuccin/latte/go.svg +3 -0
  835. package/public/icons/catppuccin/latte/graphql.svg +3 -0
  836. package/public/icons/catppuccin/latte/html.svg +6 -0
  837. package/public/icons/catppuccin/latte/javascript-react.svg +8 -0
  838. package/public/icons/catppuccin/latte/javascript.svg +6 -0
  839. package/public/icons/catppuccin/latte/json.svg +3 -0
  840. package/public/icons/catppuccin/latte/lock.svg +3 -0
  841. package/public/icons/catppuccin/latte/markdown.svg +3 -0
  842. package/public/icons/catppuccin/latte/ms-word.svg +6 -0
  843. package/public/icons/catppuccin/latte/next.svg +6 -0
  844. package/public/icons/catppuccin/latte/npm-lock.svg +7 -0
  845. package/public/icons/catppuccin/latte/pdf.svg +3 -0
  846. package/public/icons/catppuccin/latte/python.svg +8 -0
  847. package/public/icons/catppuccin/latte/rust.svg +6 -0
  848. package/public/icons/catppuccin/latte/sass.svg +3 -0
  849. package/public/icons/catppuccin/latte/terraform.svg +3 -0
  850. package/public/icons/catppuccin/latte/toml.svg +3 -0
  851. package/public/icons/catppuccin/latte/typescript-react.svg +8 -0
  852. package/public/icons/catppuccin/latte/typescript.svg +6 -0
  853. package/public/icons/catppuccin/latte/yaml.svg +3 -0
  854. package/public/icons/catppuccin/mocha/_file.svg +3 -0
  855. package/public/icons/catppuccin/mocha/_folder.svg +3 -0
  856. package/public/icons/catppuccin/mocha/_folder_open.svg +3 -0
  857. package/public/icons/catppuccin/mocha/bash.svg +7 -0
  858. package/public/icons/catppuccin/mocha/bun-lock.svg +8 -0
  859. package/public/icons/catppuccin/mocha/config.svg +3 -0
  860. package/public/icons/catppuccin/mocha/css.svg +6 -0
  861. package/public/icons/catppuccin/mocha/database.svg +3 -0
  862. package/public/icons/catppuccin/mocha/docker.svg +3 -0
  863. package/public/icons/catppuccin/mocha/env.svg +3 -0
  864. package/public/icons/catppuccin/mocha/eslint.svg +6 -0
  865. package/public/icons/catppuccin/mocha/git.svg +6 -0
  866. package/public/icons/catppuccin/mocha/go.svg +3 -0
  867. package/public/icons/catppuccin/mocha/graphql.svg +3 -0
  868. package/public/icons/catppuccin/mocha/html.svg +6 -0
  869. package/public/icons/catppuccin/mocha/javascript-react.svg +8 -0
  870. package/public/icons/catppuccin/mocha/javascript.svg +6 -0
  871. package/public/icons/catppuccin/mocha/json.svg +3 -0
  872. package/public/icons/catppuccin/mocha/lock.svg +3 -0
  873. package/public/icons/catppuccin/mocha/markdown.svg +3 -0
  874. package/public/icons/catppuccin/mocha/ms-word.svg +6 -0
  875. package/public/icons/catppuccin/mocha/next.svg +6 -0
  876. package/public/icons/catppuccin/mocha/npm-lock.svg +7 -0
  877. package/public/icons/catppuccin/mocha/pdf.svg +3 -0
  878. package/public/icons/catppuccin/mocha/python.svg +8 -0
  879. package/public/icons/catppuccin/mocha/rust.svg +6 -0
  880. package/public/icons/catppuccin/mocha/sass.svg +3 -0
  881. package/public/icons/catppuccin/mocha/terraform.svg +3 -0
  882. package/public/icons/catppuccin/mocha/toml.svg +3 -0
  883. package/public/icons/catppuccin/mocha/typescript-react.svg +8 -0
  884. package/public/icons/catppuccin/mocha/typescript.svg +6 -0
  885. package/public/icons/catppuccin/mocha/yaml.svg +3 -0
  886. package/public/icons/icon-192.png +0 -0
  887. package/public/icons/icon-512.png +0 -0
  888. package/public/offline.html +145 -0
  889. package/public/stickers/isana/approval/01.webp +0 -0
  890. package/public/stickers/isana/approval/02.webp +0 -0
  891. package/public/stickers/isana/approval/03.webp +0 -0
  892. package/public/stickers/isana/choice/01.webp +0 -0
  893. package/public/stickers/isana/choice/02.webp +0 -0
  894. package/public/stickers/isana/choice/03.webp +0 -0
  895. package/public/stickers/isana/done/01.webp +0 -0
  896. package/public/stickers/isana/done/02.webp +0 -0
  897. package/public/stickers/isana/done/03.webp +0 -0
  898. package/public/stickers/isana/failed/01.webp +0 -0
  899. package/public/stickers/isana/failed/02.webp +0 -0
  900. package/public/stickers/isana/failed/03.webp +0 -0
  901. package/public/stickers/isana/working/01.webp +0 -0
  902. package/public/stickers/mio/approval/01.webp +0 -0
  903. package/public/stickers/mio/approval/02.webp +0 -0
  904. package/public/stickers/mio/approval/03.webp +0 -0
  905. package/public/stickers/mio/choice/01.webp +0 -0
  906. package/public/stickers/mio/choice/02.webp +0 -0
  907. package/public/stickers/mio/choice/03.webp +0 -0
  908. package/public/stickers/mio/done/01.webp +0 -0
  909. package/public/stickers/mio/done/02.webp +0 -0
  910. package/public/stickers/mio/done/03.webp +0 -0
  911. package/public/stickers/mio/failed/01.webp +0 -0
  912. package/public/stickers/mio/failed/02.webp +0 -0
  913. package/public/stickers/mio/failed/03.webp +0 -0
  914. package/public/stickers/mio/working/01.webp +0 -0
  915. package/public/stickers/nova/approval/01.webp +0 -0
  916. package/public/stickers/nova/approval/02.webp +0 -0
  917. package/public/stickers/nova/approval/03.webp +0 -0
  918. package/public/stickers/nova/choice/01.webp +0 -0
  919. package/public/stickers/nova/choice/02.webp +0 -0
  920. package/public/stickers/nova/choice/03.webp +0 -0
  921. package/public/stickers/nova/done/01.webp +0 -0
  922. package/public/stickers/nova/done/02.webp +0 -0
  923. package/public/stickers/nova/done/03.webp +0 -0
  924. package/public/stickers/nova/failed/01.webp +0 -0
  925. package/public/stickers/nova/failed/02.webp +0 -0
  926. package/public/stickers/nova/failed/03.webp +0 -0
  927. package/public/stickers/nova/working/01.webp +0 -0
  928. package/public/stickers/rin/approval/01.webp +0 -0
  929. package/public/stickers/rin/approval/02.webp +0 -0
  930. package/public/stickers/rin/approval/03.webp +0 -0
  931. package/public/stickers/rin/choice/01.webp +0 -0
  932. package/public/stickers/rin/choice/02.webp +0 -0
  933. package/public/stickers/rin/choice/03.webp +0 -0
  934. package/public/stickers/rin/done/01.webp +0 -0
  935. package/public/stickers/rin/done/02.webp +0 -0
  936. package/public/stickers/rin/done/03.webp +0 -0
  937. package/public/stickers/rin/failed/01.webp +0 -0
  938. package/public/stickers/rin/failed/02.webp +0 -0
  939. package/public/stickers/rin/failed/03.webp +0 -0
  940. package/public/stickers/rin/working/01.webp +0 -0
  941. package/public/stickers/shion/approval/01.webp +0 -0
  942. package/public/stickers/shion/approval/02.webp +0 -0
  943. package/public/stickers/shion/approval/03.webp +0 -0
  944. package/public/stickers/shion/choice/01.webp +0 -0
  945. package/public/stickers/shion/choice/02.webp +0 -0
  946. package/public/stickers/shion/choice/03.webp +0 -0
  947. package/public/stickers/shion/done/01.webp +0 -0
  948. package/public/stickers/shion/done/02.webp +0 -0
  949. package/public/stickers/shion/done/03.webp +0 -0
  950. package/public/stickers/shion/failed/01.webp +0 -0
  951. package/public/stickers/shion/failed/02.webp +0 -0
  952. package/public/stickers/shion/failed/03.webp +0 -0
  953. package/public/stickers/shion/working/01.webp +0 -0
  954. package/public/stickers/yuki/approval/01.webp +0 -0
  955. package/public/stickers/yuki/approval/02.webp +0 -0
  956. package/public/stickers/yuki/approval/03.webp +0 -0
  957. package/public/stickers/yuki/choice/01.webp +0 -0
  958. package/public/stickers/yuki/choice/02.webp +0 -0
  959. package/public/stickers/yuki/choice/03.webp +0 -0
  960. package/public/stickers/yuki/done/01.webp +0 -0
  961. package/public/stickers/yuki/done/02.webp +0 -0
  962. package/public/stickers/yuki/done/03.webp +0 -0
  963. package/public/stickers/yuki/failed/01.webp +0 -0
  964. package/public/stickers/yuki/failed/02.webp +0 -0
  965. package/public/stickers/yuki/failed/03.webp +0 -0
  966. package/public/stickers/yuki/working/01.webp +0 -0
  967. package/public/sw.js +124 -0
@@ -0,0 +1,1020 @@
1
+ import { readFileSync } from "node:fs";
2
+ import type { ExtensionAPI, ExtensionContext, ToolDefinition } from "@oh-my-pi/pi-coding-agent";
3
+ import { isPathOwned, parseOwnedPaths } from "../command-guard/task-guard";
4
+ import { resolvePreparedTaskInput, storePreparedTaskBatch } from "./prepared-task";
5
+ import { assignmentsByName, summarizeHistory, type AttemptIdentity, type DispatchRecord, type RoutingHistory, type RoutingLedger } from "./routing-ledger";
6
+
7
+ export interface RoutingFacts {
8
+ goal: string;
9
+ acceptance: string[];
10
+ facts: string[];
11
+ hypotheses: string[] | null;
12
+ unknowns: string[] | null;
13
+ paths: string[];
14
+ callBoundaries: string[] | null;
15
+ settledImplementation: string[] | null;
16
+ reusedPatterns: string[] | null;
17
+ remainingJudgments: string[] | null;
18
+ invariants: string[];
19
+ checks: string[];
20
+ failureEvidence: string[] | null;
21
+ }
22
+ interface RouteTask { name: string; task: string; assessment: RoutingFacts }
23
+ export interface Owner {
24
+ name: string | null;
25
+ primaryDeliverable: string | null;
26
+ ownedPaths: string[];
27
+ active?: boolean;
28
+ }
29
+ interface Candidate { profile: string; model: string; efforts: string[] }
30
+ /** registry·추론 강도 확인에 실패한 후보. 다른 후보의 발주를 막지 않고, 다른 모델로 대체하지도 않는다. */
31
+ export interface UnavailableCandidate { profile: string; model: string; reason: string }
32
+ interface CandidateSet { available: Candidate[]; unavailable: UnavailableCandidate[] }
33
+ /** 같은 준비→발주 계약에서 공유하는 provider online 갱신 시도. 값은 실패 사유이고 null이면 성공이다. */
34
+ type RefreshAttempts = Map<string, Promise<string | null>>;
35
+ interface RoutingPolicy {
36
+ modelSelection: {
37
+ profiles: Record<string, { modelConfigPath: string; workClass: string; allowedEfforts: string[] }>;
38
+ criteria: Record<string, string>;
39
+ hardFocusCriteria: Record<string, string>;
40
+ uiUxBoundaryCriteria: string;
41
+ /** 위임 판정 정본(MAIN·MAKER·UNKNOWN). 정책이 항상 싣는다. */
42
+ delegationCriteria: Record<string, string>;
43
+ };
44
+ effortSelection: { criteria: Record<string, string> };
45
+ }
46
+ export interface RoutingQuestion {
47
+ type: "choice" | "noul";
48
+ instructions: string;
49
+ criteria?: Record<string, string | null>;
50
+ }
51
+ interface RoutingAnswer { type?: string; choice?: string; noul?: number }
52
+ export interface RoutingPlacement {
53
+ action: "dispatch-new" | "instruct-existing" | "retarget-existing" | "main-decision";
54
+ ownerIndex: number | null;
55
+ owner: Owner | null;
56
+ }
57
+ /** Main 재량용 계정 잔량 참고 정보. 후보 revision·Jev state에는 넣지 않는다. */
58
+ export interface QuotaLimit {
59
+ id: string | null;
60
+ usedFraction: number | null;
61
+ resetsAt: number | null;
62
+ daySlot: { usedPct: number | null; quotaPct: number | null; slotsLeft: number | null; quality: string | null } | null;
63
+ }
64
+ export interface QuotaAccount {
65
+ credentialId: number | null;
66
+ disabled: boolean;
67
+ autoBlockedUntilMs: number | null;
68
+ limitReached: boolean | null;
69
+ fetchedAt: number | null;
70
+ limits: QuotaLimit[];
71
+ }
72
+ export type QuotaSnapshot =
73
+ | { state: "observed"; observedAt: number; providers: Record<string, QuotaAccount[]> }
74
+ | { state: "unavailable"; observedAt: number; reason: string };
75
+ export interface RoutingDeps {
76
+ judge: (ctx: ExtensionContext, request: { state: unknown; questions: Record<string, RoutingQuestion> }, signal?: AbortSignal) => Promise<{ answers: Record<string, RoutingAnswer> }>;
77
+ settings: (ctx: ExtensionContext) => Promise<{ getModelRoles(): Readonly<Record<string, string>> } | undefined>;
78
+ owners: () => Owner[];
79
+ policy?: () => RoutingPolicy;
80
+ candidates?: (ctx: ExtensionContext, policy: RoutingPolicy) => Promise<Candidate[]>;
81
+ /** 후보 provider별 계정 잔량. 생략하면 CUELO usage 사이드카(`OMP_USAGE_PORT`, 기본 30142)를 읽는다. */
82
+ quota?: (providers: string[], signal?: AbortSignal) => Promise<QuotaSnapshot>;
83
+ /** 발주 이력. 생략하면 기록·history 요약을 하지 않는다. 실패는 발주를 막지 않는다. */
84
+ ledger?: RoutingLedger;
85
+ }
86
+
87
+ // 잔량은 참고 정보다. 실측: 사이드카 `/usage` 웜 응답 1-3ms, 콜드 경로가 실행하는
88
+ // `omp usage --json` 0.25-1.3s(4회 실측 1249·246·750·295ms), 사이드카 자체 캐시 60s.
89
+ // 이 예산을 넘기면 배치를 더 붙잡지 않고 이번 호출만 unavailable로 두며,
90
+ // 다음 호출은 사이드카 캐시가 채워져 웜으로 답한다.
91
+ const QUOTA_ADVISORY_BUDGET_MS = 2_000;
92
+ const finiteOrNull = (value: unknown): number | null => (typeof value === "number" && Number.isFinite(value) ? value : null);
93
+
94
+ /** CUELO usage 사이드카의 `/usage`를 후보 provider만 남겨 요약한다. 실패는 unavailable로 두고 발주를 막지 않는다. */
95
+ export async function readSidecarQuota(providers: string[], signal?: AbortSignal): Promise<QuotaSnapshot> {
96
+ const observedAt = Date.now();
97
+ const port = Number(process.env.OMP_USAGE_PORT || 30142);
98
+ const budget = AbortSignal.timeout(QUOTA_ADVISORY_BUDGET_MS);
99
+ try {
100
+ const response = await fetch(`http://127.0.0.1:${port}/usage`, {
101
+ redirect: "error",
102
+ signal: signal ? AbortSignal.any([signal, budget]) : budget,
103
+ });
104
+ if (!response.ok) return { state: "unavailable", observedAt, reason: `usage sidecar HTTP ${response.status}` };
105
+ const body = await response.json() as { brokerOk?: boolean; reports?: Record<string, unknown>[] };
106
+ if (body.brokerOk === false) return { state: "unavailable", observedAt, reason: "usage sidecar brokerOk=false" };
107
+ const wanted = new Set(providers);
108
+ const byProvider: Record<string, QuotaAccount[]> = Object.fromEntries(providers.map((provider) => [provider, []]));
109
+ for (const report of body.reports ?? []) {
110
+ const provider = typeof report.provider === "string" ? report.provider : "";
111
+ if (!wanted.has(provider)) continue;
112
+ const metadata = (report.metadata ?? {}) as Record<string, unknown>;
113
+ const limits = Array.isArray(report.limits) ? report.limits as Record<string, unknown>[] : [];
114
+ byProvider[provider]!.push({
115
+ credentialId: finiteOrNull(report.credentialId),
116
+ disabled: report.disabled === true,
117
+ autoBlockedUntilMs: finiteOrNull(report.autoBlockedUntilMs),
118
+ limitReached: typeof metadata.limitReached === "boolean" ? metadata.limitReached : null,
119
+ fetchedAt: finiteOrNull(report.fetchedAt),
120
+ limits: limits.map((limit) => {
121
+ const amount = (limit.amount ?? {}) as Record<string, unknown>;
122
+ const window = (limit.window ?? {}) as Record<string, unknown>;
123
+ const daySlot = limit.daySlot as Record<string, unknown> | undefined;
124
+ return {
125
+ id: typeof limit.id === "string" ? limit.id : null,
126
+ usedFraction: finiteOrNull(amount.usedFraction),
127
+ resetsAt: finiteOrNull(window.resetsAt),
128
+ daySlot: daySlot
129
+ ? {
130
+ usedPct: finiteOrNull(daySlot.usedPct),
131
+ quotaPct: finiteOrNull(daySlot.quotaPct),
132
+ slotsLeft: finiteOrNull(daySlot.slotsLeft),
133
+ quality: typeof daySlot.quality === "string" ? daySlot.quality : null,
134
+ }
135
+ : null,
136
+ };
137
+ }),
138
+ });
139
+ }
140
+ return { state: "observed", observedAt, providers: byProvider };
141
+ } catch (error) {
142
+ return {
143
+ state: "unavailable",
144
+ observedAt,
145
+ reason: budget.aborted
146
+ ? `usage sidecar advisory budget 초과 (${QUOTA_ADVISORY_BUDGET_MS}ms)`
147
+ : error instanceof Error ? error.message : String(error),
148
+ };
149
+ }
150
+ }
151
+ const policyUrl = new URL("../../rules/harness-policy.json", import.meta.url);
152
+ export function loadRoutingPolicy(): RoutingPolicy {
153
+ return JSON.parse(readFileSync(policyUrl, "utf8")).routing;
154
+ }
155
+
156
+ // 명시된 사실 필드만 전달한다. task 원문·현재 모델·이전 등급은 로컬 바인딩에만 남는다.
157
+ function routingFactsState(input: RoutingFacts) {
158
+ return {
159
+ goal: input.goal, acceptance: input.acceptance, facts: input.facts,
160
+ hypotheses: input.hypotheses ?? null, unknowns: input.unknowns ?? null,
161
+ paths: input.paths, callBoundaries: input.callBoundaries ?? null,
162
+ settledImplementation: input.settledImplementation ?? null, reusedPatterns: input.reusedPatterns ?? null,
163
+ remainingJudgments: input.remainingJudgments ?? null, invariants: input.invariants,
164
+ checks: input.checks, failureEvidence: input.failureEvidence ?? null,
165
+ };
166
+ }
167
+
168
+ export function routingState(input: RoutingFacts, owners: Owner[]) {
169
+ return {
170
+ ...routingFactsState(input),
171
+ existingOwners: owners.map((owner, index) => ({
172
+ owner: index, name: owner.name, goal: owner.primaryDeliverable, ownedPaths: owner.ownedPaths,
173
+ })),
174
+ };
175
+ }
176
+
177
+ function decisionQuestions(policy: RoutingPolicy, candidates: Candidate[]) {
178
+ const questions: Record<string, RoutingQuestion> = {
179
+ workClass: {
180
+ type: "choice", criteria: policy.modelSelection.criteria,
181
+ instructions: "위 criteria를 정본으로 facts·remainingJudgments·callBoundaries·invariants에 남은 판단을 대조한다. Main이 정한 목표·방향과 구현자가 해결할 설계·검증 판단을 구분한다. 가설과 미확인은 사실로 바꾸지 않는다. 다른 질문의 답이나 목표 분류 비율을 가정하지 않는다.",
182
+ },
183
+ hardFocus: {
184
+ type: "choice", criteria: policy.modelSelection.hardFocusCriteria,
185
+ instructions: "남은 판단의 지배적 성격을 분류한다. 프론트엔드 경로라도 실행·동시성·상태 불변식이면 CODE_SYSTEM이다. 다른 질문의 답을 가정하지 않는다.",
186
+ },
187
+ uiUxBoundary: {
188
+ type: "noul",
189
+ instructions: `${policy.modelSelection.uiUxBoundaryCriteria}. 남은 UI/UX 판단의 존재를 난이도·지배 분야와 독립적으로 판단한다. 혼합 작업의 UI/UX 경계도 포함하고 파일 확장자만으로 추정하지 않는다.`,
190
+ },
191
+ };
192
+ // 위임 판정은 정책 정본(delegationCriteria = MAIN·MAKER·UNKNOWN)을 그대로 choice 선택지로 쓴다.
193
+ questions.delegation = {
194
+ type: "choice",
195
+ criteria: policy.modelSelection.delegationCriteria,
196
+ instructions: "위 criteria를 정본으로 이 조각의 수행 주체를 독립적으로 판단한다. facts·callBoundaries·reusedPatterns·remainingJudgments·unknowns에 있는 독립 완결성, Main 보유 문맥, 실제 병렬·전문성 이득, 설명·검수 부담을 대조한다. 난이도나 병렬 실행 가능성만으로 위임 이득을 단정하지 않는다. 결과는 Main의 조언이며 자동 발주·owner 변경이 아니다.",
197
+ };
198
+ candidates.forEach((candidate, index) => {
199
+ if (candidate.efforts.filter((level) => level in policy.effortSelection.criteria).length <= 1) return;
200
+ questions[`effort${index}`] = {
201
+ type: "choice",
202
+ criteria: Object.fromEntries(candidate.efforts.filter((level) => level in policy.effortSelection.criteria).map((level) => [level, policy.effortSelection.criteria[level]!])),
203
+ instructions: "이 후보가 지원하는 구간에서 관측된 남은 판단과 수용 조건에 충분한 가장 낮은 추론 강도를 독립적으로 고른다. 작업 등급이나 다른 질문의 답을 가정하지 않는다. 위험·파일 수·경과 시간·이전 실패 횟수만으로 강도를 올리지 않는다.",
204
+ };
205
+ });
206
+ return questions;
207
+ }
208
+ function placementQuestions(owners: Owner[]) {
209
+ if (owners.length === 0) return {};
210
+ return {
211
+ duplicate: { type: "noul", instructions: "이 조각이 existingOwners 중 기존 owner의 완료물과 소유 범위를 중복하는가?" },
212
+ additionalInstruction: { type: "noul", instructions: "새 발주 없이 existingOwners 중 기존 owner에게 추가 지시하는 것으로 충분한가?" },
213
+ ownerTarget: {
214
+ type: "choice",
215
+ criteria: {
216
+ ...Object.fromEntries(owners.map((_owner, index) => [`owner${index}`, `existingOwners[${index}]가 이 조각을 이어서 맡을 식별 가능한 owner다.`])),
217
+ NONE: "어느 existingOwners와도 완료물·소유 범위가 맞지 않는다.",
218
+ UNKNOWN: "주어진 사실만으로 어느 existingOwners인지 식별할 수 없다.",
219
+ },
220
+ instructions: "duplicate/additionalInstruction의 답을 가정하지 말고, 이 조각을 맡을 식별 가능한 기존 owner 하나를 고른다.",
221
+ },
222
+ } satisfies Record<string, RoutingQuestion>;
223
+ }
224
+
225
+ export function routingQuestions(policy: RoutingPolicy, candidates: Candidate[], owners: Owner[]) {
226
+ return { ...decisionQuestions(policy, candidates), ...placementQuestions(owners) };
227
+ }
228
+
229
+ export interface DispatchContract {
230
+ workClass: string;
231
+ primaryDeliverable: string;
232
+ ownedPaths: string[];
233
+ findingId: string | null;
234
+ }
235
+
236
+ type DispatchContractLock = Pick<DispatchContract, "workClass" | "primaryDeliverable">;
237
+
238
+ /** TASK_GUARD 블록의 필드 reader. 블록이 없으면 null. */
239
+ function guardFields(task: string): ((name: string) => string) | null {
240
+ const marker = /^\s*TASK_GUARD\s*:\s*$/im.exec(task);
241
+ if (!marker) return null;
242
+ const remainderStart = marker.index + marker[0].length;
243
+ const remainder = task.slice(remainderStart);
244
+ const separator = /\r?\n\s*\r?\n/.exec(remainder);
245
+ const blockEnd = separator ? remainderStart + separator.index : task.length;
246
+ const block = task.slice(remainderStart, blockEnd).replace(/\r\n/g, "\n");
247
+ return (name) => block.match(new RegExp(`^\\s*${name}\\s*:\\s*(.+?)\\s*$`, "im"))?.[1]?.trim() ?? "";
248
+ }
249
+
250
+ function dispatchContract(task: string, lock: DispatchContractLock | undefined): DispatchContract | null {
251
+ const field = guardFields(task);
252
+ if (!field) return null;
253
+ const workClass = field("WORK_CLASS").toLowerCase() || lock?.workClass;
254
+ const primaryDeliverable = field("PRIMARY_DELIVERABLE") || lock?.primaryDeliverable;
255
+ const ownedPaths = parseOwnedPaths(field("OWNED_PATHS"));
256
+ if (!workClass || !primaryDeliverable || ownedPaths.length === 0) return null;
257
+ return {
258
+ workClass,
259
+ primaryDeliverable,
260
+ ownedPaths,
261
+ findingId: field("FINDING_ID") || null,
262
+ };
263
+ }
264
+
265
+ /**
266
+ * 소유 경로는 집합 의미다. 중복을 제거하고 결정적 순서로 정렬한 정규형을 만들며, 문자열 자체는
267
+ * `parseOwnedPaths`가 이미 한 정규화 범위 밖으로 바꾸지 않는다.
268
+ */
269
+ function canonicalOwnedPaths(paths: readonly string[]): string[] {
270
+ return [...new Set(paths)].sort();
271
+ }
272
+
273
+ function briefKey(name: string, contract: DispatchContract) {
274
+ // extension 인스턴스가 session 귀속을 보장한다. 본문·context 문구가 아니라 task 이름과
275
+ // SpawnGuard가 실제로 소비하는 Task Guard 의미 필드로 준비 판단을 연결한다.
276
+ // 소유 경로만 정규형으로 직렬화해, 같은 소유 범위를 뜻하는 계약이 표기 순서나 중복 기재만으로
277
+ // 어긋나지 않게 한다. 정규형은 키·비교용이고 파싱한 계약과 소유 판정 입력은 그대로 둔다.
278
+ return JSON.stringify([name.trim(), { ...contract, ownedPaths: canonicalOwnedPaths(contract.ownedPaths) }]);
279
+ }
280
+
281
+ /** 거절 진단에 싣는 사용자 입력 유래 값(이름·경로·식별자)의 상한. 본문·secret 후보는 싣지 않는다. */
282
+ const DIAGNOSTIC_VALUE_LIMIT = 60;
283
+ const DIAGNOSTIC_LIST_LIMIT = 8;
284
+
285
+ function clipped(value: string, limit = DIAGNOSTIC_VALUE_LIMIT): string {
286
+ const single = value.replace(/\s+/g, " ").trim();
287
+ return single.length > limit ? `${single.slice(0, limit)}…` : single;
288
+ }
289
+
290
+ function clippedList(values: readonly string[]): string {
291
+ const shown = values.slice(0, DIAGNOSTIC_LIST_LIMIT).map((value) => clipped(value, 40));
292
+ return values.length > DIAGNOSTIC_LIST_LIMIT
293
+ ? `${shown.join(", ")} 외 ${values.length - DIAGNOSTIC_LIST_LIMIT}개`
294
+ : shown.join(", ");
295
+ }
296
+
297
+ /**
298
+ * 같은 이름으로 준비된 계약과 이번 발주 계약이 어긋난 필드. 한 항목이 한 필드이므로 길이가 곧
299
+ * 어긋난 필드 수이고, 두 계약이 정확히 같으면 빈 배열이다. OWNED_PATHS는 집합으로 비교하므로
300
+ * 표기 순서와 중복 기재는 차이가 아니다.
301
+ */
302
+ function contractDelta(prepared: DispatchContract, requested: DispatchContract): string[] {
303
+ const delta: string[] = [];
304
+ const pair = (label: string, left: string | null, right: string | null) => {
305
+ if ((left ?? "") === (right ?? "")) return;
306
+ delta.push(`${label} 준비=${left === null ? "<없음>" : `'${clipped(left)}'`} 발주=${right === null ? "<없음>" : `'${clipped(right)}'`}`);
307
+ };
308
+ pair("WORK_CLASS", prepared.workClass, requested.workClass);
309
+ pair("PRIMARY_DELIVERABLE", prepared.primaryDeliverable, requested.primaryDeliverable);
310
+ pair("FINDING_ID", prepared.findingId, requested.findingId);
311
+ const preparedPaths = canonicalOwnedPaths(prepared.ownedPaths);
312
+ const requestedPaths = canonicalOwnedPaths(requested.ownedPaths);
313
+ const added = requestedPaths.filter((path) => !preparedPaths.includes(path));
314
+ const removed = preparedPaths.filter((path) => !requestedPaths.includes(path));
315
+ if (added.length > 0) delta.push(`OWNED_PATHS 추가: ${clippedList(added)}`);
316
+ if (removed.length > 0) delta.push(`OWNED_PATHS 빠짐: ${clippedList(removed)}`);
317
+ return delta;
318
+ }
319
+
320
+ /**
321
+ * 같은 이름의 준비 계약 중 이번 발주 계약과 차이가 가장 적은 것을 고른다. 어긋난 필드 수가 먼저이고,
322
+ * 동률이면 OWNED_PATHS 차집합 크기가 작은 쪽, 그마저 동률이면 목록의 마지막(최신)을 쓴다.
323
+ */
324
+ function closestPreparedContract(prepared: readonly DispatchContract[], requested: DispatchContract): DispatchContract {
325
+ const requestedPaths = canonicalOwnedPaths(requested.ownedPaths);
326
+ let best = prepared[0]!;
327
+ let bestFields = Number.POSITIVE_INFINITY;
328
+ let bestPaths = Number.POSITIVE_INFINITY;
329
+ for (const candidate of prepared) {
330
+ const fields = contractDelta(candidate, requested).length;
331
+ const candidatePaths = canonicalOwnedPaths(candidate.ownedPaths);
332
+ const paths = candidatePaths.filter((path) => !requestedPaths.includes(path)).length
333
+ + requestedPaths.filter((path) => !candidatePaths.includes(path)).length;
334
+ if (fields < bestFields || (fields === bestFields && paths <= bestPaths)) {
335
+ best = candidate;
336
+ bestFields = fields;
337
+ bestPaths = paths;
338
+ }
339
+ }
340
+ return best;
341
+ }
342
+
343
+ /** 빈 delta 안내가 무엇을 비교했는지 함께 보여줄 때 쓰는 비교 범위. */
344
+ const COMPARED_CONTRACT_FIELDS = "WORK_CLASS·PRIMARY_DELIVERABLE·OWNED_PATHS(집합)·FINDING_ID";
345
+
346
+ /**
347
+ * prepared 미일치 거절 문구. 같은 이름으로 준비된 계약이 있으면 가장 가까운 계약과 어긋난 필드만
348
+ * 지목하고, 이름 자체가 없으면 이 session에 준비된 이름 목록을 보여준 뒤 다음 한 수를 제시한다.
349
+ */
350
+ function preparedMismatchReason(
351
+ name: string,
352
+ requested: DispatchContract,
353
+ prepared: readonly DispatchContract[],
354
+ preparedNames: readonly string[],
355
+ ): string {
356
+ const label = name ? `이름 '${clipped(name)}'` : "빈 task 이름";
357
+ if (prepared.length === 0) {
358
+ const known = preparedNames.length > 0
359
+ ? `이 session에 준비된 이름: ${clippedList(preparedNames)}`
360
+ : "이 session에는 준비된 발주가 없습니다";
361
+ return `${label}으로 준비된 발주가 없습니다. ${known}. 그 이름과 이번 Task Guard 계약·관측 사실로 maker_route를 다시 부르고 그 결과의 preparedId로 발주하세요. 본문·context 문구는 연결 키가 아니며 같은 브리프를 두 번 판정하지 않습니다.`;
362
+ }
363
+ const delta = contractDelta(closestPreparedContract(prepared, requested), requested);
364
+ if (delta.length === 0) {
365
+ // 키가 정규형이라 여기 도달하면 준비 기록과 발주 입력의 연결 자체가 어긋난 상태다. 없는 차이를
366
+ // 지어내지 않고, 비교한 범위와 다음 한 수만 말한다.
367
+ return `${label}의 준비 계약과 이번 발주 계약은 ${COMPARED_CONTRACT_FIELDS}에서 차이가 없습니다. 같은 이름과 같은 Task Guard 계약으로 maker_route를 다시 불러 새 preparedId를 받은 뒤 그 값으로 발주하세요. 본문·context 문구는 연결 키가 아닙니다.`;
368
+ }
369
+ return `${label}의 준비 계약과 이번 발주 계약이 다릅니다: ${delta.join("; ")}. 위 차이를 포함한 이번 계약으로 maker_route를 다시 부르고 그 결과의 preparedId로 발주하세요. 본문·context 문구는 연결 키가 아닙니다.`;
370
+ }
371
+
372
+ function ownedPathsOverlap(left: string, right: string): boolean {
373
+ return isPathOwned([left], right) || isPathOwned([right], left);
374
+ }
375
+
376
+ function relevantOwners(contract: DispatchContract, owners: Owner[]): Owner[] {
377
+ return owners.filter((owner) =>
378
+ owner.ownedPaths.some((owned) =>
379
+ contract.ownedPaths.some((requested) => ownedPathsOverlap(owned, requested))
380
+ )
381
+ );
382
+ }
383
+
384
+ function ownerRevision(owners: Owner[]): string {
385
+ return JSON.stringify(owners.map((owner) => [
386
+ owner.name,
387
+ owner.primaryDeliverable,
388
+ owner.ownedPaths,
389
+ ]));
390
+ }
391
+
392
+ function placementOf(
393
+ prepared: { status: "judged" | "unavailable"; answers: Record<string, RoutingAnswer> | null },
394
+ owners: Owner[],
395
+ ): RoutingPlacement {
396
+ if (prepared.status !== "judged" || !prepared.answers) {
397
+ return { action: "main-decision", ownerIndex: null, owner: null };
398
+ }
399
+ const duplicate = (prepared.answers.duplicate?.noul ?? 0) >= 0.5;
400
+ const additional = (prepared.answers.additionalInstruction?.noul ?? 0) >= 0.5;
401
+ const target = prepared.answers.ownerTarget?.choice?.match(/^owner(\d+)$/);
402
+ const ownerIndex = target ? Number(target[1]) : -1;
403
+ const owner = owners[ownerIndex] ?? null;
404
+ if (!owner || (!duplicate && !additional)) {
405
+ return { action: "dispatch-new", ownerIndex: null, owner: null };
406
+ }
407
+ return {
408
+ action: additional ? "instruct-existing" : "retarget-existing",
409
+ ownerIndex,
410
+ owner,
411
+ };
412
+ }
413
+
414
+ const isRetired = (model: string) => /(?:^|\/)swe-2(?:[:/]|$)|^devin\//i.test(model);
415
+
416
+ /** Jev hardFocus 답과 HARD 후보 profile의 대응. 값은 `modelSelection.profiles`의 profile 이름이다. */
417
+ const HARD_FOCUS_PROFILES: Readonly<Record<string, string>> = {
418
+ UI_UX: "HARD_UI_OPUS",
419
+ CODE_SYSTEM: "HARD_CODE_OPUS",
420
+ };
421
+
422
+ /**
423
+ * 비-UI NORMAL은 primary(NORMAL_SOL = modelRoles.implSol)를 우선한다.
424
+ * 대안이 한도 여유가 더 크다는 이유로 primary를 밀지 않는다. 계정 사용 가능성은 core 신호
425
+ * (disabled·limitReached·autoBlockedUntil)로만 보고, 미관측은 소진으로 간주하지 않는다.
426
+ */
427
+ function normalAllocation(policy: RoutingPolicy, candidates: readonly Candidate[], quota: QuotaSnapshot) {
428
+ const normal = candidates.filter((candidate) => policy.modelSelection.profiles[candidate.profile]?.workClass === "NORMAL" && candidate.profile !== "NORMAL_OPUS");
429
+ const primary = normal.find((candidate) => candidate.profile === "NORMAL_SOL");
430
+ const unavailable = (reason: string) => ({ state: "unavailable" as const, profile: (primary ?? normal[0])?.profile ?? null, reason });
431
+ if (quota.state !== "observed") return unavailable(quota.reason);
432
+ /** 그 후보 provider의 관측된 계정이 모두 사용 불가할 때만 소진으로 본다. 계정을 관측하지 못하면 소진이 아니다. */
433
+ const exhausted = (candidate: Candidate) => {
434
+ const provider = candidate.model.slice(0, candidate.model.indexOf("/"));
435
+ const accounts = quota.providers[provider] ?? [];
436
+ if (!accounts.length) return false;
437
+ return !accounts.some((account) => !account.disabled && !account.limitReached
438
+ && !(account.autoBlockedUntilMs != null && account.autoBlockedUntilMs > quota.observedAt));
439
+ };
440
+ if (!primary) {
441
+ // primary NORMAL 후보 자체가 없으면(사용 불가·후보 제외) 사용 가능한 NORMAL 대안을 쓴다.
442
+ const alternative = normal.find((candidate) => !exhausted(candidate));
443
+ if (alternative) {
444
+ return { state: "observed" as const, profile: alternative.profile, reason: "primary NORMAL 후보가 없어 사용 가능한 NORMAL 대안을 추천합니다." };
445
+ }
446
+ return unavailable("사용 가능한 NORMAL 후보가 없습니다.");
447
+ }
448
+ if (!exhausted(primary)) {
449
+ return { state: "observed" as const, profile: primary.profile, reason: "primary NORMAL이 사용 가능해 한도 여유 크기 비교 없이 이를 추천합니다." };
450
+ }
451
+ const fallback = normal.find((candidate) => candidate.profile !== primary.profile && !exhausted(candidate));
452
+ if (fallback) {
453
+ return { state: "observed" as const, profile: fallback.profile, reason: "primary NORMAL 계정 한도가 소진되어 사용 가능한 NORMAL 대안을 추천합니다." };
454
+ }
455
+ return unavailable("primary NORMAL 계정 한도가 소진되었고 사용 가능한 NORMAL 대안이 없습니다.");
456
+ }
457
+
458
+ function recommendedProfile(answers: Record<string, RoutingAnswer> | null, candidates: readonly Candidate[]) {
459
+ const workClass = answers?.workClass?.choice;
460
+ const profile = workClass === "HARD"
461
+ ? HARD_FOCUS_PROFILES[answers?.hardFocus?.choice ?? ""] ?? null
462
+ : null;
463
+ return candidates.some((candidate) => candidate.profile === profile) ? profile : null;
464
+ }
465
+
466
+
467
+ export function registerMakerRouting(pi: ExtensionAPI, deps: RoutingDeps) {
468
+ type Judgment = {
469
+ answers: Record<string, RoutingAnswer> | null;
470
+ status: "judged" | "unavailable";
471
+ error?: string;
472
+ };
473
+ type Prepared = Judgment & {
474
+ revision: string;
475
+ profile: string | null;
476
+ candidates: Candidate[];
477
+ owners: Owner[];
478
+ publicationToken: symbol;
479
+ refreshAttempts: RefreshAttempts;
480
+ };
481
+ const bindings = new Map<string, Promise<Prepared>>();
482
+ // 검사를 통과한 발주의 이력 초안. spawn 성공(noteSpawned) 때만 identity와 함께 ledger에 남긴다.
483
+ const pendingDispatches = new Map<string, Omit<DispatchRecord, "ts" | keyof AttemptIdentity>>();
484
+ // 거절 진단 전용 색인. 준비된 계약을 이름별로 시간순으로 모아 어긋난 필드를 지목하며,
485
+ // 통과·차단 판정에는 관여하지 않는다.
486
+ const preparedContracts = new Map<string, DispatchContract[]>();
487
+ const decisionCache = new Map<string, Promise<Judgment>>();
488
+ const placementCache = new Map<string, Promise<Judgment>>();
489
+ const latestPublications = new Map<string, { identity: string; token: symbol; pending: number }>();
490
+ let generation = 0;
491
+ let contractLock: DispatchContractLock | undefined;
492
+ const reset = () => {
493
+ generation++;
494
+ bindings.clear();
495
+ pendingDispatches.clear();
496
+ preparedContracts.clear();
497
+ decisionCache.clear();
498
+ placementCache.clear();
499
+ latestPublications.clear();
500
+ contractLock = undefined;
501
+ };
502
+ const releaseContractLock = () => {
503
+ contractLock = undefined;
504
+ };
505
+ const policy = deps.policy ?? loadRoutingPolicy;
506
+ async function candidateSet(ctx: ExtensionContext, current: RoutingPolicy, attempts?: RefreshAttempts): Promise<CandidateSet> {
507
+ // registry 지원 강도 중 profile 허용 구간 안의 것만 후보 강도다. 구간 밖(max 포함)은 질문도 발주도 하지 않는다.
508
+ const allowedEfforts = (profile: string, efforts: readonly string[]) => {
509
+ const allowed = current.modelSelection.profiles[profile]?.allowedEfforts ?? [];
510
+ return efforts.filter((level) => allowed.includes(level));
511
+ };
512
+ if (deps.candidates) return {
513
+ available: (await deps.candidates(ctx, current)).map((candidate) => ({
514
+ ...candidate, efforts: allowedEfforts(candidate.profile, candidate.efforts),
515
+ })).filter((candidate) => candidate.efforts.length > 0),
516
+ unavailable: [],
517
+ };
518
+ const settings = await deps.settings(ctx);
519
+ if (!settings) throw new Error("Maker 라우팅 설정을 읽을 수 없습니다.");
520
+ // 임의 slot은 modelRoles record에서 읽는다(OMP 18.3.1은 Settings.get을 없앴고 getModelRoles만 남겼다).
521
+ const modelRoles = settings.getModelRoles();
522
+ const profiles = Object.entries(current.modelSelection.profiles);
523
+ // 후보 하나의 장애는 그 후보만 unavailable로 표시한다. 선택하지 않을 후보 때문에 발주 전체를 막지 않는다.
524
+ // 자리(slot)는 profile 순서를 지킨다. 강도 확인은 registry에서 찾은 뒤 그 자리에서 한 번만 한다.
525
+ const slots: (Candidate | UnavailableCandidate)[] = [];
526
+ const retryable: { index: number; profile: string; base: string; provider: string; id: string }[] = [];
527
+ profiles.forEach(([profile, entry], index) => {
528
+ const selector = modelRoles[entry.modelConfigPath.slice("modelRoles.".length)] ?? "";
529
+ const base = selector.replace(/:(?:off|minimal|low|medium|high|xhigh|max)$/, "");
530
+ if (isRetired(base)) { slots[index] = { profile, model: base, reason: "SWE-2는 새 작업 후보에서 제외되어 있습니다." }; return; }
531
+ const slash = base.indexOf("/");
532
+ const provider = base.slice(0, slash), id = base.slice(slash + 1);
533
+ const model = ctx.modelRegistry.find(provider, id);
534
+ if (model) {
535
+ const efforts = allowedEfforts(profile, model.thinking?.efforts ?? []);
536
+ slots[index] = efforts.length > 0
537
+ ? { profile, model: base, efforts }
538
+ : { profile, model: base, reason: "지원 추론 강도를 확인할 수 없는 후보" };
539
+ return;
540
+ }
541
+ if (slash > 0) { retryable.push({ index, profile, base, provider, id }); return; }
542
+ slots[index] = { profile, model: base, reason: "registry에 없는 Maker 후보" };
543
+ });
544
+ if (retryable.length > 0) {
545
+ // 같은 준비→발주 계약에서 같은 provider의 online 갱신은 한 번만 시작하고,
546
+ // 서로 다른 provider는 함께 시작한다. 새 prepare/reset은 새 map으로 다시 시도한다.
547
+ const attempt = (provider: string): Promise<string | null> => {
548
+ const shared = attempts?.get(provider);
549
+ if (shared) return shared;
550
+ const started = (async () => {
551
+ try {
552
+ await ctx.modelRegistry.refreshProvider(provider, "online");
553
+ return null;
554
+ } catch (error) {
555
+ return `provider 갱신 실패: ${error instanceof Error ? error.message : String(error)}`;
556
+ }
557
+ })();
558
+ attempts?.set(provider, started);
559
+ return started;
560
+ };
561
+ const failures = new Map<string, string | null>();
562
+ await Promise.all([...new Set(retryable.map((item) => item.provider))].map(async (provider) => {
563
+ failures.set(provider, await attempt(provider));
564
+ }));
565
+ for (const item of retryable) {
566
+ const failure = failures.get(item.provider);
567
+ const model = failure ? undefined : ctx.modelRegistry.find(item.provider, item.id);
568
+ const efforts = allowedEfforts(item.profile, model?.thinking?.efforts ?? []);
569
+ slots[item.index] = efforts.length > 0
570
+ ? { profile: item.profile, model: item.base, efforts }
571
+ : {
572
+ profile: item.profile,
573
+ model: item.base,
574
+ reason: model ? "지원 추론 강도를 확인할 수 없는 후보" : failure ?? "registry에 없는 Maker 후보",
575
+ };
576
+ }
577
+ }
578
+ const available = slots.filter((slot): slot is Candidate => "efforts" in slot);
579
+ const unavailable = slots.filter((slot): slot is UnavailableCandidate => !("efforts" in slot));
580
+ if (!available.length) {
581
+ throw new Error(`사용 가능한 Maker 후보가 없습니다: ${unavailable.map((item) => `${item.profile}=${item.model || "<빈 slot>"} (${item.reason})`).join("; ")}`);
582
+ }
583
+ return { available, unavailable };
584
+ }
585
+ const candidateList = async (ctx: ExtensionContext, current: RoutingPolicy, attempts?: RefreshAttempts) =>
586
+ (await candidateSet(ctx, current, attempts)).available;
587
+ const revisionOf = (current: RoutingPolicy, candidates: Candidate[]) =>
588
+ JSON.stringify([current.modelSelection, current.effortSelection, candidates]);
589
+
590
+ const answersFor = (
591
+ answers: Record<string, RoutingAnswer>,
592
+ questions: Record<string, RoutingQuestion>,
593
+ ): Record<string, RoutingAnswer> =>
594
+ Object.fromEntries(Object.keys(questions).flatMap((key) => answers[key] ? [[key, answers[key]!]] : []));
595
+ const cacheJudgment = (
596
+ cache: Map<string, Promise<Judgment>>,
597
+ key: string,
598
+ pending: Promise<Judgment>,
599
+ ): Promise<Judgment> => {
600
+ cache.set(key, pending);
601
+ void pending.then((result) => {
602
+ if (result.status === "unavailable" && cache.get(key) === pending) cache.delete(key);
603
+ });
604
+ return pending;
605
+ };
606
+
607
+ const judge = async (
608
+ ctx: ExtensionContext,
609
+ state: unknown,
610
+ questions: Record<string, RoutingQuestion>,
611
+ signal?: AbortSignal,
612
+ ): Promise<Judgment> => {
613
+ try {
614
+ const result = await deps.judge(ctx, { state, questions }, signal);
615
+ return { answers: result.answers, status: "judged" };
616
+ } catch (error) {
617
+ return {
618
+ answers: null,
619
+ status: "unavailable",
620
+ error: error instanceof Error ? error.message : String(error),
621
+ };
622
+ }
623
+ };
624
+
625
+ const INSTRUCTION = "Main은 profile·recommendations.uiUxBoundary·placement·history를 보고 후보와 concrete effort를 지정합니다. 등급 NORMAL/HARD와 모델 이름을 구분합니다. NORMAL UI/UX 경계는 NORMAL_OPUS, 비-UI는 NORMAL_SOL 우선이며 실제 소진·사용 불가 때만 NORMAL_DEEPSEEK를 추천합니다. 한도 미관측은 소진이 아닙니다. 기존 NORMAL의 명시적 Opus 선택은 ROUTING_REASON으로 유지합니다. HARD는 UI_UX→HARD_UI_OPUS, CODE_SYSTEM→HARD_CODE_OPUS이며 HARD_CODE_ASTRA는 명시적 대안입니다. 후보별 허용·registry 지원 강도만 쓰고 max나 coarse effort는 쓰지 않습니다. 작업 중 UI/UX 경계가 드러나면 기존 owner의 실제 모델을 확인하고, 비-Opus의 미완 변경·증거를 freeze해 소유권을 넘깁니다. active writer와 겹치거나 실행 중 모델·effort를 바꾸지 않습니다. 같은 Opus owner와 완료된 비-UI 작업은 재사용합니다. Opus unavailable을 다른 후보로 숨기지 않습니다. 계정 warm/exact pin·전환·쿨다운·리셋은 유지합니다. 추천 변경·Jev 불가·기존 owner 대신 새 발주는 ROUTING_REASON을 남깁니다. history는 같은 등급 최근 attempt의 중립 건수이며 후보·규칙을 자동 변경하지 않습니다. routing_verdict에는 실제 spawn identity를 씁니다. context='PREPARED_CONTEXT', task='PREPARED_TASK: <preparedId>'로 원문을 재사용하며 같은 브리프에 judge를 중복 호출하지 않습니다.";
626
+ /** 배치 공통 정보(candidates·quota·instruction)는 한 번만, task별 route는 배열로 돌려준다. */
627
+ async function prepareBatch(context: string, tasks: RouteTask[], ctx: ExtensionContext, signal?: AbortSignal, callId = "") {
628
+ const current = policy();
629
+ const allOwners = deps.owners();
630
+ const atGeneration = generation;
631
+ // TaskGuard는 같은 요청의 첫 child가 확립한 WORK_CLASS/PRIMARY_DELIVERABLE을 이후 child에
632
+ // 파생한다. 준비 도구도 같은 batch와 이미 연결된 task에서 그 두 필드만 상속한다.
633
+ let candidateLock = contractLock;
634
+ const contracts = tasks.map((task) => {
635
+ const contract = dispatchContract(task.task, candidateLock);
636
+ if (!contract) throw new Error("maker_route와 task는 TaskGuard lock으로 완성 가능한 WORK_CLASS·PRIMARY_DELIVERABLE 및 명시 OWNED_PATHS가 필요합니다.");
637
+ candidateLock ??= { workClass: contract.workClass, primaryDeliverable: contract.primaryDeliverable };
638
+ return contract;
639
+ });
640
+ const keys = tasks.map((task, index) => briefKey(task.name, contracts[index]!));
641
+ // 준비 handle. 실제 발주 identity는 spawn에서 task 호출 id·index·session으로 캡처한다.
642
+ // 이 값으로 실제 발주를 식별하지 않으며, 중첩 prepare가 서로를 덮지 않도록 공유 map에 두지 않는다.
643
+ const sessionId = (ctx.sessionManager?.getSessionId?.() ?? "").trim();
644
+ const plans = tasks.map((_task, index) => ({ sessionId, planId: `${sessionId}#${callId}#${index}` }));
645
+ const publicationClaims = tasks.map((task, index) => {
646
+ const key = keys[index]!;
647
+ const identity = JSON.stringify([
648
+ routingFactsState(task.assessment),
649
+ current.modelSelection,
650
+ current.effortSelection,
651
+ ]);
652
+ const latest = latestPublications.get(key);
653
+ if (latest?.identity === identity && latest.pending > 0) {
654
+ latest.pending += 1;
655
+ return { key, token: latest.token };
656
+ }
657
+ const token = Symbol(key);
658
+ latestPublications.set(key, { identity, token, pending: 1 });
659
+ return { key, token };
660
+ });
661
+ const requireLatest = () => {
662
+ if (atGeneration !== generation) throw new Error("session이 변경되어 이전 라우팅 판단은 폐기되었습니다.");
663
+ if (publicationClaims.some((claim) => latestPublications.get(claim.key)?.token !== claim.token)) {
664
+ throw new Error("같은 task 계약에 더 최신 facts 준비가 있어 이전 라우팅 판단은 폐기되었습니다.");
665
+ }
666
+ };
667
+ let quotaAbort: AbortController | undefined;
668
+ try {
669
+ const ownersByTask = contracts.map((contract) => relevantOwners(contract, allOwners));
670
+ const refreshAttempts: RefreshAttempts = new Map();
671
+ const { available: candidates, unavailable: unavailableCandidates } = await candidateSet(ctx, current, refreshAttempts);
672
+ requireLatest();
673
+ // 잔량은 시각마다 바뀌므로 revision·identity·Jev state 밖의 참고 정보로만 붙인다.
674
+ // Jev 판단과 함께 시작하고, 이번 계정 잔량 조회가 끝난 뒤 배정 결과를 반환한다.
675
+ // 기존 조회 시간 제한과 사용자 AbortSignal은 유지한다.
676
+ const quotaProviders = [...new Set(candidates.map((candidate) => candidate.model.slice(0, candidate.model.indexOf("/"))))];
677
+ quotaAbort = new AbortController();
678
+ const quotaSignal = signal
679
+ ? AbortSignal.any([signal, quotaAbort.signal])
680
+ : quotaAbort.signal;
681
+ let quotaPending: Promise<QuotaSnapshot>;
682
+ try {
683
+ quotaPending = (deps.quota ?? readSidecarQuota)(quotaProviders, quotaSignal).catch(
684
+ (error): QuotaSnapshot => ({
685
+ state: "unavailable",
686
+ observedAt: Date.now(),
687
+ reason: error instanceof Error ? error.message : String(error),
688
+ }),
689
+ );
690
+ } catch (error) {
691
+ quotaPending = Promise.resolve({
692
+ state: "unavailable",
693
+ observedAt: Date.now(),
694
+ reason: error instanceof Error ? error.message : String(error),
695
+ });
696
+ }
697
+ const publications = await Promise.all(tasks.map(async (task, index) => {
698
+ const contract = contracts[index]!;
699
+ const owners = ownersByTask[index]!;
700
+ const revision = revisionOf(current, candidates);
701
+ const key = keys[index]!;
702
+ const decisionState = routingFactsState(task.assessment);
703
+ const decisionKey = JSON.stringify([key, decisionState, revision]);
704
+ const placementKey = JSON.stringify([decisionKey, ownerRevision(owners)]);
705
+ const baseQuestions = decisionQuestions(current, candidates);
706
+ const ownerQuestions = placementQuestions(owners);
707
+ let decisionPending = decisionCache.get(decisionKey);
708
+ let placementPending = placementCache.get(placementKey);
709
+
710
+ if (!decisionPending) {
711
+ const fullQuestions = { ...baseQuestions, ...ownerQuestions };
712
+ const fullPending = judge(ctx, routingState(task.assessment, owners), fullQuestions, signal);
713
+ decisionPending = cacheJudgment(
714
+ decisionCache,
715
+ decisionKey,
716
+ fullPending.then((result) => ({
717
+ ...result,
718
+ answers: result.answers ? answersFor(result.answers, baseQuestions) : null,
719
+ })),
720
+ );
721
+ if (owners.length > 0) {
722
+ placementPending = cacheJudgment(
723
+ placementCache,
724
+ placementKey,
725
+ fullPending.then((result) => ({
726
+ ...result,
727
+ answers: result.answers ? answersFor(result.answers, ownerQuestions) : null,
728
+ })),
729
+ );
730
+ }
731
+ } else if (!placementPending && owners.length > 0) {
732
+ placementPending = cacheJudgment(
733
+ placementCache,
734
+ placementKey,
735
+ judge(
736
+ ctx,
737
+ routingState(task.assessment, owners),
738
+ ownerQuestions,
739
+ signal,
740
+ ).then((result) => ({
741
+ ...result,
742
+ answers: result.answers ? answersFor(result.answers, ownerQuestions) : null,
743
+ })),
744
+ );
745
+ }
746
+
747
+ const decision = await decisionPending;
748
+ const placement = placementPending
749
+ ? await placementPending
750
+ : { status: "judged" as const, answers: {} };
751
+ const prepared: Prepared = {
752
+ revision,
753
+ profile: null,
754
+ candidates,
755
+ publicationToken: publicationClaims[index]!.token,
756
+ refreshAttempts: new Map(refreshAttempts),
757
+ owners,
758
+ status: decision.status === "judged" && placement.status === "judged" ? "judged" : "unavailable",
759
+ error: [decision.error, placement.error].filter(Boolean).join("; ") || undefined,
760
+ answers: decision.answers === null
761
+ ? null
762
+ : { ...decision.answers, ...(placement.answers ?? {}) },
763
+ };
764
+ requireLatest();
765
+ return {
766
+ key,
767
+ prepared,
768
+ route: {
769
+ name: task.name,
770
+ status: prepared.status,
771
+ error: prepared.error,
772
+ recommendations: prepared.answers,
773
+ placement: placementOf(prepared, owners),
774
+ existingOwners: owners,
775
+ },
776
+ };
777
+ }));
778
+ const quota = await quotaPending;
779
+ requireLatest();
780
+ const allocation = normalAllocation(current, candidates, quota);
781
+ // 이력은 advisory다. revision·identity·Jev state 밖에 두며 읽기 실패는 빈 이력이다.
782
+ const ledgerRecords = deps.ledger?.read();
783
+ const historyOf = (answers: Record<string, RoutingAnswer> | null): RoutingHistory | null => {
784
+ const grade = answers?.workClass?.choice;
785
+ if (!ledgerRecords || !grade || !(grade in current.modelSelection.criteria)) return null;
786
+ return summarizeHistory(ledgerRecords, grade, grade === "HARD" ? answers?.hardFocus?.choice ?? null : null);
787
+ };
788
+ for (const publication of publications) {
789
+ const answers = publication.prepared.answers;
790
+ const uiUxBoundary = (answers?.uiUxBoundary?.noul ?? 0) >= 0.5;
791
+ publication.prepared.profile = answers?.workClass?.choice === "NORMAL"
792
+ ? uiUxBoundary
793
+ ? candidates.find((candidate) => candidate.profile === "NORMAL_OPUS")?.profile ?? null
794
+ : allocation.profile
795
+ : recommendedProfile(answers, candidates);
796
+ }
797
+ const sessionId = ctx.sessionManager?.getSessionId?.();
798
+ if (typeof sessionId !== "string" || !sessionId.trim()) {
799
+ throw new Error("maker_route prepared 참조를 저장할 current session id가 없습니다.");
800
+ }
801
+ const preparedIds = storePreparedTaskBatch(context, tasks, sessionId);
802
+ publications.forEach((publication, index) => {
803
+ bindings.set(publication.key, Promise.resolve(publication.prepared));
804
+ const name = tasks[index]!.name.trim();
805
+ preparedContracts.set(name, [...(preparedContracts.get(name) ?? []), contracts[index]!]);
806
+ });
807
+ return {
808
+ candidates,
809
+ unavailableCandidates,
810
+ quota,
811
+ instruction: INSTRUCTION,
812
+ routes: publications.map((publication, index) => ({
813
+ ...publication.route,
814
+ profile: publication.prepared.profile,
815
+ normalAllocation: publication.prepared.answers?.workClass?.choice === "NORMAL"
816
+ && (publication.prepared.answers?.uiUxBoundary?.noul ?? 0) < 0.5 ? allocation : null,
817
+ uiUxHandoff: (publication.prepared.answers?.uiUxBoundary?.noul ?? 0) >= 0.5
818
+ ? "기존 owner가 Opus인지 확인하세요. 비-Opus면 미완 변경·증거를 freeze하고 소유권을 넘깁니다. active owner를 동시에 새 발주하거나 실행 중 모델을 바꾸지 않습니다."
819
+ : null,
820
+ history: historyOf(publication.prepared.answers),
821
+ preparedId: preparedIds[index],
822
+ plan: plans[index] ?? { sessionId, planId: null },
823
+ })),
824
+ };
825
+ } finally {
826
+ quotaAbort?.abort();
827
+ for (const claim of publicationClaims) {
828
+ const latest = latestPublications.get(claim.key);
829
+ if (latest?.token === claim.token && latest.pending > 0) latest.pending -= 1;
830
+ }
831
+ }
832
+ }
833
+ /** task별 route만 필요한 호출부용. 배치 공통 정보는 `prepareBatch`가 준다. */
834
+ const prepare = async (context: string, tasks: RouteTask[], ctx: ExtensionContext, signal?: AbortSignal) =>
835
+ (await prepareBatch(context, tasks, ctx, signal)).routes;
836
+
837
+ async function beforeTask(input: Record<string, unknown>, ctx: ExtensionContext) {
838
+ let canonicalInput: Record<string, unknown>;
839
+ try {
840
+ const sessionId = ctx.sessionManager?.getSessionId?.();
841
+ canonicalInput = resolvePreparedTaskInput(input, typeof sessionId === "string" ? sessionId : "");
842
+ } catch (error) {
843
+ return { block: true, reason: error instanceof Error ? error.message : String(error) };
844
+ }
845
+ const tasks = (Array.isArray(canonicalInput.tasks) ? canonicalInput.tasks : [canonicalInput]) as Record<string, unknown>[];
846
+ const atGeneration = generation;
847
+ // 후보 해석은 작업마다 현재 local registry로 다시 한다. 같은 prepared 계약에서 이미 시작한
848
+ // online provider 시도만 재사용하고, 이 task 호출에서 새로 필요한 provider도 함께 공유한다.
849
+ const refreshAttempts: RefreshAttempts = new Map();
850
+ let candidateLock = contractLock;
851
+ const contracts = tasks.map((item) => {
852
+ const task = typeof item.task === "string" ? item.task : "";
853
+ const contract = dispatchContract(task, candidateLock);
854
+ if (!contract) return null;
855
+ candidateLock ??= { workClass: contract.workClass, primaryDeliverable: contract.primaryDeliverable };
856
+ return contract;
857
+ });
858
+ const drafts: [string, Omit<DispatchRecord, "ts" | keyof AttemptIdentity>][] = [];
859
+ for (const [itemIndex, item] of tasks.entries()) {
860
+ const requested = typeof item.model === "string" ? item.model : "";
861
+ const task = typeof item.task === "string" ? item.task : "";
862
+ if (isRetired(requested) || /\[character-summon[^\]]*model="devin\//.test(task)) return { block: true, reason: "SWE-2 사용은 중단되었습니다. 인증·기록·캐릭터 identity를 바꾸지 않으며 다른 모델로 몰래 대체하지 않습니다." };
863
+ // 명시적 캐릭터 summon은 일반 구현 발주가 아니며 기존 summon guard가 검증한다.
864
+ if (/\[character-summon alias="[^"]+" model="[^"]+"/.test(task)) continue;
865
+ const contract = contracts[itemIndex];
866
+ if (!contract) return { block: true, reason: "task는 TaskGuard lock으로 완성 가능한 WORK_CLASS·PRIMARY_DELIVERABLE 및 명시 OWNED_PATHS가 필요합니다." };
867
+ const name = String(item.name ?? "").trim();
868
+ const key = briefKey(String(item.name ?? ""), contract);
869
+ const pending = bindings.get(key);
870
+ if (!pending) {
871
+ return { block: true, reason: preparedMismatchReason(name, contract, preparedContracts.get(name) ?? [], [...preparedContracts.keys()]) };
872
+ }
873
+ const prepared = await pending;
874
+ for (const [provider, attempt] of prepared.refreshAttempts) {
875
+ if (!refreshAttempts.has(provider)) refreshAttempts.set(provider, attempt);
876
+ }
877
+ if (atGeneration !== generation) {
878
+ return { block: true, reason: "session이 변경되어 이전 라우팅 판단은 발주에 사용할 수 없습니다." };
879
+ }
880
+ if (latestPublications.get(key)?.token !== prepared.publicationToken) {
881
+ return { block: true, reason: "같은 task 계약에 더 최신 maker_route 준비가 있습니다. 최신 판단이 끝난 뒤 그 결과로 발주하세요." };
882
+ }
883
+ const current = policy();
884
+ const candidates = await candidateList(ctx, current, refreshAttempts);
885
+ if (atGeneration !== generation) {
886
+ return { block: true, reason: "session이 변경되어 이전 라우팅 판단은 발주에 사용할 수 없습니다." };
887
+ }
888
+ if (latestPublications.get(key)?.token !== prepared.publicationToken) {
889
+ return { block: true, reason: "candidate 확인 중 같은 task 계약에 더 최신 maker_route 준비가 생겼습니다. 최신 판단으로 발주하세요." };
890
+ }
891
+ if (prepared.revision !== revisionOf(current, candidates)) return { block: true, reason: "후보 또는 판단 기준이 바뀌었습니다. maker_route로 변경된 조건만 다시 판단하세요." };
892
+ const owners = relevantOwners(contract, deps.owners());
893
+ if (ownerRevision(prepared.owners) !== ownerRevision(owners)) return { block: true, reason: "현재 소유권 충돌 조건이 바뀌었습니다. maker_route로 owner placement만 다시 판단하세요." };
894
+ // 같은 모델이 여러 profile에 있을 수 있다(HARD_*). 추천 profile, 이어서 추천 등급의
895
+ // profile 구간으로 검사해 등급의 강도 구간을 모델 이름으로 우회하지 못하게 한다. 추천 등급에 그 모델이
896
+ // 없거나 등급을 모르면(Jev 불가) 그 강도를 허용하는 profile로 본다. 추천과 다른 profile은 아래에서 ROUTING_REASON을 요구한다.
897
+ const cut = requested.lastIndexOf(":");
898
+ const effort = cut > 0 ? requested.slice(cut + 1) : "";
899
+ const sameModel = candidates.filter((candidate) => candidate.model === (cut > 0 ? requested.slice(0, cut) : requested));
900
+ const grade = (prepared.profile ? current.modelSelection.profiles[prepared.profile]?.workClass : undefined)
901
+ ?? prepared.answers?.workClass?.choice;
902
+ const sameGrade = sameModel.filter((candidate) => current.modelSelection.profiles[candidate.profile]?.workClass === grade);
903
+ const pool = sameGrade.length > 0 ? sameGrade : sameModel;
904
+ const selected = sameModel.find((candidate) => candidate.profile === prepared.profile)
905
+ ?? pool.find((candidate) => candidate.efforts.includes(effort))
906
+ ?? pool[0];
907
+ if (!selected || item.effort !== undefined) return { block: true, reason: "maker_route가 확인한 후보와 concrete effort를 model selector에 지정하세요. coarse effort는 전달하지 않습니다." };
908
+ if (!selected.efforts.includes(effort)) return { block: true, reason: `${selected.profile}(${selected.model})의 허용 강도는 ${selected.efforts.join("·")}입니다. 구간 밖 강도('${effort || "<없음>"}')로는 발주하지 않습니다.` };
909
+ const answers = prepared.answers;
910
+ if (answers?.workClass?.choice === "NORMAL" && (answers.uiUxBoundary?.noul ?? 0) >= 0.5
911
+ && selected.profile !== "NORMAL_OPUS") {
912
+ return { block: true, reason: "NORMAL UI/UX 경계는 NORMAL_OPUS로 배정합니다. Opus가 없으면 unavailable로 보고하며 다른 후보로 조용히 대체하지 않습니다." };
913
+ }
914
+ const profile = prepared.profile;
915
+ const index = candidates.findIndex((candidate) => candidate.profile === selected.profile);
916
+ const recommendedEffort = selected.efforts.length === 1 ? selected.efforts[0] : answers?.[`effort${index}`]?.choice;
917
+ const placement = placementOf(prepared, owners);
918
+ const activeConflicts = owners.filter((owner) => owner.active === true);
919
+ if (activeConflicts.length > 0) {
920
+ return {
921
+ block: true,
922
+ reason: `현재 active owner의 소유 경로와 충돌합니다: ${activeConflicts.map((owner) => owner.name ?? "<unnamed>").join(", ")}. 오래된 owner index나 다른 경로 owner로 자동 배정하지 말고 현재 owner에게 지시하거나 maker_route로 placement를 다시 판단하세요.`,
923
+ };
924
+ }
925
+ const existingOwner = placement.action === "instruct-existing" || placement.action === "retarget-existing";
926
+ const changed = prepared.status !== "judged" || profile !== selected.profile || recommendedEffort !== effort || existingOwner;
927
+ const routingReason = /^\s*ROUTING_REASON:\s*\S.+$/m.test(task);
928
+ if (changed && !routingReason) return { block: true, reason: existingOwner ? `기존 owner${placement.owner?.name ? ` ${placement.owner.name}` : ""}에게 추가 지시하거나 범위를 retarget하세요. Main이 새 발주를 선택하면 ROUTING_REASON에 근거를 적습니다.` : "Jev 불가·불명확한 지배 판단·추천 변경은 Main이 같은 기준으로 결정하고 ROUTING_REASON 한 줄에 근거를 남깁니다." };
929
+ const recommended = candidates.findIndex((candidate) => candidate.profile === profile);
930
+ const recommendedCandidate = candidates[recommended];
931
+ const workClass = answers?.workClass?.choice ?? null;
932
+ drafts.push([key, {
933
+ type: "dispatch",
934
+ name,
935
+ workClass,
936
+ focus: workClass === "HARD" ? answers?.hardFocus?.choice ?? null : null,
937
+ recommendedProfile: profile,
938
+ recommendedModel: recommendedCandidate?.model ?? null,
939
+ recommendedEffort: !recommendedCandidate ? null
940
+ : recommendedCandidate.efforts.length === 1 ? recommendedCandidate.efforts[0]! : answers?.[`effort${recommended}`]?.choice ?? null,
941
+ chosenModel: selected.model,
942
+ chosenEffort: effort,
943
+ routingReason,
944
+ purpose: guardFields(task)?.("PURPOSE").toLowerCase() || null,
945
+ }]);
946
+ }
947
+ for (const [key, draft] of drafts) pendingDispatches.set(key, draft);
948
+ return canonicalInput === input ? undefined : { input: canonicalInput };
949
+ }
950
+
951
+ /**
952
+ * task spawn 성공 경계. TaskGuard lock을 확립하고, 검사를 통과해 실제로 spawn된 발주만 이력에 남긴다.
953
+ * 실제 attempt identity는 이 spawn의 task 호출 id·index·session으로만 캡처한다(준비 handle과 섞지 않는다).
954
+ * 돌려주는 map은 task index → 관측된 identity이며, settle 시 같은 identity로 outcome을 잇는다.
955
+ */
956
+ function noteSpawned(
957
+ input: Record<string, unknown>,
958
+ sessionId: string,
959
+ callId: string,
960
+ ids: ReadonlyMap<number, { agentId: string; jobId: string }>,
961
+ ): Map<number, AttemptIdentity> {
962
+ const tasks = (Array.isArray(input.tasks) ? input.tasks : [input]) as Record<string, unknown>[];
963
+ const dispatched = new Map<number, AttemptIdentity>();
964
+ // 같은 session 원장에서 이름별 assignment·최대 attempt를 읽어 FINDING_ID 재작업만 같은 assignment로 잇는다.
965
+ // 원장에서 읽으므로 reload 뒤에도 연결이 유지되고, 관측되지 않은 준비만으로는 연결하지 않는다.
966
+ const known = assignmentsByName(deps.ledger?.read() ?? [], sessionId);
967
+ let candidateLock = contractLock;
968
+ for (const [index, item] of tasks.entries()) {
969
+ const task = typeof item.task === "string" ? item.task : "";
970
+ const contract = dispatchContract(task, candidateLock);
971
+ if (!contract) continue;
972
+ candidateLock ??= { workClass: contract.workClass, primaryDeliverable: contract.primaryDeliverable };
973
+ const name = String(item.name ?? "").trim();
974
+ const key = briefKey(name, contract);
975
+ const draft = pendingDispatches.get(key);
976
+ if (!draft) continue;
977
+ pendingDispatches.delete(key);
978
+ // 다른 guard가 막은 뒤 다른 selector로 다시 낸 발주는 그 호출의 beforeTask 초안만 맞는다.
979
+ if (item.model !== `${draft.chosenModel}:${draft.chosenEffort}`) continue;
980
+ const linked = sessionId && contract.findingId !== null ? known.get(name) : undefined;
981
+ const assignmentId = linked?.assignmentId ?? `${sessionId}#${callId}#${index}`;
982
+ const attempt = linked ? linked.lastAttempt + 1 : 1;
983
+ const identity: AttemptIdentity = {
984
+ sessionId,
985
+ assignmentId,
986
+ attempt,
987
+ attemptId: `${assignmentId}#a${attempt}`,
988
+ // canonical child id와 그 spawn의 jobId는 관측한 값만 쓴다. 없으면 비워 두고 추측하지 않는다.
989
+ agentId: ids.get(index)?.agentId ?? "",
990
+ jobId: ids.get(index)?.jobId ?? "",
991
+ };
992
+ deps.ledger?.append({ ...draft, ...identity, ts: new Date().toISOString() });
993
+ dispatched.set(index, identity);
994
+ known.set(name, { assignmentId, lastAttempt: attempt });
995
+ }
996
+ contractLock ??= candidateLock;
997
+ return dispatched;
998
+ }
999
+
1000
+ if (pi.registerTool) {
1001
+ const z = pi.zod;
1002
+ const strings = () => z.array(z.string());
1003
+ const nullable = () => strings().nullable();
1004
+ const parameters = z.object({ context: z.string(), tasks: z.array(z.object({ name: z.string(), task: z.string(), assessment: z.object({ goal: z.string(), acceptance: strings(), facts: strings(), hypotheses: nullable(), unknowns: nullable(), paths: strings(), callBoundaries: nullable(), settledImplementation: nullable(), reusedPatterns: nullable(), remainingJudgments: nullable(), invariants: strings(), checks: strings(), failureEvidence: nullable() }) })) });
1005
+ // SDK 18.2.6 TSchema의 unknown generic 불변성만 연결한다. 실제 Zod schema 검증은 그대로다.
1006
+ const toolParameters = parameters as unknown as ToolDefinition["parameters"];
1007
+ pi.registerTool({
1008
+ name: "maker_route", label: "Maker Route", loadMode: "essential", approval: "read",
1009
+ description: "Main 전용 발주 준비. Jev가 위임 적합성·NORMAL/HARD 난이도·UI/UX 경계·HARD 지배 분야·후보별 effort·owner 중복을 한 배치에서 독립 판단한다. NORMAL UI/UX는 NORMAL_OPUS, 비-UI는 NORMAL_SOL 우선이며 실제 소진·사용 불가 때만 NORMAL_DEEPSEEK를 추천한다. HARD_UI_OPUS·HARD_CODE_OPUS는 분야에 따르고 HARD_CODE_ASTRA는 명시적 대안이다. 새 UI/UX 경계는 기존 비-Opus owner를 freeze해 이관하되 실행 중 모델을 바꾸지 않는다. 후보별 강도·소유권·warm/exact pin을 보존한다. Opus unavailable을 조용히 대체하지 않는다. 난이도를 Opus 선택 수단으로 부풀리지 않는다. history는 advisory이고 routing_verdict는 실제 spawn identity를 쓴다. task 원문을 Jev에 보내거나 동일 브리프를 중복 판단하지 않는다.",
1010
+ parameters: toolParameters,
1011
+ async execute(callId, params, signal, _onUpdate, ctx) {
1012
+ // core가 위 schema로 검증한 입력이며 SDK generic 경계에서 소실된 타입만 복원한다.
1013
+ const request = params as { context: string; tasks: RouteTask[] };
1014
+ const batch = await prepareBatch(request.context, request.tasks, ctx, signal, String(callId ?? ""));
1015
+ return { content: [{ type: "text", text: JSON.stringify(batch) }], details: batch };
1016
+ },
1017
+ });
1018
+ }
1019
+ return { prepare, prepareBatch, beforeTask, noteSpawned, reset, releaseContractLock };
1020
+ }