madarx 2.12.1 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (398) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +277 -284
  3. package/.next/standalone/.next/app-path-routes-manifest.json +67 -68
  4. package/.next/standalone/.next/build-manifest.json +2 -2
  5. package/.next/standalone/.next/prerender-manifest.json +3 -3
  6. package/.next/standalone/.next/routes-manifest.json +0 -6
  7. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  9. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  10. package/.next/standalone/.next/server/app/activity/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/admin/page.js +2 -2
  12. package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/agents/[id]/page.js +4 -4
  14. package/.next/standalone/.next/server/app/agents/[id]/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/agents/page.js +1 -1
  16. package/.next/standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  17. package/.next/standalone/.next/server/app/api/activity/route_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/api/admin/audit-export/route_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/api/admin/share-links/route_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/api/agent-memory/route_client-reference-manifest.js +1 -1
  21. package/.next/standalone/.next/server/app/api/agent-runs/[id]/cancel/route_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/api/agent-runs/[id]/events/route_client-reference-manifest.js +1 -1
  23. package/.next/standalone/.next/server/app/api/agent-runs/[id]/log/route_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/api/agent-runs/[id]/route_client-reference-manifest.js +1 -1
  25. package/.next/standalone/.next/server/app/api/agent-runs/route_client-reference-manifest.js +1 -1
  26. package/.next/standalone/.next/server/app/api/agents/[id]/chain/route_client-reference-manifest.js +1 -1
  27. package/.next/standalone/.next/server/app/api/agents/[id]/memory/route_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/app/api/agents/[id]/reports/route_client-reference-manifest.js +1 -1
  29. package/.next/standalone/.next/server/app/api/agents/[id]/run/route_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/api/agents/[id]/skills/route_client-reference-manifest.js +1 -1
  31. package/.next/standalone/.next/server/app/api/agents/create/route_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/api/agents/ops/route_client-reference-manifest.js +1 -1
  33. package/.next/standalone/.next/server/app/api/approvals/[id]/route_client-reference-manifest.js +1 -1
  34. package/.next/standalone/.next/server/app/api/approvals/route_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/api/artifacts/[id]/acl/route_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/api/artifacts/[id]/protect/route_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/api/artifacts/[id]/raw/route_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/api/artifacts/[id]/route_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/api/artifacts/[id]/share-link/[linkId]/route_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/api/artifacts/[id]/share-link/route_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/api/artifacts/upload/route_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/api/audit/list/route_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/api/audit/search/route_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/api/auth/config/route_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/api/auth/join-bootstrap/route_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/api/brand/route_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/api/chat/sessions/[id]/route_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/api/chat/sessions/route_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app/api/config/env/route_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/api/config/route_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/api/connections/[service]/route_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/api/connections/[service]/verify/route_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/api/connections/route_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/api/cron/tick/route_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/move/route_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/route_client-reference-manifest.js +1 -1
  59. package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/share-link/[linkId]/route_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/share-link/route_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/api/dashboard/spaces/import/route_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/api/dashboard/spaces/route_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/api/disk/files/[id]/blob/route_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/api/disk/files/[id]/route_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/api/disk/files/[id]/transcribe/route_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/api/disk/files/route_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/api/disk/folders/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/events/since/[cursor]/route_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/api/events/stream/route_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/api/fs/create-folder/route_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/api/fs/pick-folder/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/blueprint/route.js.nft.json +1 -1
  73. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/blueprint/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/diagnostic/route.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/diagnostic/route_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/governance/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/governance/route_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/interview/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/interview/route_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/pilot/route.js.nft.json +1 -1
  81. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/pilot/route_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/quarterly/route.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/quarterly/route_client-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/route.js.nft.json +1 -1
  85. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/route_client-reference-manifest.js +1 -1
  86. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/setup-package/route.js.nft.json +1 -1
  87. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/setup-package/route_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/api/hail/engagements/route.js.nft.json +1 -1
  89. package/.next/standalone/.next/server/app/api/hail/engagements/route_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/api/hail/interviews/[id]/responses/route.js.nft.json +1 -1
  91. package/.next/standalone/.next/server/app/api/hail/interviews/[id]/responses/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/hail/interviews/[id]/route.js.nft.json +1 -1
  93. package/.next/standalone/.next/server/app/api/hail/interviews/[id]/route_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/api/hail/setup-packages/[id]/apply/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/hail/setup-packages/[id]/apply/route_client-reference-manifest.js +1 -1
  96. package/.next/standalone/.next/server/app/api/hail/setup-packages/validate/route_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/api/heartbeat/tick/route_client-reference-manifest.js +1 -1
  98. package/.next/standalone/.next/server/app/api/heartbeat/worker/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/api/heartbeat/worker/route_client-reference-manifest.js +1 -1
  100. package/.next/standalone/.next/server/app/api/help/route_client-reference-manifest.js +1 -1
  101. package/.next/standalone/.next/server/app/api/hermes/jobs/[id]/events/route_client-reference-manifest.js +1 -1
  102. package/.next/standalone/.next/server/app/api/hermes/jobs/[id]/route_client-reference-manifest.js +1 -1
  103. package/.next/standalone/.next/server/app/api/hermes/jobs/route_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/api/integrations/google/callback/route_client-reference-manifest.js +1 -1
  105. package/.next/standalone/.next/server/app/api/integrations/google/oauth/route_client-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/app/api/marketplace/[id]/route_client-reference-manifest.js +1 -1
  107. package/.next/standalone/.next/server/app/api/marketplace/open-design/route_client-reference-manifest.js +1 -1
  108. package/.next/standalone/.next/server/app/api/marketplace/route_client-reference-manifest.js +1 -1
  109. package/.next/standalone/.next/server/app/api/mines/import-roots/route_client-reference-manifest.js +1 -1
  110. package/.next/standalone/.next/server/app/api/mines/portfolio/route_client-reference-manifest.js +1 -1
  111. package/.next/standalone/.next/server/app/api/mines/projects/[id]/chunks/route_client-reference-manifest.js +1 -1
  112. package/.next/standalone/.next/server/app/api/mines/projects/[id]/diligence/route_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/api/mines/projects/[id]/import/route_client-reference-manifest.js +1 -1
  114. package/.next/standalone/.next/server/app/api/mines/projects/[id]/publish/route_client-reference-manifest.js +1 -1
  115. package/.next/standalone/.next/server/app/api/mines/projects/route_client-reference-manifest.js +1 -1
  116. package/.next/standalone/.next/server/app/api/missions/route_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/app/api/onboarding/blueprint/route_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/api/onboarding/launch/route_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/api/orchestrator/command/route_client-reference-manifest.js +1 -1
  121. package/.next/standalone/.next/server/app/api/orchestrator/stream/route_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app/api/orchestrator/upload/route_client-reference-manifest.js +1 -1
  123. package/.next/standalone/.next/server/app/api/org/route_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/api/orgs/[id]/invites/[inviteId]/route_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/api/orgs/[id]/invites/route_client-reference-manifest.js +1 -1
  126. package/.next/standalone/.next/server/app/api/orgs/[id]/members/[userId]/role/route_client-reference-manifest.js +1 -1
  127. package/.next/standalone/.next/server/app/api/orgs/[id]/members/[userId]/route_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/api/orgs/[id]/members/route_client-reference-manifest.js +1 -1
  129. package/.next/standalone/.next/server/app/api/orgs/[id]/route_client-reference-manifest.js +1 -1
  130. package/.next/standalone/.next/server/app/api/orgs/invites/pending/route_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/api/orgs/join/route_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/api/orgs/join-complete/route_client-reference-manifest.js +1 -1
  133. package/.next/standalone/.next/server/app/api/orgs/route_client-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/app/api/printing-press/clis/route_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/api/printing-press/install/route_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/api/printing-press/security-mode/route_client-reference-manifest.js +1 -1
  137. package/.next/standalone/.next/server/app/api/privacy/config/route_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/api/privacy/verify/route_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app/api/processes/[id]/route.js.nft.json +1 -1
  140. package/.next/standalone/.next/server/app/api/processes/[id]/route_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/api/processes/[id]/share-link/route.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/api/processes/[id]/share-link/route_client-reference-manifest.js +1 -1
  143. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/override/route.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/override/route_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/retry/route.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/retry/route_client-reference-manifest.js +1 -1
  147. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/submit/route.js.nft.json +1 -1
  148. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/submit/route_client-reference-manifest.js +1 -1
  149. package/.next/standalone/.next/server/app/api/processes/definitions/[slug]/route_client-reference-manifest.js +1 -1
  150. package/.next/standalone/.next/server/app/api/processes/definitions/[slug]/settings/route_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/api/processes/definitions/route_client-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/app/api/processes/definitions/validate/route_client-reference-manifest.js +1 -1
  153. package/.next/standalone/.next/server/app/api/processes/route.js.nft.json +1 -1
  154. package/.next/standalone/.next/server/app/api/processes/route_client-reference-manifest.js +1 -1
  155. package/.next/standalone/.next/server/app/api/processes/start-and-route/route.js +1 -1
  156. package/.next/standalone/.next/server/app/api/processes/start-and-route/route.js.nft.json +1 -1
  157. package/.next/standalone/.next/server/app/api/processes/start-and-route/route_client-reference-manifest.js +1 -1
  158. package/.next/standalone/.next/server/app/api/projects/[slug]/library/route_client-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/app/api/projects/[slug]/route_client-reference-manifest.js +1 -1
  160. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/app/api/runs/approve-claude-run/route_client-reference-manifest.js +1 -1
  162. package/.next/standalone/.next/server/app/api/runs/claude-code-dry-run/route_client-reference-manifest.js +1 -1
  163. package/.next/standalone/.next/server/app/api/runs/competitor-report/route_client-reference-manifest.js +1 -1
  164. package/.next/standalone/.next/server/app/api/runs/engine-ping/route_client-reference-manifest.js +1 -1
  165. package/.next/standalone/.next/server/app/api/runs/marketing-plan/route_client-reference-manifest.js +1 -1
  166. package/.next/standalone/.next/server/app/api/schedules/upsert/route_client-reference-manifest.js +1 -1
  167. package/.next/standalone/.next/server/app/api/secrets/[name]/route_client-reference-manifest.js +1 -1
  168. package/.next/standalone/.next/server/app/api/secrets/route_client-reference-manifest.js +1 -1
  169. package/.next/standalone/.next/server/app/api/settings/trust-mode/route_client-reference-manifest.js +1 -1
  170. package/.next/standalone/.next/server/app/api/share/[token]/otp/route_client-reference-manifest.js +1 -1
  171. package/.next/standalone/.next/server/app/api/share/[token]/route_client-reference-manifest.js +1 -1
  172. package/.next/standalone/.next/server/app/api/share/[token]/verify/route_client-reference-manifest.js +1 -1
  173. package/.next/standalone/.next/server/app/api/share/space/[token]/otp/route_client-reference-manifest.js +1 -1
  174. package/.next/standalone/.next/server/app/api/share/space/[token]/route_client-reference-manifest.js +1 -1
  175. package/.next/standalone/.next/server/app/api/share/space/[token]/verify/route_client-reference-manifest.js +1 -1
  176. package/.next/standalone/.next/server/app/api/shared/spaces/[id]/acl/route_client-reference-manifest.js +1 -1
  177. package/.next/standalone/.next/server/app/api/shared/spaces/publish/route_client-reference-manifest.js +1 -1
  178. package/.next/standalone/.next/server/app/api/shared/spaces/route_client-reference-manifest.js +1 -1
  179. package/.next/standalone/.next/server/app/api/shared/spaces/status/route_client-reference-manifest.js +1 -1
  180. package/.next/standalone/.next/server/app/api/shared/spaces/unpublish/route_client-reference-manifest.js +1 -1
  181. package/.next/standalone/.next/server/app/api/state/route_client-reference-manifest.js +1 -1
  182. package/.next/standalone/.next/server/app/api/system/update/route_client-reference-manifest.js +1 -1
  183. package/.next/standalone/.next/server/app/api/tasks/[id]/active-run/route_client-reference-manifest.js +1 -1
  184. package/.next/standalone/.next/server/app/api/tasks/[id]/attachments/route_client-reference-manifest.js +1 -1
  185. package/.next/standalone/.next/server/app/api/tasks/[id]/checklist/[itemId]/route_client-reference-manifest.js +1 -1
  186. package/.next/standalone/.next/server/app/api/tasks/[id]/checklist/route_client-reference-manifest.js +1 -1
  187. package/.next/standalone/.next/server/app/api/tasks/[id]/checkout/route_client-reference-manifest.js +1 -1
  188. package/.next/standalone/.next/server/app/api/tasks/[id]/children/route_client-reference-manifest.js +1 -1
  189. package/.next/standalone/.next/server/app/api/tasks/[id]/comments/route_client-reference-manifest.js +1 -1
  190. package/.next/standalone/.next/server/app/api/tasks/[id]/events/route_client-reference-manifest.js +1 -1
  191. package/.next/standalone/.next/server/app/api/tasks/[id]/live-runs/route_client-reference-manifest.js +1 -1
  192. package/.next/standalone/.next/server/app/api/tasks/[id]/release/route_client-reference-manifest.js +1 -1
  193. package/.next/standalone/.next/server/app/api/tasks/[id]/route_client-reference-manifest.js +1 -1
  194. package/.next/standalone/.next/server/app/api/tasks/route_client-reference-manifest.js +1 -1
  195. package/.next/standalone/.next/server/app/api/tool-allowlists/[id]/route_client-reference-manifest.js +1 -1
  196. package/.next/standalone/.next/server/app/api/tool-allowlists/route_client-reference-manifest.js +1 -1
  197. package/.next/standalone/.next/server/app/api/tool-egress/route_client-reference-manifest.js +1 -1
  198. package/.next/standalone/.next/server/app/api/tools/[name]/approve/route_client-reference-manifest.js +1 -1
  199. package/.next/standalone/.next/server/app/api/tools/[name]/route_client-reference-manifest.js +1 -1
  200. package/.next/standalone/.next/server/app/api/tools/route_client-reference-manifest.js +1 -1
  201. package/.next/standalone/.next/server/app/api/transcripts/route_client-reference-manifest.js +1 -1
  202. package/.next/standalone/.next/server/app/api/voice/providers/route_client-reference-manifest.js +1 -1
  203. package/.next/standalone/.next/server/app/api/voice/realtime/context/route_client-reference-manifest.js +1 -1
  204. package/.next/standalone/.next/server/app/api/voice/realtime/session/route_client-reference-manifest.js +1 -1
  205. package/.next/standalone/.next/server/app/api/voice/realtime/tool-result/route_client-reference-manifest.js +1 -1
  206. package/.next/standalone/.next/server/app/api/voice/realtime/tools/route_client-reference-manifest.js +1 -1
  207. package/.next/standalone/.next/server/app/api/voice/tts/route_client-reference-manifest.js +1 -1
  208. package/.next/standalone/.next/server/app/api/whatsapp/allowlist/route_client-reference-manifest.js +1 -1
  209. package/.next/standalone/.next/server/app/api/whatsapp/disconnect/route_client-reference-manifest.js +1 -1
  210. package/.next/standalone/.next/server/app/api/whatsapp/messages/route_client-reference-manifest.js +1 -1
  211. package/.next/standalone/.next/server/app/api/whatsapp/qr/route_client-reference-manifest.js +1 -1
  212. package/.next/standalone/.next/server/app/api/whatsapp/send/route_client-reference-manifest.js +1 -1
  213. package/.next/standalone/.next/server/app/api/whatsapp/status/route_client-reference-manifest.js +1 -1
  214. package/.next/standalone/.next/server/app/approvals/page.js +2 -2
  215. package/.next/standalone/.next/server/app/approvals/page_client-reference-manifest.js +1 -1
  216. package/.next/standalone/.next/server/app/architecture/page_client-reference-manifest.js +1 -1
  217. package/.next/standalone/.next/server/app/architecture.html +2 -2
  218. package/.next/standalone/.next/server/app/architecture.rsc +1 -1
  219. package/.next/standalone/.next/server/app/audit/live/page_client-reference-manifest.js +1 -1
  220. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  221. package/.next/standalone/.next/server/app/brand/page_client-reference-manifest.js +1 -1
  222. package/.next/standalone/.next/server/app/brand.html +1 -1
  223. package/.next/standalone/.next/server/app/brand.rsc +1 -1
  224. package/.next/standalone/.next/server/app/disk/page_client-reference-manifest.js +1 -1
  225. package/.next/standalone/.next/server/app/federated-ai/page_client-reference-manifest.js +1 -1
  226. package/.next/standalone/.next/server/app/federated-ai.html +2 -2
  227. package/.next/standalone/.next/server/app/federated-ai.rsc +1 -1
  228. package/.next/standalone/.next/server/app/hail/[id]/governance/page.js.nft.json +1 -1
  229. package/.next/standalone/.next/server/app/hail/[id]/governance/page_client-reference-manifest.js +1 -1
  230. package/.next/standalone/.next/server/app/hail/[id]/interview/page.js +1 -1
  231. package/.next/standalone/.next/server/app/hail/[id]/interview/page.js.nft.json +1 -1
  232. package/.next/standalone/.next/server/app/hail/[id]/interview/page_client-reference-manifest.js +1 -1
  233. package/.next/standalone/.next/server/app/hail/[id]/page.js +2 -2
  234. package/.next/standalone/.next/server/app/hail/[id]/page.js.nft.json +1 -1
  235. package/.next/standalone/.next/server/app/hail/[id]/page_client-reference-manifest.js +1 -1
  236. package/.next/standalone/.next/server/app/hail/[id]/setup/page.js +1 -1
  237. package/.next/standalone/.next/server/app/hail/[id]/setup/page.js.nft.json +1 -1
  238. package/.next/standalone/.next/server/app/hail/[id]/setup/page_client-reference-manifest.js +1 -1
  239. package/.next/standalone/.next/server/app/hail/page.js +3 -3
  240. package/.next/standalone/.next/server/app/hail/page.js.nft.json +1 -1
  241. package/.next/standalone/.next/server/app/hail/page_client-reference-manifest.js +1 -1
  242. package/.next/standalone/.next/server/app/help/[slug]/page_client-reference-manifest.js +1 -1
  243. package/.next/standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  244. package/.next/standalone/.next/server/app/index.html +2 -2
  245. package/.next/standalone/.next/server/app/index.rsc +1 -1
  246. package/.next/standalone/.next/server/app/join/page_client-reference-manifest.js +1 -1
  247. package/.next/standalone/.next/server/app/join.html +1 -1
  248. package/.next/standalone/.next/server/app/join.rsc +1 -1
  249. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  250. package/.next/standalone/.next/server/app/marketplace/page.js +2 -2
  251. package/.next/standalone/.next/server/app/marketplace/page_client-reference-manifest.js +1 -1
  252. package/.next/standalone/.next/server/app/mines/[projectId]/page_client-reference-manifest.js +1 -1
  253. package/.next/standalone/.next/server/app/mines/[projectId]/results/page_client-reference-manifest.js +1 -1
  254. package/.next/standalone/.next/server/app/mines/page_client-reference-manifest.js +1 -1
  255. package/.next/standalone/.next/server/app/missions/page.js +2 -2
  256. package/.next/standalone/.next/server/app/missions/page_client-reference-manifest.js +1 -1
  257. package/.next/standalone/.next/server/app/onboarding/org/page_client-reference-manifest.js +1 -1
  258. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  259. package/.next/standalone/.next/server/app/onboarding.html +2 -2
  260. package/.next/standalone/.next/server/app/onboarding.rsc +1 -1
  261. package/.next/standalone/.next/server/app/org/page.js +1 -1
  262. package/.next/standalone/.next/server/app/org/page.js.nft.json +1 -1
  263. package/.next/standalone/.next/server/app/org/page_client-reference-manifest.js +1 -1
  264. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  265. package/.next/standalone/.next/server/app/projects/[slug]/log/page_client-reference-manifest.js +1 -1
  266. package/.next/standalone/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  267. package/.next/standalone/.next/server/app/projects/new/page.js +1 -1
  268. package/.next/standalone/.next/server/app/projects/new/page_client-reference-manifest.js +1 -1
  269. package/.next/standalone/.next/server/app/projects/new.html +1 -1
  270. package/.next/standalone/.next/server/app/projects/new.rsc +2 -2
  271. package/.next/standalone/.next/server/app/projects/page.js +28 -28
  272. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  273. package/.next/standalone/.next/server/app/reports/[file]/route_client-reference-manifest.js +1 -1
  274. package/.next/standalone/.next/server/app/reports/page_client-reference-manifest.js +1 -1
  275. package/.next/standalone/.next/server/app/runtime/page_client-reference-manifest.js +1 -1
  276. package/.next/standalone/.next/server/app/schedules/page.js +1 -1
  277. package/.next/standalone/.next/server/app/schedules/page.js.nft.json +1 -1
  278. package/.next/standalone/.next/server/app/schedules/page_client-reference-manifest.js +1 -1
  279. package/.next/standalone/.next/server/app/settings/account/page_client-reference-manifest.js +1 -1
  280. package/.next/standalone/.next/server/app/settings/advanced/page_client-reference-manifest.js +1 -1
  281. package/.next/standalone/.next/server/app/settings/appearance/page_client-reference-manifest.js +1 -1
  282. package/.next/standalone/.next/server/app/settings/brand/page_client-reference-manifest.js +1 -1
  283. package/.next/standalone/.next/server/app/settings/brand.html +2 -2
  284. package/.next/standalone/.next/server/app/settings/brand.rsc +1 -1
  285. package/.next/standalone/.next/server/app/settings/connectors/page_client-reference-manifest.js +1 -1
  286. package/.next/standalone/.next/server/app/settings/engines/page_client-reference-manifest.js +1 -1
  287. package/.next/standalone/.next/server/app/settings/onboarding/page_client-reference-manifest.js +1 -1
  288. package/.next/standalone/.next/server/app/settings/onboarding.html +2 -2
  289. package/.next/standalone/.next/server/app/settings/onboarding.rsc +1 -1
  290. package/.next/standalone/.next/server/app/settings/organization/page.js +1 -1
  291. package/.next/standalone/.next/server/app/settings/organization/page.js.nft.json +1 -1
  292. package/.next/standalone/.next/server/app/settings/organization/page_client-reference-manifest.js +1 -1
  293. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  294. package/.next/standalone/.next/server/app/settings/runtime/page_client-reference-manifest.js +1 -1
  295. package/.next/standalone/.next/server/app/settings/team/page_client-reference-manifest.js +1 -1
  296. package/.next/standalone/.next/server/app/settings/tools/page_client-reference-manifest.js +1 -1
  297. package/.next/standalone/.next/server/app/settings.html +2 -2
  298. package/.next/standalone/.next/server/app/settings.rsc +1 -1
  299. package/.next/standalone/.next/server/app/share/[token]/page_client-reference-manifest.js +1 -1
  300. package/.next/standalone/.next/server/app/share/space/[token]/page_client-reference-manifest.js +1 -1
  301. package/.next/standalone/.next/server/app/tasks/[id]/page.js +2 -2
  302. package/.next/standalone/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  303. package/.next/standalone/.next/server/app/tasks/page.js +2 -2
  304. package/.next/standalone/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  305. package/.next/standalone/.next/server/app/team/[agentId]/page_client-reference-manifest.js +1 -1
  306. package/.next/standalone/.next/server/app/team/page_client-reference-manifest.js +1 -1
  307. package/.next/standalone/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  308. package/.next/standalone/.next/server/app/whatsapp/page_client-reference-manifest.js +1 -1
  309. package/.next/standalone/.next/server/app/whatsapp.html +1 -1
  310. package/.next/standalone/.next/server/app/whatsapp.rsc +1 -1
  311. package/.next/standalone/.next/server/app/workflows/[caseId]/page.js +1 -1
  312. package/.next/standalone/.next/server/app/workflows/[caseId]/page.js.nft.json +1 -1
  313. package/.next/standalone/.next/server/app/workflows/[caseId]/page_client-reference-manifest.js +1 -1
  314. package/.next/standalone/.next/server/app/workflows/new/[caseId]/page.js +1 -1
  315. package/.next/standalone/.next/server/app/workflows/new/[caseId]/page.js.nft.json +1 -1
  316. package/.next/standalone/.next/server/app/workflows/new/[caseId]/page_client-reference-manifest.js +1 -1
  317. package/.next/standalone/.next/server/app/workflows/new/definition/page_client-reference-manifest.js +1 -1
  318. package/.next/standalone/.next/server/app/workflows/page.js +1 -1
  319. package/.next/standalone/.next/server/app/workflows/page.js.nft.json +1 -1
  320. package/.next/standalone/.next/server/app/workflows/page_client-reference-manifest.js +1 -1
  321. package/.next/standalone/.next/server/app/workflows/share/[caseId]/page.js +1 -1
  322. package/.next/standalone/.next/server/app/workflows/share/[caseId]/page.js.nft.json +1 -1
  323. package/.next/standalone/.next/server/app/workflows/share/[caseId]/page_client-reference-manifest.js +1 -1
  324. package/.next/standalone/.next/server/app-paths-manifest.json +67 -68
  325. package/.next/standalone/.next/server/chunks/1699.js +28 -28
  326. package/.next/standalone/.next/server/chunks/5185.js +4 -27
  327. package/.next/standalone/.next/server/chunks/5257.js +1 -1
  328. package/.next/standalone/.next/server/chunks/6355.js +1 -0
  329. package/.next/standalone/.next/server/chunks/{3784.js → 6474.js} +1 -1
  330. package/.next/standalone/.next/server/functions-config-manifest.json +24 -24
  331. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  332. package/.next/standalone/.next/server/pages/404.html +1 -1
  333. package/.next/standalone/.next/server/pages/500.html +1 -1
  334. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  335. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  336. package/.next/standalone/.next/static/-LlttjOnKZXGqZXDKcj-4/_buildManifest.js +1 -0
  337. package/.next/standalone/.next/static/chunks/app/projects/page-09e5c527e3ba83e2.js +1 -0
  338. package/.next/standalone/.next/static/chunks/app/workflows/[caseId]/page-9949ff1c223e771d.js +1 -0
  339. package/.next/{static/chunks/app/workflows/page-25cb2c4cb90273a8.js → standalone/.next/static/chunks/app/workflows/page-d0484521369bce4c.js} +1 -1
  340. package/.next/standalone/CHANGELOG.md +31 -0
  341. package/.next/standalone/data/.artifacts-migrated-v1 +1 -1
  342. package/.next/standalone/data/.default-project-seeded +1 -1
  343. package/.next/standalone/data/madarx.sqlite +0 -0
  344. package/.next/standalone/data/madarx.sqlite-shm +0 -0
  345. package/.next/standalone/data/madarx.sqlite-wal +0 -0
  346. package/.next/standalone/lib/process/seeds/specs/mine-project-intake.json +12 -4
  347. package/.next/standalone/lib/process/seeds/specs/mine-valuation.json +6 -2
  348. package/.next/standalone/lib/process/stages/policy-dsl-legacy.js +178 -0
  349. package/.next/standalone/lib/process/stages/policy-gate.js +24 -168
  350. package/.next/standalone/package.json +4 -1
  351. package/.next/standalone/workspace/agents/ops-agent/skills.md +24 -0
  352. package/.next/standalone/workspace/agents/tool-smith-agent/skills.md +24 -0
  353. package/.next/static/-LlttjOnKZXGqZXDKcj-4/_buildManifest.js +1 -0
  354. package/.next/static/chunks/app/projects/page-09e5c527e3ba83e2.js +1 -0
  355. package/.next/static/chunks/app/workflows/[caseId]/page-9949ff1c223e771d.js +1 -0
  356. package/.next/{standalone/.next/static/chunks/app/workflows/page-25cb2c4cb90273a8.js → static/chunks/app/workflows/page-d0484521369bce4c.js} +1 -1
  357. package/CHANGELOG.md +31 -0
  358. package/ai-docs/process-engine.md +33 -1
  359. package/app/api/processes/start-and-route/route.js +5 -3
  360. package/app/workflows/[caseId]/case-detail-client.jsx +2 -2
  361. package/app/workflows/definition-card.jsx +12 -18
  362. package/app/workflows/new/[caseId]/page.js +8 -8
  363. package/app/workflows/page.js +0 -5
  364. package/app/workflows/share/[caseId]/page.js +0 -1
  365. package/lib/cli/banner.js +200 -21
  366. package/lib/cli/run.js +33 -11
  367. package/lib/cli/splash.js +120 -0
  368. package/lib/marketplace-seeds.js +141 -3
  369. package/lib/process/artifacts.js +12 -60
  370. package/lib/process/engine.js +5 -5
  371. package/lib/process/policy-predicates.js +116 -0
  372. package/lib/process/seeds/specs/mine-project-intake.json +12 -4
  373. package/lib/process/seeds/specs/mine-valuation.json +6 -2
  374. package/lib/process/spec-validator.js +46 -1
  375. package/lib/process/stages/policy-dsl-legacy.js +178 -0
  376. package/lib/process/stages/policy-gate.js +24 -168
  377. package/lib/runtime.js +52 -3
  378. package/lib/seeds.js +5 -1
  379. package/lib/tools/registry.js +20 -0
  380. package/package.json +4 -1
  381. package/scripts/postbuild-standalone.mjs +9 -0
  382. package/scripts/postinstall-splash.mjs +81 -0
  383. package/scripts/preview-banner.mjs +24 -0
  384. package/.next/standalone/.next/server/app/workflows/new/page.js +0 -2
  385. package/.next/standalone/.next/server/app/workflows/new/page.js.nft.json +0 -1
  386. package/.next/standalone/.next/server/app/workflows/new/page_client-reference-manifest.js +0 -1
  387. package/.next/standalone/.next/static/BTzAhaVl8-xEC5Te-d7Ns/_buildManifest.js +0 -1
  388. package/.next/standalone/.next/static/chunks/app/projects/page-7b6c6e010183e070.js +0 -1
  389. package/.next/standalone/.next/static/chunks/app/workflows/[caseId]/page-423e4c194c7f5bf5.js +0 -1
  390. package/.next/standalone/.next/static/chunks/app/workflows/new/page-1eda41616cbfc4f3.js +0 -1
  391. package/.next/static/BTzAhaVl8-xEC5Te-d7Ns/_buildManifest.js +0 -1
  392. package/.next/static/chunks/app/projects/page-7b6c6e010183e070.js +0 -1
  393. package/.next/static/chunks/app/workflows/[caseId]/page-423e4c194c7f5bf5.js +0 -1
  394. package/.next/static/chunks/app/workflows/new/page-1eda41616cbfc4f3.js +0 -1
  395. package/app/workflows/new/new-case-flow.jsx +0 -256
  396. package/app/workflows/new/page.js +0 -27
  397. /package/.next/standalone/.next/static/{BTzAhaVl8-xEC5Te-d7Ns → -LlttjOnKZXGqZXDKcj-4}/_ssgManifest.js +0 -0
  398. /package/.next/static/{BTzAhaVl8-xEC5Te-d7Ns → -LlttjOnKZXGqZXDKcj-4}/_ssgManifest.js +0 -0
