nodal-agents 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/cli.js +727 -62
  2. package/docs-index.json +1524 -0
  3. package/migrations/0118_agent_jobs_deliverable_check_due.sql +53 -0
  4. package/migrations/0119_job_checkpoints_snapshot_ms.sql +51 -0
  5. package/migrations/0120_excluded_project_paths.sql +38 -0
  6. package/migrations/0121_entities_proof_repair_attempts.sql +32 -0
  7. package/migrations/0122_entities_drop_memory_curation_enabled.sql +17 -0
  8. package/migrations/meta/_journal.json +35 -0
  9. package/package.json +2 -1
  10. package/runner.js +5541 -4081
  11. package/web/.next/BUILD_ID +1 -1
  12. package/web/.next/app-path-routes-manifest.json +1 -1
  13. package/web/.next/build-manifest.json +2 -2
  14. package/web/.next/prerender-manifest.json +5 -5
  15. package/web/.next/server/app/(dashboard)/agents/[id]/channels/page.js +1 -1
  16. package/web/.next/server/app/(dashboard)/agents/[id]/channels/page_client-reference-manifest.js +1 -1
  17. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +4 -4
  18. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
  19. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +1 -1
  20. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
  21. package/web/.next/server/app/(dashboard)/agents/page.js +1 -1
  22. package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/approvals/page.js +1 -1
  24. package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
  25. package/web/.next/server/app/(dashboard)/automations/[id]/page.js +1 -1
  26. package/web/.next/server/app/(dashboard)/automations/[id]/page_client-reference-manifest.js +1 -1
  27. package/web/.next/server/app/(dashboard)/automations/page.js +1 -1
  28. package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
  29. package/web/.next/server/app/(dashboard)/chat/[id]/page.js +1 -1
  30. package/web/.next/server/app/(dashboard)/chat/[id]/page_client-reference-manifest.js +1 -1
  31. package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
  32. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  33. package/web/.next/server/app/(dashboard)/code/[id]/page.js +1 -1
  34. package/web/.next/server/app/(dashboard)/code/[id]/page_client-reference-manifest.js +1 -1
  35. package/web/.next/server/app/(dashboard)/code/page.js +1 -1
  36. package/web/.next/server/app/(dashboard)/code/page_client-reference-manifest.js +1 -1
  37. package/web/.next/server/app/(dashboard)/connectors/page.js +1 -1
  38. package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
  39. package/web/.next/server/app/(dashboard)/credentials/page.js +1 -1
  40. package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
  41. package/web/.next/server/app/(dashboard)/dashboard/page.js +1 -1
  42. package/web/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +1 -1
  44. package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/(dashboard)/jobs/page.js +1 -1
  46. package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
  47. package/web/.next/server/app/(dashboard)/learned-skills/page.js +1 -1
  48. package/web/.next/server/app/(dashboard)/learned-skills/page_client-reference-manifest.js +1 -1
  49. package/web/.next/server/app/(dashboard)/llm-providers/page.js +1 -1
  50. package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
  51. package/web/.next/server/app/(dashboard)/logs/page.js +1 -1
  52. package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
  53. package/web/.next/server/app/(dashboard)/mcp/page.js +1 -1
  54. package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/(dashboard)/memories/page.js +1 -1
  56. package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
  57. package/web/.next/server/app/(dashboard)/page.js +1 -1
  58. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  59. package/web/.next/server/app/(dashboard)/scheduled/[id]/page.js +1 -1
  60. package/web/.next/server/app/(dashboard)/scheduled/[id]/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/(dashboard)/scheduled/page.js +1 -1
  62. package/web/.next/server/app/(dashboard)/scheduled/page_client-reference-manifest.js +1 -1
  63. package/web/.next/server/app/(dashboard)/settings/page.js +1 -1
  64. package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/app/(dashboard)/settings/root-context/page.js +1 -1
  66. package/web/.next/server/app/(dashboard)/settings/root-context/page_client-reference-manifest.js +1 -1
  67. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +1 -1
  68. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
  69. package/web/.next/server/app/(dashboard)/skills/new/page.js +1 -1
  70. package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
  71. package/web/.next/server/app/(dashboard)/skills/page.js +1 -1
  72. package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app/(dashboard)/spaces/[id]/files/page.js +1 -1
  74. package/web/.next/server/app/(dashboard)/spaces/[id]/files/page_client-reference-manifest.js +1 -1
  75. package/web/.next/server/app/(dashboard)/spaces/[id]/page.js +1 -1
  76. package/web/.next/server/app/(dashboard)/spaces/[id]/page_client-reference-manifest.js +1 -1
  77. package/web/.next/server/app/(dashboard)/spaces/page.js +1 -1
  78. package/web/.next/server/app/(dashboard)/spaces/page_client-reference-manifest.js +1 -1
  79. package/web/.next/server/app/_global-error/page.js +2 -2
  80. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  81. package/web/.next/server/app/_global-error.html +1 -1
  82. package/web/.next/server/app/_global-error.rsc +2 -2
  83. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  84. package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +2 -2
  85. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  86. package/web/.next/server/app/_not-found/page.js +1 -1
  87. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  88. package/web/.next/server/app/_not-found.html +1 -1
  89. package/web/.next/server/app/_not-found.rsc +5 -4
  90. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +5 -4
  91. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -13
  92. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  93. package/web/.next/server/app/api/chat/stream/route.js +1 -1
  94. package/web/.next/server/app/api/health/route.js +1 -1
  95. package/web/.next/server/app/api/oauth/[provider]/callback/route.js +1 -1
  96. package/web/.next/server/app/api/oauth/[provider]/start/route.js +1 -1
  97. package/web/.next/server/app/login/page.js +1 -1
  98. package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
  99. package/web/.next/server/app/onboarding/page.js +2 -2
  100. package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  101. package/web/.next/server/app-paths-manifest.json +1 -1
  102. package/web/.next/server/chunks/1041.js +5 -0
  103. package/web/.next/server/chunks/1447.js +1 -1
  104. package/web/.next/server/chunks/168.js +1 -0
  105. package/web/.next/server/chunks/{3431.js → 192.js} +2 -2
  106. package/web/.next/server/chunks/1960.js +1 -0
  107. package/web/.next/server/chunks/{4332.js → 2096.js} +1 -1
  108. package/web/.next/server/chunks/292.js +1 -0
  109. package/web/.next/server/chunks/2933.js +1 -0
  110. package/web/.next/server/chunks/3370.js +1 -0
  111. package/web/.next/server/chunks/3592.js +1 -1
  112. package/web/.next/server/chunks/3675.js +1 -0
  113. package/web/.next/server/chunks/409.js +1 -0
  114. package/web/.next/server/chunks/42.js +3 -3
  115. package/web/.next/server/chunks/4357.js +1 -1
  116. package/web/.next/server/chunks/494.js +1 -0
  117. package/web/.next/server/chunks/5547.js +1 -0
  118. package/web/.next/server/chunks/5554.js +1 -0
  119. package/web/.next/server/chunks/570.js +1 -0
  120. package/web/.next/server/chunks/5804.js +1 -1
  121. package/web/.next/server/chunks/5974.js +1 -0
  122. package/web/.next/server/chunks/6020.js +1 -1
  123. package/web/.next/server/chunks/6106.js +1 -0
  124. package/web/.next/server/chunks/{2198.js → 6213.js} +39 -23
  125. package/web/.next/server/chunks/692.js +1806 -0
  126. package/web/.next/server/chunks/{2076.js → 7134.js} +7 -7
  127. package/web/.next/server/chunks/7431.js +1 -0
  128. package/web/.next/server/chunks/7533.js +1 -0
  129. package/web/.next/server/chunks/{7957.js → 7663.js} +5 -5
  130. package/web/.next/server/chunks/7709.js +1 -0
  131. package/web/.next/server/chunks/7915.js +1 -0
  132. package/web/.next/server/chunks/8022.js +1 -0
  133. package/web/.next/server/chunks/8536.js +3 -0
  134. package/web/.next/server/chunks/8974.js +63 -47
  135. package/web/.next/server/chunks/9200.js +1 -0
  136. package/web/.next/server/chunks/9557.js +1 -0
  137. package/web/.next/server/middleware-build-manifest.js +1 -1
  138. package/web/.next/server/middleware.js +67 -67
  139. package/web/.next/server/pages/404.html +1 -1
  140. package/web/.next/server/pages/500.html +1 -1
  141. package/web/.next/server/server-reference-manifest.js +1 -1
  142. package/web/.next/server/server-reference-manifest.json +1 -1
  143. package/web/.next/static/chunks/1054-08930540869affcc.js +1 -0
  144. package/web/.next/static/chunks/1091-6d0af9f18ddf99f6.js +1 -0
  145. package/web/.next/static/chunks/1332-c8bed6b750598652.js +1 -0
  146. package/web/.next/static/chunks/{1789-87079e34582418b3.js → 1789-b436bca079b82fcc.js} +1 -1
  147. package/web/.next/static/chunks/{2194-f112ed9e30bd88fb.js → 2194-f3fed902cfeb85b5.js} +1 -1
  148. package/web/.next/static/chunks/296-1b50dd61ac3198f4.js +1 -0
  149. package/web/.next/static/chunks/3051-26ddd67461f743c4.js +1 -0
  150. package/web/.next/static/chunks/3159-f25525771781f5aa.js +1 -0
  151. package/web/.next/static/chunks/341-020b1c47a0991a37.js +1 -0
  152. package/web/.next/static/chunks/{5361-f266407b731effcd.js → 3742-ab3951ecba6248c1.js} +1 -1
  153. package/web/.next/static/chunks/377-4f2ca8d34e126b26.js +1 -0
  154. package/web/.next/static/chunks/3775-3a5a749d63c785a1.js +3 -0
  155. package/web/.next/static/chunks/390-d6132d3a117487df.js +1 -0
  156. package/web/.next/static/chunks/4020-9778230f3cc2164a.js +1 -0
  157. package/web/.next/static/chunks/4771-a0aadf337f224b72.js +1 -0
  158. package/web/.next/static/chunks/494-ed02d105fa0ac132.js +1 -0
  159. package/web/.next/static/chunks/5034-fc9997ff33a114aa.js +1 -0
  160. package/web/.next/static/chunks/{8551-3e88dff507375393.js → 5925-76337eacde3c3bc8.js} +39 -23
  161. package/web/.next/static/chunks/611-e150bff7f1f9dc6c.js +1 -0
  162. package/web/.next/static/chunks/6937-f57b8514bf03179e.js +3 -0
  163. package/web/.next/static/chunks/{7717-41f70e449a27eb21.js → 7879-67ac5a52d74c20d2.js} +1 -1
  164. package/web/.next/static/chunks/7920-40dc6aa63e653d6b.js +1 -0
  165. package/web/.next/static/chunks/8312-6ca4507c5413a23d.js +1 -0
  166. package/web/.next/static/chunks/870-b7151716d04a13c3.js +1 -0
  167. package/web/.next/static/chunks/8794-2a616d1f9c210117.js +1 -0
  168. package/web/.next/static/chunks/8861-a108ed6178a56b21.js +1 -0
  169. package/web/.next/static/chunks/{3196-464a892bb967ebe9.js → 9311-bdd05e5b6fb92a88.js} +1 -1
  170. package/web/.next/static/chunks/9598-202b803aea26a949.js +1 -0
  171. package/web/.next/static/chunks/{9643-135a5b7d3abd518c.js → 9643-e9c8a744dd98813d.js} +1 -1
  172. package/web/.next/static/chunks/{8606-679d56e81c4e4550.js → 9765-1501903a64e09ac0.js} +1 -1
  173. package/web/.next/static/chunks/9952-992cabfb077d287c.js +1 -0
  174. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-5ca9c1eef4d0f837.js +6 -0
  175. package/web/.next/static/chunks/app/(dashboard)/agents/page-5ffa4a2468c1f95a.js +1 -0
  176. package/web/.next/static/chunks/app/(dashboard)/approvals/page-cd46d5e439a20d3e.js +1 -0
  177. package/web/.next/static/chunks/app/(dashboard)/automations/[id]/page-9ef1d76121b6030d.js +1 -0
  178. package/web/.next/static/chunks/app/(dashboard)/automations/page-46eeaa40df9e58f8.js +1 -0
  179. package/web/.next/static/chunks/app/(dashboard)/chat/[id]/page-25e095bf0cdd1c40.js +1 -0
  180. package/web/.next/static/chunks/app/(dashboard)/chat/page-e2df1a328e18da7a.js +1 -0
  181. package/web/.next/static/chunks/app/(dashboard)/code/[id]/page-f5f7624cfbb32ee2.js +1 -0
  182. package/web/.next/static/chunks/app/(dashboard)/connectors/page-2ecbfc5836577888.js +1 -0
  183. package/web/.next/static/chunks/app/(dashboard)/credentials/page-cb6bc64b82b8fb28.js +1 -0
  184. package/web/.next/static/chunks/app/(dashboard)/dashboard/{page-fd2a41310f716a3e.js → page-7473d1190864cbd4.js} +1 -1
  185. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-47e177ab46926fd7.js +1 -0
  186. package/web/.next/static/chunks/app/(dashboard)/layout-0b429859260736b2.js +1 -0
  187. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-596d973a31e774db.js +1 -0
  188. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-ba1968c9430c4dd4.js +1 -0
  189. package/web/.next/static/chunks/app/(dashboard)/logs/page-f74da6f66116c7e7.js +1 -0
  190. package/web/.next/static/chunks/app/(dashboard)/mcp/page-07bdc6780b13cfca.js +1 -0
  191. package/web/.next/static/chunks/app/(dashboard)/memories/page-593161bc7c2a25d7.js +1 -0
  192. package/web/.next/static/chunks/app/(dashboard)/page-889d6e89a8f679f8.js +1 -0
  193. package/web/.next/static/chunks/app/(dashboard)/scheduled/[id]/page-47e177ab46926fd7.js +1 -0
  194. package/web/.next/static/chunks/app/(dashboard)/settings/page-1b40e127c38affda.js +1 -0
  195. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-6b7e1cffcad40a6a.js +1 -0
  196. package/web/.next/static/chunks/app/(dashboard)/skills/page-3ad87d1a3fbb4f05.js +1 -0
  197. package/web/.next/static/chunks/app/(dashboard)/spaces/[id]/files/page-4e2d27f80456a1ba.js +1 -0
  198. package/web/.next/static/chunks/app/(dashboard)/spaces/[id]/page-c81023eaa26c2c7a.js +1 -0
  199. package/web/.next/static/chunks/app/(dashboard)/spaces/page-9dbb35822503481b.js +1 -0
  200. package/web/.next/static/chunks/app/layout-ef76b16f6546678c.js +1 -0
  201. package/web/.next/static/chunks/app/login/page-5357f030e5018563.js +1 -0
  202. package/web/.next/static/chunks/app/onboarding/page-9b6955cdd3033584.js +26 -0
  203. package/web/.next/static/css/099c0b54fc41e5b0.css +1 -0
  204. package/web/public/logo-128.png +0 -0
  205. package/web/.next/server/chunks/1239.js +0 -1
  206. package/web/.next/server/chunks/1505.js +0 -3
  207. package/web/.next/server/chunks/1632.js +0 -1
  208. package/web/.next/server/chunks/1813.js +0 -1
  209. package/web/.next/server/chunks/2040.js +0 -1
  210. package/web/.next/server/chunks/2310.js +0 -1
  211. package/web/.next/server/chunks/2800.js +0 -1790
  212. package/web/.next/server/chunks/3340.js +0 -1
  213. package/web/.next/server/chunks/3432.js +0 -1
  214. package/web/.next/server/chunks/3580.js +0 -1
  215. package/web/.next/server/chunks/4722.js +0 -3
  216. package/web/.next/server/chunks/5276.js +0 -1
  217. package/web/.next/server/chunks/603.js +0 -1
  218. package/web/.next/server/chunks/7719.js +0 -1
  219. package/web/.next/server/chunks/7781.js +0 -1
  220. package/web/.next/server/chunks/8025.js +0 -3
  221. package/web/.next/server/chunks/8118.js +0 -1
  222. package/web/.next/server/chunks/9637.js +0 -1
  223. package/web/.next/server/chunks/976.js +0 -1
  224. package/web/.next/server/chunks/9939.js +0 -1
  225. package/web/.next/static/chunks/1091-de54f0c0a4d82875.js +0 -1
  226. package/web/.next/static/chunks/114-26058433e4e0911e.js +0 -1
  227. package/web/.next/static/chunks/1219-d120dd8740b553b7.js +0 -1
  228. package/web/.next/static/chunks/146-923ebb6e4b12939e.js +0 -1
  229. package/web/.next/static/chunks/2057-de712956dc309abd.js +0 -1
  230. package/web/.next/static/chunks/2628-662c74c9bc8efdfd.js +0 -1
  231. package/web/.next/static/chunks/2767-84a838e67c8ed919.js +0 -1
  232. package/web/.next/static/chunks/3051-63316a56c4c77b78.js +0 -1
  233. package/web/.next/static/chunks/341-d382e4df5fdd8639.js +0 -1
  234. package/web/.next/static/chunks/4229-5ad9bb0c30eeb117.js +0 -1
  235. package/web/.next/static/chunks/443-b0581a9d59c5eddd.js +0 -1
  236. package/web/.next/static/chunks/4507-e4e79584af8a3dfb.js +0 -1
  237. package/web/.next/static/chunks/4646-daae31f9eaa82ad1.js +0 -3
  238. package/web/.next/static/chunks/5034-1424be65bb762fe0.js +0 -1
  239. package/web/.next/static/chunks/6449-2552e9fd471012bc.js +0 -1
  240. package/web/.next/static/chunks/6974-c390b37b943e5e3a.js +0 -1
  241. package/web/.next/static/chunks/750-5f0494d3bcce44e4.js +0 -1
  242. package/web/.next/static/chunks/7890-8030bd449325507e.js +0 -1
  243. package/web/.next/static/chunks/8288-46c8ea403691cbd8.js +0 -3
  244. package/web/.next/static/chunks/8571-6149c8881bddf392.js +0 -1
  245. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-0a2201e25891e65a.js +0 -6
  246. package/web/.next/static/chunks/app/(dashboard)/agents/page-8dd4afd99c54c317.js +0 -1
  247. package/web/.next/static/chunks/app/(dashboard)/approvals/page-c346b6514a0fb344.js +0 -1
  248. package/web/.next/static/chunks/app/(dashboard)/automations/[id]/page-2ff06d1d46372539.js +0 -1
  249. package/web/.next/static/chunks/app/(dashboard)/automations/page-e70ea0434087cad1.js +0 -1
  250. package/web/.next/static/chunks/app/(dashboard)/chat/[id]/page-600249784190e2a4.js +0 -1
  251. package/web/.next/static/chunks/app/(dashboard)/chat/page-48666512a1c0ac50.js +0 -1
  252. package/web/.next/static/chunks/app/(dashboard)/code/[id]/page-f84236cea1b8e8bd.js +0 -1
  253. package/web/.next/static/chunks/app/(dashboard)/connectors/page-de164554b77a1fa4.js +0 -1
  254. package/web/.next/static/chunks/app/(dashboard)/credentials/page-0741d2da25807489.js +0 -1
  255. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-702e9eeea18c7ea0.js +0 -1
  256. package/web/.next/static/chunks/app/(dashboard)/layout-1fe1669ec7dc1c13.js +0 -1
  257. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-a76814c4a20ecd33.js +0 -1
  258. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-aa611ab9ff0baff2.js +0 -1
  259. package/web/.next/static/chunks/app/(dashboard)/logs/page-f22178e7e15984c1.js +0 -1
  260. package/web/.next/static/chunks/app/(dashboard)/mcp/page-8b248ee23cc92855.js +0 -1
  261. package/web/.next/static/chunks/app/(dashboard)/memories/page-69955b9596175468.js +0 -1
  262. package/web/.next/static/chunks/app/(dashboard)/page-4432bf6e8e594109.js +0 -1
  263. package/web/.next/static/chunks/app/(dashboard)/scheduled/[id]/page-f4857bc821e8868b.js +0 -1
  264. package/web/.next/static/chunks/app/(dashboard)/settings/page-2e6cbceef74a8f8a.js +0 -1
  265. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-63c38b3c419dfbbc.js +0 -1
  266. package/web/.next/static/chunks/app/(dashboard)/skills/page-99aea8c35e06402b.js +0 -1
  267. package/web/.next/static/chunks/app/(dashboard)/spaces/[id]/files/page-226d430d003759c2.js +0 -1
  268. package/web/.next/static/chunks/app/(dashboard)/spaces/[id]/page-ded0e3c2ae3aede7.js +0 -1
  269. package/web/.next/static/chunks/app/(dashboard)/spaces/page-a833db411140fb1e.js +0 -1
  270. package/web/.next/static/chunks/app/layout-e03e26e403cc87a2.js +0 -1
  271. package/web/.next/static/chunks/app/login/page-16e874ed1f237705.js +0 -1
  272. package/web/.next/static/chunks/app/onboarding/page-5928b7dd0a4606cc.js +0 -26
  273. package/web/.next/static/css/67bc2af77aa905d1.css +0 -1
  274. /package/web/.next/static/{g828Psw_BOEBvk4rOsX86 → x5fvzE6AeZGASlemQTLwd}/_buildManifest.js +0 -0
  275. /package/web/.next/static/{g828Psw_BOEBvk4rOsX86 → x5fvzE6AeZGASlemQTLwd}/_ssgManifest.js +0 -0
