@mndrk/agx 1.4.30 → 1.4.33

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 (231) hide show
  1. package/README.md +83 -54
  2. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/BUILD_ID +1 -1
  3. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/app-build-manifest.json +89 -68
  4. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/app-path-routes-manifest.json +12 -9
  5. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/build-manifest.json +2 -2
  6. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/prerender-manifest.json +21 -21
  7. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/routes-manifest.json +8 -0
  8. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found/page.js +7 -2
  9. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found/page.js.nft.json +1 -1
  10. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  11. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found.html +1 -1
  12. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found.rsc +16 -15
  13. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/audit/route_client-reference-manifest.js +1 -1
  14. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/[...nextauth]/route_client-reference-manifest.js +1 -1
  15. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/daemon-secret/route_client-reference-manifest.js +1 -1
  16. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/device/code/route_client-reference-manifest.js +1 -1
  17. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/device/token/route_client-reference-manifest.js +1 -1
  18. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/refresh/route_client-reference-manifest.js +1 -1
  19. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  20. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/domains/[id]/route.js +1 -0
  21. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/domains/[id]/route.js.nft.json +1 -0
  22. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/domains/[id]/route_client-reference-manifest.js +1 -0
  23. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/domains/route.js +1 -0
  24. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/domains/route.js.nft.json +1 -0
  25. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/domains/route_client-reference-manifest.js +1 -0
  26. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/health/route.js +1 -0
  27. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/health/route.js.nft.json +1 -0
  28. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/health/route_client-reference-manifest.js +1 -0
  29. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/learnings/route_client-reference-manifest.js +1 -1
  30. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/logs/stream/route_client-reference-manifest.js +1 -1
  31. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  32. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/signal/route_client-reference-manifest.js +1 -1
  33. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/start/route_client-reference-manifest.js +1 -1
  34. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/status/route_client-reference-manifest.js +1 -1
  35. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/projects/[id]/route.js +1 -1
  36. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/projects/[id]/route_client-reference-manifest.js +1 -1
  37. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/projects/route.js +1 -1
  38. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  39. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/providers/route_client-reference-manifest.js +1 -1
  40. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/queue/complete/route.js +4 -1
  41. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/queue/complete/route_client-reference-manifest.js +1 -1
  42. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/queue/route_client-reference-manifest.js +1 -1
  43. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/stage-prompts/route_client-reference-manifest.js +1 -1
  44. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/comments/[commentId]/route_client-reference-manifest.js +1 -1
  45. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/comments/route_client-reference-manifest.js +1 -1
  46. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/heartbeat/route_client-reference-manifest.js +1 -1
  47. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/history/route_client-reference-manifest.js +1 -1
  48. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/logs/route.js +1 -1
  49. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/logs/route_client-reference-manifest.js +1 -1
  50. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/route_client-reference-manifest.js +1 -1
  51. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/route_client-reference-manifest.js +1 -1
  52. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/stream/route_client-reference-manifest.js +1 -1
  53. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/user-settings/route_client-reference-manifest.js +1 -1
  54. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/[id]/nodes/route_client-reference-manifest.js +1 -1
  55. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/[id]/route_client-reference-manifest.js +1 -1
  56. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  57. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/callback/route_client-reference-manifest.js +1 -1
  58. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device/page.js +10 -5
  59. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device/page.js.nft.json +1 -1
  60. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device/page_client-reference-manifest.js +1 -1
  61. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device.html +1 -1
  62. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device.rsc +20 -19
  63. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard/page.js +2 -2
  64. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard/page.js.nft.json +1 -1
  65. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard/page_client-reference-manifest.js +1 -1
  66. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard.html +1 -1
  67. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard.rsc +20 -19
  68. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/index.html +1 -1
  69. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/index.rsc +25 -23
  70. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login/page.js +7 -2
  71. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login/page.js.nft.json +1 -1
  72. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login/page_client-reference-manifest.js +1 -1
  73. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login.html +1 -1
  74. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login.rsc +20 -19
  75. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/page.js +7 -2
  76. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/page.js.nft.json +1 -1
  77. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/page_client-reference-manifest.js +1 -1
  78. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/page.js +6 -5
  79. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  80. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  81. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/tasks/page.js +2 -2
  82. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/tasks/page.js.nft.json +1 -1
  83. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/tasks/page_client-reference-manifest.js +1 -1
  84. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/workflow/page.js +7 -2
  85. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/workflow/page.js.nft.json +1 -1
  86. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/workflow/page_client-reference-manifest.js +1 -1
  87. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/page.js +2 -2
  88. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/page.js.nft.json +1 -1
  89. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  90. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects.html +1 -1
  91. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects.rsc +20 -19
  92. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings/page.js +7 -2
  93. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings/page.js.nft.json +1 -1
  94. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  95. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings.html +1 -1
  96. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings.rsc +20 -19
  97. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app-paths-manifest.json +12 -9
  98. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/2298.js +1 -1
  99. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/{8361.js → 3224.js} +3 -3
  100. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/7143.js +1 -4
  101. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/9773.js +6 -0
  102. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/middleware-manifest.json +5 -5
  103. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/pages/404.html +1 -1
  104. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/pages/500.html +1 -1
  105. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/server-reference-manifest.js +1 -1
  106. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/server-reference-manifest.json +1 -1
  107. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/DMNQmUkQjUP3zxWUwUUqb/_buildManifest.js +1 -0
  108. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/{2456-5577fa071bb78cca.js → 2456-fb622a24e9609222.js} +1 -1
  109. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/_error.js +28 -0
  110. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/audit/route-99c56d5659a15bdb.js +1 -0
  111. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/[...nextauth]/route-99c56d5659a15bdb.js +1 -0
  112. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/daemon-secret/route-99c56d5659a15bdb.js +1 -0
  113. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/device/code/route-99c56d5659a15bdb.js +1 -0
  114. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/device/token/route-99c56d5659a15bdb.js +1 -0
  115. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/refresh/route-99c56d5659a15bdb.js +1 -0
  116. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/status/route-99c56d5659a15bdb.js +1 -0
  117. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/domains/[id]/route-99c56d5659a15bdb.js +1 -0
  118. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/domains/route-99c56d5659a15bdb.js +1 -0
  119. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/health/route-99c56d5659a15bdb.js +1 -0
  120. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/learnings/route-99c56d5659a15bdb.js +1 -0
  121. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/logs/stream/route-99c56d5659a15bdb.js +1 -0
  122. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/orchestrator/tasks/[taskId]/cancel/route-99c56d5659a15bdb.js +1 -0
  123. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/orchestrator/tasks/[taskId]/signal/route-99c56d5659a15bdb.js +1 -0
  124. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/orchestrator/tasks/[taskId]/start/route-99c56d5659a15bdb.js +1 -0
  125. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/orchestrator/tasks/[taskId]/status/route-99c56d5659a15bdb.js +1 -0
  126. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/projects/[id]/route-99c56d5659a15bdb.js +1 -0
  127. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/projects/route-99c56d5659a15bdb.js +1 -0
  128. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/providers/route-99c56d5659a15bdb.js +1 -0
  129. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/queue/complete/route-99c56d5659a15bdb.js +1 -0
  130. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/queue/route-99c56d5659a15bdb.js +1 -0
  131. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/stage-prompts/route-99c56d5659a15bdb.js +1 -0
  132. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/comments/[commentId]/route-99c56d5659a15bdb.js +1 -0
  133. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/comments/route-99c56d5659a15bdb.js +1 -0
  134. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/heartbeat/route-99c56d5659a15bdb.js +1 -0
  135. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/history/route-99c56d5659a15bdb.js +1 -0
  136. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/logs/route-99c56d5659a15bdb.js +1 -0
  137. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/route-99c56d5659a15bdb.js +1 -0
  138. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/route-99c56d5659a15bdb.js +1 -0
  139. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/stream/route-99c56d5659a15bdb.js +1 -0
  140. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/user-settings/route-99c56d5659a15bdb.js +1 -0
  141. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/workflows/[id]/nodes/route-99c56d5659a15bdb.js +1 -0
  142. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/workflows/[id]/route-99c56d5659a15bdb.js +1 -0
  143. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/workflows/route-99c56d5659a15bdb.js +1 -0
  144. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/auth/callback/route-99c56d5659a15bdb.js +1 -0
  145. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/auth/device/page-ccd70ca63478d630.js +1 -0
  146. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/layout-a88b659f348808e1.js +1 -0
  147. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/projects/[slug]/layout-11d4290500b37271.js +1 -0
  148. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/projects/[slug]/page-98b32955971a9b89.js +1 -0
  149. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/fallback/amp.js +1015 -0
  150. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/fallback/main-app.js +1893 -0
  151. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/fallback/main.js +1616 -0
  152. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/fallback/pages/_app.js +28 -0
  153. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/fallback/pages/_error.js +28 -0
  154. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/fallback/react-refresh.js +62 -0
  155. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/fallback/webpack.js +1368 -0
  156. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/main.js +1616 -0
  157. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/pages/_app.js +28 -0
  158. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/pages/_error.js +28 -0
  159. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/polyfills.js +1 -0
  160. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/react-refresh.js +62 -0
  161. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/webpack.js +1405 -0
  162. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/css/684e3dda28b1eb43.css +1 -0
  163. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/development/_buildManifest.js +1 -0
  164. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/development/_ssgManifest.js +1 -0
  165. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/webpack/3f44f671f4861aa9.webpack.hot-update.json +1 -0
  166. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/webpack/webpack.3f44f671f4861aa9.hot-update.js +12 -0
  167. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/worker/index.js +16 -20
  168. package/index.js +9 -8188
  169. package/lib/cli/cloud/command.js +25 -10
  170. package/lib/cli/cloud/executeVerifySingle.js +16 -0
  171. package/lib/cli/cloud/executeVerifySwarm.js +16 -0
  172. package/lib/cli/cloud/iterations.js +6 -2
  173. package/lib/cli/cloud/taskLogger.js +79 -10
  174. package/lib/cli/cloudArtifacts.js +2 -1
  175. package/lib/cli/daemon.js +48 -32
  176. package/lib/cli/interactiveMenu.js +11 -9
  177. package/lib/cli/providers.js +26 -19
  178. package/lib/cli/runCli.js +681 -645
  179. package/lib/commands/daemonBoard.js +9 -9
  180. package/lib/executor.js +4 -11
  181. package/lib/orchestrator/httpClient.js +6 -2
  182. package/lib/proc/ProcessManager.js +197 -0
  183. package/lib/proc/commandExists.js +4 -4
  184. package/lib/proc/killProcessTree.js +157 -0
  185. package/lib/proc/spawnCloudTaskProcess.js +32 -5
  186. package/lib/prompts/cloudTask.js +72 -23
  187. package/lib/storage/paths.js +3 -0
  188. package/lib/storage/runs.js +1 -0
  189. package/lib/verifier.js +10 -9
  190. package/package.json +2 -1
  191. package/templates/stack/postgres/init/001_agx_board_schema.sql +17 -0
  192. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/6125.js +0 -1
  193. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/M4AQWpnhTFqFD3HFlSHd9/_buildManifest.js +0 -1
  194. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/audit/route-a73121242529c10c.js +0 -1
  195. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/[...nextauth]/route-a73121242529c10c.js +0 -1
  196. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/daemon-secret/route-a73121242529c10c.js +0 -1
  197. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/device/code/route-a73121242529c10c.js +0 -1
  198. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/device/token/route-a73121242529c10c.js +0 -1
  199. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/refresh/route-a73121242529c10c.js +0 -1
  200. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/auth/status/route-a73121242529c10c.js +0 -1
  201. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/learnings/route-a73121242529c10c.js +0 -1
  202. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/logs/stream/route-a73121242529c10c.js +0 -1
  203. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/orchestrator/tasks/[taskId]/cancel/route-a73121242529c10c.js +0 -1
  204. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/orchestrator/tasks/[taskId]/signal/route-a73121242529c10c.js +0 -1
  205. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/orchestrator/tasks/[taskId]/start/route-a73121242529c10c.js +0 -1
  206. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/orchestrator/tasks/[taskId]/status/route-a73121242529c10c.js +0 -1
  207. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/projects/[id]/route-a73121242529c10c.js +0 -1
  208. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/projects/route-a73121242529c10c.js +0 -1
  209. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/providers/route-a73121242529c10c.js +0 -1
  210. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/queue/complete/route-a73121242529c10c.js +0 -1
  211. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/queue/route-a73121242529c10c.js +0 -1
  212. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/stage-prompts/route-a73121242529c10c.js +0 -1
  213. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/comments/[commentId]/route-a73121242529c10c.js +0 -1
  214. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/comments/route-a73121242529c10c.js +0 -1
  215. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/heartbeat/route-a73121242529c10c.js +0 -1
  216. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/history/route-a73121242529c10c.js +0 -1
  217. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/logs/route-a73121242529c10c.js +0 -1
  218. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/[id]/route-a73121242529c10c.js +0 -1
  219. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/route-a73121242529c10c.js +0 -1
  220. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/tasks/stream/route-a73121242529c10c.js +0 -1
  221. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/user-settings/route-a73121242529c10c.js +0 -1
  222. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/workflows/[id]/nodes/route-a73121242529c10c.js +0 -1
  223. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/workflows/[id]/route-a73121242529c10c.js +0 -1
  224. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/api/workflows/route-a73121242529c10c.js +0 -1
  225. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/auth/callback/route-a73121242529c10c.js +0 -1
  226. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/auth/device/page-e2c2560ec12b421d.js +0 -1
  227. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/layout-2d6cff09e6c1e2b2.js +0 -1
  228. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/projects/[slug]/layout-c77e54e6c377c70a.js +0 -1
  229. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/projects/[slug]/page-253ca8286e8f1d68.js +0 -1
  230. package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/css/72371329e4c91108.css +0 -1
  231. /package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/{M4AQWpnhTFqFD3HFlSHd9 → DMNQmUkQjUP3zxWUwUUqb}/_ssgManifest.js +0 -0
