madarx 2.16.1 → 2.16.3
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 +339 -339
- package/.next/standalone/.next/app-path-routes-manifest.json +83 -83
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- 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 +3 -3
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/agents/[id]/page.js +3 -3
- 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/brand/share/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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_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_client-reference-manifest.js +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_client-reference-manifest.js +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_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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/interview/page.js +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/hail/[id]/setup/page.js +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_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.js +1 -1
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/marketplace/page.js +3 -3
- 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 +2 -2
- 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 +11 -11
- 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_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 +2 -2
- package/.next/standalone/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/tasks/page.js +1 -1
- 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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/whatsapp.html +2 -2
- package/.next/standalone/.next/server/app/whatsapp.rsc +2 -2
- 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 +2 -2
- 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_client-reference-manifest.js +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 +83 -83
- package/.next/standalone/.next/server/chunks/1699.js +2 -2
- package/.next/standalone/.next/server/chunks/{3066.js → 9860.js} +1 -1
- package/.next/standalone/.next/server/functions-config-manifest.json +28 -28
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- 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/app/login/page-e23d5fe32a5160d5.js +1 -0
- package/.next/standalone/.next/static/chunks/app/projects/page-9792d7b57f298e6f.js +1 -0
- package/.next/{static/css/3d77d4b95ab1c602.css → standalone/.next/static/css/54018a2de582f8bf.css} +1 -1
- package/.next/standalone/CHANGELOG.md +14 -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-shm +0 -0
- package/.next/standalone/data/madarx.sqlite-wal +0 -0
- package/.next/standalone/package.json +1 -1
- package/.next/static/chunks/app/login/page-e23d5fe32a5160d5.js +1 -0
- package/.next/static/chunks/app/projects/page-9792d7b57f298e6f.js +1 -0
- package/.next/{standalone/.next/static/css/3d77d4b95ab1c602.css → static/css/54018a2de582f8bf.css} +1 -1
- package/CHANGELOG.md +14 -0
- package/ai-docs/api-surface.md +1 -1
- package/ai-docs/key-constraints.md +1 -1
- package/app/globals.css +31 -6
- package/app/login/login-client.jsx +43 -23
- package/lib/tts.js +75 -5
- package/package.json +1 -1
- package/scripts/misotts-local-server.py +150 -0
- package/.next/standalone/.next/static/chunks/app/login/page-a2344c0b1ef6d31a.js +0 -1
- package/.next/standalone/.next/static/chunks/app/projects/page-8c8e47863c240ec7.js +0 -1
- package/.next/static/chunks/app/login/page-a2344c0b1ef6d31a.js +0 -1
- package/.next/static/chunks/app/projects/page-8c8e47863c240ec7.js +0 -1
- /package/.next/standalone/.next/static/{rhk5TnKsJ_4Rj__U8e3JH → PoL-cD5mauHkRGcYCq0A2}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{rhk5TnKsJ_4Rj__U8e3JH → PoL-cD5mauHkRGcYCq0A2}/_ssgManifest.js +0 -0
- /package/.next/static/{rhk5TnKsJ_4Rj__U8e3JH → PoL-cD5mauHkRGcYCq0A2}/_buildManifest.js +0 -0
- /package/.next/static/{rhk5TnKsJ_4Rj__U8e3JH → PoL-cD5mauHkRGcYCq0A2}/_ssgManifest.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Madarx OS. Newest first.
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## [2.16.3] - 2026-06-05
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Local MisoTTS-compatible voice fallback.** `voice_speak` and `/api/voice/tts` now support a `local` provider through `MADARX_LOCAL_TTS_URL`, with optional `MADARX_LOCAL_TTS_MODEL` / `MADARX_LOCAL_TTS_VOICE`, so self-hosted engines can speak replies without OpenAI or ElevenLabs. Added `scripts/misotts-local-server.py` as a minimal bridge for `MisoLabsAI/MisoTTS`.
|
|
12
|
+
|
|
13
|
+
## [2.16.2] - 2026-06-05
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **Login brand motion polish.** Added the animated madarX orbit/mark lockup to the login hero, including reduced-motion fallbacks and mobile sizing, so the app entrance matches the public madarX brand language.
|
|
18
|
+
|
|
5
19
|
## [2.16.1] - 2026-06-05
|
|
6
20
|
|
|
7
21
|
### Added
|
package/ai-docs/api-surface.md
CHANGED
|
@@ -57,7 +57,7 @@ Reference for every `app/api/**/route.js` route. Read this when you need to find
|
|
|
57
57
|
|
|
58
58
|
| Route | Description |
|
|
59
59
|
|-------|-------------|
|
|
60
|
-
| `GET/POST /api/voice/tts` | TTS provider status + audio synthesis for OpenAI / ElevenLabs. Audio streams; credentials stay in vault. |
|
|
60
|
+
| `GET/POST /api/voice/tts` | TTS provider status + audio synthesis for OpenAI / ElevenLabs / local HTTP TTS (`MADARX_LOCAL_TTS_URL`, including the optional MisoTTS bridge). Audio streams; credentials stay in vault. |
|
|
61
61
|
| `GET/POST /api/voice/realtime/session` | OpenAI Realtime availability + ephemeral browser session. Client secret returned but never stored. Body accepts `project_id`/`agent_id`. |
|
|
62
62
|
| `POST /api/voice/realtime/tool-result` | Relays model-requested tools through `executeVoiceTool` / `executeRegistryTool`. All gates preserved. |
|
|
63
63
|
| `GET /api/voice/providers` | Provider capabilities snapshot (realtime/tts/stt/llm) + default mode + local slot URLs. |
|
|
@@ -50,7 +50,7 @@ Integration credentials (`GITHUB_TOKEN`, `RESEND_API_KEY`, `SUPABASE_*`, `VERCEL
|
|
|
50
50
|
|
|
51
51
|
## Voice tools (Jarvis console)
|
|
52
52
|
|
|
53
|
-
Provider abstraction lives in `lib/voice/providers.js`. Lanes: `realtime` (primary — OpenAI Realtime via WebRTC; vault keys `OPENAI_API_KEY`, optional `OPENAI_REALTIME_MODEL`, `OPENAI_REALTIME_VOICE`), `tts` (fallback — existing typed chat speaks final reply via OpenAI TTS or
|
|
53
|
+
Provider abstraction lives in `lib/voice/providers.js`. Lanes: `realtime` (primary — OpenAI Realtime via WebRTC; vault keys `OPENAI_API_KEY`, optional `OPENAI_REALTIME_MODEL`, `OPENAI_REALTIME_VOICE`), `tts` (fallback — existing typed chat speaks final reply via OpenAI TTS, ElevenLabs, or the env-driven local HTTP TTS slot; vault keys `OPENAI_API_KEY`/`ELEVENLABS_API_KEY` + optional `ELEVENLABS_VOICE_ID`; local uses `MADARX_LOCAL_TTS_URL`, optional `MADARX_LOCAL_TTS_MODEL`/`MADARX_LOCAL_TTS_VOICE`), and `local` (open-source STT/TTS slots — `MADARX_LOCAL_STT_URL`/`MADARX_LOCAL_TTS_URL`; `scripts/misotts-local-server.py` provides a minimal MisoLabsAI/MisoTTS bridge). Default mode resolves at runtime (`realtime` → `tts` → `local` → `off`) and respects `MADARX_VOICE_DEFAULT_PROVIDER`. Every voice session is minted with a durable Madarx context (`lib/voice/context.js`): today's ISO date, active project, brand voice, open tasks, recent artifact titles, pending approvals, and non-`local_only` agent memory — never API keys, ephemeral tokens, or `local_only` memory. The voice model sees a curated tool catalog (`lib/voice/tools.js`): `create_artifact`, `update_artifact`, `delete_artifact`, `find_artifacts`, `get_state`, `web_search`, `web_fetch`, `voice_speak`. All calls flow through `executeVoiceTool` → `executeTool` → `executeRegistryTool`, so trust-mode, approval gates (including the never-bypassable `irreversible_external` tier), allowlists, rate limits, egress logging, and audit rows are preserved exactly as for typed chat. Realtime ephemeral client secrets are returned to the browser but never persisted; the long-lived OpenAI key never crosses to the browser. UI: `app/components/dashboard/voice-panel.jsx` + `voice-orb.jsx` + `use-realtime-voice.js`. Brand: Onyx surface, Bone/Graphite text, Mars Red only on active speech peaks + approval banners. Operator guide: `docs/voice/jarvis.md`. `cli-printing-press` documented as a deferred external companion in `docs/integrations/cli-printing-press.md`.
|
|
54
54
|
|
|
55
55
|
## WhatsApp gateway
|
|
56
56
|
|
package/app/globals.css
CHANGED
|
@@ -3647,11 +3647,29 @@ a.admin-record-link{display:block;text-decoration:none;color:inherit;transition:
|
|
|
3647
3647
|
.login-page-shell--local .login-local-card{width:min(620px,100%);min-height:auto;border:1px solid rgba(232,232,229,.10);border-radius:28px;box-shadow:0 30px 100px rgba(0,0,0,.34);}
|
|
3648
3648
|
.login-hero-panel{padding:clamp(34px,6vw,84px);display:flex;flex-direction:column;justify-content:center;min-height:100vh;}
|
|
3649
3649
|
.login-hero-panel::before{content:'';position:absolute;inset:8%;border:1px solid rgba(232,232,229,.08);transform:skewX(-8deg);pointer-events:none;}
|
|
3650
|
+
/* Orbital rings + self-drawing madarX mark (shared brand motif from madarx.io) */
|
|
3651
|
+
.login-orbit{position:absolute;right:-170px;top:50%;width:680px;height:680px;transform:translateY(-50%);pointer-events:none;z-index:0;opacity:0;animation:loginOrbitIn 1.3s ease .15s forwards;}
|
|
3652
|
+
.login-orbit svg{display:block;width:100%;height:100%;}
|
|
3653
|
+
.login-orbit-spin{transform-origin:350px 350px;animation:loginOrbitSpin 90s linear infinite;}
|
|
3654
|
+
.login-orbit-spin--rev{animation-duration:130s;animation-direction:reverse;}
|
|
3655
|
+
.login-orbit-bead{transform-origin:350px 350px;animation:loginOrbitSpin 26s linear infinite;}
|
|
3656
|
+
.login-orbit-bead--outer{animation-duration:60s;animation-direction:reverse;}
|
|
3657
|
+
.login-brand-lockup{position:relative;z-index:1;display:flex;align-items:center;gap:14px;}
|
|
3658
|
+
.login-mark{display:block;flex:0 0 auto;overflow:visible;}
|
|
3659
|
+
.login-mark .lm-arc{stroke-dasharray:252;stroke-dashoffset:252;animation:loginDraw 1.4s cubic-bezier(.4,0,.2,1) .3s forwards;}
|
|
3660
|
+
.login-mark .lm-x1{stroke-dasharray:80;stroke-dashoffset:80;animation:loginDraw .5s cubic-bezier(.4,0,.2,1) 1.5s forwards;}
|
|
3661
|
+
.login-mark .lm-x2{stroke-dasharray:80;stroke-dashoffset:80;animation:loginDraw .5s cubic-bezier(.4,0,.2,1) 1.85s forwards;}
|
|
3662
|
+
.login-mark .lm-bead{opacity:0;animation:loginBeadIn .3s ease 2.1s forwards;}
|
|
3663
|
+
@keyframes loginOrbitIn{to{opacity:1;}}
|
|
3664
|
+
@keyframes loginOrbitSpin{to{transform:rotate(360deg);}}
|
|
3665
|
+
@keyframes loginDraw{to{stroke-dashoffset:0;}}
|
|
3666
|
+
@keyframes loginBeadIn{0%{opacity:0;r:0;}80%{r:4;}100%{opacity:1;r:3;}}
|
|
3667
|
+
@media (prefers-reduced-motion:reduce){.login-orbit{animation:none;opacity:1;}.login-orbit-spin,.login-orbit-spin--rev,.login-orbit-bead{animation:none;}.login-mark .lm-arc,.login-mark .lm-x1,.login-mark .lm-x2{animation:none;stroke-dashoffset:0;}.login-mark .lm-bead{animation:none;opacity:1;}}
|
|
3650
3668
|
.login-wordmark{font:500 22px/1 var(--font-mono-brand,'IBM Plex Mono',ui-monospace,monospace);letter-spacing:-.06em;color:#E8E8E5;position:relative;z-index:1;}.login-wordmark span{color:#C2452A;}
|
|
3651
3669
|
.login-kicker{margin:72px 0 16px;color:#DCDCD8;text-transform:uppercase;letter-spacing:.18em;font-size:11px;position:relative;z-index:1;}.login-hero-panel h1{font-size:clamp(48px,7.8vw,104px);line-height:.88;letter-spacing:-.09em;max-width:960px;margin:0;color:#E8E8E5;position:relative;z-index:1;}.login-lede{max-width:690px;margin:28px 0 0;color:#BEBEB9;line-height:1.75;font-family:ui-sans-serif,system-ui,sans-serif;font-size:16px;position:relative;z-index:1;}
|
|
3652
3670
|
.login-proof-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;margin-top:56px;border:1px solid rgba(232,232,229,.10);position:relative;z-index:1;}.login-proof-grid div{padding:18px;background:rgba(232,232,229,.035);}.login-proof-grid b{display:block;color:#E8E8E5;font-size:12px;margin-bottom:8px;text-transform:uppercase;letter-spacing:.08em;}.login-proof-grid span{display:block;color:#A9AAA5;font:13px/1.55 ui-sans-serif,system-ui,sans-serif;}
|
|
3653
|
-
.login-card{padding:clamp(24px,5vw,56px);display:flex;flex-direction:column;justify-content:center;min-height:100vh;border-left:1px solid rgba(232,232,229,.10);}.login-card-head p{margin:0 0 10px;color:#C2452A;text-transform:uppercase;letter-spacing:.16em;font-size:11px;font-weight:800;}.login-card-head h2{margin:0 0 24px;color:#E8E8E5;font-size:28px;letter-spacing:-.05em;}.login-mode-toggle{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;border:1px solid rgba(232,232,229,.12);border-radius:
|
|
3654
|
-
.login-link-button--ghost{margin-top:12px;background:transparent;color:#
|
|
3671
|
+
.login-card{padding:clamp(24px,5vw,56px);display:flex;flex-direction:column;justify-content:center;min-height:100vh;border-left:1px solid rgba(232,232,229,.10);}.login-card-head p{margin:0 0 10px;color:#C2452A;text-transform:uppercase;letter-spacing:.16em;font-size:11px;font-weight:800;}.login-card-head h2{margin:0 0 24px;color:#E8E8E5;font-size:28px;letter-spacing:-.05em;}.login-mode-toggle{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;border:1px solid rgba(232,232,229,.12);border-radius:8px;background:rgba(232,232,229,.04);margin-bottom:18px;}.login-mode-toggle button{border:0;border-radius:5px;background:transparent;color:#A9AAA5;padding:10px 12px;cursor:pointer;font-family:var(--font-mono-brand,'IBM Plex Mono',ui-monospace,monospace);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;transition:background .14s ease,color .14s ease,box-shadow .14s ease;}.login-mode-toggle button.active{background:rgba(194,69,42,.14);color:#E8E8E5;box-shadow:inset 0 0 0 1px rgba(194,69,42,.5);}.login-message{border-left:2px solid #C2452A;background:rgba(194,69,42,.10);padding:12px 14px;margin-bottom:16px;color:#E8E8E5;font:13px/1.45 ui-sans-serif,system-ui,sans-serif;}.login-form{display:grid;gap:14px;}.login-form label{display:grid;gap:8px;color:#DCDCD8;font-size:11px;text-transform:uppercase;letter-spacing:.12em;font-weight:800;}.login-sso{display:grid;gap:10px;margin-top:18px;}.login-sso>span{display:flex;align-items:center;gap:12px;color:#8D8E8A;font-size:11px;text-transform:uppercase;letter-spacing:.12em;}.login-sso>span::before,.login-sso>span::after{content:'';height:1px;background:rgba(232,232,229,.12);flex:1;}.login-footnote{margin:22px 0 0;color:#8D8E8A;font:12px/1.65 ui-sans-serif,system-ui,sans-serif;}.login-local-card{min-height:100vh;display:grid;place-content:center;padding:36px;text-align:center;}.login-local-card h1{font-size:42px;letter-spacing:-.07em;margin:22px 0 12px;}.login-local-card p{max-width:560px;color:#BEBEB9;font:15px/1.7 ui-sans-serif,system-ui,sans-serif;}.login-link-button{display:inline-flex;align-items:center;gap:10px;justify-content:center;margin:24px auto 0;padding:13px 20px;border-radius:4px;background:#C2452A;color:#fff;text-decoration:none;font-family:var(--font-mono-brand,'IBM Plex Mono',ui-monospace,monospace);font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.14em;transition:opacity .15s ease;}.login-link-button:hover{opacity:.86;}
|
|
3672
|
+
.login-link-button--ghost{margin-top:12px;background:transparent;color:#C2452A;border:1px solid rgba(194,69,42,.4);}.login-link-button--ghost:hover{opacity:1;background:rgba(194,69,42,.1);border-color:#C2452A;}
|
|
3655
3673
|
.login-message--warn{border-left-color:#C2452A;background:rgba(194,69,42,.08);}
|
|
3656
3674
|
.login-message--warn code,.login-local-card code{font:600 12px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;color:#E8E8E5;background:rgba(232,232,229,.10);padding:1px 6px;border-radius:6px;}
|
|
3657
3675
|
.login-env-block{text-align:left;max-width:560px;margin:18px auto;padding:16px 18px;border-radius:14px;background:rgba(0,0,0,.34);border:1px solid rgba(232,232,229,.12);color:#DCDCD8;font:600 12.5px/1.7 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre;overflow-x:auto;}
|
|
@@ -3659,9 +3677,9 @@ a.admin-record-link{display:block;text-decoration:none;color:inherit;transition:
|
|
|
3659
3677
|
.login-text-button{background:none;border:0;padding:0;color:#C2452A;font:inherit;font-weight:700;cursor:pointer;text-decoration:underline;}
|
|
3660
3678
|
.login-text-button:disabled{opacity:.6;cursor:default;}
|
|
3661
3679
|
/* Personal vs Team chooser (top of the login card) */
|
|
3662
|
-
.login-seg{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;border:1px solid rgba(232,232,229,.12);border-radius:
|
|
3663
|
-
.login-seg button{border:0;border-radius:
|
|
3664
|
-
.login-seg button.active{background
|
|
3680
|
+
.login-seg{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;border:1px solid rgba(232,232,229,.12);border-radius:8px;background:rgba(232,232,229,.04);margin-bottom:22px;}
|
|
3681
|
+
.login-seg button{border:0;border-radius:5px;background:transparent;color:#A9AAA5;padding:11px 12px;cursor:pointer;font-family:var(--font-mono-brand,'IBM Plex Mono',ui-monospace,monospace);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;transition:background .14s ease,color .14s ease,box-shadow .14s ease;}
|
|
3682
|
+
.login-seg button.active{background:rgba(194,69,42,.14);color:#E8E8E5;box-shadow:inset 0 0 0 1px rgba(194,69,42,.5);}
|
|
3665
3683
|
/* Join-with-a-link row (Team view) */
|
|
3666
3684
|
.login-join{margin-top:22px;padding-top:18px;border-top:1px solid rgba(232,232,229,.10);}
|
|
3667
3685
|
.login-join-label{display:block;color:#8D8E8A;font-size:11px;text-transform:uppercase;letter-spacing:.12em;font-weight:800;margin-bottom:10px;}
|
|
@@ -3669,6 +3687,13 @@ a.admin-record-link{display:block;text-decoration:none;color:inherit;transition:
|
|
|
3669
3687
|
/* Inline Create-a-team form (Team view, fresh install) */
|
|
3670
3688
|
.login-create-team{margin-top:2px;}
|
|
3671
3689
|
.login-create-actions{display:flex;gap:8px;align-items:stretch;}
|
|
3690
|
+
/* Marketing-matched buttons (madarx.io): solid Mars primary, Mars-outline secondary, uppercase mono, crisp corners */
|
|
3691
|
+
.login-btn{width:100%;min-height:46px;display:inline-flex;align-items:center;justify-content:center;gap:10px;padding:0 18px;border:0;border-radius:4px;background:#C2452A;color:#fff;font-family:var(--font-mono-brand,'IBM Plex Mono',ui-monospace,monospace);font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.14em;cursor:pointer;transition:opacity .15s ease,background .15s ease,border-color .15s ease;}
|
|
3692
|
+
.login-btn:hover:not(:disabled){opacity:.86;}
|
|
3693
|
+
.login-btn:disabled{opacity:.5;cursor:default;}
|
|
3694
|
+
.login-btn--ghost{background:transparent;color:#C2452A;border:1px solid rgba(194,69,42,.4);}
|
|
3695
|
+
.login-btn--ghost:hover:not(:disabled){opacity:1;background:rgba(194,69,42,.1);border-color:#C2452A;}
|
|
3696
|
+
.login-btn--inline{width:auto;flex:0 0 auto;}
|
|
3672
3697
|
.auth-mode-toggle{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
|
|
3673
3698
|
.auth-mode-toggle button{display:flex;flex-direction:column;gap:3px;text-align:left;padding:12px 14px;border-radius:12px;border:1px solid rgba(20,22,26,.14);background:#fff;color:#313740;font-weight:700;cursor:pointer;transition:border-color 140ms ease,background 140ms ease;}
|
|
3674
3699
|
.auth-mode-toggle button small{font-weight:450;color:#737a85;font-size:11.5px;}
|
|
@@ -3708,7 +3733,7 @@ a.admin-record-link{display:block;text-decoration:none;color:inherit;transition:
|
|
|
3708
3733
|
.ssm-cloud-status{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
|
|
3709
3734
|
.ssm-badge{font-size:11px;font-weight:700;border-radius:999px;padding:3px 10px;}
|
|
3710
3735
|
.ssm-badge-on{background:rgba(34,139,84,.12);color:#1d7a47;}
|
|
3711
|
-
@media(max-width:980px){.login-page-shell{min-height:100dvh;height:100dvh;grid-template-columns:1fr;grid-auto-rows:max-content;}.login-hero-panel,.login-card{min-height:auto;overflow:visible;}.login-card{border-left:0;border-top:1px solid rgba(232,232,229,.10);}.login-proof-grid{grid-template-columns:1fr;}.login-hero-panel h1{font-size:48px;}}
|
|
3736
|
+
@media(max-width:980px){.login-page-shell{min-height:100dvh;height:100dvh;grid-template-columns:1fr;grid-auto-rows:max-content;}.login-hero-panel,.login-card{min-height:auto;overflow:visible;}.login-hero-panel{overflow:clip;}.login-orbit{right:-220px;width:520px;height:520px;opacity:.6;}.login-card{border-left:0;border-top:1px solid rgba(232,232,229,.10);}.login-proof-grid{grid-template-columns:1fr;}.login-hero-panel h1{font-size:48px;}}
|
|
3712
3737
|
.mkt-page[data-page="project-detail"] .project-info-disclosure > summary::-webkit-details-marker{display:none;}
|
|
3713
3738
|
.mkt-page[data-page="project-detail"] .project-info-disclosure > summary::after{content:'\\203A';color:#8a8f99;font-size:18px;transition:transform 160ms ease;}
|
|
3714
3739
|
.mkt-page[data-page="project-detail"] .project-info-disclosure[open] > summary::after{transform:rotate(90deg);}
|
|
@@ -17,15 +17,9 @@ const inputStyle = {
|
|
|
17
17
|
border: '1px solid rgba(232,232,229,.18)', background: 'rgba(255,255,255,.06)',
|
|
18
18
|
color: '#E8E8E5', outline: 'none', fontSize: 14,
|
|
19
19
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
|
|
24
|
-
cursor: 'pointer', letterSpacing: '-0.01em',
|
|
25
|
-
};
|
|
26
|
-
const secondaryButtonStyle = {
|
|
27
|
-
...buttonStyle, background: 'rgba(232,232,229,.06)', color: '#E8E8E5', border: '1px solid rgba(232,232,229,.16)',
|
|
28
|
-
};
|
|
20
|
+
// Button visuals live in globals.css (.login-btn / --ghost / --inline) so they can
|
|
21
|
+
// carry hover + disabled states. Marketing-matched: solid Mars red primary, Mars
|
|
22
|
+
// outline secondary, uppercase mono labels, crisp corners.
|
|
29
23
|
|
|
30
24
|
export default function LoginClient({ authMode, nextPath = '/', errorCode = '', forceSupabase = false, initialView = '' }) {
|
|
31
25
|
const isLocalServer = authMode === 'local';
|
|
@@ -230,7 +224,7 @@ export default function LoginClient({ authMode, nextPath = '/', errorCode = '',
|
|
|
230
224
|
<input style={inputStyle} type="text" value={recoveryToken} onChange={(e) => setRecoveryToken(e.target.value)} placeholder="paste recovery token" autoComplete="off" />
|
|
231
225
|
</label>
|
|
232
226
|
<span className="login-footnote" style={{ marginTop: 0 }}>Found in <code>data/.auth-recovery-token</code> on the server machine.</span>
|
|
233
|
-
<button type="button"
|
|
227
|
+
<button type="button" className="login-btn" disabled={resetting} onClick={resetToLocal}>
|
|
234
228
|
{resetting ? 'Switching…' : 'Switch to personal mode'}
|
|
235
229
|
</button>
|
|
236
230
|
</div>
|
|
@@ -258,13 +252,13 @@ export default function LoginClient({ authMode, nextPath = '/', errorCode = '',
|
|
|
258
252
|
<form onSubmit={signIn} className="login-form">
|
|
259
253
|
<label>Email<input style={inputStyle} type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@company.com" autoComplete="email" required /></label>
|
|
260
254
|
{mode === 'password' ? <label>Password<input style={inputStyle} type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" autoComplete="current-password" required /></label> : null}
|
|
261
|
-
<button type="submit"
|
|
255
|
+
<button type="submit" className="login-btn" disabled={loading}>{loading ? 'Working...' : mode === 'password' ? 'Sign in' : 'Send magic link'} {!loading ? <IconArrowRight /> : null}</button>
|
|
262
256
|
</form>
|
|
263
257
|
{(process.env.NEXT_PUBLIC_GOOGLE_SSO_ENABLED === 'true' || process.env.NEXT_PUBLIC_MICROSOFT_SSO_ENABLED === 'true') ? (
|
|
264
258
|
<div className="login-sso">
|
|
265
259
|
<span>or continue with</span>
|
|
266
|
-
{process.env.NEXT_PUBLIC_GOOGLE_SSO_ENABLED === 'true' ? <button type="button" onClick={() => sso('google')}
|
|
267
|
-
{process.env.NEXT_PUBLIC_MICROSOFT_SSO_ENABLED === 'true' ? <button type="button" onClick={() => sso('azure')}
|
|
260
|
+
{process.env.NEXT_PUBLIC_GOOGLE_SSO_ENABLED === 'true' ? <button type="button" onClick={() => sso('google')} className="login-btn login-btn--ghost"><IconGoogle /> Google</button> : null}
|
|
261
|
+
{process.env.NEXT_PUBLIC_MICROSOFT_SSO_ENABLED === 'true' ? <button type="button" onClick={() => sso('azure')} className="login-btn login-btn--ghost"><IconMicrosoft /> Microsoft</button> : null}
|
|
268
262
|
</div>
|
|
269
263
|
) : null}
|
|
270
264
|
</>
|
|
@@ -281,8 +275,8 @@ export default function LoginClient({ authMode, nextPath = '/', errorCode = '',
|
|
|
281
275
|
<label>Anon key<input style={inputStyle} type="text" value={ct.anonKey} onChange={(e) => setCt((s) => ({ ...s, anonKey: e.target.value }))} placeholder="eyJ…" autoComplete="off" required /></label>
|
|
282
276
|
<label>Service-role key<input style={inputStyle} type="password" value={ct.serviceKey} onChange={(e) => setCt((s) => ({ ...s, serviceKey: e.target.value }))} placeholder="eyJ… (kept server-side)" autoComplete="off" required /></label>
|
|
283
277
|
<div className="login-create-actions">
|
|
284
|
-
<button type="button"
|
|
285
|
-
<button type="submit"
|
|
278
|
+
<button type="button" className="login-btn login-btn--ghost login-btn--inline" disabled={Boolean(ctBusy)} onClick={testTeam}>{ctBusy === 'test' ? 'Testing…' : 'Test'}</button>
|
|
279
|
+
<button type="submit" className="login-btn" disabled={Boolean(ctBusy)}>{ctBusy === 'save' ? 'Creating…' : 'Create team'} {!ctBusy ? <IconArrowRight /> : null}</button>
|
|
286
280
|
</div>
|
|
287
281
|
</form>
|
|
288
282
|
);
|
|
@@ -299,7 +293,7 @@ export default function LoginClient({ authMode, nextPath = '/', errorCode = '',
|
|
|
299
293
|
<span className="login-join-label">Have an invite link?</span>
|
|
300
294
|
<form className="login-join-row" onSubmit={joinWithLink}>
|
|
301
295
|
<input style={inputStyle} type="text" value={inviteLink} onChange={(e) => setInviteLink(e.target.value)} placeholder="paste invite link" autoComplete="off" />
|
|
302
|
-
<button type="submit"
|
|
296
|
+
<button type="submit" className="login-btn login-btn--ghost login-btn--inline">Join</button>
|
|
303
297
|
</form>
|
|
304
298
|
</div>
|
|
305
299
|
|
|
@@ -313,14 +307,40 @@ export default function LoginClient({ authMode, nextPath = '/', errorCode = '',
|
|
|
313
307
|
return (
|
|
314
308
|
<main className="login-page-shell">
|
|
315
309
|
<section className="login-hero-panel" aria-label="madarX OS landing">
|
|
316
|
-
<div className="login-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
310
|
+
<div className="login-orbit" aria-hidden="true">
|
|
311
|
+
<svg viewBox="0 0 700 700" width="700" height="700">
|
|
312
|
+
<g className="login-orbit-spin">
|
|
313
|
+
<circle cx="350" cy="350" r="320" stroke="#E8E8E5" strokeWidth="1" fill="none" opacity=".10" />
|
|
314
|
+
<circle cx="350" cy="350" r="240" stroke="#E8E8E5" strokeWidth="1" fill="none" opacity=".08" />
|
|
315
|
+
</g>
|
|
316
|
+
<g className="login-orbit-spin login-orbit-spin--rev">
|
|
317
|
+
<circle cx="350" cy="350" r="160" stroke="#C2452A" strokeWidth="1.2" fill="none" opacity=".30" />
|
|
318
|
+
<circle cx="350" cy="350" r="80" stroke="#E8E8E5" strokeWidth=".8" fill="none" opacity=".06" />
|
|
319
|
+
</g>
|
|
320
|
+
<g className="login-orbit-bead">
|
|
321
|
+
<circle cx="350" cy="190" r="3.5" fill="#C2452A" />
|
|
322
|
+
</g>
|
|
323
|
+
<g className="login-orbit-bead login-orbit-bead--outer">
|
|
324
|
+
<circle cx="350" cy="30" r="2.5" fill="#E8E8E5" opacity=".5" />
|
|
325
|
+
</g>
|
|
326
|
+
</svg>
|
|
327
|
+
</div>
|
|
328
|
+
<div className="login-brand-lockup">
|
|
329
|
+
<svg className="login-mark" width="40" height="40" viewBox="0 0 100 100" aria-hidden="true">
|
|
330
|
+
<path className="lm-arc" d="M 85.32 31.22 A 40 40 0 1 1 78.78 22.20" stroke="#E8E8E5" strokeWidth="2.4" fill="none" strokeLinecap="round" />
|
|
331
|
+
<line className="lm-x1" x1="21.72" y1="21.72" x2="78.28" y2="78.28" stroke="#E8E8E5" strokeWidth="2.4" strokeLinecap="round" />
|
|
332
|
+
<line className="lm-x2" x1="21.72" y1="78.28" x2="78.28" y2="21.72" stroke="#E8E8E5" strokeWidth="2.4" strokeLinecap="round" />
|
|
333
|
+
<circle className="lm-bead" cx="82.36" cy="26.49" r="3" fill="#C2452A" />
|
|
334
|
+
</svg>
|
|
335
|
+
<div className="login-wordmark">madar<span>X</span> OS</div>
|
|
336
|
+
</div>
|
|
337
|
+
<p className="login-kicker">Core operating layer</p>
|
|
338
|
+
<h1>AI does the work. You hold the controls.</h1>
|
|
339
|
+
<p className="login-lede">madarX OS is the operating layer for AI-run operations. Agents draft, plan, and execute — every consequential action waits for a human, and nothing happens off the record.</p>
|
|
320
340
|
<div className="login-proof-grid">
|
|
321
|
-
<div><b>
|
|
322
|
-
<div><b>
|
|
323
|
-
<div><b>
|
|
341
|
+
<div><b>Human in the loop</b><span>Agents propose. People approve. The HAIL methodology, built in.</span></div>
|
|
342
|
+
<div><b>One operating logic</b><span>Workflows, governance, and orchestration in a single layer.</span></div>
|
|
343
|
+
<div><b>Every action logged</b><span>Nothing is inferred. Creation, access, and approval are recorded.</span></div>
|
|
324
344
|
</div>
|
|
325
345
|
</section>
|
|
326
346
|
<section className="login-card" aria-label="Sign in">
|
package/lib/tts.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Text-to-speech domain layer.
|
|
2
2
|
//
|
|
3
|
-
// Providers: 'openai' (default — uses `tts-1` / `tts-1-hd`)
|
|
3
|
+
// Providers: 'openai' (default — uses `tts-1` / `tts-1-hd`), 'elevenlabs',
|
|
4
|
+
// and 'local' (env-driven HTTP slot for self-hosted engines such as MisoTTS).
|
|
4
5
|
// Returns the raw audio buffer plus mime metadata. When `save_to_disk` is
|
|
5
6
|
// requested AND a project_id is supplied, writes an artifact under
|
|
6
7
|
// data/disk/<project>/voice/ mirroring the transcribeFile pattern.
|
|
@@ -16,7 +17,7 @@ import { wrapFetch } from './egress.js';
|
|
|
16
17
|
import { uploadFile, getRootFolder, createFolder } from './disk.js';
|
|
17
18
|
import { getProject } from './projects.js';
|
|
18
19
|
|
|
19
|
-
export const TTS_PROVIDERS = ['openai', 'elevenlabs'];
|
|
20
|
+
export const TTS_PROVIDERS = ['openai', 'elevenlabs', 'local'];
|
|
20
21
|
export const DEFAULT_OPENAI_TTS_MODEL = 'tts-1';
|
|
21
22
|
export const DEFAULT_OPENAI_VOICE = 'alloy';
|
|
22
23
|
export const DEFAULT_ELEVENLABS_MODEL = 'eleven_multilingual_v2';
|
|
@@ -24,6 +25,11 @@ export const DEFAULT_ELEVENLABS_VOICE_ID = '21m00Tcm4TlvDq8ikWAM'; // Rachel —
|
|
|
24
25
|
|
|
25
26
|
const OPENAI_VOICES = new Set(['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer']);
|
|
26
27
|
|
|
28
|
+
function localTtsUrl() {
|
|
29
|
+
const value = process.env.MADARX_LOCAL_TTS_URL;
|
|
30
|
+
return value && /^https?:\/\//i.test(value.trim()) ? value.trim() : null;
|
|
31
|
+
}
|
|
32
|
+
|
|
27
33
|
function ensureVoiceFolder(projectId) {
|
|
28
34
|
const db = getDb();
|
|
29
35
|
const root = getRootFolder(projectId);
|
|
@@ -130,12 +136,75 @@ async function synthesizeElevenLabs({ text, voice, model, format, fetchFn }) {
|
|
|
130
136
|
};
|
|
131
137
|
}
|
|
132
138
|
|
|
139
|
+
async function synthesizeLocal({ text, voice, model, format, fetchFn }) {
|
|
140
|
+
const url = localTtsUrl();
|
|
141
|
+
if (!url) throw new Error('MADARX_LOCAL_TTS_URL missing for local TTS');
|
|
142
|
+
const useFormat = format || 'wav';
|
|
143
|
+
const useModel = model || process.env.MADARX_LOCAL_TTS_MODEL || 'local';
|
|
144
|
+
const useVoice = voice || process.env.MADARX_LOCAL_TTS_VOICE || 'default';
|
|
145
|
+
|
|
146
|
+
let res;
|
|
147
|
+
try {
|
|
148
|
+
res = await fetchFn(url, {
|
|
149
|
+
method: 'POST',
|
|
150
|
+
headers: {
|
|
151
|
+
'Content-Type': 'application/json',
|
|
152
|
+
Accept: useFormat === 'mp3' ? 'audio/mpeg,application/json' : 'audio/wav,audio/*,application/json',
|
|
153
|
+
},
|
|
154
|
+
body: JSON.stringify({
|
|
155
|
+
text,
|
|
156
|
+
voice: useVoice,
|
|
157
|
+
model: useModel,
|
|
158
|
+
format: useFormat,
|
|
159
|
+
}),
|
|
160
|
+
});
|
|
161
|
+
} catch (err) {
|
|
162
|
+
throw new Error(`local tts failed: ${maskMessage(err?.message)}`);
|
|
163
|
+
}
|
|
164
|
+
if (!res.ok) {
|
|
165
|
+
let detail = '';
|
|
166
|
+
try { detail = (await res.text()).slice(0, 256); } catch {}
|
|
167
|
+
throw new Error(`local tts http ${res.status}: ${detail}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const contentType = String(res.headers.get('content-type') || '').toLowerCase();
|
|
171
|
+
if (contentType.includes('application/json')) {
|
|
172
|
+
let payload;
|
|
173
|
+
try { payload = await res.json(); } catch {
|
|
174
|
+
throw new Error('local tts returned invalid JSON');
|
|
175
|
+
}
|
|
176
|
+
const b64 = payload?.audio_base64 || payload?.audio;
|
|
177
|
+
if (!b64) throw new Error('local tts JSON must include audio_base64');
|
|
178
|
+
const mime = payload.mime_type || payload.content_type || (useFormat === 'mp3' ? 'audio/mpeg' : 'audio/wav');
|
|
179
|
+
const ext = payload.extension || (String(mime).includes('mpeg') || String(mime).includes('mp3') ? 'mp3' : 'wav');
|
|
180
|
+
return {
|
|
181
|
+
audio_buffer: Buffer.from(String(b64), 'base64'),
|
|
182
|
+
mime_type: mime,
|
|
183
|
+
extension: ext,
|
|
184
|
+
provider: 'local',
|
|
185
|
+
voice: payload.voice || useVoice,
|
|
186
|
+
model: payload.model || useModel,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
191
|
+
const isMp3 = contentType.includes('mpeg') || contentType.includes('mp3') || useFormat === 'mp3';
|
|
192
|
+
return {
|
|
193
|
+
audio_buffer: buffer,
|
|
194
|
+
mime_type: contentType || (isMp3 ? 'audio/mpeg' : 'audio/wav'),
|
|
195
|
+
extension: isMp3 ? 'mp3' : 'wav',
|
|
196
|
+
provider: 'local',
|
|
197
|
+
voice: useVoice,
|
|
198
|
+
model: useModel,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
133
202
|
/**
|
|
134
203
|
* Synthesize speech.
|
|
135
204
|
*
|
|
136
205
|
* @param {{
|
|
137
206
|
* text: string,
|
|
138
|
-
* provider?: 'openai' | 'elevenlabs',
|
|
207
|
+
* provider?: 'openai' | 'elevenlabs' | 'local',
|
|
139
208
|
* voice?: string,
|
|
140
209
|
* model?: string,
|
|
141
210
|
* format?: 'mp3' | 'wav',
|
|
@@ -156,11 +225,11 @@ export async function synthesizeSpeech(opts = {}) {
|
|
|
156
225
|
if (!text) throw new Error('text is required');
|
|
157
226
|
if (text.length > 4000) throw new Error('text too long: max 4000 characters');
|
|
158
227
|
|
|
159
|
-
const providerHint = String(opts.provider || process.env.TTS_DEFAULT_PROVIDER || 'openai').toLowerCase();
|
|
228
|
+
const providerHint = String(opts.provider || process.env.MADARX_VOICE_DEFAULT_PROVIDER || process.env.TTS_DEFAULT_PROVIDER || 'openai').toLowerCase();
|
|
160
229
|
const provider = TTS_PROVIDERS.includes(providerHint) ? providerHint : 'openai';
|
|
161
230
|
const fetchFn = wrapFetch('voice_speak', opts.agent_id ?? null, opts.fetch || fetch);
|
|
162
231
|
|
|
163
|
-
const synth = provider === 'elevenlabs' ? synthesizeElevenLabs : synthesizeOpenAi;
|
|
232
|
+
const synth = provider === 'elevenlabs' ? synthesizeElevenLabs : provider === 'local' ? synthesizeLocal : synthesizeOpenAi;
|
|
164
233
|
const result = await synth({ text, voice: opts.voice, model: opts.model, format: opts.format, fetchFn });
|
|
165
234
|
|
|
166
235
|
// Rough estimate: ~14 chars per second of speech at default rate.
|
|
@@ -221,5 +290,6 @@ export function ttsProvidersConfigured() {
|
|
|
221
290
|
return {
|
|
222
291
|
openai: Boolean(getSecret('OPENAI_API_KEY') || process.env.OPENAI_API_KEY),
|
|
223
292
|
elevenlabs: Boolean(getSecret('ELEVENLABS_API_KEY') || process.env.ELEVENLABS_API_KEY),
|
|
293
|
+
local: Boolean(localTtsUrl()),
|
|
224
294
|
};
|
|
225
295
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Minimal local HTTP bridge for MisoLabsAI/MisoTTS.
|
|
3
|
+
|
|
4
|
+
Run this outside the Next.js process and point Madarx at it:
|
|
5
|
+
|
|
6
|
+
git clone https://github.com/MisoLabsAI/MisoTTS.git ~/MisoTTS
|
|
7
|
+
cd ~/MisoTTS
|
|
8
|
+
uv sync --python 3.10
|
|
9
|
+
MISO_TTS_REPO_DIR=$PWD uv run python /path/to/madarx-os/scripts/misotts-local-server.py
|
|
10
|
+
MADARX_LOCAL_TTS_URL=http://127.0.0.1:8799/tts MADARX_VOICE_DEFAULT_PROVIDER=local npm run dev
|
|
11
|
+
|
|
12
|
+
POST /tts with JSON {"text":"...","voice":"0","format":"wav"} returns audio/wav.
|
|
13
|
+
The model is loaded lazily on first request and cached in-process.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import sys
|
|
21
|
+
import tempfile
|
|
22
|
+
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
# MisoTTS is intentionally not vendored into Madarx. Point at a local clone or
|
|
27
|
+
# install it into this Python environment with `pip install -e /path/to/MisoTTS`.
|
|
28
|
+
_repo_dir = os.environ.get("MISO_TTS_REPO_DIR")
|
|
29
|
+
if _repo_dir:
|
|
30
|
+
sys.path.insert(0, _repo_dir)
|
|
31
|
+
|
|
32
|
+
os.environ.setdefault("HF_HUB_ETAG_TIMEOUT", "60")
|
|
33
|
+
os.environ.setdefault("HF_HUB_DOWNLOAD_TIMEOUT", "60")
|
|
34
|
+
os.environ.setdefault("NO_TORCH_COMPILE", "1")
|
|
35
|
+
|
|
36
|
+
_generator: Any | None = None
|
|
37
|
+
_torch: Any | None = None
|
|
38
|
+
_torchaudio: Any | None = None
|
|
39
|
+
_segment_cls: Any | None = None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _load_generator():
|
|
43
|
+
global _generator, _torch, _torchaudio, _segment_cls
|
|
44
|
+
if _generator is not None:
|
|
45
|
+
return _generator
|
|
46
|
+
|
|
47
|
+
import torch # type: ignore
|
|
48
|
+
import torchaudio # type: ignore
|
|
49
|
+
from generator import DEFAULT_MISO_TTS_REPO_ID, load_miso_8b, Segment # type: ignore
|
|
50
|
+
|
|
51
|
+
device = os.environ.get("MISO_TTS_DEVICE") or ("cuda" if torch.cuda.is_available() else "cpu")
|
|
52
|
+
model_source = os.environ.get("MISO_TTS_8B_MODEL", DEFAULT_MISO_TTS_REPO_ID)
|
|
53
|
+
_generator = load_miso_8b(device=device, model_path_or_repo_id=model_source)
|
|
54
|
+
_torch = torch
|
|
55
|
+
_torchaudio = torchaudio
|
|
56
|
+
_segment_cls = Segment
|
|
57
|
+
return _generator
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _speaker_id(raw: Any) -> int:
|
|
61
|
+
if raw is None or raw == "":
|
|
62
|
+
return 0
|
|
63
|
+
if isinstance(raw, int):
|
|
64
|
+
return raw
|
|
65
|
+
value = str(raw).strip().lower()
|
|
66
|
+
if value.startswith("speaker-"):
|
|
67
|
+
value = value.split("-", 1)[1]
|
|
68
|
+
try:
|
|
69
|
+
return int(value)
|
|
70
|
+
except ValueError:
|
|
71
|
+
return 0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class Handler(BaseHTTPRequestHandler):
|
|
75
|
+
server_version = "MadarxMisoTTS/0.1"
|
|
76
|
+
|
|
77
|
+
def _json(self, status: int, payload: dict[str, Any]) -> None:
|
|
78
|
+
data = json.dumps(payload).encode("utf-8")
|
|
79
|
+
self.send_response(status)
|
|
80
|
+
self.send_header("Content-Type", "application/json")
|
|
81
|
+
self.send_header("Content-Length", str(len(data)))
|
|
82
|
+
self.end_headers()
|
|
83
|
+
self.wfile.write(data)
|
|
84
|
+
|
|
85
|
+
def do_GET(self) -> None: # noqa: N802 - stdlib handler name
|
|
86
|
+
if self.path.rstrip("/") in ("", "/health"):
|
|
87
|
+
self._json(200, {"ok": True, "provider": "misotts", "loaded": _generator is not None})
|
|
88
|
+
return
|
|
89
|
+
self._json(404, {"error": "not_found"})
|
|
90
|
+
|
|
91
|
+
def do_POST(self) -> None: # noqa: N802 - stdlib handler name
|
|
92
|
+
if self.path.rstrip("/") != "/tts":
|
|
93
|
+
self._json(404, {"error": "not_found"})
|
|
94
|
+
return
|
|
95
|
+
try:
|
|
96
|
+
length = int(self.headers.get("Content-Length", "0"))
|
|
97
|
+
body = json.loads(self.rfile.read(length).decode("utf-8"))
|
|
98
|
+
except Exception as exc: # pragma: no cover - defensive request parsing
|
|
99
|
+
self._json(400, {"error": f"invalid_json: {exc}"})
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
text = str(body.get("text") or "").strip()
|
|
103
|
+
if not text:
|
|
104
|
+
self._json(400, {"error": "text is required"})
|
|
105
|
+
return
|
|
106
|
+
if len(text) > int(os.environ.get("MISO_TTS_MAX_CHARS", "800")):
|
|
107
|
+
self._json(413, {"error": "text too long for local MisoTTS bridge"})
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
try:
|
|
111
|
+
generator = _load_generator()
|
|
112
|
+
if generator is None:
|
|
113
|
+
raise RuntimeError("MisoTTS generator did not initialize")
|
|
114
|
+
torchaudio = _torchaudio
|
|
115
|
+
if torchaudio is None:
|
|
116
|
+
raise RuntimeError("torchaudio did not initialize")
|
|
117
|
+
audio = generator.generate(
|
|
118
|
+
text=text,
|
|
119
|
+
speaker=_speaker_id(body.get("voice")),
|
|
120
|
+
context=[],
|
|
121
|
+
max_audio_length_ms=int(body.get("max_audio_length_ms") or os.environ.get("MISO_TTS_MAX_AUDIO_MS", "10000")),
|
|
122
|
+
)
|
|
123
|
+
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp:
|
|
124
|
+
tmp_path = Path(tmp.name)
|
|
125
|
+
try:
|
|
126
|
+
torchaudio.save(str(tmp_path), audio.unsqueeze(0).cpu(), generator.sample_rate)
|
|
127
|
+
data = tmp_path.read_bytes()
|
|
128
|
+
finally:
|
|
129
|
+
tmp_path.unlink(missing_ok=True)
|
|
130
|
+
except Exception as exc:
|
|
131
|
+
self._json(500, {"error": f"misotts_generation_failed: {exc}"})
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
self.send_response(200)
|
|
135
|
+
self.send_header("Content-Type", "audio/wav")
|
|
136
|
+
self.send_header("Content-Length", str(len(data)))
|
|
137
|
+
self.send_header("X-Provider", "misotts")
|
|
138
|
+
self.end_headers()
|
|
139
|
+
self.wfile.write(data)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def main() -> None:
|
|
143
|
+
host = os.environ.get("MISO_TTS_HOST", "127.0.0.1")
|
|
144
|
+
port = int(os.environ.get("MISO_TTS_PORT", "8799"))
|
|
145
|
+
print(f"MisoTTS local bridge listening on http://{host}:{port}/tts", flush=True)
|
|
146
|
+
ThreadingHTTPServer((host, port), Handler).serve_forever()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
if __name__ == "__main__":
|
|
150
|
+
main()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4520],{30407:(e,t,n)=>{Promise.resolve().then(n.bind(n,57622))},57622:(e,t,n)=>{"use strict";n.d(t,{default:()=>u});var a=n(95155),s=n(12115),i=n(95704);function o(){return(0,a.jsx)("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:(0,a.jsx)("path",{d:"M5 12h14M12 5l7 7-7 7"})})}function l(){return(0,a.jsxs)("svg",{width:"18",height:"18",viewBox:"0 0 24 24","aria-hidden":"true",children:[(0,a.jsx)("path",{fill:"#4285F4",d:"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"}),(0,a.jsx)("path",{fill:"#34A853",d:"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"}),(0,a.jsx)("path",{fill:"#FBBC05",d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),(0,a.jsx)("path",{fill:"#EA4335",d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]})}function r(){return(0,a.jsxs)("svg",{width:"18",height:"18",viewBox:"0 0 24 24","aria-hidden":"true",children:[(0,a.jsx)("rect",{x:"1",y:"1",width:"10",height:"10",fill:"#f25022"}),(0,a.jsx)("rect",{x:"13",y:"1",width:"10",height:"10",fill:"#7fba00"}),(0,a.jsx)("rect",{x:"1",y:"13",width:"10",height:"10",fill:"#00a4ef"}),(0,a.jsx)("rect",{x:"13",y:"13",width:"10",height:"10",fill:"#ffb900"})]})}let c={width:"100%",padding:"13px 14px",borderRadius:14,border:"1px solid rgba(232,232,229,.18)",background:"rgba(255,255,255,.06)",color:"#E8E8E5",outline:"none",fontSize:14},d={width:"100%",minHeight:46,border:0,borderRadius:14,background:"#E8E8E5",color:"#0F0F11",fontWeight:800,display:"inline-flex",alignItems:"center",justifyContent:"center",gap:8,cursor:"pointer",letterSpacing:"-0.01em"},h={...d,background:"rgba(232,232,229,.06)",color:"#E8E8E5",border:"1px solid rgba(232,232,229,.16)"};function u(e){let{authMode:t,nextPath:u="/",errorCode:p="",forceSupabase:g=!1,initialView:m=""}=e,x="local"===t,y="string"==typeof u&&u.startsWith("/")?u:"/",[j,f]=(0,s.useState)("personal"===m||"team"===m?m:x&&!g?"personal":"team"),[b,v]=(0,s.useState)("password"),[w,S]=(0,s.useState)(""),[k,C]=(0,s.useState)(""),[N,E]=(0,s.useState)(!1),[O,T]=(0,s.useState)(p?"Supabase could not complete sign-in. Try again.":""),[_,A]=(0,s.useState)(null),[L,K]=(0,s.useState)(!1),[P,I]=(0,s.useState)(!1),[B,R]=(0,s.useState)(""),[U,M]=(0,s.useState)(""),[F,z]=(0,s.useState)({url:"",anonKey:"",serviceKey:""}),[W,D]=(0,s.useState)("");(0,s.useEffect)(()=>{let e=!0;return fetch("/api/auth/config",{cache:"no-store"}).then(e=>e.json()).then(t=>{e&&A(t)}).catch(()=>{e&&A({authMode:t,supabaseConfigured:!1})}),()=>{e=!1}},[t]);let H=!!((null==_?void 0:_.supabaseUrl)&&(null==_?void 0:_.supabaseAnonKey)),X=!x||g||H;async function J(){if(!B.trim())return void T("Enter the recovery token to switch.");K(!0),T("");try{let e=await fetch("/api/auth/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"save",mode:"local",recoveryToken:B.trim()})}),t=await e.json().catch(()=>({}));if(e.ok&&t.ok)return void window.location.assign("/");K(!1),T(403===e.status?"Invalid recovery token.":"Could not switch to personal mode.")}catch(e){K(!1),T("Could not switch to personal mode.")}}async function q(e){e.preventDefault(),D("save"),T("");try{let e=await fetch("/api/auth/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"save",mode:"supabase",url:F.url.trim(),anonKey:F.anonKey.trim(),serviceKey:F.serviceKey.trim()})}),t=await e.json().catch(()=>({}));if(!e.ok||!t.ok)throw Error("connection_failed"===t.error?"Could not connect to that Supabase project. Check the URL and keys.":t.error||"Could not save team settings.");A(e=>({...e||{},authMode:"supabase",supabaseConfigured:!0,supabaseUrl:F.url.trim(),supabaseAnonKey:F.anonKey.trim()})),T("Team created. Sign in to finish — your first sign-in makes you the owner.")}catch(e){T((null==e?void 0:e.message)||"Could not create the team.")}finally{D("")}}async function G(){D("test"),T("");try{let e=await fetch("/api/auth/config",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"test",url:F.url.trim(),anonKey:F.anonKey.trim()})}),t=await e.json().catch(()=>({}));T(t.ok?"Connection OK. Create the team to continue.":"Connection failed. Check the URL and anon key.")}catch(e){T("Connection test failed.")}finally{D("")}}async function Y(){let{createBrowserClient:e}=await Promise.all([n.e(5730),n.e(840)]).then(n.bind(n,9230)),t=null==_?void 0:_.supabaseUrl,a=null==_?void 0:_.supabaseAnonKey;if(!t||!a)throw Error("Supabase is not configured. Create a team or set it in Settings → Account.");return e(t,a)}async function V(e){e.preventDefault(),E(!0),T("");try{let e=await Y(),t="".concat(window.location.origin,"/api/auth/callback?next=").concat(encodeURIComponent(y)),n="magic"===b?await e.auth.signInWithOtp({email:w,options:{emailRedirectTo:t}}):await e.auth.signInWithPassword({email:w,password:k});if(n.error)throw n.error;"magic"===b?T("Secure sign-in link sent to ".concat(w,".")):window.location.assign(y)}catch(e){T((null==e?void 0:e.message)||"Sign-in failed.")}finally{E(!1)}}async function Q(e){E(!0),T("");try{let t=await Y(),{error:n}=await t.auth.signInWithOAuth({provider:e,options:{redirectTo:"".concat(window.location.origin,"/api/auth/callback?next=").concat(encodeURIComponent(y))}});if(n)throw n}catch(e){T((null==e?void 0:e.message)||"SSO failed."),E(!1)}}return(0,a.jsxs)("main",{className:"login-page-shell",children:[(0,a.jsxs)("section",{className:"login-hero-panel","aria-label":"madarX OS landing",children:[(0,a.jsxs)("div",{className:"login-wordmark",children:["madar",(0,a.jsx)("span",{children:"X"})," OS"]}),(0,a.jsx)("p",{className:"login-kicker",children:"Institutional agent control plane"}),(0,a.jsx)("h1",{children:"AI generates. Humans approve. Regulators can inspect."}),(0,a.jsx)("p",{className:"login-lede",children:"Run it personally on your machine, or set up an organization boundary with Supabase and share generated HTML artifacts through signed, expiring access links."}),(0,a.jsxs)("div",{className:"login-proof-grid",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("b",{children:"Personal or team"}),(0,a.jsx)("span",{children:"Local-first by default. Add Supabase when you want an org."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("b",{children:"Artifact ACLs"}),(0,a.jsx)("span",{children:"Private, organization, team-ready, and link-scoped controls."})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("b",{children:"Audit ledger"}),(0,a.jsx)("span",{children:"Share creation, access, and revocation are recorded."})]})]})]}),(0,a.jsxs)("section",{className:"login-card","aria-label":"Sign in",children:[(0,a.jsxs)("div",{className:"login-seg",role:"tablist","aria-label":"Account type",children:[(0,a.jsx)("button",{type:"button",role:"tab","aria-selected":"personal"===j,className:"personal"===j?"active":"",onClick:()=>f("personal"),children:"Personal"}),(0,a.jsx)("button",{type:"button",role:"tab","aria-selected":"team"===j,className:"team"===j?"active":"",onClick:()=>f("team"),children:"Team"})]}),"personal"===j?x&&!H?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"login-card-head",children:[(0,a.jsx)("p",{children:"This device"}),(0,a.jsx)("h2",{children:"Personal mode"})]}),(0,a.jsx)("p",{className:"login-footnote",style:{marginTop:0},children:"You're the local owner — no account needed. Work stays on this machine and sharing uses the local signed-link registry."}),O?(0,a.jsx)("div",{className:"login-message",children:O}):null,(0,a.jsxs)("a",{className:"login-link-button",href:y,style:{margin:"20px 0 0"},children:["Enter dashboard ",(0,a.jsx)(o,{})]}),(0,a.jsxs)("button",{type:"button",className:"login-link-button login-link-button--ghost",style:{margin:"12px 0 0",cursor:"pointer"},onClick:()=>{T(""),f("team")},children:["Create or join a team ",(0,a.jsx)(o,{})]}),(0,a.jsx)("p",{className:"login-footnote",style:{textAlign:"center"},children:"Collaborate with others through a shared Supabase organization."})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"login-card-head",children:[(0,a.jsx)("p",{children:"This device"}),(0,a.jsx)("h2",{children:"Use it personally"})]}),(0,a.jsxs)("div",{className:"login-message login-message--warn",children:["This server runs in ",(0,a.jsx)("b",{children:"team mode"}),". Switching to personal (local) mode turns off organization sign-in for everyone on this server, so it needs the on-disk recovery token."]}),O?(0,a.jsx)("div",{className:"login-message",children:O}):null,P?(0,a.jsxs)("div",{className:"login-form",children:[(0,a.jsxs)("label",{children:["Recovery token",(0,a.jsx)("input",{style:c,type:"text",value:B,onChange:e=>R(e.target.value),placeholder:"paste recovery token",autoComplete:"off"})]}),(0,a.jsxs)("span",{className:"login-footnote",style:{marginTop:0},children:["Found in ",(0,a.jsx)("code",{children:"data/.auth-recovery-token"})," on the server machine."]}),(0,a.jsx)("button",{type:"button",style:{...d,opacity:L?.65:1},disabled:L,onClick:J,children:L?"Switching…":"Switch to personal mode"})]}):(0,a.jsxs)("button",{type:"button",className:"login-link-button login-link-button--ghost",style:{cursor:"pointer"},onClick:()=>I(!0),children:["Switch to personal mode ",(0,a.jsx)(o,{})]})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"login-card-head",children:[(0,a.jsx)("p",{children:"Secure access"}),(0,a.jsx)("h2",{children:X?"Sign in to your team":"Set up your team"})]}),O?(0,a.jsx)("div",{className:"login-message",children:O}):null,X?(0,a.jsxs)(a.Fragment,{children:[x?(0,a.jsxs)("div",{className:"login-message login-message--warn",children:["Server is in ",(0,a.jsx)("b",{children:"local mode"}),". You can sign in to test, but sessions persist only after switching to team mode in ",(0,a.jsx)("a",{href:"/settings/account",children:"Settings → Account"}),"."]}):null,(0,a.jsxs)("div",{className:"login-mode-toggle",role:"tablist","aria-label":"Sign-in method",children:[(0,a.jsx)("button",{type:"button",className:"password"===b?"active":"",onClick:()=>v("password"),children:"Password"}),(0,a.jsx)("button",{type:"button",className:"magic"===b?"active":"",onClick:()=>v("magic"),children:"Magic link"})]}),(0,a.jsxs)("form",{onSubmit:V,className:"login-form",children:[(0,a.jsxs)("label",{children:["Email",(0,a.jsx)("input",{style:c,type:"email",value:w,onChange:e=>S(e.target.value),placeholder:"you@company.com",autoComplete:"email",required:!0})]}),"password"===b?(0,a.jsxs)("label",{children:["Password",(0,a.jsx)("input",{style:c,type:"password",value:k,onChange:e=>C(e.target.value),placeholder:"Password",autoComplete:"current-password",required:!0})]}):null,(0,a.jsxs)("button",{type:"submit",disabled:N,style:{...d,opacity:N?.65:1},children:[N?"Working...":"password"===b?"Sign in":"Send magic link"," ",N?null:(0,a.jsx)(o,{})]})]}),"true"===i.env.NEXT_PUBLIC_GOOGLE_SSO_ENABLED||"true"===i.env.NEXT_PUBLIC_MICROSOFT_SSO_ENABLED?(0,a.jsxs)("div",{className:"login-sso",children:[(0,a.jsx)("span",{children:"or continue with"}),"true"===i.env.NEXT_PUBLIC_GOOGLE_SSO_ENABLED?(0,a.jsxs)("button",{type:"button",onClick:()=>Q("google"),style:h,children:[(0,a.jsx)(l,{})," Google"]}):null,"true"===i.env.NEXT_PUBLIC_MICROSOFT_SSO_ENABLED?(0,a.jsxs)("button",{type:"button",onClick:()=>Q("azure"),style:h,children:[(0,a.jsx)(r,{})," Microsoft"]}):null]}):null]}):(0,a.jsxs)("form",{className:"login-form login-create-team",onSubmit:q,children:[(0,a.jsx)("p",{className:"login-footnote",style:{marginTop:0},children:"Connect a Supabase project to host your team. Your first sign-in becomes the owner. Keys are stored encrypted on this server, never in the browser."}),(0,a.jsxs)("label",{children:["Supabase URL",(0,a.jsx)("input",{style:c,type:"url",value:F.url,onChange:e=>z(t=>({...t,url:e.target.value})),placeholder:"https://xxxx.supabase.co",autoComplete:"off",required:!0})]}),(0,a.jsxs)("label",{children:["Anon key",(0,a.jsx)("input",{style:c,type:"text",value:F.anonKey,onChange:e=>z(t=>({...t,anonKey:e.target.value})),placeholder:"eyJ…",autoComplete:"off",required:!0})]}),(0,a.jsxs)("label",{children:["Service-role key",(0,a.jsx)("input",{style:c,type:"password",value:F.serviceKey,onChange:e=>z(t=>({...t,serviceKey:e.target.value})),placeholder:"eyJ… (kept server-side)",autoComplete:"off",required:!0})]}),(0,a.jsxs)("div",{className:"login-create-actions",children:[(0,a.jsx)("button",{type:"button",style:{...h,width:"auto",flex:"0 0 auto",padding:"0 16px"},disabled:!!W,onClick:G,children:"test"===W?"Testing…":"Test"}),(0,a.jsxs)("button",{type:"submit",style:{...d,opacity:W?.65:1},disabled:!!W,children:["save"===W?"Creating…":"Create team"," ",W?null:(0,a.jsx)(o,{})]})]})]}),(0,a.jsxs)("div",{className:"login-join",children:[(0,a.jsx)("span",{className:"login-join-label",children:"Have an invite link?"}),(0,a.jsxs)("form",{className:"login-join-row",onSubmit:function(e){e.preventDefault();let t=U.trim();if(!t)return void T("Paste your invite link first.");let n="#invite=",a=t.indexOf(n),s=a>=0?t.slice(a+n.length):t;if(!(s=s.split(/[?&\s]/)[0]))return void T("That invite link looks incomplete.");window.location.href="/join#invite=".concat(s)},children:[(0,a.jsx)("input",{style:c,type:"text",value:U,onChange:e=>M(e.target.value),placeholder:"paste invite link",autoComplete:"off"}),(0,a.jsx)("button",{type:"submit",style:{...h,width:"auto",flex:"0 0 auto",padding:"0 18px",whiteSpace:"nowrap"},children:"Join"})]})]}),X?(0,a.jsx)("p",{className:"login-footnote",children:"Supabase stores identity. madarX OS stores local runtime state, artifact ACLs, and share-link audit events."}):null]})]})]})}}},e=>{e.O(0,[8441,1255,7358],()=>e(e.s=30407)),_N_E=e.O()}]);
|