madarx 2.13.0 → 2.15.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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-build-manifest.json +544 -551
- package/.next/standalone/.next/app-path-routes-manifest.json +76 -77
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/react-loadable-manifest.json +1 -1
- package/.next/standalone/.next/routes-manifest.json +0 -6
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/activity/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/page.js +2 -2
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/agents/[id]/page.js +4 -4
- package/.next/standalone/.next/server/app/agents/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/agents/page.js +1 -1
- package/.next/standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/activity/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/audit-export/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/share-links/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-memory/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-runs/[id]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-runs/[id]/events/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-runs/[id]/log/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-runs/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-runs/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[id]/chain/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[id]/memory/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[id]/reports/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[id]/run/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/create/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/ops/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/approvals/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/approvals/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/artifacts/[id]/acl/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/artifacts/[id]/protect/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/artifacts/[id]/raw/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/artifacts/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/artifacts/[id]/share-link/[linkId]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/artifacts/[id]/share-link/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/artifacts/upload/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/audit/list/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/audit/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/config/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/join-bootstrap/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/brand/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/chat/sessions/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/chat/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/config/env/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/config/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/connections/[service]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/connections/[service]/verify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/connections/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/cron/tick/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/move/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/share-link/[linkId]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/share-link/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/dashboard/spaces/import/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/dashboard/spaces/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/disk/files/[id]/blob/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/disk/files/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/disk/files/[id]/transcribe/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/disk/files/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/disk/folders/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/since/[cursor]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/stream/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/fs/create-folder/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/fs/pick-folder/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/blueprint/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/blueprint/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/diagnostic/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/diagnostic/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/governance/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/governance/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/interview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/interview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/pilot/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/pilot/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/quarterly/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/quarterly/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/setup-package/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/[id]/setup-package/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/engagements/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/interviews/[id]/responses/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/interviews/[id]/responses/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/interviews/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/interviews/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/setup-packages/[id]/apply/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/hail/setup-packages/[id]/apply/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hail/setup-packages/validate/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/heartbeat/tick/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/heartbeat/worker/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/heartbeat/worker/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/help/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hermes/jobs/[id]/events/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hermes/jobs/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/hermes/jobs/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/integrations/google/callback/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/integrations/google/oauth/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/marketplace/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/marketplace/open-design/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/marketplace/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mines/import-roots/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mines/portfolio/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mines/projects/[id]/chunks/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mines/projects/[id]/diligence/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mines/projects/[id]/import/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mines/projects/[id]/publish/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mines/projects/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/missions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/onboarding/blueprint/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/onboarding/launch/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orchestrator/command/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orchestrator/stream/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orchestrator/upload/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/org/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/[id]/invites/[inviteId]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/[id]/invites/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/[id]/members/[userId]/role/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/[id]/members/[userId]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/[id]/members/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/invites/pending/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/join/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/join-complete/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/orgs/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/printing-press/clis/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/printing-press/install/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/printing-press/security-mode/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/privacy/config/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/privacy/verify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/share-link/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/share-link/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/override/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/override/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/retry/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/retry/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/submit/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/submit/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/definitions/[slug]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/definitions/[slug]/settings/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/definitions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/definitions/validate/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/processes/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/start-and-route/route.js +1 -1
- package/.next/standalone/.next/server/app/api/processes/start-and-route/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/processes/start-and-route/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[slug]/library/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[slug]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/runs/approve-claude-run/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/runs/claude-code-dry-run/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/runs/competitor-report/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/runs/engine-ping/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/runs/marketing-plan/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/schedules/upsert/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/secrets/[name]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/secrets/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/settings/trust-mode/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/otp/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/verify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/share/space/[token]/otp/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/share/space/[token]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/share/space/[token]/verify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/shared/spaces/[id]/acl/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/shared/spaces/publish/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/shared/spaces/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/shared/spaces/status/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/shared/spaces/unpublish/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/state/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/system/update/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/active-run/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/attachments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/checklist/[itemId]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/checklist/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/checkout/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/children/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/comments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/events/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/live-runs/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tool-allowlists/[id]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tool-allowlists/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tool-egress/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tools/[name]/approve/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tools/[name]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tools/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/transcripts/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/voice/providers/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/voice/realtime/context/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/voice/realtime/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/voice/realtime/tool-result/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/voice/realtime/tools/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/voice/tts/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/whatsapp/allowlist/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/whatsapp/disconnect/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/whatsapp/messages/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/whatsapp/qr/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/whatsapp/send/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/whatsapp/status/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/approvals/page.js +2 -2
- package/.next/standalone/.next/server/app/approvals/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/architecture/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/architecture.html +2 -2
- package/.next/standalone/.next/server/app/architecture.rsc +2 -2
- package/.next/standalone/.next/server/app/audit/live/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/brand/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/brand.html +1 -1
- package/.next/standalone/.next/server/app/brand.rsc +2 -2
- package/.next/standalone/.next/server/app/disk/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/federated-ai/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/federated-ai.html +2 -2
- package/.next/standalone/.next/server/app/federated-ai.rsc +2 -2
- package/.next/standalone/.next/server/app/hail/[id]/governance/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/governance/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/interview/page.js +2 -2
- package/.next/standalone/.next/server/app/hail/[id]/interview/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/interview/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/page.js +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/setup/page.js +2 -2
- package/.next/standalone/.next/server/app/hail/[id]/setup/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/hail/page.js +3 -3
- package/.next/standalone/.next/server/app/hail/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/hail/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/help/[slug]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +2 -2
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/join/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/join.html +1 -1
- package/.next/standalone/.next/server/app/join.rsc +2 -2
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/marketplace/page.js +2 -2
- package/.next/standalone/.next/server/app/marketplace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/mines/[projectId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/mines/[projectId]/results/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/mines/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/missions/page.js +1 -1
- package/.next/standalone/.next/server/app/missions/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding/org/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding.html +2 -2
- package/.next/standalone/.next/server/app/onboarding.rsc +2 -2
- package/.next/standalone/.next/server/app/org/page.js +1 -1
- package/.next/standalone/.next/server/app/org/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/org/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/[slug]/log/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/new/page.js +1 -1
- package/.next/standalone/.next/server/app/projects/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/new.html +1 -1
- package/.next/standalone/.next/server/app/projects/new.rsc +3 -3
- package/.next/standalone/.next/server/app/projects/page.js +20 -20
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/reports/[file]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/reports/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/runtime/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/schedules/page.js +2 -2
- package/.next/standalone/.next/server/app/schedules/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/schedules/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/account/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/advanced/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/appearance/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/brand/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/brand.html +2 -2
- package/.next/standalone/.next/server/app/settings/brand.rsc +2 -2
- package/.next/standalone/.next/server/app/settings/connectors/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/engines/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/onboarding.html +2 -2
- package/.next/standalone/.next/server/app/settings/onboarding.rsc +2 -2
- package/.next/standalone/.next/server/app/settings/organization/page.js +1 -1
- package/.next/standalone/.next/server/app/settings/organization/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/organization/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/runtime/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/team/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/tools/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings.html +2 -2
- package/.next/standalone/.next/server/app/settings.rsc +2 -2
- package/.next/standalone/.next/server/app/share/[token]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/share/space/[token]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/tasks/[id]/page.js +1 -1
- package/.next/standalone/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/tasks/page.js +2 -2
- package/.next/standalone/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/team/[agentId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/team/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/whatsapp/page.js +1 -1
- package/.next/standalone/.next/server/app/whatsapp/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/whatsapp.html +1 -1
- package/.next/standalone/.next/server/app/whatsapp.rsc +3 -3
- package/.next/standalone/.next/server/app/workflows/[caseId]/page.js +1 -1
- package/.next/standalone/.next/server/app/workflows/[caseId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workflows/[caseId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workflows/new/[caseId]/page.js +1 -1
- package/.next/standalone/.next/server/app/workflows/new/[caseId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workflows/new/[caseId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workflows/new/definition/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workflows/page.js +1 -1
- package/.next/standalone/.next/server/app/workflows/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workflows/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workflows/share/[caseId]/page.js +1 -1
- package/.next/standalone/.next/server/app/workflows/share/[caseId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workflows/share/[caseId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +76 -77
- package/.next/standalone/.next/server/chunks/1699.js +19 -19
- package/.next/standalone/.next/server/chunks/51.js +1 -0
- package/.next/standalone/.next/server/chunks/5185.js +4 -27
- package/.next/standalone/.next/server/chunks/5257.js +1 -1
- package/.next/standalone/.next/server/chunks/6355.js +1 -0
- package/.next/standalone/.next/server/functions-config-manifest.json +15 -15
- package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/4119-cfb6260557a0a3d2.js +1 -0
- package/.next/standalone/.next/static/chunks/app/projects/page-f136822590202f9f.js +1 -0
- package/.next/standalone/.next/static/chunks/app/workflows/[caseId]/page-9949ff1c223e771d.js +1 -0
- package/.next/{static/chunks/app/workflows/page-25cb2c4cb90273a8.js → standalone/.next/static/chunks/app/workflows/page-d0484521369bce4c.js} +1 -1
- package/.next/standalone/.next/static/chunks/{webpack-0cfb048137bd7fce.js → webpack-f916d679fe38a701.js} +1 -1
- package/.next/standalone/.next/static/css/0bd4c357d4f0c4f2.css +1 -0
- package/.next/standalone/.next/static/tMcPS9JR5cRXSe0u5ne95/_buildManifest.js +1 -0
- package/.next/standalone/CHANGELOG.md +28 -0
- package/.next/standalone/data/.artifacts-migrated-v1 +1 -1
- package/.next/standalone/data/.default-project-seeded +1 -1
- package/.next/standalone/data/madarx.sqlite +0 -0
- package/.next/standalone/data/madarx.sqlite-shm +0 -0
- package/.next/standalone/data/madarx.sqlite-wal +0 -0
- package/.next/standalone/lib/process/seeds/specs/mine-project-intake.json +12 -4
- package/.next/standalone/lib/process/seeds/specs/mine-valuation.json +6 -2
- package/.next/standalone/lib/process/stages/policy-dsl-legacy.js +178 -0
- package/.next/standalone/lib/process/stages/policy-gate.js +24 -168
- package/.next/standalone/package.json +2 -2
- package/.next/static/chunks/4119-cfb6260557a0a3d2.js +1 -0
- package/.next/static/chunks/app/projects/page-f136822590202f9f.js +1 -0
- package/.next/static/chunks/app/workflows/[caseId]/page-9949ff1c223e771d.js +1 -0
- package/.next/{standalone/.next/static/chunks/app/workflows/page-25cb2c4cb90273a8.js → static/chunks/app/workflows/page-d0484521369bce4c.js} +1 -1
- package/.next/static/chunks/{webpack-0cfb048137bd7fce.js → webpack-f916d679fe38a701.js} +1 -1
- package/.next/static/css/0bd4c357d4f0c4f2.css +1 -0
- package/.next/static/tMcPS9JR5cRXSe0u5ne95/_buildManifest.js +1 -0
- package/CHANGELOG.md +28 -0
- package/ai-docs/process-engine.md +33 -1
- package/app/api/processes/start-and-route/route.js +5 -3
- package/app/components/dashboard/whatsapp-section.jsx +54 -13
- package/app/workflows/[caseId]/case-detail-client.jsx +2 -2
- package/app/workflows/definition-card.jsx +12 -18
- package/app/workflows/new/[caseId]/page.js +8 -8
- package/app/workflows/page.js +0 -5
- package/app/workflows/share/[caseId]/page.js +0 -1
- package/lib/cli/prompt.js +110 -0
- package/lib/cli/setup.js +152 -87
- package/lib/process/artifacts.js +12 -60
- package/lib/process/engine.js +5 -5
- package/lib/process/policy-predicates.js +116 -0
- package/lib/process/seeds/specs/mine-project-intake.json +12 -4
- package/lib/process/seeds/specs/mine-valuation.json +6 -2
- package/lib/process/spec-validator.js +46 -1
- package/lib/process/stages/policy-dsl-legacy.js +178 -0
- package/lib/process/stages/policy-gate.js +24 -168
- package/lib/runtime.js +8 -2
- package/package.json +2 -2
- package/scripts/postbuild-standalone.mjs +9 -0
- package/scripts/whatsapp-reset.mjs +15 -0
- package/.next/standalone/.next/server/app/workflows/new/page.js +0 -2
- package/.next/standalone/.next/server/app/workflows/new/page.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/workflows/new/page_client-reference-manifest.js +0 -1
- package/.next/standalone/.next/server/chunks/1092.js +0 -1
- package/.next/standalone/.next/static/cR6E_4o8_rHXujVNesWiZ/_buildManifest.js +0 -1
- package/.next/standalone/.next/static/chunks/4119-3b6adff3c7187ef3.js +0 -1
- package/.next/standalone/.next/static/chunks/app/projects/page-2166c214f854766e.js +0 -1
- package/.next/standalone/.next/static/chunks/app/workflows/[caseId]/page-423e4c194c7f5bf5.js +0 -1
- package/.next/standalone/.next/static/chunks/app/workflows/new/page-1eda41616cbfc4f3.js +0 -1
- package/.next/standalone/.next/static/css/0bfed9e12afa1dc1.css +0 -1
- package/.next/static/cR6E_4o8_rHXujVNesWiZ/_buildManifest.js +0 -1
- package/.next/static/chunks/4119-3b6adff3c7187ef3.js +0 -1
- package/.next/static/chunks/app/projects/page-2166c214f854766e.js +0 -1
- package/.next/static/chunks/app/workflows/[caseId]/page-423e4c194c7f5bf5.js +0 -1
- package/.next/static/chunks/app/workflows/new/page-1eda41616cbfc4f3.js +0 -1
- package/.next/static/css/0bfed9e12afa1dc1.css +0 -1
- package/app/workflows/new/new-case-flow.jsx +0 -256
- package/app/workflows/new/page.js +0 -27
- /package/.next/standalone/.next/static/{cR6E_4o8_rHXujVNesWiZ → tMcPS9JR5cRXSe0u5ne95}/_ssgManifest.js +0 -0
- /package/.next/static/{cR6E_4o8_rHXujVNesWiZ → tMcPS9JR5cRXSe0u5ne95}/_ssgManifest.js +0 -0
package/lib/cli/setup.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `madarx setup` — interactive first-run wizard.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* An arrow-key guided setup that decides the things that shape the whole
|
|
5
|
+
* install up front, then fills in credentials and preferences:
|
|
6
|
+
*
|
|
7
|
+
* 1. Usage mode personal (local-only) vs team (Supabase shared layer)
|
|
8
|
+
* 2. Main agent which model/engine the orchestrator runs on
|
|
9
|
+
* 3. Sub-agents default model/engine new agents inherit
|
|
10
|
+
* 4. Secrets vault master key (generated + persisted on first run)
|
|
11
|
+
* 5. API keys Anthropic / OpenAI → encrypted vault
|
|
12
|
+
* 6. Folder grants MADARX_ALLOWED_ROOTS (the agent's file/exec boundary)
|
|
13
|
+
* 7. WhatsApp bridge on/off
|
|
14
|
+
* 8. Auto-update weekly notify / hands-off / off
|
|
8
15
|
*
|
|
9
16
|
* Sets MADARX_DISABLE_INPROC_DAEMON=1 before importing the runtime — a setup run
|
|
10
17
|
* must not spin up cron/heartbeat loops.
|
|
@@ -13,42 +20,33 @@
|
|
|
13
20
|
import { createInterface } from 'node:readline/promises';
|
|
14
21
|
import { applyHomeEnv } from './home.js';
|
|
15
22
|
import { upsertEnvVar, removeEnvVar, readEnvFile } from './env-file.js';
|
|
16
|
-
import { renderHeader } from './banner.js';
|
|
23
|
+
import { renderHeader, _palette as P, fg, bold, dim } from './banner.js';
|
|
17
24
|
import { readVersion } from './dispatch.js';
|
|
25
|
+
import { select, confirm } from './prompt.js';
|
|
18
26
|
|
|
19
27
|
function isInteractive() {
|
|
20
28
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
21
29
|
}
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
rl.stdoutMuted = false;
|
|
27
|
-
rl._writeToOutput = function (str) {
|
|
28
|
-
if (rl.stdoutMuted) rl.output.write('*');
|
|
29
|
-
else rl.output.write(str);
|
|
30
|
-
};
|
|
31
|
-
return rl;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function ask(rl, prompt, dflt = '') {
|
|
35
|
-
const suffix = dflt ? ` [${dflt}]` : '';
|
|
36
|
-
const ans = (await rl.question(`${prompt}${suffix}: `)).trim();
|
|
37
|
-
return ans || dflt;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function askYesNo(rl, prompt, dfltYes = true) {
|
|
41
|
-
const ans = (await rl.question(`${prompt} ${dfltYes ? '[Y/n]' : '[y/N]'}: `)).trim().toLowerCase();
|
|
42
|
-
if (!ans) return dfltYes;
|
|
43
|
-
return ans === 'y' || ans === 'yes';
|
|
44
|
-
}
|
|
31
|
+
const h2 = (s) => console.log('\n' + bold(fg(P.platinum, s)));
|
|
32
|
+
const note = (s) => console.log(' ' + dim(fg(P.muted, s)));
|
|
33
|
+
const ok = (s) => console.log(' ' + fg(P.mars, '●') + ' ' + fg(P.bone, s));
|
|
45
34
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
/** Open an ephemeral readline for one text prompt, then close it (so it never
|
|
36
|
+
* competes with the raw-mode arrow menus). `secret` echoes `*`. */
|
|
37
|
+
async function ask(prompt, { dflt = '', secret = false } = {}) {
|
|
38
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
49
39
|
rl.stdoutMuted = false;
|
|
50
|
-
rl.output.write('
|
|
51
|
-
|
|
40
|
+
rl._writeToOutput = function (str) { rl.output.write(rl.stdoutMuted ? '*' : str); };
|
|
41
|
+
try {
|
|
42
|
+
rl.stdoutMuted = secret;
|
|
43
|
+
const suffix = dflt ? ` [${dflt}]` : '';
|
|
44
|
+
const ans = (await rl.question(` ${fg(P.bone, prompt)}${dim(suffix)}: `)).trim();
|
|
45
|
+
if (secret) rl.output.write('\n');
|
|
46
|
+
return ans || dflt;
|
|
47
|
+
} finally {
|
|
48
|
+
rl.close();
|
|
49
|
+
}
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
export async function setup() {
|
|
@@ -57,87 +55,154 @@ export async function setup() {
|
|
|
57
55
|
return 1;
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
//
|
|
61
|
-
process.env.MADARX_DISABLE_INPROC_DAEMON = '1';
|
|
62
|
-
|
|
58
|
+
process.env.MADARX_DISABLE_INPROC_DAEMON = '1'; // management command — no daemons
|
|
63
59
|
const layout = applyHomeEnv();
|
|
64
|
-
const rl = makeReader();
|
|
65
60
|
|
|
66
61
|
try {
|
|
67
62
|
console.log(renderHeader('setup', readVersion()));
|
|
68
|
-
console.log(`Data home: ${layout.home}`);
|
|
69
|
-
|
|
63
|
+
console.log(`Data home: ${fg(P.bone, layout.home)}`);
|
|
64
|
+
note('override anytime with the MADARX_HOME env var');
|
|
70
65
|
|
|
71
|
-
//
|
|
72
|
-
// to $MADARX_HOME/.env.local on first run, prints the backup instruction).
|
|
73
|
-
console.log('1) Secrets vault');
|
|
74
|
-
const { resolveMasterKey } = await import('../master-key.js');
|
|
66
|
+
// Open the DB once so vault + config tables exist for the steps below.
|
|
75
67
|
const { getDb } = await import('../db.js');
|
|
76
|
-
getDb();
|
|
77
|
-
|
|
78
|
-
console.log(' Master key ready.\n');
|
|
68
|
+
getDb();
|
|
69
|
+
const { setConfig } = await import('../config.js');
|
|
79
70
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
71
|
+
// ── 1. Usage mode ────────────────────────────────────────────────────────
|
|
72
|
+
h2('1 · How will you use madarX?');
|
|
73
|
+
const mode = await select('Choose a setup', [
|
|
74
|
+
{ label: 'Personal', value: 'local', tag: 'recommended', hint: 'local-only, everything on this machine' },
|
|
75
|
+
{ label: 'Team', value: 'supabase', hint: 'shared with a team via Supabase (auth, orgs, sharing)' },
|
|
76
|
+
], { default: 0 });
|
|
77
|
+
|
|
78
|
+
if (mode === 'supabase') {
|
|
79
|
+
setConfig('auth_mode', 'supabase');
|
|
80
|
+
note('Enter your Supabase project credentials (stored in ' + layout.envFile + ').');
|
|
81
|
+
const existing = readEnvFile(layout.envFile);
|
|
82
|
+
const url = await ask('Supabase URL', { dflt: existing.SUPABASE_URL || existing.NEXT_PUBLIC_SUPABASE_URL || '' });
|
|
83
|
+
const anon = await ask('Supabase anon key', { dflt: existing.SUPABASE_ANON_KEY || '' });
|
|
84
|
+
const service = await ask('Supabase service-role key', { secret: true });
|
|
85
|
+
if (url) { upsertEnvVar(layout.envFile, 'SUPABASE_URL', url); upsertEnvVar(layout.envFile, 'NEXT_PUBLIC_SUPABASE_URL', url); }
|
|
86
|
+
if (anon) { upsertEnvVar(layout.envFile, 'SUPABASE_ANON_KEY', anon); upsertEnvVar(layout.envFile, 'NEXT_PUBLIC_SUPABASE_ANON_KEY', anon); }
|
|
87
|
+
if (service) upsertEnvVar(layout.envFile, 'SUPABASE_SERVICE_ROLE_KEY', service);
|
|
88
|
+
ok('Team mode (Supabase) configured.');
|
|
89
|
+
note('Apply the cloud schema once: see supabase/README.md.');
|
|
90
|
+
} else {
|
|
91
|
+
setConfig('auth_mode', 'local');
|
|
92
|
+
ok('Personal mode — local-only.');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ── Model catalog (probes installed CLIs + Ollama; Anthropic always listed) ─
|
|
96
|
+
const { getModels, setModel, getModel } = await import('../agent-config.js');
|
|
97
|
+
const { defaultModelForEngine } = await import('../agent-engines.js');
|
|
98
|
+
let models = [];
|
|
99
|
+
try { models = await getModels(); } catch { models = []; }
|
|
100
|
+
const recommendedId = models.find((m) => m.engine === 'claude-code') ? 'claude-code'
|
|
101
|
+
: (models.find((m) => m.id === 'claude-sonnet-4-6') ? 'claude-sonnet-4-6' : models[0]?.id);
|
|
102
|
+
const modelOption = (m) => ({
|
|
103
|
+
label: m.label,
|
|
104
|
+
value: { id: m.id, engine: m.engine },
|
|
105
|
+
hint: m.engine,
|
|
106
|
+
tag: m.id === recommendedId ? 'recommended' : undefined,
|
|
107
|
+
});
|
|
108
|
+
const orderedModels = [
|
|
109
|
+
...models.filter((m) => m.id === recommendedId),
|
|
110
|
+
...models.filter((m) => m.id !== recommendedId),
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
// ── 2. Main agent model ──────────────────────────────────────────────────
|
|
114
|
+
h2('2 · Main agent model');
|
|
115
|
+
note('the orchestrator that plans your work and dispatches sub-agents');
|
|
116
|
+
const current = getModel();
|
|
117
|
+
const mainChoice = await select('Select the main agent model', [
|
|
118
|
+
...orderedModels.map(modelOption),
|
|
119
|
+
{ label: `Keep current (${current})`, value: { keep: true } },
|
|
120
|
+
], { default: 0 });
|
|
121
|
+
if (!mainChoice.keep) { setModel(mainChoice.id); ok(`Main agent → ${mainChoice.id}`); }
|
|
122
|
+
else ok(`Main agent unchanged (${current})`);
|
|
123
|
+
const mainEngine = mainChoice.keep ? null : mainChoice.engine;
|
|
124
|
+
|
|
125
|
+
// ── 3. Sub-agent default model ───────────────────────────────────────────
|
|
126
|
+
h2('3 · Sub-agent default model');
|
|
127
|
+
note('what newly created agents inherit unless you pick another at creation');
|
|
128
|
+
const subChoice = await select('Select the default sub-agent model', [
|
|
129
|
+
{ label: 'Same as main agent', value: { same: true }, tag: 'recommended' },
|
|
130
|
+
...orderedModels.map(modelOption),
|
|
131
|
+
], { default: 0 });
|
|
132
|
+
let subEngine, subModel;
|
|
133
|
+
if (subChoice.same) {
|
|
134
|
+
subEngine = mainEngine || (orderedModels.find((m) => m.id === current)?.engine) || 'claude-code';
|
|
135
|
+
subModel = mainChoice.keep ? current : mainChoice.id;
|
|
90
136
|
} else {
|
|
91
|
-
|
|
137
|
+
subEngine = subChoice.engine;
|
|
138
|
+
subModel = subChoice.engine === 'anthropic' ? subChoice.id : defaultModelForEngine(subChoice.engine);
|
|
92
139
|
}
|
|
140
|
+
setConfig('default_agent_engine', subEngine);
|
|
141
|
+
setConfig('default_agent_model', subModel);
|
|
142
|
+
ok(`Sub-agents → ${subEngine}${subModel ? ' · ' + subModel : ''}`);
|
|
143
|
+
|
|
144
|
+
// ── 4. Secrets vault master key ──────────────────────────────────────────
|
|
145
|
+
h2('4 · Secrets vault');
|
|
146
|
+
const { resolveMasterKey } = await import('../master-key.js');
|
|
147
|
+
resolveMasterKey({ allowGenerate: true });
|
|
148
|
+
ok('Master key ready (AES-256-GCM).');
|
|
93
149
|
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
150
|
+
// ── 5. API keys → encrypted vault ────────────────────────────────────────
|
|
151
|
+
h2('5 · API keys');
|
|
152
|
+
note('stored encrypted in the vault · press Enter to skip any');
|
|
153
|
+
const { setSecret, getSecret } = await import('../secrets.js');
|
|
154
|
+
const usesAnthropic = [mainEngine, subEngine].includes('anthropic');
|
|
97
155
|
const keyPrompts = [
|
|
98
|
-
['ANTHROPIC_API_KEY', 'Anthropic API key (Claude)'],
|
|
156
|
+
['ANTHROPIC_API_KEY', 'Anthropic API key (Claude)' + (usesAnthropic ? ' — required for your selection' : '')],
|
|
99
157
|
['OPENAI_API_KEY', 'OpenAI API key (voice/realtime, optional)'],
|
|
100
158
|
];
|
|
101
159
|
for (const [name, label] of keyPrompts) {
|
|
102
|
-
|
|
160
|
+
let have = false;
|
|
161
|
+
try { have = Boolean(getSecret(name)); } catch { /* vault may be empty */ }
|
|
162
|
+
const val = await ask(label + (have ? ' (set — Enter to keep)' : ''), { secret: true });
|
|
103
163
|
if (val) {
|
|
104
|
-
try { setSecret(name, val, { scope: 'global' });
|
|
105
|
-
catch (err) { console.error(`
|
|
164
|
+
try { setSecret(name, val, { scope: 'global' }); ok(`Stored ${name}.`); }
|
|
165
|
+
catch (err) { console.error(' ' + fg(P.mars, '✗') + ` Could not store ${name}: ${err.message}`); }
|
|
106
166
|
}
|
|
107
167
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
168
|
+
|
|
169
|
+
// ── 6. Folder permissions ────────────────────────────────────────────────
|
|
170
|
+
h2('6 · Folder permissions');
|
|
171
|
+
note('the agent can read/write/run ONLY inside roots you grant (repo + workspace/ always allowed)');
|
|
172
|
+
const existingRoots = readEnvFile(layout.envFile).MADARX_ALLOWED_ROOTS || '';
|
|
173
|
+
const roots = await ask('Extra allowed roots (comma-separated absolute paths)', { dflt: existingRoots });
|
|
174
|
+
if (roots) {
|
|
175
|
+
const cleaned = roots.split(',').map((r) => r.trim()).filter(Boolean).join(',');
|
|
176
|
+
upsertEnvVar(layout.envFile, 'MADARX_ALLOWED_ROOTS', cleaned);
|
|
177
|
+
ok(`Granted: ${cleaned}`);
|
|
116
178
|
} else {
|
|
117
|
-
|
|
118
|
-
console.log(' Disabled.\n');
|
|
179
|
+
note('no extra roots granted');
|
|
119
180
|
}
|
|
120
181
|
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
182
|
+
// ── 7. WhatsApp bridge ───────────────────────────────────────────────────
|
|
183
|
+
h2('7 · WhatsApp bridge');
|
|
184
|
+
const enableWa = await confirm('Run the WhatsApp bridge with `madarx`?', { default: true });
|
|
185
|
+
if (enableWa) { removeEnvVar(layout.envFile, 'MADARX_DISABLE_WHATSAPP'); ok('Enabled — idles until you pair a dedicated number.'); }
|
|
186
|
+
else { upsertEnvVar(layout.envFile, 'MADARX_DISABLE_WHATSAPP', '1'); ok('Disabled.'); }
|
|
187
|
+
|
|
188
|
+
// ── 8. Auto-update ───────────────────────────────────────────────────────
|
|
189
|
+
h2('8 · Auto-update');
|
|
190
|
+
const upd = await select('How should madarX handle updates?', [
|
|
191
|
+
{ label: 'Notify weekly', value: 'notify', tag: 'recommended', hint: 'check weekly, tell me — I apply' },
|
|
192
|
+
{ label: 'Auto-apply weekly', value: 'auto', hint: 'hands-off, gated by the approval/trust tier' },
|
|
193
|
+
{ label: 'Off', value: 'off', hint: 'I will run `madarx update` myself' },
|
|
194
|
+
], { default: 0 });
|
|
195
|
+
if (upd === 'off') { setConfig('auto_update_mode', 'off'); ok('Auto-update off.'); }
|
|
196
|
+
else {
|
|
127
197
|
setConfig('auto_update_mode', 'weekly');
|
|
128
|
-
setConfig('auto_update_apply',
|
|
129
|
-
|
|
130
|
-
} else {
|
|
131
|
-
setConfig('auto_update_mode', 'off');
|
|
132
|
-
console.log(' Auto-update off. Run `madarx update` manually.\n');
|
|
198
|
+
setConfig('auto_update_apply', upd === 'auto' ? 'auto' : 'notify');
|
|
199
|
+
ok(`Weekly check on — ${upd === 'auto' ? 'auto-apply' : 'notify only'}.`);
|
|
133
200
|
}
|
|
134
201
|
|
|
135
|
-
console.log('Setup complete. Start everything with: madarx\n');
|
|
202
|
+
console.log('\n' + bold(fg(P.platinum, 'Setup complete.')) + ' Start everything with: ' + fg(P.mars, 'madarx') + '\n');
|
|
136
203
|
return 0;
|
|
137
204
|
} catch (err) {
|
|
138
205
|
console.error(`\nsetup failed: ${err?.stack || err}`);
|
|
139
206
|
return 1;
|
|
140
|
-
} finally {
|
|
141
|
-
rl.close();
|
|
142
207
|
}
|
|
143
208
|
}
|
package/lib/process/artifacts.js
CHANGED
|
@@ -230,59 +230,12 @@ function htmlShell({ title, kicker, bodyHtml }) {
|
|
|
230
230
|
|
|
231
231
|
// ── Renderers ───────────────────────────────────────────────────────────────
|
|
232
232
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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> ${escapeHtml(definition?.name || definition?.slug || '')}</span>
|
|
266
|
-
<span><strong>Case:</strong> ${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,
|
|
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,
|
|
719
|
-
const
|
|
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
|
|
727
|
-
//
|
|
728
|
-
dedupe_key: `process_intake_form:${caseRow.id}
|
|
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
|
|
package/lib/process/engine.js
CHANGED
|
@@ -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.
|
|
108
|
-
//
|
|
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
|
-
|
|
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
|
-
"
|
|
68
|
-
"
|
|
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
|
-
"
|
|
72
|
-
"
|
|
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
|
-
"
|
|
54
|
-
"
|
|
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
|
},
|
|
@@ -116,6 +116,46 @@ function validateAgentRun(stage, errors, prefix, opts, stageSlugs) {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// Predicate operator sets (mirror lib/process/policy-predicates.js).
|
|
120
|
+
const PREDICATE_LOGICAL_OPS = new Set(['and', 'or']);
|
|
121
|
+
const PREDICATE_COMPARE_OPS = new Set(['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'in', 'nin']);
|
|
122
|
+
const PREDICATE_MAX_DEPTH = 20;
|
|
123
|
+
|
|
124
|
+
// Validate a JSON predicate tree structurally. Mirrors the evaluator so an
|
|
125
|
+
// invalid predicate is rejected at authoring time, not at case run time.
|
|
126
|
+
function validatePredicate(pred, errors, prefix, depth = 0) {
|
|
127
|
+
if (depth > PREDICATE_MAX_DEPTH) {
|
|
128
|
+
pushErr(errors, prefix, 'predicate nesting too deep');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (!isPlainObject(pred)) {
|
|
132
|
+
pushErr(errors, prefix, 'predicate must be an object');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const op = pred.op;
|
|
136
|
+
if (PREDICATE_LOGICAL_OPS.has(op)) {
|
|
137
|
+
if (!Array.isArray(pred.rules) || pred.rules.length === 0) {
|
|
138
|
+
pushErr(errors, `${prefix}.rules`, `"${op}" requires a non-empty rules[] array`);
|
|
139
|
+
} else {
|
|
140
|
+
pred.rules.forEach((r, i) => validatePredicate(r, errors, `${prefix}.rules[${i}]`, depth + 1));
|
|
141
|
+
}
|
|
142
|
+
} else if (op === 'not') {
|
|
143
|
+
if (!isPlainObject(pred.rule)) pushErr(errors, `${prefix}.rule`, '"not" requires a rule object');
|
|
144
|
+
else validatePredicate(pred.rule, errors, `${prefix}.rule`, depth + 1);
|
|
145
|
+
} else if (PREDICATE_COMPARE_OPS.has(op)) {
|
|
146
|
+
if (typeof pred.path !== 'string' || !pred.path.trim()) {
|
|
147
|
+
pushErr(errors, `${prefix}.path`, 'required (non-empty string)');
|
|
148
|
+
}
|
|
149
|
+
if (!('value' in pred)) {
|
|
150
|
+
pushErr(errors, `${prefix}.value`, 'required');
|
|
151
|
+
} else if ((op === 'in' || op === 'nin') && !Array.isArray(pred.value)) {
|
|
152
|
+
pushErr(errors, `${prefix}.value`, `"${op}" requires an array value`);
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
pushErr(errors, `${prefix}.op`, `unknown predicate op "${op}"`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
119
159
|
function validatePolicyGate(stage, errors, prefix) {
|
|
120
160
|
const config = stage.config || {};
|
|
121
161
|
if (!Array.isArray(config.rules) || config.rules.length === 0) {
|
|
@@ -125,13 +165,18 @@ function validatePolicyGate(stage, errors, prefix) {
|
|
|
125
165
|
config.rules.forEach((rule, i) => {
|
|
126
166
|
const rpath = `${prefix}.config.rules[${i}]`;
|
|
127
167
|
if (typeof rule === 'string') {
|
|
168
|
+
// Legacy string DSL (deprecated; accepted one release for migration).
|
|
128
169
|
if (!rule.trim()) pushErr(errors, rpath, 'empty rule expression');
|
|
170
|
+
} else if (isPlainObject(rule) && typeof rule.op === 'string') {
|
|
171
|
+
// JSON predicate (canonical form).
|
|
172
|
+
validatePredicate(rule, errors, rpath);
|
|
129
173
|
} else if (isPlainObject(rule)) {
|
|
174
|
+
// Legacy { expr, label } wrapper.
|
|
130
175
|
if (!rule.expr || typeof rule.expr !== 'string' || !rule.expr.trim()) {
|
|
131
176
|
pushErr(errors, `${rpath}.expr`, 'required (non-empty string)');
|
|
132
177
|
}
|
|
133
178
|
} else {
|
|
134
|
-
pushErr(errors, rpath, 'rule must be a string or { expr, label }
|
|
179
|
+
pushErr(errors, rpath, 'rule must be a JSON predicate, a string, or { expr, label }');
|
|
135
180
|
}
|
|
136
181
|
});
|
|
137
182
|
}
|