package/cli.js CHANGED
@@ -11129,6 +11129,9 @@ var init_migrator2 = __esm({
11129
11129
  // ../../packages/db/src/migrate.ts
11130
11130
  var migrate_exports = {};
11131
11131
  __export(migrate_exports, {
11132
+ findMigrationGaps: () => findMigrationGaps,
11133
+ gapsBetween: () => gapsBetween,
11134
+ repairMigrations: () => repairMigrations,
11132
11135
  runMigrations: () => runMigrations
11133
11136
  });
11134
11137
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -11142,6 +11145,7 @@ import {
11142
11145
  mkdirSync as mkdirSync3
11143
11146
  } from "fs";
11144
11147
  import { tmpdir } from "os";
11148
+ import { createHash as createHash2 } from "crypto";
11145
11149
  async function runMigrations(connectionString, opts = {}) {
11146
11150
  const sql2 = src_default(connectionString, {
11147
11151
  max: 1,
@@ -11151,13 +11155,24 @@ async function runMigrations(connectionString, opts = {}) {
11151
11155
  }
11152
11156
  });
11153
11157
  const db = drizzle(sql2);
11154
- const here = dirname2(fileURLToPath2(import.meta.url));
11155
- const sibling = join4(here, "migrations");
11156
- const sourceFolder = existsSync4(sibling) ? sibling : join4(here, "../migrations");
11157
- const migrationsFolder = opts.patchVectorAsText ? patchMigrationsForNoVector(sourceFolder) : sourceFolder;
11158
+ const migrationsFolder = effectiveMigrationsFolder(opts);
11158
11159
  await migrate(db, { migrationsFolder });
11159
11160
  await sql2.end();
11160
11161
  }
11162
+ function sourceMigrationsFolder() {
11163
+ const here = dirname2(fileURLToPath2(import.meta.url));
11164
+ const sibling = join4(here, "migrations");
11165
+ return existsSync4(sibling) ? sibling : join4(here, "../migrations");
11166
+ }
11167
+ function effectiveMigrationsFolder(opts) {
11168
+ const source = sourceMigrationsFolder();
11169
+ if (opts.patchVectorAsText !== true) return source;
11170
+ const deja = dossiersPatches.get(source);
11171
+ if (deja !== void 0) return deja;
11172
+ const patche = patchMigrationsForNoVector(source);
11173
+ dossiersPatches.set(source, patche);
11174
+ return patche;
11175
+ }
11161
11176
  function patchMigrationsForNoVector(sourceFolder) {
11162
11177
  const tmpFolder = mkdtempSync(join4(tmpdir(), "nodalai-migrations-"));
11163
11178
  const metaDir = join4(tmpFolder, "meta");
@@ -11176,12 +11191,74 @@ function patchMigrationsForNoVector(sourceFolder) {
11176
11191
  }
11177
11192
  return tmpFolder;
11178
11193
  }
11194
+ function gapsBetween(journal, horodatagesAppliques) {
11195
+ const applique = new Set(horodatagesAppliques.map((w) => Number(w)));
11196
+ return journal.filter((e) => !applique.has(Number(e.when))).map((e) => ({ idx: e.idx, tag: e.tag, when: e.when }));
11197
+ }
11198
+ function readJournal(folder) {
11199
+ const chemin = join4(folder, "meta", "_journal.json");
11200
+ if (!existsSync4(chemin)) {
11201
+ throw new Error(`migration journal not found at ${chemin}`);
11202
+ }
11203
+ const brut = JSON.parse(readFileSync3(chemin, "utf8"));
11204
+ return brut.entries ?? [];
11205
+ }
11206
+ async function appliedWhen(sql2) {
11207
+ const [present] = await sql2`
11208
+ SELECT to_regclass('drizzle.__drizzle_migrations') IS NOT NULL AS ok`;
11209
+ if (present?.ok !== true) return null;
11210
+ const lignes = await sql2`
11211
+ SELECT created_at FROM drizzle.__drizzle_migrations`;
11212
+ return lignes.map((l) => Number(l.created_at)).filter((n) => Number.isFinite(n));
11213
+ }
11214
+ async function findMigrationGaps(connectionString, opts = {}) {
11215
+ const sql2 = src_default(connectionString, { max: 1, onnotice: () => {
11216
+ } });
11217
+ try {
11218
+ const applique = await appliedWhen(sql2);
11219
+ if (applique === null) return [];
11220
+ return gapsBetween(readJournal(effectiveMigrationsFolder(opts)), applique);
11221
+ } finally {
11222
+ await sql2.end();
11223
+ }
11224
+ }
11225
+ async function repairMigrations(connectionString, opts = {}) {
11226
+ const folder = effectiveMigrationsFolder(opts);
11227
+ const sql2 = src_default(connectionString, { max: 1, onnotice: () => {
11228
+ } });
11229
+ try {
11230
+ const applique = await appliedWhen(sql2);
11231
+ if (applique === null) return [];
11232
+ const trous = gapsBetween(readJournal(folder), applique);
11233
+ for (const trou of trous) {
11234
+ const fichier = join4(folder, `${trou.tag}.sql`);
11235
+ if (!existsSync4(fichier)) {
11236
+ throw new Error(`migration file missing for journal entry ${trou.tag}: ${fichier}`);
11237
+ }
11238
+ const contenu = readFileSync3(fichier, "utf8");
11239
+ const hash = createHash2("sha256").update(contenu).digest("hex");
11240
+ await sql2.begin(async (tx) => {
11241
+ for (const instruction of contenu.split("--> statement-breakpoint")) {
11242
+ if (instruction.trim() === "") continue;
11243
+ await tx.unsafe(instruction).simple();
11244
+ }
11245
+ await tx`INSERT INTO drizzle.__drizzle_migrations ("hash", "created_at")
11246
+ VALUES (${hash}, ${trou.when})`;
11247
+ });
11248
+ }
11249
+ return trous;
11250
+ } finally {
11251
+ await sql2.end();
11252
+ }
11253
+ }
11254
+ var dossiersPatches;
11179
11255
  var init_migrate = __esm({
11180
11256
  "../../packages/db/src/migrate.ts"() {
11181
11257
  "use strict";
11182
11258
  init_src();
11183
11259
  init_postgres_js();
11184
11260
  init_migrator2();
11261
+ dossiersPatches = /* @__PURE__ */ new Map();
11185
11262
  }
11186
11263
  });
11187
11264
 
@@ -11193,6 +11270,7 @@ __export(postgres_exports, {
11193
11270
  PG_USER: () => PG_USER,
11194
11271
  POSTMASTER_GAVE_UP: () => POSTMASTER_GAVE_UP,
11195
11272
  buildPgUrl: () => buildPgUrl,
11273
+ findMigrationGaps: () => findMigrationGaps2,
11196
11274
  isPostgresAuthFailure: () => isPostgresAuthFailure,
11197
11275
  livePostmasterPid: () => livePostmasterPid,
11198
11276
  postgresProcessesForDataDir: () => postgresProcessesForDataDir,
@@ -11200,6 +11278,7 @@ __export(postgres_exports, {
11200
11278
  processStartedAtMs: () => processStartedAtMs,
11201
11279
  readPostmasterClaim: () => readPostmasterClaim,
11202
11280
  readPostmasterPid: () => readPostmasterPid,
11281
+ repairMigrations: () => repairMigrations2,
11203
11282
  resolvePgCtl: () => resolvePgCtl,
11204
11283
  runMigrations: () => runMigrations2,
11205
11284
  startAndWaitUntilReady: () => startAndWaitUntilReady,
@@ -11346,8 +11425,8 @@ function postmasterHoldsDataDir(pid, dataDir) {
11346
11425
  function processStartedAtMs(pid) {
11347
11426
  if (process.platform !== "linux") return null;
11348
11427
  try {
11349
- const stat2 = readFileSync4(`/proc/${pid}/stat`, "utf-8");
11350
- const after = stat2.slice(stat2.lastIndexOf(")") + 2).split(" ");
11428
+ const stat3 = readFileSync4(`/proc/${pid}/stat`, "utf-8");
11429
+ const after = stat3.slice(stat3.lastIndexOf(")") + 2).split(" ");
11351
11430
  const ticksSinceBoot = Number.parseInt(after[19] ?? "", 10);
11352
11431
  if (!Number.isFinite(ticksSinceBoot)) return null;
11353
11432
  const uptimeSeconds = Number.parseFloat(
@@ -11637,6 +11716,14 @@ async function runMigrations2(databaseUrl, opts = {}) {
11637
11716
  const { runMigrations: migrate2 } = await Promise.resolve().then(() => (init_migrate(), migrate_exports));
11638
11717
  await migrate2(databaseUrl, opts);
11639
11718
  }
11719
+ async function findMigrationGaps2(databaseUrl, opts = {}) {
11720
+ const { findMigrationGaps: chercher } = await Promise.resolve().then(() => (init_migrate(), migrate_exports));
11721
+ return chercher(databaseUrl, opts);
11722
+ }
11723
+ async function repairMigrations2(databaseUrl, opts = {}) {
11724
+ const { repairMigrations: reparer } = await Promise.resolve().then(() => (init_migrate(), migrate_exports));
11725
+ return reparer(databaseUrl, opts);
11726
+ }
11640
11727
  var LEGACY_PG_PASSWORD, PG_USER, PG_DATABASE, READY_TIMEOUT_MS, POSTMASTER_GAVE_UP;
11641
11728
  var init_postgres = __esm({
11642
11729
  "src/lib/postgres.ts"() {
@@ -12651,6 +12738,13 @@ var init_webhook_trigger = __esm({
12651
12738
  }
12652
12739
  });
12653
12740
 
12741
+ // ../../packages/shared/src/entities/automation.ts
12742
+ var init_automation = __esm({
12743
+ "../../packages/shared/src/entities/automation.ts"() {
12744
+ "use strict";
12745
+ }
12746
+ });
12747
+
12654
12748
  // ../../packages/shared/src/entities/skill.ts
12655
12749
  import { z as z16 } from "zod";
12656
12750
  var SkillOperationSchema, SkillRequiredConfigSchema, AgentSkillSchema, AgentSkillInsertSchema, AgentSkillAssignmentSchema, AgentSkillAssignmentInsertSchema;
@@ -13610,17 +13704,6 @@ var init_model_catalog = __esm({
13610
13704
  cacheWritePerMillionUsd: 6.25
13611
13705
  }
13612
13706
  },
13613
- {
13614
- modelId: "anthropic/claude-opus-5-fast",
13615
- label: "Claude Opus 5 (fast)",
13616
- capabilities: {
13617
- tools: true,
13618
- forcedToolChoice: true,
13619
- reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13620
- },
13621
- contextWindow: 1e6,
13622
- pricing: { inputPerMillionUsd: 10, outputPerMillionUsd: 50 }
13623
- },
13624
13707
  {
13625
13708
  modelId: "anthropic/claude-sonnet-5",
13626
13709
  label: "Claude Sonnet 5",
@@ -13653,6 +13736,34 @@ var init_model_catalog = __esm({
13653
13736
  cacheWritePerMillionUsd: 12.5
13654
13737
  }
13655
13738
  },
13739
+ {
13740
+ // The newest of the family (2026-09-01), read off /api/v1/models on
13741
+ // 2026-09-22: same window, prices and modalities as Fable 5 except the
13742
+ // cache READ price, four times lower (0.25 vs 1). Its `reasoning` object
13743
+ // says mandatory:true with efforts max/xhigh/high/medium/low, so Off is
13744
+ // hidden here — the Fable 5 entry above predates that object and still
13745
+ // offers it (#417). No always-on `reasoning` flag, as for every Claude
13746
+ // route in this file: the flag would flip openrouter.ts's default
13747
+ // injection, and a mandatory model thinks anyway.
13748
+ modelId: "anthropic/claude-fable-5.1",
13749
+ label: "Claude Fable 5.1",
13750
+ capabilities: {
13751
+ tools: true,
13752
+ forcedToolChoice: true,
13753
+ reasoningControl: {
13754
+ kind: "effort",
13755
+ levels: ["low", "medium", "high", "max"],
13756
+ mandatory: true
13757
+ }
13758
+ },
13759
+ contextWindow: 1e6,
13760
+ pricing: {
13761
+ inputPerMillionUsd: 10,
13762
+ outputPerMillionUsd: 50,
13763
+ cacheReadPerMillionUsd: 0.25,
13764
+ cacheWritePerMillionUsd: 12.5
13765
+ }
13766
+ },
13656
13767
  // ─── OpenAI ───────────────────────────────────────────────────────────────
13657
13768
  // OpenAI was absent from the OpenRouter list entirely — not a curation
13658
13769
  // choice, a gap: the native `openai` provider carried gpt-5 while anyone
@@ -13705,6 +13816,107 @@ var init_model_catalog = __esm({
13705
13816
  cacheWritePerMillionUsd: 2.5
13706
13817
  }
13707
13818
  },
13819
+ // The rest of the 5.6 series and GPT-6 Astra, read off OpenRouter's
13820
+ // /api/v1/models on 2026-09-22 — including its `reasoning` object
13821
+ // ({mandatory, default_enabled, supported_efforts}), which is what the
13822
+ // control below follows. Sol, Sol Pro and Terra: mandatory:false,
13823
+ // supported_efforts max/xhigh/high/medium/low/none → the Luna posture
13824
+ // (four levels, Off offered). Astra and Astra Pro: mandatory:true, no
13825
+ // 'none' → the same four levels with Off hidden. Prices are the
13826
+ // STANDARD OpenAI service tier, the one the list endpoint reports; the
13827
+ // endpoints list also carries a flex tier at half and a priority tier at
13828
+ // double, and an override above 272K prompt tokens — the flat catalogue
13829
+ // price is the standard tier, as for Luna and Terra Pro above. Upstream
13830
+ // copy: Sol is the 5.6 flagship, Terra the balanced tier between Sol and
13831
+ // Luna, Astra "OpenAI's flagship model for demanding end-to-end work".
13832
+ {
13833
+ modelId: "openai/gpt-5.6-terra",
13834
+ label: "GPT-5.6 Terra",
13835
+ capabilities: {
13836
+ tools: true,
13837
+ forcedToolChoice: true,
13838
+ reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13839
+ },
13840
+ contextWindow: 105e4,
13841
+ pricing: {
13842
+ inputPerMillionUsd: 2,
13843
+ outputPerMillionUsd: 12,
13844
+ cacheReadPerMillionUsd: 0.2,
13845
+ cacheWritePerMillionUsd: 2.5
13846
+ }
13847
+ },
13848
+ {
13849
+ modelId: "openai/gpt-5.6-sol",
13850
+ label: "GPT-5.6 Sol",
13851
+ capabilities: {
13852
+ tools: true,
13853
+ forcedToolChoice: true,
13854
+ reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13855
+ },
13856
+ contextWindow: 105e4,
13857
+ pricing: {
13858
+ inputPerMillionUsd: 2,
13859
+ outputPerMillionUsd: 10,
13860
+ cacheReadPerMillionUsd: 0.2,
13861
+ cacheWritePerMillionUsd: 2.5
13862
+ }
13863
+ },
13864
+ {
13865
+ modelId: "openai/gpt-5.6-sol-pro",
13866
+ label: "GPT-5.6 Sol Pro",
13867
+ capabilities: {
13868
+ tools: true,
13869
+ forcedToolChoice: true,
13870
+ reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13871
+ },
13872
+ contextWindow: 105e4,
13873
+ pricing: {
13874
+ inputPerMillionUsd: 2,
13875
+ outputPerMillionUsd: 10,
13876
+ cacheReadPerMillionUsd: 0.2,
13877
+ cacheWritePerMillionUsd: 2.5
13878
+ }
13879
+ },
13880
+ {
13881
+ modelId: "openai/gpt-6-astra",
13882
+ label: "GPT-6 Astra",
13883
+ capabilities: {
13884
+ tools: true,
13885
+ forcedToolChoice: true,
13886
+ reasoningControl: {
13887
+ kind: "effort",
13888
+ levels: ["low", "medium", "high", "max"],
13889
+ mandatory: true
13890
+ }
13891
+ },
13892
+ contextWindow: 105e4,
13893
+ pricing: {
13894
+ inputPerMillionUsd: 10,
13895
+ outputPerMillionUsd: 50,
13896
+ cacheReadPerMillionUsd: 1,
13897
+ cacheWritePerMillionUsd: 12.5
13898
+ }
13899
+ },
13900
+ {
13901
+ modelId: "openai/gpt-6-astra-pro",
13902
+ label: "GPT-6 Astra Pro",
13903
+ capabilities: {
13904
+ tools: true,
13905
+ forcedToolChoice: true,
13906
+ reasoningControl: {
13907
+ kind: "effort",
13908
+ levels: ["low", "medium", "high", "max"],
13909
+ mandatory: true
13910
+ }
13911
+ },
13912
+ contextWindow: 105e4,
13913
+ pricing: {
13914
+ inputPerMillionUsd: 10,
13915
+ outputPerMillionUsd: 50,
13916
+ cacheReadPerMillionUsd: 1,
13917
+ cacheWritePerMillionUsd: 12.5
13918
+ }
13919
+ },
13708
13920
  // Anthropic — reasoningControl WITHOUT the `reasoning` flag, on purpose:
13709
13921
  // the flag would flip openrouter.ts's always-on default injection; here
13710
13922
  // thinking is engaged only when the agent explicitly sets an effort.
@@ -13741,17 +13953,6 @@ var init_model_catalog = __esm({
13741
13953
  cacheWritePerMillionUsd: 6.25
13742
13954
  }
13743
13955
  },
13744
- {
13745
- modelId: "anthropic/claude-opus-4.7-fast",
13746
- label: "Claude Opus 4.7 (fast)",
13747
- capabilities: {
13748
- tools: true,
13749
- forcedToolChoice: true,
13750
- reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13751
- },
13752
- contextWindow: 1e6,
13753
- pricing: { inputPerMillionUsd: 30, outputPerMillionUsd: 150 }
13754
- },
13755
13956
  {
13756
13957
  modelId: "anthropic/claude-opus-4.8",
13757
13958
  label: "Claude Opus 4.8",
@@ -13768,17 +13969,6 @@ var init_model_catalog = __esm({
13768
13969
  cacheWritePerMillionUsd: 6.25
13769
13970
  }
13770
13971
  },
13771
- {
13772
- modelId: "anthropic/claude-opus-4.8-fast",
13773
- label: "Claude Opus 4.8 (fast)",
13774
- capabilities: {
13775
- tools: true,
13776
- forcedToolChoice: true,
13777
- reasoningControl: { kind: "effort", levels: ["low", "medium", "high", "max"] }
13778
- },
13779
- contextWindow: 1e6,
13780
- pricing: { inputPerMillionUsd: 10, outputPerMillionUsd: 50 }
13781
- },
13782
13972
  {
13783
13973
  modelId: "anthropic/claude-sonnet-4.6",
13784
13974
  label: "Claude Sonnet 4.6",
@@ -13869,6 +14059,58 @@ var init_model_catalog = __esm({
13869
14059
  cacheReadPerMillionUsd: 0.064902
13870
14060
  }
13871
14061
  },
14062
+ {
14063
+ // "The GA release of DeepSeek V4 Pro" (upstream copy) — the dated
14064
+ // successor of the undated alias above. Pricing (DeepSeek's own
14065
+ // endpoint), context and supported_parameters read off /api/v1/models
14066
+ // on 2026-09-22. The levels follow the list endpoint's `reasoning`
14067
+ // object: supported_efforts max/high/low, mandatory:false — so no
14068
+ // 'medium', unlike the older entries above that predate that field.
14069
+ modelId: "deepseek/deepseek-v4-pro-0813",
14070
+ label: "DeepSeek V4 Pro (0813)",
14071
+ capabilities: {
14072
+ tools: true,
14073
+ forcedToolChoice: true,
14074
+ reasoning: true,
14075
+ reasoningControl: { kind: "effort", levels: ["low", "high", "max"] }
14076
+ },
14077
+ contextWindow: 1048576,
14078
+ providerOrder: ["deepseek"],
14079
+ pricing: {
14080
+ inputPerMillionUsd: 0.66,
14081
+ outputPerMillionUsd: 1.98,
14082
+ cacheReadPerMillionUsd: 0.022
14083
+ }
14084
+ },
14085
+ {
14086
+ // The newest Flash (2026-09-10), first on DeepSeek's Causal
14087
+ // Encoder-Decoder architecture. One difference from every V4 Flash
14088
+ // above: it takes IMAGE input (input_modalities: text, image), so it is
14089
+ // in VISION_MODEL_IDS. Same reasoning caveat as its siblings; levels
14090
+ // from the list endpoint's `reasoning` object (max/high/low,
14091
+ // mandatory:false, default_enabled:true). forcedToolChoice:false —
14092
+ // DeepSeek's own endpoint (the one providerOrder prefers) reports
14093
+ // supports_tool_choice.required:false; some fallbacks (DeepInfra,
14094
+ // Wafer) report true, and the runtime floor relaxes it anyway.
14095
+ // 'max' → OpenRouter 'xhigh' and Auto → 'medium' are not in this
14096
+ // model's supported_efforts; OpenRouter documents that it "will map
14097
+ // your requested effort to the nearest supported level".
14098
+ modelId: "deepseek/deepseek-v4.1-flash",
14099
+ label: "DeepSeek V4.1 Flash",
14100
+ capabilities: {
14101
+ tools: true,
14102
+ forcedToolChoice: false,
14103
+ reasoning: true,
14104
+ reasoningControl: { kind: "effort", levels: ["low", "high", "max"] }
14105
+ },
14106
+ contextWindow: 1048576,
14107
+ providerOrder: ["deepseek"],
14108
+ pricing: {
14109
+ inputPerMillionUsd: 0.15,
14110
+ outputPerMillionUsd: 0.6,
14111
+ cacheReadPerMillionUsd: 3e-3
14112
+ }
14113
+ },
13872
14114
  // Google — all three are thinking models on OpenRouter (supported_parameters
13873
14115
  // includes "reasoning", verified via openrouter.ai/google/… 2026-07-12).
13874
14116
  // reasoning:true makes the OpenRouter provider enable reasoning + round-trip
@@ -14120,6 +14362,93 @@ var init_model_catalog = __esm({
14120
14362
  cacheReadPerMillionUsd: 0.015
14121
14363
  }
14122
14364
  },
14365
+ {
14366
+ // "The high-speed variant of GLM-5.3-Flash ... up to 200 tokens/s"
14367
+ // (upstream copy, 2026-09-18). Same model family as Flash: multimodal
14368
+ // (text, image, video → VISION_MODEL_IDS), forcedToolChoice:false
14369
+ // (supports_tool_choice.required:false on its endpoint). The control
14370
+ // follows the list endpoint's `reasoning` object, read 2026-09-22:
14371
+ // mandatory:true, supported_efforts max/high/low, default max — the
14372
+ // full 5.3's posture, and the same object upstream now reports for
14373
+ // Flash too (the Flash entry above predates that field). It differs
14374
+ // from Flash on price (~5x) and context (1.05M, not 1.31M).
14375
+ modelId: "z-ai/glm-5.3-flashx",
14376
+ label: "GLM 5.3 FlashX",
14377
+ capabilities: {
14378
+ tools: true,
14379
+ forcedToolChoice: false,
14380
+ reasoning: true,
14381
+ reasoningControl: {
14382
+ kind: "effort",
14383
+ levels: ["low", "high", "max"],
14384
+ mandatory: true
14385
+ }
14386
+ },
14387
+ contextWindow: 1048576,
14388
+ pricing: {
14389
+ inputPerMillionUsd: 0.37,
14390
+ outputPerMillionUsd: 1.25,
14391
+ cacheReadPerMillionUsd: 0.075
14392
+ }
14393
+ },
14394
+ // Xiaomi MiMo-V2.6 — the three 2.6 models OpenRouter serves (2026-09-21),
14395
+ // all read off /api/v1/models and /models/<id>/endpoints on 2026-09-22:
14396
+ // 1.05M context, 131K max output, input_modalities text+image+video+audio
14397
+ // (→ VISION_MODEL_IDS), supported_parameters tools, tool_choice,
14398
+ // reasoning, include_reasoning — and NO reasoning_effort. The list
14399
+ // endpoint's `reasoning` object says only {mandatory:false}: no
14400
+ // supported_efforts, so thinking can be switched on or off and nothing
14401
+ // else — kind 'onoff', not a made-up scale. No always-on `reasoning`
14402
+ // flag: Auto keeps the provider's default. forcedToolChoice:true —
14403
+ // every endpoint reports supports_tool_choice.required:true.
14404
+ // Upstream copy: Flash = 309B MoE / 15B active; Pro = the >1T flagship;
14405
+ // Pro-UltraSpeed = the same Pro checkpoint "roughly 10x" faster, 10x the
14406
+ // price.
14407
+ {
14408
+ modelId: "xiaomi/mimo-v2.6-flash",
14409
+ label: "MiMo V2.6 Flash",
14410
+ capabilities: {
14411
+ tools: true,
14412
+ forcedToolChoice: true,
14413
+ reasoningControl: { kind: "onoff" }
14414
+ },
14415
+ contextWindow: 1048576,
14416
+ pricing: {
14417
+ inputPerMillionUsd: 0.14,
14418
+ outputPerMillionUsd: 0.28,
14419
+ cacheReadPerMillionUsd: 28e-4
14420
+ }
14421
+ },
14422
+ {
14423
+ modelId: "xiaomi/mimo-v2.6-pro",
14424
+ label: "MiMo V2.6 Pro",
14425
+ capabilities: {
14426
+ tools: true,
14427
+ forcedToolChoice: true,
14428
+ reasoningControl: { kind: "onoff" }
14429
+ },
14430
+ contextWindow: 1048576,
14431
+ pricing: {
14432
+ inputPerMillionUsd: 0.435,
14433
+ outputPerMillionUsd: 0.87,
14434
+ cacheReadPerMillionUsd: 36e-4
14435
+ }
14436
+ },
14437
+ {
14438
+ modelId: "xiaomi/mimo-v2.6-pro-ultraspeed",
14439
+ label: "MiMo V2.6 Pro UltraSpeed",
14440
+ capabilities: {
14441
+ tools: true,
14442
+ forcedToolChoice: true,
14443
+ reasoningControl: { kind: "onoff" }
14444
+ },
14445
+ contextWindow: 1048576,
14446
+ pricing: {
14447
+ inputPerMillionUsd: 4.35,
14448
+ outputPerMillionUsd: 8.7,
14449
+ cacheReadPerMillionUsd: 0.036
14450
+ }
14451
+ },
14123
14452
  // Moonshot (Kimi)
14124
14453
  {
14125
14454
  modelId: "moonshotai/kimi-k2.6",
@@ -14198,6 +14527,56 @@ var init_model_catalog = __esm({
14198
14527
  cacheReadPerMillionUsd: 0.3
14199
14528
  }
14200
14529
  },
14530
+ // Grok 4.6 (2026-08-12) and 4.7 (2026-09-21, "succeeding Grok 4.6" per
14531
+ // upstream copy): same 500K context, same text+image+file input
14532
+ // (→ VISION_MODEL_IDS), same supported_parameters as 4.5 (tools,
14533
+ // tool_choice, reasoning, reasoning_effort), read off /api/v1/models and
14534
+ // /models/<id>/endpoints on 2026-09-22. The control follows the list
14535
+ // endpoint's `reasoning` object: mandatory:true (no Off), and — unlike
14536
+ // 4.5, whose object stops at high — supported_efforts xhigh/high/medium/
14537
+ // low, so 'max' (→ xhigh) is offered. Pricing: 4.6 = 4.5; 4.7 is 20%
14538
+ // cheaper. Both double above 200K prompt tokens (an override the flat
14539
+ // price does not carry, same as 4.5).
14540
+ {
14541
+ modelId: "x-ai/grok-4.6",
14542
+ label: "Grok 4.6",
14543
+ capabilities: {
14544
+ tools: true,
14545
+ forcedToolChoice: true,
14546
+ reasoning: true,
14547
+ reasoningControl: {
14548
+ kind: "effort",
14549
+ levels: ["low", "medium", "high", "max"],
14550
+ mandatory: true
14551
+ }
14552
+ },
14553
+ contextWindow: 5e5,
14554
+ pricing: {
14555
+ inputPerMillionUsd: 2,
14556
+ outputPerMillionUsd: 6,
14557
+ cacheReadPerMillionUsd: 0.5
14558
+ }
14559
+ },
14560
+ {
14561
+ modelId: "x-ai/grok-4.7",
14562
+ label: "Grok 4.7",
14563
+ capabilities: {
14564
+ tools: true,
14565
+ forcedToolChoice: true,
14566
+ reasoning: true,
14567
+ reasoningControl: {
14568
+ kind: "effort",
14569
+ levels: ["low", "medium", "high", "max"],
14570
+ mandatory: true
14571
+ }
14572
+ },
14573
+ contextWindow: 5e5,
14574
+ pricing: {
14575
+ inputPerMillionUsd: 1.6,
14576
+ outputPerMillionUsd: 4.8,
14577
+ cacheReadPerMillionUsd: 0.4
14578
+ }
14579
+ },
14201
14580
  // Qwen — both verified via OpenRouter /api/v1/models (2026-07-20): 1M
14202
14581
  // context, tools + tool_choice + reasoning params (no native
14203
14582
  // reasoning_effort — OpenRouter's unified param drives the hybrid
@@ -14280,13 +14659,12 @@ var init_model_catalog = __esm({
14280
14659
  VISION_MODEL_IDS = /* @__PURE__ */ new Set([
14281
14660
  // OpenRouter (verified via /api/v1/models)
14282
14661
  "anthropic/claude-fable-5",
14662
+ // input_modalities ["text","image","file"] on /api/v1/models, 2026-09-22.
14663
+ "anthropic/claude-fable-5.1",
14283
14664
  "anthropic/claude-haiku-4.5",
14284
14665
  "anthropic/claude-opus-4.7",
14285
- "anthropic/claude-opus-4.7-fast",
14286
14666
  "anthropic/claude-opus-4.8",
14287
- "anthropic/claude-opus-4.8-fast",
14288
14667
  "anthropic/claude-opus-5",
14289
- "anthropic/claude-opus-5-fast",
14290
14668
  "anthropic/claude-sonnet-4.6",
14291
14669
  "anthropic/claude-sonnet-5",
14292
14670
  "google/gemini-3.1-flash-lite-preview",
@@ -14302,14 +14680,35 @@ var init_model_catalog = __esm({
14302
14680
  "openai/gpt-5.6-luna",
14303
14681
  "openai/gpt-5.6-luna-pro",
14304
14682
  "openai/gpt-5.6-terra-pro",
14683
+ // The rest of the 5.6 series and GPT-6 Astra: input_modalities
14684
+ // ["file","image","text"] on /api/v1/models, 2026-09-22.
14685
+ "openai/gpt-5.6-terra",
14686
+ "openai/gpt-5.6-sol",
14687
+ "openai/gpt-5.6-sol-pro",
14688
+ "openai/gpt-6-astra",
14689
+ "openai/gpt-6-astra-pro",
14690
+ // deepseek/deepseek-v4.1-flash reports ["text","image"] (2026-09-22) — the
14691
+ // first V4 Flash that does; v4-flash, v4-flash-0731 and both V4 Pro are
14692
+ // text-only per the same source and deliberately NOT in this set.
14693
+ "deepseek/deepseek-v4.1-flash",
14305
14694
  "qwen/qwen3.8-max",
14306
14695
  // Verified via OpenRouter /api/v1/models input_modalities on 2026-08-28:
14307
14696
  // z-ai/glm-5.3-flash reports ["text","image","video"]. The full z-ai/glm-5.3
14308
14697
  // reports ["text"] only and is deliberately NOT in this set.
14309
14698
  "z-ai/glm-5.3-flash",
14699
+ // z-ai/glm-5.3-flashx reports the same ["text","image","video"] (2026-09-22).
14700
+ "z-ai/glm-5.3-flashx",
14701
+ // Xiaomi MiMo-V2.6: all three report ["text","image","video","audio"]
14702
+ // (2026-09-22).
14703
+ "xiaomi/mimo-v2.6-flash",
14704
+ "xiaomi/mimo-v2.6-pro",
14705
+ "xiaomi/mimo-v2.6-pro-ultraspeed",
14310
14706
  // Verified via OpenRouter /api/v1/models input_modalities (2026-07-20).
14311
14707
  // qwen/qwen3.7-max is deliberately absent — text-only per the same source.
14312
14708
  "x-ai/grok-4.5",
14709
+ // 4.6 and 4.7 report the same ["text","image","file"] (2026-09-22).
14710
+ "x-ai/grok-4.6",
14711
+ "x-ai/grok-4.7",
14313
14712
  "qwen/qwen3.7-plus",
14314
14713
  // Native-provider forms
14315
14714
  "claude-fable-5",
@@ -14379,6 +14778,53 @@ var init_approval_explain = __esm({
14379
14778
  }
14380
14779
  });
14381
14780
 
14781
+ // ../../packages/shared/src/approval-rules-chain.ts
14782
+ var init_approval_rules_chain = __esm({
14783
+ "../../packages/shared/src/approval-rules-chain.ts"() {
14784
+ "use strict";
14785
+ }
14786
+ });
14787
+
14788
+ // ../../packages/shared/src/approval-tool-default.ts
14789
+ var SAFE_BY_DEFAULT_TOOL_NAMES, SAFE_BY_DEFAULT;
14790
+ var init_approval_tool_default = __esm({
14791
+ "../../packages/shared/src/approval-tool-default.ts"() {
14792
+ "use strict";
14793
+ init_approval_rules_chain();
14794
+ SAFE_BY_DEFAULT_TOOL_NAMES = [
14795
+ "attach_agent",
14796
+ "attach_connector",
14797
+ "attach_mcp",
14798
+ "attach_skill",
14799
+ "cloudflare_delete_worker",
14800
+ "cloudflare_deploy",
14801
+ "code_task",
14802
+ "create_agent",
14803
+ "create_connector",
14804
+ "create_mcp",
14805
+ "create_schedule",
14806
+ "create_skill",
14807
+ "declare_verification",
14808
+ "detach_agent",
14809
+ "detach_connector",
14810
+ "detach_mcp",
14811
+ "detach_skill",
14812
+ "register_project",
14813
+ "run_command",
14814
+ "run_schedule",
14815
+ "run_skill_script",
14816
+ "skill_file_write",
14817
+ "toggle_schedule",
14818
+ "update_agent",
14819
+ "update_schedule",
14820
+ "update_skill",
14821
+ "xlsx_delete_columns",
14822
+ "xlsx_delete_rows"
14823
+ ];
14824
+ SAFE_BY_DEFAULT = new Set(SAFE_BY_DEFAULT_TOOL_NAMES);
14825
+ }
14826
+ });
14827
+
14382
14828
  // ../../packages/shared/src/untrusted.ts
14383
14829
  var init_untrusted = __esm({
14384
14830
  "../../packages/shared/src/untrusted.ts"() {
@@ -14599,7 +15045,7 @@ function parseVerificationSurfaces(raw) {
14599
15045
  shell: pick("shell")
14600
15046
  };
14601
15047
  }
14602
- var VerificationSurfacesSchema, DEFAULT_VERIFICATION_SURFACES, VERIFICATION_SURFACE_TOOLS;
15048
+ var VerificationSurfacesSchema, DEFAULT_VERIFICATION_SURFACES, VERIFICATION_SURFACE_TOOLS, PROOF_REPAIR_ATTEMPTS_CHOICES;
14603
15049
  var init_verification_surfaces = __esm({
14604
15050
  "../../packages/shared/src/verification-surfaces.ts"() {
14605
15051
  "use strict";
@@ -14648,6 +15094,7 @@ var init_verification_surfaces = __esm({
14648
15094
  ],
14649
15095
  shell: ["run_command", "run_skill_script"]
14650
15096
  });
15097
+ PROOF_REPAIR_ATTEMPTS_CHOICES = Object.freeze([0, 1, 2, 3]);
14651
15098
  }
14652
15099
  });
14653
15100
 
@@ -14694,6 +15141,7 @@ var init_src2 = __esm({
14694
15141
  init_approval();
14695
15142
  init_memory();
14696
15143
  init_webhook_trigger();
15144
+ init_automation();
14697
15145
  init_skill();
14698
15146
  init_schedule();
14699
15147
  init_llm_key();
@@ -14712,6 +15160,8 @@ var init_src2 = __esm({
14712
15160
  init_redact_secrets();
14713
15161
  init_approval_impact();
14714
15162
  init_approval_explain();
15163
+ init_approval_rules_chain();
15164
+ init_approval_tool_default();
14715
15165
  init_untrusted();
14716
15166
  init_redact_transcript();
14717
15167
  init_agent_slug();
@@ -14845,10 +15295,10 @@ var init_entities = __esm({
14845
15295
  updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
14846
15296
  lastCuratorRunAt: timestamp("last_curator_run_at", { withTimezone: true }),
14847
15297
  reflectionEnabled: boolean("reflection_enabled").notNull().default(false),
14848
- // Decoupled from reflection_enabled (which gates the skill-learning loop,
14849
- // opt-in). Gates the memory curator (Phase 2 LLM pass) — ON by default so
14850
- // memory curation runs even for entities that never opted into reflection.
14851
- memoryCurationEnabled: boolean("memory_curation_enabled").notNull().default(true),
15298
+ // `memory_curation_enabled` lived here from 0.7.0 to migration 0122 (#411):
15299
+ // a per-workspace gate on the memory curator that no screen ever exposed.
15300
+ // Memory curation is now gated by the runner's MEMORY_CURATION_ENABLED
15301
+ // kill-switch only; "do not touch this fact" is the pin on the fact.
14852
15302
  // Controls whether agent-authored skills are auto-assigned to the authoring
14853
15303
  // agent ('auto') or queued for the entity owner to approve ('approval').
14854
15304
  skillAssignmentMode: text("skill_assignment_mode").notNull().default("approval").$type(),
@@ -14880,9 +15330,27 @@ var init_entities = __esm({
14880
15330
  * vit dans le parseur, jamais deviné par un backfill (même leçon que
14881
15331
  * 0084 : un réglage est un geste, pas un état inventé).
14882
15332
  */
14883
- verificationSurfaces: jsonb("verification_surfaces").notNull().default(sql`'{}'::jsonb`)
15333
+ verificationSurfaces: jsonb("verification_surfaces").notNull().default(sql`'{}'::jsonb`),
15334
+ /**
15335
+ * Combien de tours de réparation un run reçoit au plus après une preuve
15336
+ * rouge (issue #377, migration 0121). La borne de #375 était écrite en
15337
+ * dur dans `finalize.ts` ; elle se règle désormais par espace.
15338
+ *
15339
+ * `0` — le run finit avec le verdict rouge immédiatement, comme avant
15340
+ * #375. `1` (défaut) — un tour, la décision D2 du plan. Jusqu'à `3`.
15341
+ *
15342
+ * LE CHECK EST EN BASE, pas seulement dans le formulaire : cette colonne
15343
+ * borne une boucle du runner (invariant #8), et une valeur de 9 999 écrite
15344
+ * par un script ferait tourner un agent toute la nuit sur une preuve qui
15345
+ * ne passera jamais.
15346
+ */
15347
+ proofRepairAttempts: integer("proof_repair_attempts").notNull().default(1)
14884
15348
  },
14885
15349
  (table) => [
15350
+ check(
15351
+ "entities_proof_repair_attempts_check",
15352
+ sql`${table.proofRepairAttempts} >= 0 AND ${table.proofRepairAttempts} <= 3`
15353
+ ),
14886
15354
  uniqueIndex("entities_mcp_token_idx").on(table.mcpToken),
14887
15355
  index("idx_entities_user_id").on(table.userId),
14888
15356
  index("idx_entities_root_agent_id").on(table.rootAgentId)
@@ -15446,6 +15914,35 @@ var init_jobs = __esm({
15446
15914
  * référence déjà agent_jobs pour `registered_job_id`.
15447
15915
  */
15448
15916
  projectId: uuid("project_id"),
15917
+ /**
15918
+ * UN LIVRABLE DE CE RUN ATTEND LE REGARD DE LA PERSONNE (#255, migration
15919
+ * 0118). L'instant où le run a livré ; NULL = rien n'attend.
15920
+ *
15921
+ * POSÉ par la porte terminale de succès (`finalizeJobSuccess`), dans la
15922
+ * MÊME transaction que le statut terminal, quand le run a produit au moins
15923
+ * un livrable `addressed AND produced` — nommé par un outil, ET réellement
15924
+ * écrit. Les deux ensemble : `addressed` seul est une intention, qu'une
15925
+ * écriture ratée laisse en place.
15926
+ *
15927
+ * EFFACÉ par le seul côté web, et par les deux gestes qui sont des
15928
+ * regards : ouvrir le run (`getSpaceConversationAction`, la page qui
15929
+ * MONTRE les livrables) ou ouvrir le fil (`markConversationRead`, au même
15930
+ * endroit que le marqueur de lecture). Le runner ne l'efface jamais : une
15931
+ * livraison de canal ne fait rien regarder à personne, exactement comme
15932
+ * pour `conversation_reads`.
15933
+ *
15934
+ * PORTÉ PAR LE JOB DE TÊTE, jamais par le délégué qui a produit : c'est le
15935
+ * run que la personne ouvre, et la page d'un run remonte déjà les
15936
+ * livrables de toute sa descendance (`collectDescendants`). La chaîne est
15937
+ * remontée à l'écriture, bornée par la profondeur de délégation.
15938
+ *
15939
+ * PAR ESPACE, pas par personne — au contraire de `conversation_reads`.
15940
+ * C'est la règle de la PASTILLE d'attention, à laquelle ce fait s'ajoute :
15941
+ * une approbation résolue par l'un tombe pour tous, et un livrable regardé
15942
+ * par l'un aussi. Une colonne unique dit donc ici la même chose que les
15943
+ * deux autres sources de la pastille.
15944
+ */
15945
+ deliverableCheckDueAt: timestamp("deliverable_check_due_at", { withTimezone: true }),
15449
15946
  completedAt: timestamp("completed_at", { withTimezone: true }),
15450
15947
  createdAt: timestamp("created_at", { withTimezone: true }).defaultNow(),
15451
15948
  updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow()
@@ -15484,6 +15981,12 @@ var init_jobs = __esm({
15484
15981
  // liste des projets) — partiel, la colonne reste NULL sur l'immense
15485
15982
  // majorité des jobs.
15486
15983
  index("idx_agent_jobs_project").on(table.projectId).where(sql`${table.projectId} IS NOT NULL`),
15984
+ // 0118 (#255) : la pastille d'attention relit « quels runs de cet espace
15985
+ // attendent un regard » toutes les 15 secondes, sur toutes les pages du
15986
+ // tableau de bord. PARTIEL : la colonne est NULL sur presque tous les
15987
+ // jobs, et elle le redevient dès que la personne a regardé — l'index reste
15988
+ // donc de la taille de ce qui attend, pas de celle de la table.
15989
+ index("idx_agent_jobs_deliverable_check_due").on(table.entityId).where(sql`${table.deliverableCheckDueAt} IS NOT NULL`),
15487
15990
  check(
15488
15991
  "agent_jobs_status_check",
15489
15992
  sql`${table.status} IN ('pending','processing','completed','failed','awaiting_approval','awaiting_delegation','cancelled')`
@@ -16368,6 +16871,32 @@ var init_code_projects = __esm({
16368
16871
  }
16369
16872
  });
16370
16873
 
16874
+ // ../../packages/db/src/schema/excluded-project-paths.ts
16875
+ var excludedProjectPaths;
16876
+ var init_excluded_project_paths = __esm({
16877
+ "../../packages/db/src/schema/excluded-project-paths.ts"() {
16878
+ "use strict";
16879
+ init_pg_core();
16880
+ init_entities();
16881
+ excludedProjectPaths = pgTable(
16882
+ "excluded_project_paths",
16883
+ {
16884
+ id: uuid("id").primaryKey().defaultRandom(),
16885
+ entityId: uuid("entity_id").notNull().references(() => entities.id, { onDelete: "cascade" }),
16886
+ /** Chemin absolu slash-normalisé, tel qu'il s'affiche — jamais recasé après coup. */
16887
+ projectPath: text("project_path").notNull(),
16888
+ /** `projectKey(project_path)` — l'identité, et ce que porte l'unicité. */
16889
+ projectKey: text("project_key").notNull(),
16890
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
16891
+ },
16892
+ (table) => [
16893
+ unique("excluded_project_paths_entity_key_unique").on(table.entityId, table.projectKey),
16894
+ index("idx_excluded_project_paths_entity").on(table.entityId)
16895
+ ]
16896
+ );
16897
+ }
16898
+ });
16899
+
16371
16900
  // ../../packages/db/src/schema/auth.ts
16372
16901
  var sessions, accounts, verifications;
16373
16902
  var init_auth = __esm({
@@ -17193,6 +17722,7 @@ var init_job_checkpoints = __esm({
17193
17722
  "../../packages/db/src/schema/job-checkpoints.ts"() {
17194
17723
  "use strict";
17195
17724
  init_pg_core();
17725
+ init_drizzle_orm();
17196
17726
  init_jobs();
17197
17727
  jobCheckpoints = pgTable(
17198
17728
  "job_checkpoints",
@@ -17205,7 +17735,23 @@ var init_job_checkpoints = __esm({
17205
17735
  workspace: text("workspace").notNull(),
17206
17736
  /** Le commit dans le magasin fantôme — l'état d'avant de ce tour. */
17207
17737
  sha: text("sha").notNull(),
17208
- takenAt: timestamp("taken_at", { withTimezone: true }).notNull().defaultNow()
17738
+ takenAt: timestamp("taken_at", { withTimezone: true }).notNull().defaultNow(),
17739
+ /**
17740
+ * COMBIEN DE TEMPS LA PHOTO A PRIS, en millisecondes (#261, migration 0119).
17741
+ *
17742
+ * Mesurée autour du seul appel de `snapshot`, aux deux endroits qui
17743
+ * photographient : le seam de `packages/tools` et le harnais CLI du runner.
17744
+ *
17745
+ * Elle existe pour que la montée d'un dossier SE VOIE avant qu'elle ne
17746
+ * refuse quoi que ce soit : `git add` est borné à 30 secondes, et jusqu'ici
17747
+ * la durée ne vivait que sur le chemin d'ÉCHEC, en mémoire, le temps de
17748
+ * rendre la phrase du refus. Une photo qui réussit en 24 secondes ne
17749
+ * laissait aucune trace — le cas qu'il faut justement voir venir.
17750
+ *
17751
+ * NULL = pas mesurée (une ligne d'avant la colonne). L'écran le dit ; il
17752
+ * n'affiche jamais un zéro, qui se lirait « instantané » (invariant #4).
17753
+ */
17754
+ snapshotMs: integer("snapshot_ms")
17209
17755
  },
17210
17756
  (table) => [
17211
17757
  unique("job_checkpoints_job_turn_workspace_unique").on(
@@ -17213,7 +17759,19 @@ var init_job_checkpoints = __esm({
17213
17759
  table.turn,
17214
17760
  table.workspace
17215
17761
  ),
17216
- index("idx_job_checkpoints_job").on(table.jobId)
17762
+ index("idx_job_checkpoints_job").on(table.jobId),
17763
+ // 0119 (#261) : « la dernière photo de cet espace », un `ORDER BY taken_at
17764
+ // DESC LIMIT 1` par espace. Sans lui, le parcours dégénère pour un espace
17765
+ // SILENCIEUX — dont la dernière photo est justement la plus ancienne, donc
17766
+ // la plus loin (revue C, passe 2 de la PR #324).
17767
+ index("idx_job_checkpoints_taken_at").on(sql`${table.takenAt} DESC`),
17768
+ // La durée est un CONSTAT, jamais négative. Pas de borne supérieure : une
17769
+ // photo peut légitimement durer plus que le budget de `git add`, et une
17770
+ // borne inventée refuserait la ligne au moment où elle intéresse le plus.
17771
+ check(
17772
+ "job_checkpoints_snapshot_ms_check",
17773
+ sql`${table.snapshotMs} IS NULL OR ${table.snapshotMs} >= 0`
17774
+ )
17217
17775
  ]
17218
17776
  );
17219
17777
  }
@@ -17313,6 +17871,7 @@ __export(schema_exports, {
17313
17871
  entityLlmKeys: () => entityLlmKeys,
17314
17872
  entityMembers: () => entityMembers,
17315
17873
  entitySettings: () => entitySettings,
17874
+ excludedProjectPaths: () => excludedProjectPaths,
17316
17875
  jobCheckpoints: () => jobCheckpoints,
17317
17876
  jobDeliverableVerificationState: () => jobDeliverableVerificationState,
17318
17877
  jobDeliveries: () => jobDeliveries,
@@ -17353,6 +17912,7 @@ var init_schema2 = __esm({
17353
17912
  init_llm_keys();
17354
17913
  init_mcp();
17355
17914
  init_code_projects();
17915
+ init_excluded_project_paths();
17356
17916
  init_auth();
17357
17917
  init_agent_connector_assignments();
17358
17918
  init_agent_workspaces();
@@ -17731,7 +18291,7 @@ var init_master_key_guard = __esm({
17731
18291
  });
17732
18292
 
17733
18293
  // ../../packages/db/src/queries/channel-identity.ts
17734
- import { createHash as createHash2 } from "crypto";
18294
+ import { createHash as createHash3 } from "crypto";
17735
18295
  async function resolveOwnerConversation(db, agentId, channel) {
17736
18296
  if (channel === "telegram") {
17737
18297
  const [row2] = await db.select({ chatId: telegramAllowedChats.chatId }).from(telegramAllowedChats).where(
@@ -17807,7 +18367,7 @@ function credentialsFingerprint(creds) {
17807
18367
  const canonical = JSON.stringify(
17808
18368
  Object.keys(creds).sort().map((k) => [k, creds[k]])
17809
18369
  );
17810
- return createHash2("sha256").update(canonical).digest("hex");
18370
+ return createHash3("sha256").update(canonical).digest("hex");
17811
18371
  }
17812
18372
  async function getBindingCredentials(db, agentId, channel) {
17813
18373
  if (channel === "telegram") {
@@ -18488,6 +19048,7 @@ __export(src_exports, {
18488
19048
  entityMembers: () => entityMembers,
18489
19049
  entitySettings: () => entitySettings,
18490
19050
  eq: () => eq,
19051
+ excludedProjectPaths: () => excludedProjectPaths,
18491
19052
  getAppSetting: () => getAppSetting,
18492
19053
  getBindingCredentials: () => getBindingCredentials,
18493
19054
  getChannelBinding: () => getChannelBinding,
@@ -18627,7 +19188,7 @@ var init_local_auth = __esm({
18627
19188
  });
18628
19189
 
18629
19190
  // ../../packages/auth/src/lib/constant-time.ts
18630
- import { createHash as createHash3, timingSafeEqual } from "crypto";
19191
+ import { createHash as createHash4, timingSafeEqual } from "crypto";
18631
19192
  var init_constant_time = __esm({
18632
19193
  "../../packages/auth/src/lib/constant-time.ts"() {
18633
19194
  "use strict";
@@ -19656,6 +20217,7 @@ var init_processes = __esm({
19656
20217
  // src/commands/up.ts
19657
20218
  var up_exports = {};
19658
20219
  __export(up_exports, {
20220
+ migrationGapRefusal: () => migrationGapRefusal,
19659
20221
  runUp: () => runUp
19660
20222
  });
19661
20223
  import chalk from "chalk";
@@ -19690,6 +20252,21 @@ function printLogTail(service, lines) {
19690
20252
  ${service}: could not read ${logFile}`));
19691
20253
  }
19692
20254
  }
20255
+ function migrationGapRefusal(gaps, opts) {
20256
+ const combien = `${gaps.length} migration${gaps.length === 1 ? "" : "s"}`;
20257
+ return [
20258
+ `The database is missing ${combien} the journal announces:`,
20259
+ "",
20260
+ ...gaps.map((g) => ` ${g.tag}`),
20261
+ "",
20262
+ " Tables are short of columns the code expects, so writes to them will fail.",
20263
+ " Nodal-Agents will not serve a database in that state.",
20264
+ "",
20265
+ " Apply them with:",
20266
+ "",
20267
+ ` nodal-agents up --repair-migrations${opts.dev ? " --dev" : ""}${opts.detach ? " --detach" : ""}`
20268
+ ].join("\n");
20269
+ }
19693
20270
  async function runUp(opts = {}) {
19694
20271
  const binaries = await probeEmbeddedPostgres();
19695
20272
  if (!binaries.ok) {
@@ -19996,6 +20573,35 @@ ${lines}
19996
20573
  await pg.stop();
19997
20574
  throw err;
19998
20575
  }
20576
+ const vectorPatched = { patchVectorAsText: !pg.vectorAvailable };
20577
+ const gapSpinner = ora("Checking the migration journal\u2026").start();
20578
+ let gaps = await findMigrationGaps2(databaseUrl, vectorPatched).catch(async (err) => {
20579
+ gapSpinner.fail("Could not read the migration journal");
20580
+ await pg.stop();
20581
+ throw err;
20582
+ });
20583
+ if (gaps.length > 0 && opts.repairMigrations === true) {
20584
+ gapSpinner.text = `Repairing ${gaps.length} skipped migration${gaps.length === 1 ? "" : "s"}\u2026`;
20585
+ try {
20586
+ const repaired = await repairMigrations2(databaseUrl, vectorPatched);
20587
+ gapSpinner.succeed(chalk.green(`Repaired: ${repaired.map((g) => g.tag).join(", ")}`));
20588
+ } catch (err) {
20589
+ gapSpinner.fail("Repair failed");
20590
+ await pg.stop();
20591
+ throw err;
20592
+ }
20593
+ gaps = await findMigrationGaps2(databaseUrl, vectorPatched);
20594
+ }
20595
+ if (gaps.length > 0) {
20596
+ gapSpinner.fail(
20597
+ `${gaps.length} migration${gaps.length === 1 ? "" : "s"} in the journal never reached this database`
20598
+ );
20599
+ await pg.stop();
20600
+ throw new Error(
20601
+ migrationGapRefusal(gaps, { dev: opts.dev === true, detach: opts.detach === true })
20602
+ );
20603
+ }
20604
+ gapSpinner.succeed(chalk.green("Migration journal complete"));
19999
20605
  {
20000
20606
  const { db, close } = createClient(databaseUrl, { max: 1 });
20001
20607
  try {
@@ -20683,8 +21289,45 @@ var init_logs = __esm({
20683
21289
  }
20684
21290
  });
20685
21291
 
21292
+ // ../../packages/shared/src/git-binary.ts
21293
+ import { stat } from "fs/promises";
21294
+ import { delimiter as PATH_DELIMITER } from "path";
21295
+ function enBarresObliques(chemin) {
21296
+ return chemin.replace(/\\/g, "/");
21297
+ }
21298
+ async function estFichier(chemin) {
21299
+ try {
21300
+ return (await stat(chemin)).isFile();
21301
+ } catch {
21302
+ return false;
21303
+ }
21304
+ }
21305
+ async function resolveGitBinary() {
21306
+ gitBinaire ??= (async () => {
21307
+ const chemins = (process.env["PATH"] ?? "").split(PATH_DELIMITER).filter((d) => d !== "");
21308
+ const windows = process.platform === "win32";
21309
+ for (const dossier of chemins) {
21310
+ const base = `${enBarresObliques(dossier)}/git`;
21311
+ for (const ext of windows ? EXTENSIONS_WINDOWS : [""]) {
21312
+ if (await estFichier(base + ext)) return base + ext;
21313
+ }
21314
+ }
21315
+ console.warn("[git] GIT_NOT_ON_PATH");
21316
+ return null;
21317
+ })();
21318
+ return gitBinaire;
21319
+ }
21320
+ var EXTENSIONS_WINDOWS, gitBinaire;
21321
+ var init_git_binary = __esm({
21322
+ "../../packages/shared/src/git-binary.ts"() {
21323
+ "use strict";
21324
+ EXTENSIONS_WINDOWS = [".exe", ".com"];
21325
+ gitBinaire = null;
21326
+ }
21327
+ });
21328
+
20686
21329
  // ../../packages/checkpoints/src/failure.ts
20687
- import { readdir, stat } from "fs/promises";
21330
+ import { readdir, stat as stat2 } from "fs/promises";
20688
21331
  import { basename, join as join13 } from "path";
20689
21332
  function checkpointFailureCode(cause, operation) {
20690
21333
  if (cause === "git_missing") return "git_missing";
@@ -20729,7 +21372,7 @@ async function measureWorkspace(workspace, limits = {}) {
20729
21372
  }
20730
21373
  files++;
20731
21374
  try {
20732
- bytes += (await stat(join13(dir, entry.name))).size;
21375
+ bytes += (await stat2(join13(dir, entry.name))).size;
20733
21376
  } catch {
20734
21377
  }
20735
21378
  }
@@ -20842,7 +21485,7 @@ var init_failure = __esm({
20842
21485
 
20843
21486
  // ../../packages/checkpoints/src/checkpoints.ts
20844
21487
  import { execFile, spawn } from "child_process";
20845
- import { createHash as createHash4, randomBytes as randomBytes6 } from "crypto";
21488
+ import { createHash as createHash5, randomBytes as randomBytes6 } from "crypto";
20846
21489
  import { mkdir, rm, writeFile } from "fs/promises";
20847
21490
  import { existsSync as existsSync13 } from "fs";
20848
21491
  import { join as join14 } from "path";
@@ -20869,7 +21512,13 @@ function isTimeoutError(err) {
20869
21512
  const e = err;
20870
21513
  return e.killed === true || e.code === "ETIMEDOUT";
20871
21514
  }
21515
+ async function gitBinary() {
21516
+ const binaire = await resolveGitBinary();
21517
+ if (binaire === null) throw new GitBinaryMissingError();
21518
+ return binaire;
21519
+ }
20872
21520
  function isGitMissingError(err) {
21521
+ if (err instanceof GitBinaryMissingError) return true;
20873
21522
  if (typeof err !== "object" || err === null) return false;
20874
21523
  const e = err;
20875
21524
  return e.code === "ENOENT" && typeof e.syscall === "string" && e.syscall.startsWith("spawn");
@@ -20917,7 +21566,7 @@ function workspaceKey(workspace) {
20917
21566
  norm = norm.toLowerCase().replace(/\//g, "\\");
20918
21567
  }
20919
21568
  norm = norm.replace(/[\\/]+$/, "");
20920
- return createHash4("sha256").update(norm).digest("hex").slice(0, 16);
21569
+ return createHash5("sha256").update(norm).digest("hex").slice(0, 16);
20921
21570
  }
20922
21571
  function gitEnv(store, workspace, indexFile) {
20923
21572
  const key = workspaceKey(workspace);
@@ -20941,7 +21590,7 @@ function gitEnv(store, workspace, indexFile) {
20941
21590
  };
20942
21591
  }
20943
21592
  async function git(store, workspace, args, indexFile, timeoutMs = storeTimeoutMs()) {
20944
- const { stdout } = await run("git", args, {
21593
+ const { stdout } = await run(await gitBinary(), args, {
20945
21594
  timeout: timeoutMs,
20946
21595
  windowsHide: true,
20947
21596
  env: gitEnv(store, workspace, indexFile)
@@ -20954,7 +21603,7 @@ async function ensureStore(store) {
20954
21603
  await writeFile(join14(store, "gitconfig"), "", { flag: "a" });
20955
21604
  if (!existsSync13(join14(gitDir, "HEAD"))) {
20956
21605
  await mkdir(gitDir, { recursive: true });
20957
- await run("git", ["init", "--bare", "--quiet", gitDir], {
21606
+ await run(await gitBinary(), ["init", "--bare", "--quiet", gitDir], {
20958
21607
  timeout: GIT_TIMEOUT_MS,
20959
21608
  windowsHide: true
20960
21609
  });
@@ -21020,14 +21669,23 @@ async function restoreCheckpoint(store, workspace, sha) {
21020
21669
  await git(store, workspace, ["checkout", "-f", sha, "--", "."]);
21021
21670
  return { restored: sha, safety };
21022
21671
  }
21023
- var run, GIT_TIMEOUT_MS, badTimeoutSaid, EXCLUDES, CHECKPOINT_COVERAGE_NOTE;
21672
+ var run, GIT_TIMEOUT_MS, badTimeoutSaid, GitBinaryMissingError, EXCLUDES, CHECKPOINT_COVERAGE_NOTE;
21024
21673
  var init_checkpoints = __esm({
21025
21674
  "../../packages/checkpoints/src/checkpoints.ts"() {
21026
21675
  "use strict";
21676
+ init_git_binary();
21027
21677
  init_failure();
21028
21678
  run = promisify(execFile);
21029
21679
  GIT_TIMEOUT_MS = 3e4;
21030
21680
  badTimeoutSaid = false;
21681
+ GitBinaryMissingError = class extends Error {
21682
+ constructor() {
21683
+ super(
21684
+ "git is not on PATH: no checkpoint can be taken or read. Install git, or make it reachable from the process PATH."
21685
+ );
21686
+ this.name = "GitBinaryMissingError";
21687
+ }
21688
+ };
21031
21689
  EXCLUDES = [
21032
21690
  ...SKIPPED_DIRS.map((dir) => `${dir}/`),
21033
21691
  ...SKIPPED_FILE_SUFFIXES.map((suffixe) => `*${suffixe}`)
@@ -34835,10 +35493,17 @@ program.command("init").description("Interactive wizard \u2014 configure LLM, po
34835
35493
  process.exit(1);
34836
35494
  }
34837
35495
  });
34838
- program.command("up").description("Start Postgres, runner, and web \u2014 open browser when ready").option("--dev", "Run web in `next dev` mode (HMR, no prebuild required)").option("-d, --detach", "Return to the prompt once healthy \u2014 services keep running").action(async (opts) => {
35496
+ program.command("up").description("Start Postgres, runner, and web \u2014 open browser when ready").option("--dev", "Run web in `next dev` mode (HMR, no prebuild required)").option("-d, --detach", "Return to the prompt once healthy \u2014 services keep running").option(
35497
+ "--repair-migrations",
35498
+ "Apply migrations the journal announces and this database never got"
35499
+ ).action(async (opts) => {
34839
35500
  const { runUp: runUp2 } = await Promise.resolve().then(() => (init_up(), up_exports));
34840
35501
  try {
34841
- await runUp2({ dev: opts.dev, detach: opts.detach });
35502
+ await runUp2({
35503
+ dev: opts.dev,
35504
+ detach: opts.detach,
35505
+ repairMigrations: opts.repairMigrations
35506
+ });
34842
35507
  } catch (err) {
34843
35508
  console.error(chalk8.red("Error:"), err instanceof Error ? err.message : String(err));
34844
35509
  process.exit(1);