package/lib/cli/run.js CHANGED
@@ -17,7 +17,8 @@ import fs from 'node:fs';
17
17
  import { spawn } from 'node:child_process';
18
18
  import { applyHomeEnv } from './home.js';
19
19
  import { PKG_ROOT } from './dispatch.js';
20
- import { renderBanner } from './banner.js';
20
+ import { renderBanner, renderHeroBanner } from './banner.js';
21
+ import { readyPanel } from './splash.js';
21
22
  import { readUpdateCheck } from '../update-check.js';
22
23
  import { loadProjectEnv } from '../load-env.js';
23
24
 
@@ -157,25 +158,39 @@ export async function run({ flags = {} } = {}) {
157
158
  // Catalog counts: best-effort dynamic import so a count never blocks or
158
159
  // breaks boot. These modules build static catalogs at eval time and do NOT
159
160
  // open the database, so the supervisor stays DB-free.
160
- let tools, skills;
161
+ let toolCats = [];
162
+ let toolCount;
163
+ let skillGroups = [];
164
+ let skillCount;
161
165
  try {
162
- const [{ MARKETPLACE_TOOL_COUNT }, seeds] = await Promise.all([
166
+ const [{ MARKETPLACE_TOOL_COUNT, listToolCategories }, seeds] = await Promise.all([
163
167
  import('../tools/registry.js'),
164
168
  import('../marketplace-seeds.js'),
165
169
  ]);
166
- tools = MARKETPLACE_TOOL_COUNT;
167
- skills = (seeds.PHASE1_SKILL_SLUGS?.length || 0) + (seeds.OPEN_DESIGN_SKILL_SLUGS?.length || 0);
168
- } catch { /* counts are optional */ }
170
+ toolCount = MARKETPLACE_TOOL_COUNT;
171
+ toolCats = listToolCategories();
172
+ // Showcase the business-default skill pack (research, comms, documents,
173
+ // data, web) grouped by category — what most teams need out of the box.
174
+ skillGroups = seeds.listDefaultSkillGroups ? seeds.listDefaultSkillGroups() : [];
175
+ skillCount = (seeds.DEFAULT_SKILL_SLUGS || []).length;
176
+ } catch { /* catalog is optional — banner still renders without it */ }
169
177
  const version = pkgVersion() || '0.0.0';
170
- console.log(renderBanner({
178
+ const hero = process.env.MADARX_BANNER_LEGACY !== '1';
179
+ const render = hero ? renderHeroBanner : renderBanner;
180
+ console.log(render({
171
181
  version,
172
182
  home: layout.home,
173
183
  url: BASE_URL,
174
- engine: process.env.MADARX_DEFAULT_ENGINE || 'claude-code (default)',
184
+ engine: process.env.MADARX_DEFAULT_ENGINE || 'claude-code',
185
+ commit: process.env.MADARX_COMMIT || undefined,
175
186
  latest: ledger?.latest || null,
176
187
  behind: Boolean(ledger?.latest && ledger.latest !== version && ledger?.behind),
177
- tools,
178
- skills,
188
+ toolCats,
189
+ toolCount,
190
+ skillGroups,
191
+ skillCount,
192
+ // legacy renderBanner still understands these:
193
+ tools: toolCount,
179
194
  }));
180
195
  } else {
181
196
  log(`data home: ${layout.home}`);
@@ -213,7 +228,14 @@ export async function run({ flags = {} } = {}) {
213
228
  // Health gate + browser open run alongside; never block shutdown on them.
214
229
  waitForHealth().then((ok) => {
215
230
  if (stopping) return;
216
- if (ok) { log(`ready → ${BASE_URL}`); openBrowser(BASE_URL, flags); }
231
+ if (ok) {
232
+ if (!flags.quiet && process.env.MADARX_NO_BANNER !== '1') {
233
+ console.log('\n' + readyPanel({ version: pkgVersion() || undefined, url: BASE_URL }) + '\n');
234
+ } else {
235
+ log(`ready → ${BASE_URL}`);
236
+ }
237
+ openBrowser(BASE_URL, flags);
238
+ }
217
239
  else warn(`web tier did not answer on ${BASE_URL} within the timeout — it may still be starting.`);
218
240
  });
219
241
  });
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Branded boot/install splash for the madarX OS CLI.
3
+ *
4
+ * Zero dependencies — node builtins + the ANSI primitives in ./banner.js only —
5
+ * so it is safe to import from the CLI supervisor (lib/cli/run.js) and from the
6
+ * postinstall script (scripts/postinstall-splash.mjs) without pulling in the
7
+ * runtime or opening the database.
8
+ *
9
+ * Look is the brand-guidelines v1.3 "Sovereign-Mono" splash (see preview.svg):
10
+ * the whole step list prints upfront — pending in Graphite, the active step
11
+ * carries the single live Mars spinner, settled steps resolve to a neutral
12
+ * Platinum ✓ (never green, so Mars never repeats on a settled surface). Closes
13
+ * on a Muted dateline. Degrades to a plain auditable record off-TTY.
14
+ */
15
+
16
+ import { _palette as P, fg, bold, dim, wordmark, colorEnabled, visibleLength } from './banner.js';
17
+
18
+ const ON = colorEnabled();
19
+ const isTTY = ON && Boolean(process.stdout && process.stdout.isTTY);
20
+
21
+ // Monospace-safe braille spinner — reads as motion without noise.
22
+ const SPINNER = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
23
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
24
+
25
+ const GLYPH = {
26
+ done: fg(P.platinum, '✓'),
27
+ fail: fg(P.mars, '✗'),
28
+ pending: fg(P.graphite, '·'),
29
+ bead: fg(P.mars, '●'),
30
+ };
31
+
32
+ // ── cursor hygiene: hide during animation, always restore ─────────────────────
33
+ let cursorHidden = false;
34
+ function hideCursor() { if (isTTY && !cursorHidden) { process.stdout.write('\x1b[?25l'); cursorHidden = true; } }
35
+ function showCursor() { if (cursorHidden) { process.stdout.write('\x1b[?25h'); cursorHidden = false; } }
36
+ process.on('exit', showCursor);
37
+ process.on('SIGINT', () => { showCursor(); process.exit(130); });
38
+
39
+ // A step line at a given state. `state`: 'pending' | 'active' | 'done' | 'fail'.
40
+ function lineFor(label, state, frame) {
41
+ if (state === 'pending') return ` ${GLYPH.pending} ${fg(P.graphite, label)}`;
42
+ if (state === 'active') return ` ${fg(P.mars, frame)} ${fg(P.bone, label)}`;
43
+ if (state === 'fail') return ` ${GLYPH.fail} ${fg(P.bone, label)}`;
44
+ return ` ${GLYPH.done} ${fg(P.bone, label)}`;
45
+ }
46
+
47
+ /**
48
+ * Run a list of boot steps, rendered the way preview.svg shows them: the whole
49
+ * list appears at once (pending/Graphite), then each step lights its Mars
50
+ * spinner while its real work runs and resolves to a Platinum ✓.
51
+ *
52
+ * @param {Array<{label: string, work: () => Promise<any>}>} steps
53
+ */
54
+ export async function bootSequence(steps) {
55
+ if (!isTTY) {
56
+ // CI / piped / NO_COLOR: no animation, just the record an auditor would want.
57
+ for (const s of steps) {
58
+ try { await s.work(); process.stdout.write(lineFor(s.label, 'done') + '\n'); }
59
+ catch { process.stdout.write(lineFor(s.label, 'fail') + '\n'); }
60
+ }
61
+ return;
62
+ }
63
+
64
+ const n = steps.length;
65
+ hideCursor();
66
+ try {
67
+ // Paint the full list pending, then park the cursor below it.
68
+ for (const s of steps) process.stdout.write(lineFor(s.label, 'pending') + '\n');
69
+
70
+ // Redraw line `i` (0 = top) in place: jump up, clear, write, jump back down.
71
+ const redraw = (i, text) => {
72
+ const up = n - i;
73
+ process.stdout.write(`\x1b[${up}A\r\x1b[2K${text}\r\x1b[${up}B`);
74
+ };
75
+
76
+ for (let i = 0; i < n; i++) {
77
+ const s = steps[i];
78
+ let spinning = true, f = 0;
79
+ const anim = (async () => {
80
+ while (spinning) { redraw(i, lineFor(s.label, 'active', SPINNER[f++ % SPINNER.length])); await sleep(80); }
81
+ })();
82
+ try { await s.work(); spinning = false; await anim; redraw(i, lineFor(s.label, 'done')); }
83
+ catch { spinning = false; await anim; redraw(i, lineFor(s.label, 'fail')); }
84
+ }
85
+ } finally {
86
+ showCursor();
87
+ }
88
+ }
89
+
90
+ /** The dateline rule: a Muted mono `date · place · version` stamp. */
91
+ export function dateline(version, place = 'Designed in UAE') {
92
+ const stamp = new Date().toISOString().slice(0, 10).replace(/-/g, '.');
93
+ const v = version ? ` · v${version}` : '';
94
+ return fg(P.muted, `${stamp} · ${place}${v}`);
95
+ }
96
+
97
+ // ── optional framed panel (used by `madarx run` ready-state, not the splash) ──
98
+
99
+ /** A framed panel. Graphite border; a single Mars bead leads the headline. */
100
+ export function readyBox(lines) {
101
+ const pad = 2;
102
+ const inner = Math.max(...lines.map(visibleLength)) + pad * 2;
103
+ const top = fg(P.graphite, '╭' + '─'.repeat(inner) + '╮');
104
+ const bot = fg(P.graphite, '╰' + '─'.repeat(inner) + '╯');
105
+ const bar = fg(P.graphite, '│');
106
+ const body = lines.map((l) => {
107
+ const gap = inner - visibleLength(l) - pad * 2;
108
+ return `${bar}${' '.repeat(pad)}${l}${' '.repeat(pad + gap)}${bar}`;
109
+ });
110
+ return [' ' + top, ...body.map((b) => ' ' + b), ' ' + bot].join('\n');
111
+ }
112
+
113
+ /** Standard "ready" panel for a booted instance (the `madarx run` close). */
114
+ export function readyPanel({ version, url } = {}) {
115
+ const head = `${GLYPH.bead} ${bold(fg(P.platinum, 'madarX is ready'))}`;
116
+ const hint = `${fg(P.muted, 'run')} ${fg(P.mars, 'madarx')} ${fg(P.muted, '→ dashboard on')} ${fg(P.bone, url || 'http://127.0.0.1:8787')}`;
117
+ return [readyBox([head, hint]), ' ' + dateline(version)].join('\n');
118
+ }
119
+
120
+ export { GLYPH, isTTY as splashIsTTY };
@@ -161,6 +161,99 @@ const SKILL_SEEDS = [
161
161
  },
162
162
  ];
163
163
 
164
+ // Business-default skill pack — the capabilities most teams reach for first, so
165
+ // a fresh agent can do real work out of the box (research, comms, documents,
166
+ // data, web). Each is a builtin skill catalog item backed by the default tools
167
+ // (web/email/calendar/files/supabase/browser). These are what the banner
168
+ // showcases; the design/QA skills above stay in the marketplace but are not the
169
+ // default highlight reel.
170
+ const BUSINESS_SKILL_SEEDS = [
171
+ {
172
+ slug: 'market-research', title: 'Market Research', category: 'research',
173
+ description: 'Research any market, company, or topic across the web and deliver a cited, structured brief.',
174
+ tools: ['web_search', 'web_fetch', 'file_write'], risk_summary: 'Read-only research; writes only the report file.',
175
+ tags: ['research', 'web', 'brief'], invocation: '/research',
176
+ trigger_examples: ['research this market', 'competitive landscape for X', 'brief me on company Y'],
177
+ },
178
+ {
179
+ slug: 'competitor-watch', title: 'Competitor Watch', category: 'research',
180
+ description: 'Track competitor pricing, features, and news on a schedule and alert you when something changes.',
181
+ tools: ['web_fetch', 'web_extract', 'email_send'], risk_summary: 'Read-only monitoring; sends a summary email.',
182
+ tags: ['research', 'monitoring', 'competitive'], invocation: '/watch',
183
+ trigger_examples: ['watch competitor pricing', 'alert me when X changes', 'track this page weekly'],
184
+ },
185
+ {
186
+ slug: 'inbox-triage', title: 'Inbox Triage', category: 'comms',
187
+ description: 'Summarize, prioritize, and draft replies across your inbox so you act on what matters first.',
188
+ tools: ['gmail_messages_list', 'gmail_thread_read', 'email_send'], risk_summary: 'Drafts replies; sending is approval-gated.',
189
+ tags: ['email', 'inbox', 'comms'], invocation: '/inbox',
190
+ trigger_examples: ['triage my inbox', 'summarize unread email', 'draft replies'],
191
+ },
192
+ {
193
+ slug: 'meeting-scheduler', title: 'Meeting Scheduler', category: 'comms',
194
+ description: 'Find times, schedule meetings, and send invites from your calendar and email.',
195
+ tools: ['calendar_events_list', 'calendar_event_read', 'email_send'], risk_summary: 'Proposes times; invites are approval-gated.',
196
+ tags: ['calendar', 'scheduling', 'comms'], invocation: '/schedule-meeting',
197
+ trigger_examples: ['schedule a meeting', 'find a time with X', 'book a call next week'],
198
+ },
199
+ {
200
+ slug: 'document-extract', title: 'Document Extraction', category: 'documents',
201
+ description: 'Pull structured data and key facts from PDFs, documents, and audio into clean, usable output.',
202
+ tools: ['file_read', 'transcribe_audio', 'file_write'], risk_summary: 'Read-only extraction; writes only the output file.',
203
+ tags: ['documents', 'extraction', 'pdf'], invocation: '/extract',
204
+ trigger_examples: ['extract data from this PDF', 'pull the numbers from these docs', 'transcribe this audio'],
205
+ },
206
+ {
207
+ slug: 'report-builder', title: 'Report Builder', category: 'documents',
208
+ description: 'Turn raw data and notes into a polished, formatted report or one-pager ready to share.',
209
+ tools: ['file_read', 'file_write'], risk_summary: 'Generates a document; no external writes.',
210
+ tags: ['documents', 'reporting', 'writing'], invocation: '/report',
211
+ trigger_examples: ['build a report from this data', 'write a one-pager', 'summarize into a deck outline'],
212
+ },
213
+ {
214
+ slug: 'database-query', title: 'Database Q&A', category: 'data',
215
+ description: 'Ask questions of your database in plain English and get answers, tables, and charts.',
216
+ tools: ['supabase_rest_select', 'supabase_sql'], risk_summary: 'Read-only queries by default; writes are approval-gated.',
217
+ tags: ['data', 'sql', 'analytics'], invocation: '/ask-data',
218
+ trigger_examples: ['how many orders last month', 'query the users table', 'top customers by revenue'],
219
+ },
220
+ {
221
+ slug: 'spreadsheet-analysis', title: 'Spreadsheet Analysis', category: 'data',
222
+ description: 'Clean, analyze, and summarize spreadsheets and CSVs — pivots, trends, and outliers.',
223
+ tools: ['file_read', 'file_write'], risk_summary: 'Local file analysis; no external writes.',
224
+ tags: ['data', 'spreadsheet', 'csv'], invocation: '/analyze-sheet',
225
+ trigger_examples: ['analyze this spreadsheet', 'summarize this CSV', 'find trends in this data'],
226
+ },
227
+ {
228
+ slug: 'web-automation', title: 'Web Automation', category: 'web',
229
+ description: 'Fill forms, extract data, and run repetitive flows in a real browser, end to end.',
230
+ tools: ['browser_open', 'browser_act', 'browser_extract'], risk_summary: 'Browser actions are bounded and audited.',
231
+ tags: ['web', 'automation', 'browser'], invocation: '/automate-web',
232
+ trigger_examples: ['automate this form', 'scrape this site', 'run this flow for each row'],
233
+ },
234
+ ];
235
+
236
+ function buildBusinessSkillSeed(s) {
237
+ return {
238
+ slug: s.slug,
239
+ title: s.title,
240
+ description: s.description,
241
+ category: s.category,
242
+ author: 'madarx',
243
+ source_kind: 'builtin',
244
+ source_url: null,
245
+ version: null,
246
+ risk_summary: s.risk_summary,
247
+ tags: s.tags,
248
+ manifest: {
249
+ invocation: s.invocation,
250
+ default: true,
251
+ uses_tools: s.tools,
252
+ trigger_examples: s.trigger_examples,
253
+ },
254
+ };
255
+ }
256
+
164
257
  const BUNDLE_SEEDS = [
165
258
  {
166
259
  slug: 'gstack',
@@ -240,10 +333,13 @@ function upsertItem(db, kind, seed) {
240
333
  new Date().toISOString(),
241
334
  );
242
335
 
336
+ // Default-on capabilities (manifest.default) seed as installed so the
337
+ // marketplace reflects what the agent ships with out of the box.
338
+ const installedDefault = seed?.manifest?.default ? 1 : 0;
243
339
  db.prepare(`
244
- INSERT OR IGNORE INTO marketplace_installations (item_id, installed)
245
- VALUES (?, 0)
246
- `).run(id);
340
+ INSERT OR IGNORE INTO marketplace_installations (item_id, installed, installed_at)
341
+ VALUES (?, ?, ?)
342
+ `).run(id, installedDefault, installedDefault ? new Date().toISOString() : null);
247
343
  }
248
344
  }
249
345
 
@@ -288,6 +384,7 @@ const MINES_MODULE_SEED = {
288
384
 
289
385
  export function seedMarketplaceItems(db) {
290
386
  try {
387
+ for (const s of BUSINESS_SKILL_SEEDS) upsertItem(db, 'skill', buildBusinessSkillSeed(s));
291
388
  for (const seed of SKILL_SEEDS) upsertItem(db, 'skill', seed);
292
389
  for (const seed of BUNDLE_SEEDS) upsertItem(db, 'bundle', seed);
293
390
  for (const curated of OPEN_DESIGN_CURATED_SKILLS) {
@@ -302,6 +399,47 @@ export function seedMarketplaceItems(db) {
302
399
  }
303
400
  }
304
401
 
402
+ // The default business skills, grouped by category for the CLI banner showcase.
403
+ export const DEFAULT_SKILL_SLUGS = BUSINESS_SKILL_SEEDS.map(s => s.slug);
404
+ const DEFAULT_SKILL_CATEGORY_ORDER = ['research', 'comms', 'documents', 'data', 'web'];
405
+ export function listDefaultSkillGroups() {
406
+ const byCat = new Map();
407
+ for (const s of BUSINESS_SKILL_SEEDS) {
408
+ if (!byCat.has(s.category)) byCat.set(s.category, []);
409
+ byCat.get(s.category).push(s.slug);
410
+ }
411
+ return DEFAULT_SKILL_CATEGORY_ORDER
412
+ .filter(c => byCat.has(c))
413
+ .map(category => ({ category, count: byCat.get(category).length, names: byCat.get(category) }));
414
+ }
415
+
416
+ /**
417
+ * The default business skills rendered as a `skills.md` section — injected into
418
+ * an agent's skills file so the runtime (which reads skills.md) actually surfaces
419
+ * them. Grouped by category, with invocation, description, and the tools each
420
+ * leans on.
421
+ */
422
+ export function defaultSkillsMarkdown() {
423
+ const titleCase = (s) => s.charAt(0).toUpperCase() + s.slice(1);
424
+ const lines = [
425
+ '## Default skills',
426
+ '',
427
+ 'You ship with these ready-to-use business skills. Reach for them by intent;',
428
+ 'each is backed by your enabled tools and stays within the usual approval gates.',
429
+ '',
430
+ ];
431
+ for (const g of listDefaultSkillGroups()) {
432
+ lines.push(`### ${titleCase(g.category)}`);
433
+ for (const slug of g.names) {
434
+ const s = BUSINESS_SKILL_SEEDS.find((x) => x.slug === slug);
435
+ if (!s) continue;
436
+ lines.push(`- **${s.title}** (\`${s.invocation}\`) — ${s.description} _Tools: ${s.tools.join(', ')}._`);
437
+ }
438
+ lines.push('');
439
+ }
440
+ return lines.join('\n').trimEnd() + '\n';
441
+ }
442
+
305
443
  export const PHASE1_SKILL_SLUGS = SKILL_SEEDS.map(s => s.slug);
306
444
  export const PHASE1_BUNDLE_SLUGS = BUNDLE_SEEDS.map(s => s.slug);
307
445
  export const OPEN_DESIGN_SKILL_SLUGS = OPEN_DESIGN_CURATED_SKILLS.map(s => `open-design-${s.slug}`);
@@ -230,59 +230,12 @@ function htmlShell({ title, kicker, bodyHtml }) {
230
230
 
231
231
  // ── Renderers ───────────────────────────────────────────────────────────────
232
232
 
233
- export function renderIntakeFormHtml({ definition, schema, caseRow, settings = null, mode = 'preview', submit_endpoint = null, submit_token = null }) {
234
- if (mode === 'interactive') {
235
- return renderIntakeFormInteractiveHtml({ definition, schema, caseRow, settings, submit_endpoint, submit_token });
236
- }
237
- // Preview (Phase 1 / no flag) read-only artifact.
238
- const fields = Array.isArray(schema?.fields) ? schema.fields : [];
239
- const fieldsHtml = fields
240
- .map((f) => {
241
- const req = f.required ? '<span class="req"></span>' : '';
242
- const help = f.help ? `<p class="field-help">${escapeHtml(f.help)}</p>` : '';
243
- let preview = '<em class="muted">Field will be captured at intake.</em>';
244
- if (f.type === 'select' && Array.isArray(f.options)) {
245
- preview = `<span class="muted">Choose one of:</span> ${f.options.map((o) => `<span class="pill">${escapeHtml(o)}</span>`).join(' ')}`;
246
- } else if (f.type === 'shareholders') {
247
- preview = '<span class="muted">Repeatable rows: shareholder name + percentage (must sum to 100).</span>';
248
- } else if (f.placeholder) {
249
- preview = `<span class="muted">${escapeHtml(f.placeholder)}</span>`;
250
- } else if (f.type) {
251
- preview = `<span class="muted">Type: ${escapeHtml(f.type)}</span>`;
252
- }
253
- return `
254
- <div class="field">
255
- <span class="field-label">${escapeHtml(f.label || f.name)}${req}</span>
256
- ${help}
257
- <div class="field-value">${preview}</div>
258
- </div>`;
259
- })
260
- .join('');
261
-
262
- const body = `
263
- <h1>${escapeHtml(schema?.title || `${definition?.name || 'Process'} — intake`)}</h1>
264
- <div class="meta">
265
- <span><strong>Process:</strong>&nbsp;${escapeHtml(definition?.name || definition?.slug || '')}</span>
266
- <span><strong>Case:</strong>&nbsp;${escapeHtml(caseRow?.title || '')}</span>
267
- <span class="pill">awaiting submission</span>
268
- </div>
269
- ${schema?.description ? `<p class="muted">${escapeHtml(schema.description)}</p>` : ''}
270
- <div class="note">
271
- This artifact is the source-of-record intake page for case <code>${escapeHtml(caseRow?.id || '')}</code>.
272
- Submit the live form via the workflows dashboard; on submit a companion <em>intake submission</em> artifact
273
- is generated and linked to this case.
274
- </div>
275
- <h2>Fields</h2>
276
- ${fieldsHtml || '<p class="muted">No fields configured.</p>'}
277
- <div class="art-footer">
278
- Generated by Madarx OS process engine · definition <code>${escapeHtml(definition?.slug || '')}</code>
279
- </div>
280
- `;
281
- return htmlShell({
282
- title: schema?.title || `Intake — ${definition?.name || ''}`,
283
- kicker: 'Intake form · awaiting submission',
284
- bodyHtml: body,
285
- });
233
+ // Renders the branded interactive intake form a single self-contained HTML
234
+ // document with REAL form controls that POSTs to `submit_endpoint`. This is the
235
+ // only intake-form shape as of v2.14.0; the legacy read-only "preview" renderer
236
+ // and its MADARX_BRANDED_INTAKE flag were removed.
237
+ export function renderIntakeFormHtml({ definition, schema, caseRow, settings = null, submit_endpoint = null, submit_token = null }) {
238
+ return renderIntakeFormInteractiveHtml({ definition, schema, caseRow, settings, submit_endpoint, submit_token });
286
239
  }
287
240
 
288
241
  // ── Branded interactive renderer (Phase 2) ──────────────────────────────────
@@ -713,19 +666,18 @@ function safeCreate(opts) {
713
666
  }
714
667
  }
715
668
 
716
- export function createIntakeFormArtifact({ definition, schema, caseRow, settings = null, mode = 'preview', submit_endpoint = null, submit_token = null }) {
669
+ export function createIntakeFormArtifact({ definition, schema, caseRow, settings = null, submit_endpoint = null, submit_token = null }) {
717
670
  if (!definition || !caseRow) return null;
718
- const html = renderIntakeFormHtml({ definition, schema, caseRow, settings, mode, submit_endpoint, submit_token });
719
- const modeSuffix = mode === 'interactive' ? ' (branded)' : '';
720
- const title = `${definition.name || definition.slug || 'Process'} — intake form${modeSuffix} — ${caseRow.title || caseRow.id.slice(-8)}`;
671
+ const html = renderIntakeFormHtml({ definition, schema, caseRow, settings, submit_endpoint, submit_token });
672
+ const title = `${definition.name || definition.slug || 'Process'} intake form — ${caseRow.title || caseRow.id.slice(-8)}`;
721
673
  return safeCreate({
722
674
  title,
723
675
  kind: 'html',
724
676
  content: html,
725
677
  project_id: caseRow.project_id,
726
- // Dedupe keyed on case + mode so re-rendering with a fresh token (share-
727
- // link mint) replaces rather than spawns a new artifact.
728
- dedupe_key: `process_intake_form:${caseRow.id}:${mode}`,
678
+ // Dedupe keyed on case so re-rendering with a fresh token (share-link mint)
679
+ // replaces rather than spawns a new artifact.
680
+ dedupe_key: `process_intake_form:${caseRow.id}`,
729
681
  });
730
682
  }
731
683
 
@@ -104,20 +104,20 @@ function appendProcessAudit({ case_id, stage_id = null, action, status = 'succes
104
104
 
105
105
  // Render the case-level intake-form artifact at startCase time. Failure is
106
106
  // observation-only — engine state stays the source of truth and the case can
107
- // still progress without a presentation artifact. MADARX_BRANDED_INTAKE=1
108
- // switches to the interactive (in-document form) shape; off renders preview.
107
+ // still progress without a presentation artifact. The artifact is always the
108
+ // branded interactive (in-document form) shape; it posts to the stage submit
109
+ // endpoint. (The legacy read-only "preview" shape and its MADARX_BRANDED_INTAKE
110
+ // flag were removed in v2.14.0 — branded intake is the only start path.)
109
111
  function seedIntakeArtifact({ definition, firstStage, caseRow, snapshot }) {
110
112
  if (firstStage.kind !== 'intake_form') return null;
111
113
  try {
112
114
  const schema = parseIntakeFormSchema(definition);
113
- const branded = process.env.MADARX_BRANDED_INTAKE === '1';
114
115
  return createIntakeFormArtifact({
115
116
  definition,
116
117
  schema,
117
118
  caseRow,
118
119
  settings: snapshot,
119
- mode: branded ? 'interactive' : 'preview',
120
- submit_endpoint: branded ? `/api/processes/${caseRow.id}/stages/${firstStage.slug}/submit` : null,
120
+ submit_endpoint: `/api/processes/${caseRow.id}/stages/${firstStage.slug}/submit`,
121
121
  });
122
122
  } catch { return null; }
123
123
  }
@@ -0,0 +1,116 @@
1
+ // lib/process/policy-predicates.js — JSON predicate evaluator for policy_gate.
2
+ //
3
+ // Replaces the hand-rolled string DSL (`stages/policy-dsl-legacy.js`) with a
4
+ // declarative predicate tree. No tokenizer, no parser, no escaping bugs — a
5
+ // predicate is plain JSON that the spec-validator can validate structurally
6
+ // and an agent can author without learning an expression grammar.
7
+ //
8
+ // Shape:
9
+ // { "op": "and", "rules": [ <predicate>, ... ] }
10
+ // { "op": "or", "rules": [ <predicate>, ... ] }
11
+ // { "op": "not", "rule": <predicate> }
12
+ // { "op": "eq", "path": "intake.country", "value": "US" }
13
+ // { "op": "gte", "path": "prior_stage.kyc-risk.risk_score", "value": 0.3 }
14
+ // { "op": "in", "path": "intake.type", "value": ["MSA", "SOW", "NDA"] }
15
+ //
16
+ // Path resolution (read-only):
17
+ // intake.<field…> → case intake payload
18
+ // prior_stage.<slug>.<field…> → that stage's accumulated context output
19
+ // context.<field…> → raw context bag
20
+ // <bare> → resolved against the whole ctx object
21
+ //
22
+ // Equality (`eq`/`neq`) is intentionally loose (`==`/`!=`) so a `neq null`
23
+ // check treats a missing path the same as an explicit null — matching the
24
+ // "field must be provided" idiom the legacy DSL expressed as `x != null`.
25
+
26
+ const MAX_DEPTH = 20;
27
+
28
+ export const LOGICAL_OPS = new Set(['and', 'or', 'not']);
29
+ export const COMPARE_OPS = new Set(['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'in', 'nin']);
30
+
31
+ const COMPARATORS = {
32
+ eq: (a, b) => a == b, // eslint-disable-line eqeqeq
33
+ neq: (a, b) => a != b, // eslint-disable-line eqeqeq
34
+ lt: (a, b) => Number(a) < Number(b),
35
+ lte: (a, b) => Number(a) <= Number(b),
36
+ gt: (a, b) => Number(a) > Number(b),
37
+ gte: (a, b) => Number(a) >= Number(b),
38
+ in: (a, b) => Array.isArray(b) && b.some((v) => v === a),
39
+ nin: (a, b) => Array.isArray(b) && !b.some((v) => v === a),
40
+ };
41
+
42
+ function isPlainObject(v) {
43
+ return v != null && typeof v === 'object' && !Array.isArray(v);
44
+ }
45
+
46
+ function readDeep(obj, path) {
47
+ if (!path) return obj;
48
+ return path.split('.').reduce((acc, key) => (acc == null ? acc : acc[key]), obj);
49
+ }
50
+
51
+ // Resolve a `path` string against the evaluation context. `ctx` carries
52
+ // `intake` and `context` (the accumulated per-stage output bag).
53
+ export function resolvePath(path, ctx) {
54
+ if (typeof path !== 'string' || !path) return undefined;
55
+ const dot = path.indexOf('.');
56
+ const head = dot === -1 ? path : path.slice(0, dot);
57
+ const rest = dot === -1 ? '' : path.slice(dot + 1);
58
+ if (head === 'intake') return readDeep(ctx?.intake, rest);
59
+ if (head === 'context') return readDeep(ctx?.context, rest);
60
+ if (head === 'prior_stage') {
61
+ const slugDot = rest.indexOf('.');
62
+ const slug = slugDot === -1 ? rest : rest.slice(0, slugDot);
63
+ const field = slugDot === -1 ? '' : rest.slice(slugDot + 1);
64
+ return readDeep(ctx?.context?.[slug], field);
65
+ }
66
+ return readDeep(ctx, path);
67
+ }
68
+
69
+ // True when a rule entry is a JSON predicate (vs a legacy string / { expr }).
70
+ export function isPredicateRule(rule) {
71
+ return isPlainObject(rule) && typeof rule.op === 'string';
72
+ }
73
+
74
+ // Evaluate a predicate tree against { intake, context }. Throws on a malformed
75
+ // predicate so the caller can surface the error in the gate trace.
76
+ export function evaluatePredicate(pred, ctx, depth = 0) {
77
+ if (depth > MAX_DEPTH) throw new Error('policy-predicate: maximum nesting depth exceeded');
78
+ if (!isPlainObject(pred)) throw new Error('policy-predicate: predicate must be an object');
79
+ const op = pred.op;
80
+ if (op === 'and' || op === 'or') {
81
+ if (!Array.isArray(pred.rules)) throw new Error(`policy-predicate: "${op}" requires a rules[] array`);
82
+ const results = pred.rules.map((r) => evaluatePredicate(r, ctx, depth + 1));
83
+ return op === 'and' ? results.every(Boolean) : results.some(Boolean);
84
+ }
85
+ if (op === 'not') {
86
+ if (!isPlainObject(pred.rule)) throw new Error('policy-predicate: "not" requires a rule object');
87
+ return !evaluatePredicate(pred.rule, ctx, depth + 1);
88
+ }
89
+ const cmp = COMPARATORS[op];
90
+ if (!cmp) throw new Error(`policy-predicate: unknown op "${op}"`);
91
+ if (typeof pred.path !== 'string' || !pred.path) {
92
+ throw new Error(`policy-predicate: "${op}" requires a path`);
93
+ }
94
+ const left = resolvePath(pred.path, ctx);
95
+ return Boolean(cmp(left, pred.value));
96
+ }
97
+
98
+ // Non-throwing wrapper mirroring the legacy `evaluateRule` return shape.
99
+ export function evaluatePredicateSafe(pred, ctx) {
100
+ try {
101
+ return { result: Boolean(evaluatePredicate(pred, ctx)), error: null };
102
+ } catch (err) {
103
+ return { result: false, error: err?.message || String(err) };
104
+ }
105
+ }
106
+
107
+ // Short human-readable label for a predicate when the author supplied none.
108
+ export function describePredicate(pred) {
109
+ if (!isPlainObject(pred)) return String(pred);
110
+ if (pred.label) return pred.label;
111
+ if (pred.op === 'and' || pred.op === 'or') {
112
+ return `(${(pred.rules || []).map(describePredicate).join(` ${pred.op} `)})`;
113
+ }
114
+ if (pred.op === 'not') return `not ${describePredicate(pred.rule)}`;
115
+ return `${pred.path} ${pred.op} ${JSON.stringify(pred.value)}`;
116
+ }
@@ -64,12 +64,20 @@
64
64
  "config": {
65
65
  "rules": [
66
66
  {
67
- "expr": "intake.project_name != null && intake.project_slug != null",
68
- "label": "Project name and slug must be provided"
67
+ "label": "Project name and slug must be provided",
68
+ "op": "and",
69
+ "rules": [
70
+ { "op": "neq", "path": "intake.project_name", "value": null },
71
+ { "op": "neq", "path": "intake.project_slug", "value": null }
72
+ ]
69
73
  },
70
74
  {
71
- "expr": "intake.data_directory_path != null && intake.data_directory_path != ''",
72
- "label": "Data directory path must be non-empty"
75
+ "label": "Data directory path must be non-empty",
76
+ "op": "and",
77
+ "rules": [
78
+ { "op": "neq", "path": "intake.data_directory_path", "value": null },
79
+ { "op": "neq", "path": "intake.data_directory_path", "value": "" }
80
+ ]
73
81
  }
74
82
  ]
75
83
  },
@@ -50,8 +50,12 @@
50
50
  "config": {
51
51
  "rules": [
52
52
  {
53
- "expr": "intake.project_id != null && intake.project_id != ''",
54
- "label": "Project ID must be provided"
53
+ "label": "Project ID must be provided",
54
+ "op": "and",
55
+ "rules": [
56
+ { "op": "neq", "path": "intake.project_id", "value": null },
57
+ { "op": "neq", "path": "intake.project_id", "value": "" }
58
+ ]
55
59
  }
56
60
  ]
57
61
  },