package/lib/cli/runCli.js CHANGED
@@ -21,7 +21,7 @@
21
21
  // → spawns: agx <provider> --continue <task>
22
22
  // ============================================================
23
23
 
24
- const { spawn, spawnSync, execSync } = require('child_process');
24
+ const execa = require('execa');
25
25
  const pMap = require('p-map');
26
26
  const pRetry = require("p-retry");
27
27
  const pRetryFn = pRetry.default || pRetry;
@@ -37,6 +37,8 @@ const { loadCloudConfigFile, saveCloudConfigFile, clearCloudConfig } = require('
37
37
  const { truncateForComment, cleanAgentOutputForComment, extractFileRefsFromText } = require('../ui/text');
38
38
  const { commandExists } = require('../proc/commandExists');
39
39
  const { spawnCloudTaskProcess } = require('../proc/spawnCloudTaskProcess');
40
+ const { scheduleTermination } = require('../proc/killProcessTree');
41
+ const { getProcessManager } = require('../proc/ProcessManager');
40
42
  const { createCloudClient } = require('../cloud/client');
41
43
  const { buildContinueCloudTaskPrompt, buildNewAutonomousCloudTaskPrompt } = require('../prompts/cloudTask');
42
44
  const {
@@ -132,9 +134,11 @@ const {
132
134
  createDaemonArtifactsRecorder,
133
135
  buildLocalRunIndexEntry,
134
136
  saveAugmentedPrompt,
137
+ extractSection,
135
138
  buildFullDaemonPromptContext,
136
139
  resolveTaskTicketType,
137
140
  parseList,
141
+ localArtifactKey,
138
142
  } = cloudArtifacts;
139
143
 
140
144
  // Config paths
@@ -180,6 +184,11 @@ async function postTaskLog(taskId, content, logType) {
180
184
  if (!cloudConfig?.apiUrl) return;
181
185
 
182
186
  try {
187
+ const text = String(content ?? '');
188
+ // Server rejects empty/whitespace-only log bodies (400). Skip to avoid noisy failures.
189
+ if (!text.trim()) return;
190
+
191
+ const type = (typeof logType === 'string' && logType.trim()) ? logType.trim() : 'output';
183
192
  await fetch(`${cloudConfig.apiUrl}/api/tasks/${taskId}/logs`, {
184
193
  method: 'POST',
185
194
  headers: {
@@ -187,7 +196,7 @@ async function postTaskLog(taskId, content, logType) {
187
196
  ...(cloudConfig?.token ? { 'Authorization': `Bearer ${cloudConfig.token}` } : {}),
188
197
  'x-user-id': cloudConfig.userId || '',
189
198
  },
190
- body: JSON.stringify({ content, log_type: logType })
199
+ body: JSON.stringify({ content: text, log_type: type })
191
200
  });
192
201
  } catch { }
193
202
  }
@@ -244,6 +253,7 @@ const cloudRunner = createCloudRunner({
244
253
  fetch: globalThis.fetch,
245
254
 
246
255
  // config + transport
256
+ loadConfig,
247
257
  loadCloudConfigFile,
248
258
  postTaskLog,
249
259
  postTaskComment,
@@ -252,6 +262,8 @@ const cloudRunner = createCloudRunner({
252
262
  sanitizeCliArgs,
253
263
  commandExists,
254
264
  spawnCloudTaskProcess,
265
+ scheduleTermination,
266
+ getProcessManager,
255
267
  pMap,
256
268
  pRetryFn,
257
269
 
@@ -691,66 +703,66 @@ async function checkOnboarding() {
691
703
  console.log(`${c.green}✓${c.reset} Running task inline`);
692
704
  console.log(`${c.dim}Task: ${taskId}${c.reset}`);
693
705
 
694
- const decisionPayload = await runCloudDaemonTask(effectiveTask);
695
- // Inline run: always print the explanation so failures are actionable.
696
- if (decisionPayload?.decision && decisionPayload.decision !== 'done') {
697
- const detail = String(decisionPayload.summary || decisionPayload.explanation || '').trim();
698
- if (detail) {
699
- console.error(`${c.red}✗${c.reset} ${decisionPayload.decision}: ${detail}`);
700
- } else {
701
- console.error(`${c.red}✗${c.reset} ${decisionPayload.decision}`);
702
- }
703
- }
704
- const decision = String(decisionPayload?.decision || 'failed').toLowerCase();
705
- return decision === 'done' ? 0 : 1;
706
- }
707
-
708
- function normalizeDaemonDecision(decision, fallbackSummary = '', extra = {}) {
709
- const allowed = new Set(['done', 'blocked', 'not_done', 'failed']);
710
- const extractedDecision = typeof decision?.decision === 'string' ? decision.decision.trim() : '';
711
- const normalizedDecision = allowed.has(extractedDecision) ? extractedDecision : 'failed';
712
-
713
- const extraErr = typeof extra?.error === 'string' && extra.error.trim() ? extra.error.trim() : '';
714
- const explanation = typeof decision?.explanation === 'string' && decision.explanation.trim()
715
- ? decision.explanation.trim()
716
- : (extraErr || fallbackSummary || `Daemon decision: ${normalizedDecision}`);
717
- const finalResult = typeof decision?.final_result === 'string' && decision.final_result.trim()
718
- ? decision.final_result.trim()
719
- : explanation;
720
- const summary = typeof decision?.summary === 'string' && decision.summary.trim()
721
- ? decision.summary.trim()
722
- : (extraErr || '');
723
-
724
- return {
725
- decision: normalizedDecision,
726
- explanation,
727
- final_result: finalResult,
728
- summary,
729
- };
730
- }
731
-
732
- async function runCloudDaemonTask(task) {
733
- const { buildCloudTaskTerminalPatch } = require('../cloud/status');
734
-
735
- const taskId = String(task?.id || '').trim();
736
- if (!taskId) {
737
- throw new Error('Queue returned task without id');
738
- }
739
-
740
- const provider = String(task?.provider || task?.engine || 'claude').toLowerCase();
741
- const model = typeof task?.model === 'string' && task.model.trim() ? task.model.trim() : null;
742
- const logger = createTaskLogger(taskId);
743
- const localArtifacts = isLocalArtifactsEnabled();
744
- const storage = localArtifacts ? require('../storage') : null;
745
- const stageLocal = mapCloudStageToLocalStage(task?.stage);
746
- let projectSlug = null;
747
- let taskSlug = null;
748
- const orchestrator = getOrchestrator();
749
- const cancellationWatcher = createCancellationWatcher({ orchestrator, taskId });
750
-
751
- let lockHandle = null;
752
- let lastRun = null;
753
- let runIndexEntry = null;
706
+ const decisionPayload = await runCloudDaemonTask(effectiveTask);
707
+ // Inline run: always print the explanation so failures are actionable.
708
+ if (decisionPayload?.decision && decisionPayload.decision !== 'done') {
709
+ const detail = String(decisionPayload.summary || decisionPayload.explanation || '').trim();
710
+ if (detail) {
711
+ console.error(`${c.red}✗${c.reset} ${decisionPayload.decision}: ${detail}`);
712
+ } else {
713
+ console.error(`${c.red}✗${c.reset} ${decisionPayload.decision}`);
714
+ }
715
+ }
716
+ const decision = String(decisionPayload?.decision || 'failed').toLowerCase();
717
+ return decision === 'done' ? 0 : 1;
718
+ }
719
+
720
+ function normalizeDaemonDecision(decision, fallbackSummary = '', extra = {}) {
721
+ const allowed = new Set(['done', 'blocked', 'not_done', 'failed']);
722
+ const extractedDecision = typeof decision?.decision === 'string' ? decision.decision.trim() : '';
723
+ const normalizedDecision = allowed.has(extractedDecision) ? extractedDecision : 'failed';
724
+
725
+ const extraErr = typeof extra?.error === 'string' && extra.error.trim() ? extra.error.trim() : '';
726
+ const explanation = typeof decision?.explanation === 'string' && decision.explanation.trim()
727
+ ? decision.explanation.trim()
728
+ : (extraErr || fallbackSummary || `Daemon decision: ${normalizedDecision}`);
729
+ const finalResult = typeof decision?.final_result === 'string' && decision.final_result.trim()
730
+ ? decision.final_result.trim()
731
+ : explanation;
732
+ const summary = typeof decision?.summary === 'string' && decision.summary.trim()
733
+ ? decision.summary.trim()
734
+ : (extraErr || '');
735
+
736
+ return {
737
+ decision: normalizedDecision,
738
+ explanation,
739
+ final_result: finalResult,
740
+ summary,
741
+ };
742
+ }
743
+
744
+ async function runCloudDaemonTask(task) {
745
+ const { buildCloudTaskTerminalPatch } = require('../cloud/status');
746
+
747
+ const taskId = String(task?.id || '').trim();
748
+ if (!taskId) {
749
+ throw new Error('Queue returned task without id');
750
+ }
751
+
752
+ const provider = String(task?.provider || task?.engine || 'claude').toLowerCase();
753
+ const model = typeof task?.model === 'string' && task.model.trim() ? task.model.trim() : null;
754
+ const logger = createTaskLogger(taskId);
755
+ const localArtifacts = isLocalArtifactsEnabled();
756
+ const storage = localArtifacts ? require('../storage') : null;
757
+ const stageLocal = mapCloudStageToLocalStage(task?.stage);
758
+ let projectSlug = null;
759
+ let taskSlug = null;
760
+ const orchestrator = getOrchestrator();
761
+ const cancellationWatcher = createCancellationWatcher({ orchestrator, taskId });
762
+
763
+ let lockHandle = null;
764
+ let lastRun = null;
765
+ let runIndexEntry = null;
754
766
 
755
767
  logger.log('system', `[daemon] picked task ${taskId} (${task?.stage || 'unknown'})\n`);
756
768
  console.log(`${c.dim}[daemon] picked ${taskId} (${task?.stage || 'unknown'}) via ${provider}${model ? `/${model}` : ''}${c.reset}`);
@@ -836,19 +848,19 @@ async function checkOnboarding() {
836
848
 
837
849
  // Execute+verify loop runs per-iteration local runs under the mapped cloud stage.
838
850
  let loopResult;
839
- if (task?.swarm) {
840
- loopResult = await runSwarmExecuteVerifyLoop({
841
- taskId,
842
- task,
843
- logger,
844
- storage,
845
- projectSlug,
846
- taskSlug,
847
- stageLocal,
848
- initialPromptContext: fullPromptContext,
849
- cancellationWatcher,
850
- });
851
- } else {
851
+ if (task?.swarm) {
852
+ loopResult = await runSwarmExecuteVerifyLoop({
853
+ taskId,
854
+ task,
855
+ logger,
856
+ storage,
857
+ projectSlug,
858
+ taskSlug,
859
+ stageLocal,
860
+ initialPromptContext: fullPromptContext,
861
+ cancellationWatcher,
862
+ });
863
+ } else {
852
864
  loopResult = await runSingleAgentExecuteVerifyLoop({
853
865
  taskId,
854
866
  task,
@@ -866,20 +878,20 @@ async function checkOnboarding() {
866
878
 
867
879
  lastRun = loopResult?.lastRun || null;
868
880
  runIndexEntry = loopResult?.runIndexEntry || null;
869
- decisionPayload = normalizeDaemonDecision(
870
- loopResult?.decision,
871
- loopResult?.code === 0 ? 'Execution completed.' : 'Execution failed.',
872
- { error: task?.error || '' }
873
- );
881
+ decisionPayload = normalizeDaemonDecision(
882
+ loopResult?.decision,
883
+ loopResult?.code === 0 ? 'Execution completed.' : 'Execution failed.',
884
+ { error: task?.error || '' }
885
+ );
874
886
  } else {
875
887
  // Fallback: cloud-only execution path (legacy).
876
888
  if (task?.swarm) {
877
- runResult = await runSwarmLoop({ taskId, task, artifacts: null, cancellationWatcher });
878
- decisionPayload = normalizeDaemonDecision(
879
- runResult?.decision,
880
- runResult?.code === 0 ? 'Swarm execution completed.' : 'Swarm execution failed.',
881
- { error: task?.error || '' }
882
- );
889
+ runResult = await runSwarmLoop({ taskId, task, artifacts: null, cancellationWatcher });
890
+ decisionPayload = normalizeDaemonDecision(
891
+ runResult?.decision,
892
+ runResult?.code === 0 ? 'Swarm execution completed.' : 'Swarm execution failed.',
893
+ { error: task?.error || '' }
894
+ );
883
895
  } else {
884
896
  runResult = await runSingleAgentLoop({
885
897
  taskId,
@@ -890,36 +902,36 @@ async function checkOnboarding() {
890
902
  artifacts: null,
891
903
  cancellationWatcher,
892
904
  });
893
- decisionPayload = normalizeDaemonDecision(
894
- runResult?.decision,
895
- runResult?.code === 0 ? 'Single-agent execution completed.' : 'Single-agent execution failed.',
896
- { error: task?.error || '' }
897
- );
905
+ decisionPayload = normalizeDaemonDecision(
906
+ runResult?.decision,
907
+ runResult?.code === 0 ? 'Single-agent execution completed.' : 'Single-agent execution failed.',
908
+ { error: task?.error || '' }
909
+ );
898
910
  }
899
911
  }
900
- } catch (err) {
901
- const message = err?.message || 'Daemon execution failed.';
902
- // This error is in the daemon process (not the spawned agx subprocess), so also write it
903
- // to the run container when local artifacts are enabled.
904
- if (localArtifacts && lastRun?.paths?.root) {
905
- const runContainerPath = path.dirname(lastRun.paths.root);
906
- const detail = err?.stack || message;
907
- await appendRunContainerLog(runContainerPath, 'daemon/daemon_error.log', `[${new Date().toISOString()}] ${detail}`);
908
- }
909
- decisionPayload = {
910
- decision: 'failed',
911
- explanation: message,
912
- final_result: message,
913
- summary: message,
914
- };
915
- logger.log('error', `[daemon] execution failed: ${message}\n`);
916
- } finally {
917
- await logger.flushAll();
918
- try { cancellationWatcher?.destroy?.(); } catch { }
919
- if (localArtifacts) {
920
- try {
921
- // Runs are finalized per-iteration inside the execute/verify loop.
922
- } catch (e) {
912
+ } catch (err) {
913
+ const message = err?.message || 'Daemon execution failed.';
914
+ // This error is in the daemon process (not the spawned agx subprocess), so also write it
915
+ // to the run container when local artifacts are enabled.
916
+ if (localArtifacts && lastRun?.paths?.root) {
917
+ const runContainerPath = path.dirname(lastRun.paths.root);
918
+ const detail = err?.stack || message;
919
+ await appendRunContainerLog(runContainerPath, 'daemon/daemon_error.log', `[${new Date().toISOString()}] ${detail}`);
920
+ }
921
+ decisionPayload = {
922
+ decision: 'failed',
923
+ explanation: message,
924
+ final_result: message,
925
+ summary: message,
926
+ };
927
+ logger.log('error', `[daemon] execution failed: ${message}\n`);
928
+ } finally {
929
+ await logger.flushAll();
930
+ try { cancellationWatcher?.destroy?.(); } catch { }
931
+ if (localArtifacts) {
932
+ try {
933
+ // Runs are finalized per-iteration inside the execute/verify loop.
934
+ } catch (e) {
923
935
  // Never break cloud completion because local artifacts failed.
924
936
  logger?.log('error', `[daemon] local artifact finalize failed: ${e?.message || e}\n`);
925
937
  } finally {
@@ -930,40 +942,40 @@ async function checkOnboarding() {
930
942
  }
931
943
  }
932
944
 
933
- const completionResult = await cloudRequest('POST', '/api/queue/complete', {
934
- taskId,
935
- log: decisionPayload.summary || decisionPayload.explanation,
936
- decision: decisionPayload.decision,
937
- final_result: decisionPayload.final_result,
945
+ const completionResult = await cloudRequest('POST', '/api/queue/complete', {
946
+ taskId,
947
+ log: decisionPayload.summary || decisionPayload.explanation,
948
+ decision: decisionPayload.decision,
949
+ final_result: decisionPayload.final_result,
938
950
  explanation: decisionPayload.explanation,
939
951
  ...(localArtifacts && lastRun?.paths?.root ? {
940
952
  artifact_path: lastRun.paths.root,
941
953
  artifact_host: os.hostname(),
942
954
  artifact_key: localArtifactKey(lastRun.paths.root),
943
955
  } : {}),
944
- ...(runIndexEntry ? { run_entry: runIndexEntry } : {}),
945
- });
946
-
947
- // Best-effort: ensure cloud task status is terminal when stage/decision indicates completion.
948
- // Some board runtimes advance `stage` to "done" but leave `status` as "in_progress".
949
- try {
950
- let newStage = completionResult?.newStage || completionResult?.task?.stage || null;
951
- if (!newStage) {
952
- try {
953
- const { task: refreshed } = await cloudRequest('GET', `/api/tasks/${taskId}`);
954
- newStage = refreshed?.stage || null;
955
- } catch { }
956
- }
957
- const patch = buildCloudTaskTerminalPatch({ decision: decisionPayload?.decision, newStage });
958
- if (patch) {
959
- await cloudRequest('PATCH', `/api/tasks/${taskId}`, patch);
960
- }
961
- } catch { }
962
-
963
- // Post a structured outcome comment (separate from queue completion log).
964
- await postTaskComment(taskId, [
965
- `## ${task?.stage || 'stage'} completed`,
966
- '',
956
+ ...(runIndexEntry ? { run_entry: runIndexEntry } : {}),
957
+ });
958
+
959
+ // Best-effort: ensure cloud task status is terminal when stage/decision indicates completion.
960
+ // Some board runtimes advance `stage` to "done" but leave `status` as "in_progress".
961
+ try {
962
+ let newStage = completionResult?.newStage || completionResult?.task?.stage || null;
963
+ if (!newStage) {
964
+ try {
965
+ const { task: refreshed } = await cloudRequest('GET', `/api/tasks/${taskId}`);
966
+ newStage = refreshed?.stage || null;
967
+ } catch { }
968
+ }
969
+ const patch = buildCloudTaskTerminalPatch({ decision: decisionPayload?.decision, newStage });
970
+ if (patch) {
971
+ await cloudRequest('PATCH', `/api/tasks/${taskId}`, patch);
972
+ }
973
+ } catch { }
974
+
975
+ // Post a structured outcome comment (separate from queue completion log).
976
+ await postTaskComment(taskId, [
977
+ `## ${task?.stage || 'stage'} completed`,
978
+ '',
967
979
  `Decision: ${decisionPayload.decision}`,
968
980
  '',
969
981
  decisionPayload.summary || decisionPayload.explanation || '',
@@ -996,15 +1008,22 @@ async function checkOnboarding() {
996
1008
  const inFlight = new Map();
997
1009
  let stopping = false;
998
1010
 
1011
+ const pm = getProcessManager();
1012
+
999
1013
  const requestStop = () => {
1000
1014
  if (stopping) return;
1001
1015
  stopping = true;
1002
1016
  console.log(`\n${c.dim}[daemon] stopping... waiting for ${inFlight.size} active task(s)${c.reset}`);
1017
+ pm.killAll();
1003
1018
  };
1004
1019
 
1005
1020
  process.on('SIGINT', requestStop);
1006
1021
  process.on('SIGTERM', requestStop);
1007
1022
 
1023
+ // Periodic orphan heartbeat sweep
1024
+ const orphanSweep = setInterval(() => pm.sweepOrphanedHeartbeats(), 60_000);
1025
+ orphanSweep.unref();
1026
+
1008
1027
  console.log(`${c.green}✓${c.reset} Daemon loop started (workers=${maxWorkers}, poll=${pollMs}ms)`);
1009
1028
 
1010
1029
  while (!stopping) {
@@ -1557,14 +1576,14 @@ async function checkOnboarding() {
1557
1576
 
1558
1577
  console.log(`${c.bold}Tasks${c.reset} (${tasks.length})\n`);
1559
1578
  let idx = 1;
1560
- for (const task of tasks) {
1561
- const statusIcon = {
1562
- queued: c.yellow + '○' + c.reset,
1563
- in_progress: c.blue + '●' + c.reset,
1564
- blocked: c.yellow + '!' + c.reset,
1565
- completed: c.green + '✓' + c.reset,
1566
- failed: c.red + '✗' + c.reset,
1567
- }[task.status] || '?';
1579
+ for (const task of tasks) {
1580
+ const statusIcon = {
1581
+ queued: c.yellow + '○' + c.reset,
1582
+ in_progress: c.blue + '●' + c.reset,
1583
+ blocked: c.yellow + '!' + c.reset,
1584
+ completed: c.green + '✓' + c.reset,
1585
+ failed: c.red + '✗' + c.reset,
1586
+ }[task.status] || '?';
1568
1587
 
1569
1588
  console.log(` ${c.dim}${idx}.${c.reset} ${statusIcon} ${task.slug || 'task'}`);
1570
1589
  const displayProvider = task.swarm
@@ -1632,35 +1651,35 @@ async function checkOnboarding() {
1632
1651
  process.exit(0);
1633
1652
  }
1634
1653
 
1635
- const message = log || 'Stage completed via agx CLI';
1636
- const { task, newStage } = await cloudRequest('POST', '/api/queue/complete', {
1637
- taskId: resolvedTaskId,
1638
- log: message,
1639
- decision: 'done',
1640
- explanation: message,
1641
- final_result: message,
1642
- });
1643
- let stageAfter = newStage || task?.stage || null;
1644
- if (!stageAfter) {
1645
- try {
1646
- const { task: refreshed } = await cloudRequest('GET', `/api/tasks/${resolvedTaskId}`);
1647
- stageAfter = refreshed?.stage || null;
1648
- } catch { }
1649
- }
1650
-
1651
- // If this completion transitioned the task into a terminal stage, align `status` too.
1652
- try {
1653
- const patch = buildCloudTaskTerminalPatch({ newStage: stageAfter });
1654
- if (patch) {
1655
- await cloudRequest('PATCH', `/api/tasks/${resolvedTaskId}`, patch);
1656
- }
1657
- } catch { }
1658
-
1659
- console.log(`${c.green}✓${c.reset} Stage completed`);
1660
- console.log(` New stage: ${stageAfter || 'unknown'}`);
1661
- if (String(stageAfter || '').toLowerCase() === 'done') {
1662
- console.log(` ${c.green}Task is now complete!${c.reset}`);
1663
- }
1654
+ const message = log || 'Stage completed via agx CLI';
1655
+ const { task, newStage } = await cloudRequest('POST', '/api/queue/complete', {
1656
+ taskId: resolvedTaskId,
1657
+ log: message,
1658
+ decision: 'done',
1659
+ explanation: message,
1660
+ final_result: message,
1661
+ });
1662
+ let stageAfter = newStage || task?.stage || null;
1663
+ if (!stageAfter) {
1664
+ try {
1665
+ const { task: refreshed } = await cloudRequest('GET', `/api/tasks/${resolvedTaskId}`);
1666
+ stageAfter = refreshed?.stage || null;
1667
+ } catch { }
1668
+ }
1669
+
1670
+ // If this completion transitioned the task into a terminal stage, align `status` too.
1671
+ try {
1672
+ const patch = buildCloudTaskTerminalPatch({ newStage: stageAfter });
1673
+ if (patch) {
1674
+ await cloudRequest('PATCH', `/api/tasks/${resolvedTaskId}`, patch);
1675
+ }
1676
+ } catch { }
1677
+
1678
+ console.log(`${c.green}✓${c.reset} Stage completed`);
1679
+ console.log(` New stage: ${stageAfter || 'unknown'}`);
1680
+ if (String(stageAfter || '').toLowerCase() === 'done') {
1681
+ console.log(` ${c.green}Task is now complete!${c.reset}`);
1682
+ }
1664
1683
  } catch (err) {
1665
1684
  console.log(`${c.red}✗${c.reset} Failed: ${err.message}`);
1666
1685
  process.exit(1);
@@ -2160,9 +2179,12 @@ async function checkOnboarding() {
2160
2179
 
2161
2180
  // agx container ls (Docker-style namespace - list running daemons)
2162
2181
  if (cmd === 'container' && args[1] === 'ls') {
2163
- const { execSync } = require('child_process');
2164
2182
  try {
2165
- const result = execSync('pgrep -fl "agx.*daemon" 2>/dev/null || echo ""', { encoding: 'utf8' });
2183
+ const result = execa.commandSync('pgrep -fl "agx.*daemon" 2>/dev/null || echo \"\"', {
2184
+ shell: true,
2185
+ encoding: 'utf8',
2186
+ reject: false,
2187
+ }).stdout || '';
2166
2188
  if (result.trim()) {
2167
2189
  console.log(`${c.bold}Running Containers${c.reset}\n`);
2168
2190
  console.log(result.trim());
@@ -2216,13 +2238,18 @@ async function checkOnboarding() {
2216
2238
 
2217
2239
  // agx container stop (Docker-style namespace - stop daemon)
2218
2240
  if (cmd === 'container' && args[1] === 'stop') {
2219
- const { execSync } = require('child_process');
2220
2241
  try {
2221
- const result = execSync('pgrep -fl "agx.*daemon" 2>/dev/null || echo ""', { encoding: 'utf8' });
2242
+ const result = execa.commandSync('pgrep -fl "agx.*daemon" 2>/dev/null || echo \"\"', {
2243
+ shell: true,
2244
+ encoding: 'utf8',
2245
+ reject: false,
2246
+ }).stdout || '';
2222
2247
  if (result.trim()) {
2223
- const pids = result.trim().split('\n').map(line => line.split(' ')[0]);
2248
+ const pids = result.trim().split('\n').map(line => line.trim().split(/\s+/)[0]).filter(Boolean);
2224
2249
  for (const pid of pids) {
2225
- execSync(`kill ${pid}`, { encoding: 'utf8' });
2250
+ const n = Number.parseInt(pid, 10);
2251
+ if (!Number.isFinite(n) || n <= 0) continue;
2252
+ try { process.kill(n, 'SIGTERM'); } catch { }
2226
2253
  }
2227
2254
  console.log(`${c.green}✓${c.reset} Container(s) stopped`);
2228
2255
  } else {
@@ -2307,7 +2334,7 @@ async function checkOnboarding() {
2307
2334
  // Helper to get current crontab
2308
2335
  const getCrontab = () => {
2309
2336
  try {
2310
- return execSync('crontab -l 2>/dev/null', { encoding: 'utf8' });
2337
+ return execa.commandSync('crontab -l 2>/dev/null', { shell: true, encoding: 'utf8', reject: false }).stdout || '';
2311
2338
  } catch {
2312
2339
  return '';
2313
2340
  }
@@ -2318,9 +2345,9 @@ async function checkOnboarding() {
2318
2345
  const tmp = path.join(os.tmpdir(), `agx-crontab-${Date.now()}`);
2319
2346
  fs.writeFileSync(tmp, content);
2320
2347
  try {
2321
- execSync(`crontab ${tmp}`, { timeout: 5000 });
2348
+ execa.commandSync(`crontab ${tmp}`, { shell: true, timeout: 5000, reject: false });
2322
2349
  } finally {
2323
- try { fs.unlinkSync(tmp); } catch {}
2350
+ try { fs.unlinkSync(tmp); } catch { }
2324
2351
  }
2325
2352
  };
2326
2353
 
@@ -2374,11 +2401,13 @@ async function checkOnboarding() {
2374
2401
  // Default: update now
2375
2402
  console.log(`${c.cyan}→${c.reset} Checking for updates...`);
2376
2403
  try {
2377
- const result = spawnSync('npm', ['update', '-g', '@mndrk/agx'], {
2404
+ const child = execa('npm', ['update', '-g', '@mndrk/agx'], {
2378
2405
  stdio: 'inherit',
2379
- shell: true
2406
+ shell: false,
2407
+ reject: false,
2380
2408
  });
2381
- if (result.status === 0) {
2409
+ const result = await child;
2410
+ if (result.exitCode === 0) {
2382
2411
  console.log(`${c.green}✓${c.reset} Update complete`);
2383
2412
  } else {
2384
2413
  console.log(`${c.red}✗${c.reset} Update failed`);
@@ -2456,35 +2485,35 @@ async function runCli(argv = process.argv) {
2456
2485
  const originalArgv = process.argv;
2457
2486
  if (Array.isArray(argv)) process.argv = argv;
2458
2487
  try {
2459
- if (await checkOnboarding()) return;
2488
+ if (await checkOnboarding()) return;
2460
2489
 
2461
- const args = process.argv.slice(2);
2462
- let provider = args[0];
2463
- const config = loadConfig();
2490
+ const args = process.argv.slice(2);
2491
+ let provider = args[0];
2492
+ const config = loadConfig();
2464
2493
 
2465
- // Normalize provider aliases
2466
- const PROVIDER_ALIASES = {
2467
- 'g': 'gemini',
2468
- 'gem': 'gemini',
2469
- 'gemini': 'gemini',
2470
- 'c': 'claude',
2471
- 'cl': 'claude',
2472
- 'claude': 'claude',
2473
- 'x': 'codex',
2474
- 'codex': 'codex',
2475
- 'o': 'ollama',
2476
- 'ol': 'ollama',
2477
- 'ollama': 'ollama'
2478
- };
2494
+ // Normalize provider aliases
2495
+ const PROVIDER_ALIASES = {
2496
+ 'g': 'gemini',
2497
+ 'gem': 'gemini',
2498
+ 'gemini': 'gemini',
2499
+ 'c': 'claude',
2500
+ 'cl': 'claude',
2501
+ 'claude': 'claude',
2502
+ 'x': 'codex',
2503
+ 'codex': 'codex',
2504
+ 'o': 'ollama',
2505
+ 'ol': 'ollama',
2506
+ 'ollama': 'ollama'
2507
+ };
2479
2508
 
2480
- const VALID_PROVIDERS = ['gemini', 'claude', 'ollama', 'codex'];
2509
+ const VALID_PROVIDERS = ['gemini', 'claude', 'ollama', 'codex'];
2481
2510
 
2482
- // Handle help
2483
- if (args.includes('--help') || args.includes('-h')) {
2484
- const defaultNote = config?.defaultProvider
2485
- ? ` Default: ${config.defaultProvider}`
2486
- : '';
2487
- console.log(`agx - Autonomous AI Agent CLI
2511
+ // Handle help
2512
+ if (args.includes('--help') || args.includes('-h')) {
2513
+ const defaultNote = config?.defaultProvider
2514
+ ? ` Default: ${config.defaultProvider}`
2515
+ : '';
2516
+ console.log(`agx - Autonomous AI Agent CLI
2488
2517
 
2489
2518
  USAGE:
2490
2519
  agx -a -p "build something" Autonomous: works until done
@@ -2548,386 +2577,338 @@ EXAMPLES:
2548
2577
  agx codex -p "refactor this" # One-shot question
2549
2578
  agx task ls # Check cloud tasks
2550
2579
  agx container logs # See what's happening`);
2551
- process.exit(0);
2552
- }
2553
-
2554
- // Detect if first arg is a provider or an option
2555
- const isProviderArg = provider && PROVIDER_ALIASES[provider.toLowerCase()];
2556
-
2557
- // If no provider specified, use default from config
2558
- if (!provider || (!isProviderArg && provider.startsWith('-'))) {
2559
- if (config?.defaultProvider) {
2560
- // Shift: treat current args as options, use default provider
2561
- if (provider && provider.startsWith('-')) {
2562
- // First arg is an option, not a provider
2563
- provider = config.defaultProvider;
2564
- } else if (!provider) {
2565
- provider = config.defaultProvider;
2566
- }
2567
- } else {
2568
- console.log(`${c.yellow}No provider specified and no default configured.${c.reset}`);
2569
- console.log(`\nRun ${c.cyan}agx init${c.reset} to set up, or specify a provider:\n`);
2570
- console.log(` ${c.dim}agx claude --prompt "hello"${c.reset}`);
2571
- console.log(` ${c.dim}agx codex --prompt "hello"${c.reset}`);
2572
- console.log(` ${c.dim}agx gemini --prompt "hello"${c.reset}`);
2573
- console.log(` ${c.dim}agx ollama --prompt "hello"${c.reset}\n`);
2574
- process.exit(1);
2580
+ process.exit(0);
2575
2581
  }
2576
- }
2577
2582
 
2578
- // Resolve provider
2579
- const resolvedProvider = PROVIDER_ALIASES[provider.toLowerCase()];
2580
- if (!resolvedProvider) {
2581
- console.error(`${c.red}Error:${c.reset} Unknown provider "${provider}"`);
2582
- console.error(`Valid providers: ${VALID_PROVIDERS.join(', ')}`);
2583
- process.exit(1);
2584
- }
2585
- provider = resolvedProvider;
2586
-
2587
- // Determine remaining args - if first arg wasn't a provider, include it
2588
- const remainingArgs = isProviderArg ? args.slice(1) : args;
2589
- const translatedArgs = [];
2590
- const rawArgs = [];
2591
- let env = { ...process.env };
2592
-
2593
- // Split raw arguments at --
2594
- const dashIndex = remainingArgs.indexOf('--');
2595
- let processedArgs = remainingArgs;
2596
- if (dashIndex !== -1) {
2597
- processedArgs = remainingArgs.slice(0, dashIndex);
2598
- rawArgs.push(...remainingArgs.slice(dashIndex + 1));
2599
- }
2600
-
2601
- // Parsed options (explicit structure for predictability)
2602
- const options = {
2603
- prompt: null,
2604
- model: null,
2605
- yolo: false,
2606
- print: false,
2607
- interactive: false,
2608
- sandbox: false,
2609
- debug: false,
2610
- mcp: null,
2611
- cloud: null, // null = auto-detect, true = force on, false = force off
2612
- cloudTaskId: null,
2613
- autonomous: false,
2614
- daemon: false
2615
- };
2583
+ // Detect if first arg is a provider or an option
2584
+ const isProviderArg = provider && PROVIDER_ALIASES[provider.toLowerCase()];
2616
2585
 
2617
- // Collect positional args (legacy support, but --prompt is preferred)
2618
- const positionalArgs = [];
2619
-
2620
- for (let i = 0; i < processedArgs.length; i++) {
2621
- const arg = processedArgs[i];
2622
- const nextArg = processedArgs[i + 1];
2623
-
2624
- switch (arg) {
2625
- case '--prompt':
2626
- case '-p':
2627
- if (nextArg && !nextArg.startsWith('-')) {
2628
- options.prompt = nextArg;
2629
- i++;
2630
- }
2631
- break;
2632
- case '--model':
2633
- case '-m':
2634
- if (nextArg && !nextArg.startsWith('-')) {
2635
- options.model = nextArg;
2636
- i++;
2637
- }
2638
- break;
2639
- case '--yolo':
2640
- case '-y':
2641
- options.yolo = true;
2642
- break;
2643
- case '--print':
2644
- options.print = true;
2645
- break;
2646
- case '--interactive':
2647
- case '-i':
2648
- options.interactive = true;
2649
- break;
2650
- case '--sandbox':
2651
- case '-s':
2652
- options.sandbox = true;
2653
- break;
2654
- case '--debug':
2655
- case '-d':
2656
- options.debug = true;
2657
- break;
2658
- case '--mcp':
2659
- if (nextArg && !nextArg.startsWith('-')) {
2660
- options.mcp = nextArg;
2661
- i++;
2662
- }
2663
- break;
2664
- case '--autonomous':
2665
- case '--auto':
2666
- case '-a':
2667
- options.autonomous = true;
2668
- options.yolo = true; // Autonomous = unattended, skip prompts
2669
- break;
2670
- case '--cloud-task':
2671
- if (nextArg && !nextArg.startsWith('-')) {
2672
- options.cloudTaskId = nextArg;
2673
- i++;
2674
- }
2675
- break;
2676
- case '--daemon':
2677
- options.daemon = true;
2678
- break;
2679
- default:
2680
- if (arg.startsWith('-')) {
2681
- // Unknown flag - pass through
2682
- translatedArgs.push(arg);
2683
- } else {
2684
- // Positional argument (legacy prompt support)
2685
- positionalArgs.push(arg);
2586
+ // If no provider specified, use default from config
2587
+ if (!provider || (!isProviderArg && provider.startsWith('-'))) {
2588
+ if (config?.defaultProvider) {
2589
+ // Shift: treat current args as options, use default provider
2590
+ if (provider && provider.startsWith('-')) {
2591
+ // First arg is an option, not a provider
2592
+ provider = config.defaultProvider;
2593
+ } else if (!provider) {
2594
+ provider = config.defaultProvider;
2686
2595
  }
2596
+ } else {
2597
+ console.log(`${c.yellow}No provider specified and no default configured.${c.reset}`);
2598
+ console.log(`\nRun ${c.cyan}agx init${c.reset} to set up, or specify a provider:\n`);
2599
+ console.log(` ${c.dim}agx claude --prompt "hello"${c.reset}`);
2600
+ console.log(` ${c.dim}agx codex --prompt "hello"${c.reset}`);
2601
+ console.log(` ${c.dim}agx gemini --prompt "hello"${c.reset}`);
2602
+ console.log(` ${c.dim}agx ollama --prompt "hello"${c.reset}\n`);
2603
+ process.exit(1);
2604
+ }
2687
2605
  }
2688
- }
2689
-
2690
- // Determine final prompt: explicit --prompt takes precedence
2691
- const finalPrompt = options.prompt || positionalArgs.join(' ');
2692
2606
 
2693
- // Apply default model from config when --model is not specified
2694
- if (!options.model) {
2695
- const configuredModel = config?.models?.[provider] || (provider === 'ollama' ? config?.ollama?.model : null);
2696
- if (configuredModel) options.model = configuredModel;
2697
- }
2698
-
2699
- // Build command based on provider
2700
- let command = '';
2701
-
2702
- // Apply common options to translatedArgs
2703
- if (options.model) {
2704
- translatedArgs.push('--model', options.model);
2705
- }
2706
- if (options.debug) {
2707
- translatedArgs.push('--debug');
2708
- }
2607
+ // Resolve provider
2608
+ const resolvedProvider = PROVIDER_ALIASES[provider.toLowerCase()];
2609
+ if (!resolvedProvider) {
2610
+ console.error(`${c.red}Error:${c.reset} Unknown provider "${provider}"`);
2611
+ console.error(`Valid providers: ${VALID_PROVIDERS.join(', ')}`);
2612
+ process.exit(1);
2613
+ }
2614
+ provider = resolvedProvider;
2615
+
2616
+ // Determine remaining args - if first arg wasn't a provider, include it
2617
+ const remainingArgs = isProviderArg ? args.slice(1) : args;
2618
+ const translatedArgs = [];
2619
+ const rawArgs = [];
2620
+ let env = { ...process.env };
2621
+
2622
+ // Split raw arguments at --
2623
+ const dashIndex = remainingArgs.indexOf('--');
2624
+ let processedArgs = remainingArgs;
2625
+ if (dashIndex !== -1) {
2626
+ processedArgs = remainingArgs.slice(0, dashIndex);
2627
+ rawArgs.push(...remainingArgs.slice(dashIndex + 1));
2628
+ }
2629
+
2630
+ // Parsed options (explicit structure for predictability)
2631
+ const options = {
2632
+ prompt: null,
2633
+ model: null,
2634
+ yolo: false,
2635
+ print: false,
2636
+ interactive: false,
2637
+ sandbox: false,
2638
+ debug: false,
2639
+ mcp: null,
2640
+ cloud: null, // null = auto-detect, true = force on, false = force off
2641
+ cloudTaskId: null,
2642
+ autonomous: false,
2643
+ daemon: false
2644
+ };
2709
2645
 
2710
- if (provider === 'gemini') {
2711
- command = 'gemini';
2646
+ // Collect positional args (legacy support, but --prompt is preferred)
2647
+ const positionalArgs = [];
2712
2648
 
2713
- // Gemini-specific translations
2714
- if (options.yolo) translatedArgs.push('--yolo');
2715
- if (options.sandbox) translatedArgs.push('--sandbox');
2649
+ for (let i = 0; i < processedArgs.length; i++) {
2650
+ const arg = processedArgs[i];
2651
+ const nextArg = processedArgs[i + 1];
2716
2652
 
2717
- // Gemini prompt handling
2718
- if (finalPrompt) {
2719
- if (options.print) {
2720
- translatedArgs.push('--prompt', finalPrompt);
2721
- } else if (options.interactive) {
2722
- translatedArgs.push('--prompt-interactive', finalPrompt);
2723
- } else {
2724
- translatedArgs.push(finalPrompt);
2725
- }
2726
- }
2727
- } else if (provider === 'codex') {
2728
- command = 'codex';
2729
-
2730
- // Use non-interactive mode whenever this is a scripted invocation.
2731
- const shouldUseExec = options.cloudTaskId
2732
- || options.autonomous
2733
- || options.daemon
2734
- || options.print
2735
- || (finalPrompt && !options.interactive);
2736
- if (shouldUseExec) {
2737
- translatedArgs.unshift('exec');
2738
- }
2739
-
2740
- // Codex approval/sandbox modes:
2741
- // - Officially documented: --auto-edit, --full-auto
2742
- // - Some Codex builds also accept: --dangerously-bypass-approvals-and-sandbox
2743
- // We only attempt the dangerous bypass for unattended runs, and we add a runtime
2744
- // retry below if the installed Codex CLI rejects the flag.
2745
- // If we're using `codex exec`, choose exactly one execution policy:
2746
- // - default unattended: --full-auto (sandboxed, workspace-write)
2747
- // - explicit yolo: --dangerously-bypass-approvals-and-sandbox (unsandboxed)
2748
- //
2749
- // Codex CLI rejects using both at once.
2750
- if (shouldUseExec) {
2751
- if (options.yolo) {
2752
- translatedArgs.push('--dangerously-bypass-approvals-and-sandbox');
2753
- } else {
2754
- translatedArgs.push('--full-auto');
2653
+ switch (arg) {
2654
+ case '--prompt':
2655
+ case '-p':
2656
+ if (nextArg && !nextArg.startsWith('-')) {
2657
+ options.prompt = nextArg;
2658
+ i++;
2659
+ }
2660
+ break;
2661
+ case '--model':
2662
+ case '-m':
2663
+ if (nextArg && !nextArg.startsWith('-')) {
2664
+ options.model = nextArg;
2665
+ i++;
2666
+ }
2667
+ break;
2668
+ case '--yolo':
2669
+ case '-y':
2670
+ options.yolo = true;
2671
+ break;
2672
+ case '--print':
2673
+ options.print = true;
2674
+ break;
2675
+ case '--interactive':
2676
+ case '-i':
2677
+ options.interactive = true;
2678
+ break;
2679
+ case '--sandbox':
2680
+ case '-s':
2681
+ options.sandbox = true;
2682
+ break;
2683
+ case '--debug':
2684
+ case '-d':
2685
+ options.debug = true;
2686
+ break;
2687
+ case '--mcp':
2688
+ if (nextArg && !nextArg.startsWith('-')) {
2689
+ options.mcp = nextArg;
2690
+ i++;
2691
+ }
2692
+ break;
2693
+ case '--autonomous':
2694
+ case '--auto':
2695
+ case '-a':
2696
+ options.autonomous = true;
2697
+ options.yolo = true; // Autonomous = unattended, skip prompts
2698
+ break;
2699
+ case '--cloud-task':
2700
+ if (nextArg && !nextArg.startsWith('-')) {
2701
+ options.cloudTaskId = nextArg;
2702
+ i++;
2703
+ }
2704
+ break;
2705
+ case '--daemon':
2706
+ options.daemon = true;
2707
+ break;
2708
+ default:
2709
+ if (arg.startsWith('-')) {
2710
+ // Unknown flag - pass through
2711
+ translatedArgs.push(arg);
2712
+ } else {
2713
+ // Positional argument (legacy prompt support)
2714
+ positionalArgs.push(arg);
2715
+ }
2755
2716
  }
2756
2717
  }
2757
2718
 
2758
- if (finalPrompt) {
2759
- translatedArgs.push(finalPrompt);
2719
+ // Determine final prompt: explicit --prompt takes precedence
2720
+ const finalPrompt = options.prompt || positionalArgs.join(' ');
2721
+
2722
+ // Apply default model from config when --model is not specified
2723
+ if (!options.model) {
2724
+ const configuredModel = config?.models?.[provider] || (provider === 'ollama' ? config?.ollama?.model : null);
2725
+ if (configuredModel) options.model = configuredModel;
2760
2726
  }
2761
- } else if (provider === 'ollama') {
2762
- // Ollama now routes through Claude CLI with Ollama base URL
2763
- command = 'claude';
2764
- translatedArgs.length = 0; // Clear any accumulated args
2765
2727
 
2766
- // Environment variables for Ollama-via-Claude
2767
- env.ANTHROPIC_AUTH_TOKEN = 'ollama';
2768
- env.ANTHROPIC_BASE_URL = 'http://localhost:11434';
2769
- env.ANTHROPIC_API_KEY = '';
2728
+ // Build command based on provider
2729
+ let command = '';
2770
2730
 
2771
- // Claude flags for Ollama compatibility
2772
- translatedArgs.push('--dangerously-skip-permissions');
2731
+ // Apply common options to translatedArgs
2732
+ if (options.model) {
2733
+ translatedArgs.push('--model', options.model);
2734
+ }
2735
+ if (options.debug) {
2736
+ translatedArgs.push('--debug');
2737
+ }
2773
2738
 
2774
- // Get model from options or config
2775
- const ollamaModel = options.model || config?.models?.ollama || config?.ollama?.model || 'llama3.2:3b';
2776
- translatedArgs.push('--model', ollamaModel);
2739
+ if (provider === 'gemini') {
2740
+ command = 'gemini';
2777
2741
 
2778
- if (finalPrompt) {
2779
- translatedArgs.push('-p', finalPrompt);
2780
- }
2781
- } else {
2782
- // Claude
2783
- command = 'claude';
2742
+ // Gemini-specific translations
2743
+ if (options.yolo) translatedArgs.push('--yolo');
2744
+ if (options.sandbox) translatedArgs.push('--sandbox');
2784
2745
 
2785
- // Claude-specific translations
2786
- if (options.yolo) translatedArgs.push('--dangerously-skip-permissions');
2787
- // Default to --print when prompt is provided and --interactive not specified
2788
- if (options.print || (finalPrompt && !options.interactive)) {
2789
- translatedArgs.push('--print');
2790
- }
2791
- if (options.mcp) translatedArgs.push('--mcp-config', options.mcp);
2746
+ // Gemini prompt handling
2747
+ if (finalPrompt) {
2748
+ if (options.print) {
2749
+ translatedArgs.push('--prompt', finalPrompt);
2750
+ } else if (options.interactive) {
2751
+ translatedArgs.push('--prompt-interactive', finalPrompt);
2752
+ } else {
2753
+ translatedArgs.push(finalPrompt);
2754
+ }
2755
+ }
2756
+ } else if (provider === 'codex') {
2757
+ command = 'codex';
2758
+
2759
+ // Use non-interactive mode whenever this is a scripted invocation.
2760
+ const shouldUseExec = options.cloudTaskId
2761
+ || options.autonomous
2762
+ || options.daemon
2763
+ || options.print
2764
+ || (finalPrompt && !options.interactive);
2765
+ if (shouldUseExec) {
2766
+ translatedArgs.unshift('exec');
2767
+ }
2768
+
2769
+ // Codex approval/sandbox modes:
2770
+ // - Officially documented: --auto-edit, --full-auto
2771
+ // - Some Codex builds also accept: --dangerously-bypass-approvals-and-sandbox
2772
+ // We only attempt the dangerous bypass for unattended runs, and we add a runtime
2773
+ // retry below if the installed Codex CLI rejects the flag.
2774
+ // If we're using `codex exec`, choose exactly one execution policy:
2775
+ // - default unattended: --full-auto (sandboxed, workspace-write)
2776
+ // - explicit yolo: --dangerously-bypass-approvals-and-sandbox (unsandboxed)
2777
+ //
2778
+ // Codex CLI rejects using both at once.
2779
+ if (shouldUseExec) {
2780
+ if (options.yolo) {
2781
+ translatedArgs.push('--dangerously-bypass-approvals-and-sandbox');
2782
+ } else {
2783
+ translatedArgs.push('--full-auto');
2784
+ }
2785
+ }
2792
2786
 
2793
- // Claude prompt (positional at end)
2794
- if (finalPrompt) {
2795
- translatedArgs.push(finalPrompt);
2796
- }
2797
- }
2787
+ if (finalPrompt) {
2788
+ translatedArgs.push(finalPrompt);
2789
+ }
2790
+ } else if (provider === 'ollama') {
2791
+ // Ollama now routes through Claude CLI with Ollama base URL
2792
+ command = 'claude';
2793
+ translatedArgs.length = 0; // Clear any accumulated args
2798
2794
 
2799
- // Append raw args at the end
2800
- translatedArgs.push(...rawArgs);
2795
+ // Environment variables for Ollama-via-Claude
2796
+ env.ANTHROPIC_AUTH_TOKEN = 'ollama';
2797
+ env.ANTHROPIC_BASE_URL = 'http://localhost:11434';
2798
+ env.ANTHROPIC_API_KEY = '';
2801
2799
 
2802
- // ==================== CLOUD INTEGRATION ====================
2800
+ // Claude flags for Ollama compatibility
2801
+ translatedArgs.push('--dangerously-skip-permissions');
2803
2802
 
2804
- // Cloud context logic:
2805
- // - agx -p "..." one-shot, no task
2806
- // - agx -a -p "..." → create new task in cloud
2807
- // - agx --cloud-task <id> → continue cloud task (used by daemon)
2803
+ // Get model from options or config
2804
+ const ollamaModel = options.model || config?.models?.ollama || config?.ollama?.model || 'llama3.2:3b';
2805
+ translatedArgs.push('--model', ollamaModel);
2808
2806
 
2809
- const cloudClient = createCloudClient({ configDir: CONFIG_DIR });
2810
- const loadCloudConfig = cloudClient.loadConfig;
2811
- const saveCloudConfig = cloudClient.saveConfig;
2812
- const cloudRequest = cloudClient.request;
2807
+ if (finalPrompt) {
2808
+ translatedArgs.push('-p', finalPrompt);
2809
+ }
2810
+ } else {
2811
+ // Claude
2812
+ command = 'claude';
2813
2813
 
2814
- // Best-effort: if local CLI settings are newer than DB settings, up-sync to cloud.
2815
- // Non-fatal on failure (offline DB, schema missing, etc.).
2816
- try {
2817
- const meta = config?.settingsMeta || {};
2818
- const cliChangedAt = typeof meta.changedAt === 'string' ? meta.changedAt : '';
2819
- const cliChangedTs = cliChangedAt ? Date.parse(cliChangedAt) : NaN;
2820
- const cliProvider = config?.defaultProvider || '';
2821
- const cliModel = cliProvider
2822
- ? (config?.models?.[cliProvider] || (cliProvider === 'ollama' ? config?.ollama?.model : null))
2823
- : null;
2824
-
2825
- if (Number.isFinite(cliChangedTs) && cliProvider && cliModel) {
2826
- let dbChangedTs = NaN;
2827
- try {
2828
- const db = await cloudRequest('GET', '/api/user-settings');
2829
- const dbChangedAt = typeof db?.settings?.changed_at === 'string' ? db.settings.changed_at : '';
2830
- dbChangedTs = dbChangedAt ? Date.parse(dbChangedAt) : NaN;
2831
- } catch { }
2814
+ // Claude-specific translations
2815
+ if (options.yolo) translatedArgs.push('--dangerously-skip-permissions');
2816
+ // Default to --print when prompt is provided and --interactive not specified
2817
+ if (options.print || (finalPrompt && !options.interactive)) {
2818
+ translatedArgs.push('--print');
2819
+ }
2820
+ if (options.mcp) translatedArgs.push('--mcp-config', options.mcp);
2832
2821
 
2833
- if (!Number.isFinite(dbChangedTs) || cliChangedTs > dbChangedTs) {
2834
- await cloudRequest('PUT', '/api/user-settings', {
2835
- default_provider: cliProvider,
2836
- default_model: cliModel,
2837
- models: config?.models || { [cliProvider]: cliModel },
2838
- provenance: 'cli',
2839
- changed_at: cliChangedAt,
2840
- });
2822
+ // Claude prompt (positional at end)
2823
+ if (finalPrompt) {
2824
+ translatedArgs.push(finalPrompt);
2841
2825
  }
2842
2826
  }
2843
- } catch { }
2844
2827
 
2845
- // --cloud-task: load existing task from cloud (used by daemon)
2846
- if (options.cloudTaskId) {
2847
- try {
2848
- const { task } = await cloudRequest('GET', `/api/tasks/${options.cloudTaskId}`);
2828
+ // Append raw args at the end
2829
+ translatedArgs.push(...rawArgs);
2849
2830
 
2850
- // Fetch task comments
2851
- let taskComments = [];
2852
- try {
2853
- const commentsResponse = await cloudRequest('GET', `/api/tasks/${options.cloudTaskId}/comments`);
2854
- taskComments = commentsResponse?.comments || [];
2855
- } catch (err) {
2856
- console.error(`${c.yellow}Warning: Could not fetch task comments:${c.reset} ${err.message}`);
2857
- }
2858
-
2859
- // Build augmented prompt with task context
2860
- const plan = extractSection(task.content, 'Plan');
2861
- const todo = extractSection(task.content, 'Todo') || extractSection(task.content, 'TODO');
2862
- const checkpoints = extractSection(task.content, 'Checkpoints');
2863
- const learnings = extractSection(task.content, 'Learnings');
2864
-
2865
- const stageKey = task?.stage || 'unknown';
2866
- const stagePrompt = resolveStageObjective(task, stageKey, '');
2867
- const stageRequirement = buildStageRequirementPrompt({ stage: stageKey, stagePrompt });
2868
-
2869
- const augmentedPrompt = buildContinueCloudTaskPrompt({
2870
- task,
2871
- taskComments,
2872
- finalPrompt,
2873
- stagePrompt,
2874
- stageRequirement,
2875
- extracted: { plan, todo, checkpoints, learnings },
2876
- });
2831
+ // ==================== CLOUD INTEGRATION ====================
2877
2832
 
2878
- const promptIndex = translatedArgs.indexOf(finalPrompt);
2879
- if (promptIndex !== -1) {
2880
- translatedArgs[promptIndex] = augmentedPrompt;
2881
- } else {
2882
- translatedArgs.push(augmentedPrompt);
2883
- }
2884
- saveAugmentedPrompt(augmentedPrompt, options.debug);
2833
+ // Cloud context logic:
2834
+ // - agx -p "..." → one-shot, no task
2835
+ // - agx -a -p "..." → create new task in cloud
2836
+ // - agx --cloud-task <id> → continue cloud task (used by daemon)
2885
2837
 
2886
- console.log(`${c.dim}[cloud] Loaded task: ${task.title || task.id}${c.reset}\n`);
2887
- } catch (err) {
2888
- console.error(`${c.red}Failed to load cloud task:${c.reset} ${err.message}`);
2889
- process.exit(1);
2890
- }
2891
- }
2892
-
2893
- // Auto-create task in cloud if --autonomous specified
2894
- if (options.autonomous && finalPrompt && !options.cloudTaskId) {
2895
- console.log(`${c.dim}[cloud] Creating task...${c.reset}`);
2838
+ const cloudClient = createCloudClient({ configDir: CONFIG_DIR });
2839
+ const loadCloudConfig = cloudClient.loadConfig;
2840
+ const saveCloudConfig = cloudClient.saveConfig;
2841
+ const cloudRequest = cloudClient.request;
2896
2842
 
2843
+ // Best-effort: if local CLI settings are newer than DB settings, up-sync to cloud.
2844
+ // Non-fatal on failure (offline DB, schema missing, etc.).
2897
2845
  try {
2898
- const cloudConfig = loadCloudConfig();
2899
- if (cloudConfig?.apiUrl) {
2900
- const frontmatter = ['status: queued', 'stage: ideation'];
2901
- frontmatter.push(`engine: ${provider}`);
2902
-
2903
- const content = `---\n${frontmatter.join('\n')}\n---\n\n# ${finalPrompt}\n`;
2846
+ const meta = config?.settingsMeta || {};
2847
+ const cliChangedAt = typeof meta.changedAt === 'string' ? meta.changedAt : '';
2848
+ const cliChangedTs = cliChangedAt ? Date.parse(cliChangedAt) : NaN;
2849
+ const cliProvider = config?.defaultProvider || '';
2850
+ const cliModel = cliProvider
2851
+ ? (config?.models?.[cliProvider] || (cliProvider === 'ollama' ? config?.ollama?.model : null))
2852
+ : null;
2853
+
2854
+ if (Number.isFinite(cliChangedTs) && cliProvider && cliModel) {
2855
+ let dbChangedTs = NaN;
2856
+ try {
2857
+ const db = await cloudRequest('GET', '/api/user-settings');
2858
+ const dbChangedAt = typeof db?.settings?.changed_at === 'string' ? db.settings.changed_at : '';
2859
+ dbChangedTs = dbChangedAt ? Date.parse(dbChangedAt) : NaN;
2860
+ } catch { }
2904
2861
 
2905
- const { task } = await cloudRequest('POST', '/api/tasks', { content });
2862
+ if (!Number.isFinite(dbChangedTs) || cliChangedTs > dbChangedTs) {
2863
+ await cloudRequest('PUT', '/api/user-settings', {
2864
+ default_provider: cliProvider,
2865
+ default_model: cliModel,
2866
+ models: config?.models || { [cliProvider]: cliModel },
2867
+ provenance: 'cli',
2868
+ changed_at: cliChangedAt,
2869
+ });
2870
+ }
2871
+ }
2872
+ } catch { }
2906
2873
 
2907
- console.log(`${c.green}✓${c.reset} Task created in cloud: ${task.id}`);
2908
- options.cloudTaskId = task.id;
2874
+ // --cloud-task: load existing task from cloud (used by daemon)
2875
+ if (options.cloudTaskId) {
2876
+ try {
2877
+ const { task } = await cloudRequest('GET', `/api/tasks/${options.cloudTaskId}`);
2909
2878
 
2910
- // Fetch task comments (should be empty for new tasks, but good practice)
2879
+ // Fetch task comments
2911
2880
  let taskComments = [];
2912
2881
  try {
2913
- const commentsResponse = await cloudRequest('GET', `/api/tasks/${task.id}/comments`);
2882
+ const commentsResponse = await cloudRequest('GET', `/api/tasks/${options.cloudTaskId}/comments`);
2914
2883
  taskComments = commentsResponse?.comments || [];
2915
2884
  } catch (err) {
2916
2885
  console.error(`${c.yellow}Warning: Could not fetch task comments:${c.reset} ${err.message}`);
2917
2886
  }
2918
2887
 
2919
- // Update prompt with task context
2920
- const stageKey = task?.stage || 'unknown';
2921
- const stagePrompt = resolveStageObjective(task, stageKey, '');
2922
- const stageRequirement = buildStageRequirementPrompt({ stage: stageKey, stagePrompt });
2923
-
2924
- const augmentedPrompt = buildNewAutonomousCloudTaskPrompt({
2925
- task,
2926
- taskComments,
2927
- finalPrompt,
2928
- stagePrompt,
2929
- stageRequirement,
2930
- });
2888
+ // Build augmented prompt with task context
2889
+ const plan = cloudArtifacts.extractSection(task.content, 'Plan');
2890
+ const todo = cloudArtifacts.extractSection(task.content, 'Todo') || cloudArtifacts.extractSection(task.content, 'TODO');
2891
+ const checkpoints = cloudArtifacts.extractSection(task.content, 'Checkpoints');
2892
+ const learnings = cloudArtifacts.extractSection(task.content, 'Learnings');
2893
+
2894
+ const stageKey = task?.stage || 'unknown';
2895
+ const stagePrompt = resolveStageObjective(task, stageKey, '');
2896
+ const stageRequirement = buildStageRequirementPrompt({ stage: stageKey, stagePrompt });
2897
+ const runContext = {
2898
+ run_root: process.env.AGX_RUN_ROOT || '',
2899
+ plan_dir: process.env.AGX_RUN_PLAN_DIR || '',
2900
+ artifacts_dir: process.env.AGX_RUN_ARTIFACTS_DIR || '',
2901
+ };
2902
+
2903
+ const augmentedPrompt = buildContinueCloudTaskPrompt({
2904
+ task,
2905
+ taskComments,
2906
+ finalPrompt,
2907
+ stagePrompt,
2908
+ stageRequirement,
2909
+ extracted: { plan, todo, checkpoints, learnings },
2910
+ runContext,
2911
+ });
2931
2912
 
2932
2913
  const promptIndex = translatedArgs.indexOf(finalPrompt);
2933
2914
  if (promptIndex !== -1) {
@@ -2937,115 +2918,170 @@ EXAMPLES:
2937
2918
  }
2938
2919
  saveAugmentedPrompt(augmentedPrompt, options.debug);
2939
2920
 
2940
- // Start daemon for autonomous mode
2941
- if (options.autonomous) {
2942
- startDaemon();
2943
- console.log(`${c.green}✓${c.reset} Autonomous mode: daemon running\n`);
2944
- }
2945
- } else {
2946
- console.log(`${c.yellow}Cloud API URL not configured. Set AGX_CLOUD_URL (default http://localhost:41741).${c.reset}`);
2947
- console.log(`${c.dim}Task not created. Running in one-shot mode.${c.reset}`);
2921
+ console.log(`${c.dim}[cloud] Loaded task: ${task.title || task.id}${c.reset}\n`);
2922
+ } catch (err) {
2923
+ console.error(`${c.red}Failed to load cloud task:${c.reset} ${err.message}`);
2924
+ process.exit(1);
2948
2925
  }
2949
- } catch (err) {
2950
- console.error(`${c.yellow}Warning: Could not create cloud task:${c.reset} ${err.message}`);
2951
- console.log(`${c.dim}Running in one-shot mode.${c.reset}`);
2952
2926
  }
2953
- }
2954
2927
 
2955
- // Normal mode - just pass through to provider
2956
- const useOllamaPipe = provider === 'ollama' && options.ollamaPrompt && command === 'ollama';
2957
- const shouldRetryCodexBypassFlag = command === 'codex'
2958
- && translatedArgs.includes('--dangerously-bypass-approvals-and-sandbox');
2928
+ // Auto-create task in cloud if --autonomous specified
2929
+ if (options.autonomous && finalPrompt && !options.cloudTaskId) {
2930
+ console.log(`${c.dim}[cloud] Creating task...${c.reset}`);
2959
2931
 
2960
- const spawnProvider = (cmd, args, spawnOpts) => {
2961
- const childProc = spawn(cmd, args, spawnOpts);
2962
- // Send prompt to Ollama via stdin
2963
- if (useOllamaPipe && childProc.stdin) {
2964
- childProc.stdin.write(options.ollamaPrompt);
2965
- childProc.stdin.end();
2966
- }
2932
+ try {
2933
+ const cloudConfig = loadCloudConfig();
2934
+ if (cloudConfig?.apiUrl) {
2935
+ const frontmatter = ['status: queued', 'stage: ideation'];
2936
+ frontmatter.push(`engine: ${provider}`);
2967
2937
 
2968
- childProc.on('exit', (code) => {
2969
- process.exit(code || 0);
2970
- });
2938
+ const content = `---\n${frontmatter.join('\n')}\n---\n\n# ${finalPrompt}\n`;
2939
+
2940
+ const { task } = await cloudRequest('POST', '/api/tasks', { content });
2941
+
2942
+ console.log(`${c.green}✓${c.reset} Task created in cloud: ${task.id}`);
2943
+ options.cloudTaskId = task.id;
2944
+
2945
+ // Fetch task comments (should be empty for new tasks, but good practice)
2946
+ let taskComments = [];
2947
+ try {
2948
+ const commentsResponse = await cloudRequest('GET', `/api/tasks/${task.id}/comments`);
2949
+ taskComments = commentsResponse?.comments || [];
2950
+ } catch (err) {
2951
+ console.error(`${c.yellow}Warning: Could not fetch task comments:${c.reset} ${err.message}`);
2952
+ }
2953
+
2954
+ // Update prompt with task context
2955
+ const stageKey = task?.stage || 'unknown';
2956
+ const stagePrompt = resolveStageObjective(task, stageKey, '');
2957
+ const stageRequirement = buildStageRequirementPrompt({ stage: stageKey, stagePrompt });
2958
+
2959
+ const augmentedPrompt = buildNewAutonomousCloudTaskPrompt({
2960
+ task,
2961
+ taskComments,
2962
+ finalPrompt,
2963
+ stagePrompt,
2964
+ stageRequirement,
2965
+ });
2966
+
2967
+ const promptIndex = translatedArgs.indexOf(finalPrompt);
2968
+ if (promptIndex !== -1) {
2969
+ translatedArgs[promptIndex] = augmentedPrompt;
2970
+ } else {
2971
+ translatedArgs.push(augmentedPrompt);
2972
+ }
2973
+ saveAugmentedPrompt(augmentedPrompt, options.debug);
2971
2974
 
2972
- childProc.on('error', (err) => {
2973
- if (err.code === 'ENOENT') {
2974
- console.error(`${c.red}Error:${c.reset} "${cmd}" command not found.`);
2975
- console.error(`\n${c.dim}Install it first:${c.reset}`);
2976
- if (cmd === 'claude') {
2977
- console.error(` npm install -g @anthropic-ai/claude-code`);
2978
- } else if (cmd === 'gemini') {
2979
- console.error(` npm install -g @google/gemini-cli`);
2980
- } else if (cmd === 'ollama') {
2981
- console.error(` brew install ollama # macOS`);
2982
- console.error(` curl -fsSL https://ollama.ai/install.sh | sh # Linux`);
2983
- } else if (cmd === 'codex') {
2984
- console.error(` npm install -g @openai/codex`);
2975
+ // Start daemon for autonomous mode
2976
+ if (options.autonomous) {
2977
+ startDaemon();
2978
+ console.log(`${c.green}✓${c.reset} Autonomous mode: daemon running\n`);
2979
+ }
2980
+ } else {
2981
+ console.log(`${c.yellow}Cloud API URL not configured. Set AGX_CLOUD_URL (default http://localhost:41741).${c.reset}`);
2982
+ console.log(`${c.dim}Task not created. Running in one-shot mode.${c.reset}`);
2985
2983
  }
2986
- } else {
2987
- console.error(`${c.red}Failed to start ${cmd}:${c.reset}`, err.message);
2984
+ } catch (err) {
2985
+ console.error(`${c.yellow}Warning: Could not create cloud task:${c.reset} ${err.message}`);
2986
+ console.log(`${c.dim}Running in one-shot mode.${c.reset}`);
2988
2987
  }
2989
- process.exit(1);
2990
- });
2988
+ }
2991
2989
 
2992
- return childProc;
2993
- };
2990
+ // Normal mode - just pass through to provider
2991
+ const useOllamaPipe = provider === 'ollama' && options.ollamaPrompt && command === 'ollama';
2992
+ const shouldRetryCodexBypassFlag = command === 'codex'
2993
+ && translatedArgs.includes('--dangerously-bypass-approvals-and-sandbox');
2994
2994
 
2995
- if (!shouldRetryCodexBypassFlag) {
2996
- spawnProvider(command, translatedArgs, {
2997
- env,
2998
- stdio: useOllamaPipe ? ['pipe', 'inherit', 'inherit'] : 'inherit',
2999
- shell: false
3000
- });
3001
- } else {
3002
- // Best-effort compatibility: if the local Codex CLI doesn't recognize
3003
- // --dangerously-bypass-approvals-and-sandbox, retry without it.
3004
- const firstArgs = translatedArgs.slice();
3005
- const retryArgs = translatedArgs.filter((a) => a !== '--dangerously-bypass-approvals-and-sandbox');
3006
-
3007
- let stderrBuf = '';
3008
- const maxBuf = 16 * 1024;
3009
-
3010
- const child = spawn(command, firstArgs, {
3011
- env,
3012
- stdio: ['inherit', 'pipe', 'pipe'],
3013
- shell: false
3014
- });
2995
+ const spawnProvider = (cmd, args, spawnOpts) => {
2996
+ const childProc = execa(cmd, args, { reject: false, ...spawnOpts });
2997
+ // Send prompt to Ollama via stdin
2998
+ if (useOllamaPipe && childProc.stdin) {
2999
+ childProc.stdin.write(options.ollamaPrompt);
3000
+ childProc.stdin.end();
3001
+ }
3015
3002
 
3016
- if (child.stdout) {
3017
- child.stdout.on('data', (d) => process.stdout.write(d));
3018
- }
3019
- if (child.stderr) {
3020
- child.stderr.on('data', (d) => {
3021
- process.stderr.write(d);
3022
- if (stderrBuf.length < maxBuf) {
3023
- stderrBuf += d.toString('utf8').slice(0, maxBuf - stderrBuf.length);
3003
+ childProc.on('exit', (code) => {
3004
+ process.exit(code || 0);
3005
+ });
3006
+
3007
+ childProc.on('error', (err) => {
3008
+ if (err.code === 'ENOENT') {
3009
+ console.error(`${c.red}Error:${c.reset} "${cmd}" command not found.`);
3010
+ console.error(`\n${c.dim}Install it first:${c.reset}`);
3011
+ if (cmd === 'claude') {
3012
+ console.error(` npm install -g @anthropic-ai/claude-code`);
3013
+ } else if (cmd === 'gemini') {
3014
+ console.error(` npm install -g @google/gemini-cli`);
3015
+ } else if (cmd === 'ollama') {
3016
+ console.error(` brew install ollama # macOS`);
3017
+ console.error(` curl -fsSL https://ollama.ai/install.sh | sh # Linux`);
3018
+ } else if (cmd === 'codex') {
3019
+ console.error(` npm install -g @openai/codex`);
3020
+ }
3021
+ } else {
3022
+ console.error(`${c.red}Failed to start ${cmd}:${c.reset}`, err.message);
3024
3023
  }
3024
+ process.exit(1);
3025
3025
  });
3026
- }
3027
3026
 
3028
- child.on('close', (code) => {
3029
- const failed = (code || 0) !== 0;
3030
- const looksLikeUnknownFlag = /unknown option|unknown flag|unrecognized option|unexpected argument|invalid option/i.test(stderrBuf)
3031
- && /dangerously-bypass-approvals-and-sandbox/i.test(stderrBuf);
3032
- if (failed && looksLikeUnknownFlag) {
3033
- console.error(`${c.yellow}[agx] Codex CLI rejected --dangerously-bypass-approvals-and-sandbox; retrying without it.${c.reset}`);
3034
- spawnProvider(command, retryArgs, {
3035
- env,
3036
- stdio: 'inherit',
3037
- shell: false
3027
+ return childProc;
3028
+ };
3029
+
3030
+ if (!shouldRetryCodexBypassFlag) {
3031
+ spawnProvider(command, translatedArgs, {
3032
+ env,
3033
+ stdio: useOllamaPipe ? ['pipe', 'inherit', 'inherit'] : 'inherit',
3034
+ shell: false
3035
+ });
3036
+ } else {
3037
+ // Best-effort compatibility: if the local Codex CLI doesn't recognize
3038
+ // --dangerously-bypass-approvals-and-sandbox, retry without it.
3039
+ const firstArgs = translatedArgs.slice();
3040
+ const retryArgs = translatedArgs.filter((a) => a !== '--dangerously-bypass-approvals-and-sandbox');
3041
+
3042
+ let stderrBuf = '';
3043
+ const maxBuf = 16 * 1024;
3044
+
3045
+ const child = execa(command, firstArgs, {
3046
+ env,
3047
+ stdio: ['inherit', 'pipe', 'pipe'],
3048
+ shell: false,
3049
+ reject: false,
3050
+ });
3051
+
3052
+ if (child.stdout) {
3053
+ child.stdout.on('data', (d) => process.stdout.write(d));
3054
+ }
3055
+ if (child.stderr) {
3056
+ child.stderr.on('data', (d) => {
3057
+ process.stderr.write(d);
3058
+ if (stderrBuf.length < maxBuf) {
3059
+ stderrBuf += d.toString('utf8').slice(0, maxBuf - stderrBuf.length);
3060
+ }
3038
3061
  });
3039
- return;
3040
3062
  }
3041
- process.exit(code || 0);
3042
- });
3043
3063
 
3044
- child.on('error', (err) => {
3045
- console.error(`${c.red}Failed to start ${command}:${c.reset}`, err.message);
3046
- process.exit(1);
3047
- });
3048
- }
3064
+ child.on('close', (code) => {
3065
+ const failed = (code || 0) !== 0;
3066
+ const looksLikeUnknownFlag = /unknown option|unknown flag|unrecognized option|unexpected argument|invalid option/i.test(stderrBuf)
3067
+ && /dangerously-bypass-approvals-and-sandbox/i.test(stderrBuf);
3068
+ if (failed && looksLikeUnknownFlag) {
3069
+ console.error(`${c.yellow}[agx] Codex CLI rejected --dangerously-bypass-approvals-and-sandbox; retrying without it.${c.reset}`);
3070
+ spawnProvider(command, retryArgs, {
3071
+ env,
3072
+ stdio: 'inherit',
3073
+ shell: false
3074
+ });
3075
+ return;
3076
+ }
3077
+ process.exit(code || 0);
3078
+ });
3079
+
3080
+ child.on('error', (err) => {
3081
+ console.error(`${c.red}Failed to start ${command}:${c.reset}`, err.message);
3082
+ process.exit(1);
3083
+ });
3084
+ }
3049
3085
 
3050
3086
  } finally {
3051
3087
  process.argv = originalArgv;