manigent-server 0.1.0__py3-none-any.whl
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.
- manigent/_catalog/mcps/chess/README.md +38 -0
- manigent/_catalog/mcps/chess/mcp.json +9 -0
- manigent/_catalog/mcps/registry.json +9 -0
- manigent/_catalog/skills/brief/SKILL.md +339 -0
- manigent/_catalog/skills/broaden-options/SKILL.md +133 -0
- manigent/_catalog/skills/calendar/SKILL.md +44 -0
- manigent/_catalog/skills/calendar/starter_config.jsonc +25 -0
- manigent/_catalog/skills/gmail/SKILL.md +73 -0
- manigent/_catalog/skills/google-calendar/SKILL.md +44 -0
- manigent/_catalog/skills/google-drive/SKILL.md +42 -0
- manigent/_catalog/skills/google-drive-write/SKILL.md +45 -0
- manigent/_catalog/skills/google-drive-write/starter_config.jsonc +45 -0
- manigent/_catalog/skills/grill-me/SKILL.md +173 -0
- manigent/_catalog/skills/homekit/SKILL.md +37 -0
- manigent/_catalog/skills/http-api/SKILL.md +117 -0
- manigent/_catalog/skills/ib/SKILL.md +89 -0
- manigent/_catalog/skills/ib/starter_config.jsonc +35 -0
- manigent/_catalog/skills/mailbox/SKILL.md +47 -0
- manigent/_catalog/skills/mailbox/starter_config.jsonc +38 -0
- manigent/_catalog/skills/media/SKILL.md +93 -0
- manigent/_catalog/skills/media/starter_config.jsonc +63 -0
- manigent/_catalog/skills/osxphotos/SKILL.md +41 -0
- manigent/_catalog/skills/photo-story/SKILL.md +285 -0
- manigent/_catalog/skills/playwright-browser/SKILL.md +291 -0
- manigent/_catalog/skills/playwright-browser/starter_config.jsonc +44 -0
- manigent/_catalog/skills/playwright-save-skill/SKILL.md +149 -0
- manigent/_catalog/skills/registry.json +166 -0
- manigent/_catalog/skills/web-artifacts/SKILL.md +194 -0
- manigent/api/action_executor.py +404 -0
- manigent/api/action_validator.py +531 -0
- manigent/api/actions.py +221 -0
- manigent/api/client.py +558 -0
- manigent/api/control.py +806 -0
- manigent/api/edge_protocol.py +123 -0
- manigent/api/fs_protocol.py +450 -0
- manigent/api/host_protocol.py +298 -0
- manigent/api/managed_job_client.py +124 -0
- manigent/api/responses.py +342 -0
- manigent/api/retry_transport.py +178 -0
- manigent/api/turn_protocol.py +78 -0
- manigent/cli_lifecycle.py +467 -0
- manigent/cli_server.py +978 -0
- manigent/doctor.py +1167 -0
- manigent/hub_protocol/canonical.py +375 -0
- manigent/hub_protocol/codes.py +171 -0
- manigent/hub_protocol/constants.py +71 -0
- manigent/hub_protocol/envelope.py +218 -0
- manigent/hub_protocol/frames.py +788 -0
- manigent/hub_protocol/http.py +260 -0
- manigent/hub_protocol/ids.py +170 -0
- manigent/hub_protocol/keys.py +195 -0
- manigent/hub_protocol/text.py +75 -0
- manigent/llm/base.py +1072 -0
- manigent/llm/prompt_builder.py +2450 -0
- manigent/llm/triggers.py +68 -0
- manigent/models/agent.py +2905 -0
- manigent/models/agent_bundle.py +298 -0
- manigent/models/brief_tab.py +311 -0
- manigent/models/chat_message.py +231 -0
- manigent/models/chatroom.py +1108 -0
- manigent/models/context.py +1159 -0
- manigent/models/desk_label.py +836 -0
- manigent/models/desk_read_state.py +220 -0
- manigent/models/desk_sign_off.py +267 -0
- manigent/models/desk_sop.py +965 -0
- manigent/models/desk_todo.py +1603 -0
- manigent/models/desk_todo_link.py +404 -0
- manigent/models/file_cache.py +75 -0
- manigent/models/host.py +732 -0
- manigent/models/install_token.py +401 -0
- manigent/models/invitation_code.py +162 -0
- manigent/models/knowledge_pack.py +552 -0
- manigent/models/managed_job.py +295 -0
- manigent/models/model_config.py +564 -0
- manigent/models/model_defaults.py +238 -0
- manigent/models/onboarding_plan.py +161 -0
- manigent/models/participant.py +449 -0
- manigent/models/persistable.py +892 -0
- manigent/models/plan_markdown.py +1774 -0
- manigent/models/project.py +1343 -0
- manigent/models/project_plan.py +8104 -0
- manigent/models/project_report.py +145 -0
- manigent/models/provenance.py +261 -0
- manigent/models/provider_agents.py +101 -0
- manigent/models/public_request.py +108 -0
- manigent/models/reflection_schedule.py +191 -0
- manigent/models/scheduled_message.py +285 -0
- manigent/models/share_token.py +190 -0
- manigent/models/skill_version.py +31 -0
- manigent/models/sop_template.py +187 -0
- manigent/models/thinking_partner_plan.py +187 -0
- manigent/models/tunnel_binding.py +129 -0
- manigent/models/user.py +1276 -0
- manigent/models/work_tracker.py +510 -0
- manigent/runner/invocation_registry.py +187 -0
- manigent/server/agent_capabilities.py +119 -0
- manigent/server/agent_visibility.py +119 -0
- manigent/server/announcements.py +119 -0
- manigent/server/app.py +807 -0
- manigent/server/auth.py +355 -0
- manigent/server/batch_timeout.py +94 -0
- manigent/server/channels/access.py +194 -0
- manigent/server/channels/adapter.py +295 -0
- manigent/server/channels/config.py +693 -0
- manigent/server/channels/contacts.py +39 -0
- manigent/server/channels/email_adapter.py +436 -0
- manigent/server/channels/email_address.py +145 -0
- manigent/server/channels/email_form.py +242 -0
- manigent/server/channels/email_format.py +285 -0
- manigent/server/channels/email_mail.py +427 -0
- manigent/server/channels/email_mailgun.py +164 -0
- manigent/server/channels/email_text.py +280 -0
- manigent/server/channels/file_links.py +127 -0
- manigent/server/channels/gateway.py +2998 -0
- manigent/server/channels/hub_delivery.py +211 -0
- manigent/server/channels/hub_store.py +1730 -0
- manigent/server/channels/line.py +645 -0
- manigent/server/channels/line_format.py +589 -0
- manigent/server/channels/log_redaction.py +145 -0
- manigent/server/channels/store.py +3316 -0
- manigent/server/channels/telegram.py +422 -0
- manigent/server/channels/telegram_format.py +312 -0
- manigent/server/channels/webchat.py +261 -0
- manigent/server/channels/webchat_widget.js +1310 -0
- manigent/server/channels/whatsapp.py +707 -0
- manigent/server/channels/whatsapp_format.py +511 -0
- manigent/server/chat_search_index.py +1203 -0
- manigent/server/config.py +61 -0
- manigent/server/context.py +121 -0
- manigent/server/coordinator_rule.py +115 -0
- manigent/server/desk_todo_notify.py +300 -0
- manigent/server/edge_hub.py +577 -0
- manigent/server/email.py +354 -0
- manigent/server/errors.py +83 -0
- manigent/server/home_fs_relay.py +392 -0
- manigent/server/hub/adapter.py +1395 -0
- manigent/server/hub/agent_send_guard.py +196 -0
- manigent/server/hub/avatar.py +342 -0
- manigent/server/hub/browser.py +778 -0
- manigent/server/hub/client.py +859 -0
- manigent/server/hub/demand.py +49 -0
- manigent/server/hub/directory.py +385 -0
- manigent/server/hub/enroll.py +400 -0
- manigent/server/hub/http.py +134 -0
- manigent/server/hub/identity.py +61 -0
- manigent/server/hub/keys.py +588 -0
- manigent/server/hub/mirror.py +802 -0
- manigent/server/hub/operator.py +817 -0
- manigent/server/hub/retain.py +361 -0
- manigent/server/hub/room_bridge.py +741 -0
- manigent/server/hub/runtime.py +691 -0
- manigent/server/hub/trust.py +182 -0
- manigent/server/hub/views.py +316 -0
- manigent/server/idempotency.py +205 -0
- manigent/server/in_flight_restore.py +181 -0
- manigent/server/inspection.py +816 -0
- manigent/server/isolation_gate.py +516 -0
- manigent/server/isolation_notice.py +310 -0
- manigent/server/managed_job_events.py +242 -0
- manigent/server/mcp_registry.py +118 -0
- manigent/server/message_forward.py +78 -0
- manigent/server/message_scheduler.py +176 -0
- manigent/server/notification_assets.py +164 -0
- manigent/server/oauth_login/cli_state.py +120 -0
- manigent/server/oauth_login/config.py +90 -0
- manigent/server/oauth_login/errors.py +78 -0
- manigent/server/oauth_login/flow.py +223 -0
- manigent/server/oauth_login/handoff.py +63 -0
- manigent/server/oauth_login/providers.py +45 -0
- manigent/server/oauth_state.py +81 -0
- manigent/server/owner_isolation.py +466 -0
- manigent/server/participant_liveness.py +82 -0
- manigent/server/public_profile.py +149 -0
- manigent/server/public_requests/candidates.py +116 -0
- manigent/server/public_requests/dispatch.py +121 -0
- manigent/server/public_requests/ranking.py +153 -0
- manigent/server/recent_activity.py +250 -0
- manigent/server/reflection_completion_subscriber.py +151 -0
- manigent/server/reflection_scheduler.py +239 -0
- manigent/server/requester_key_migration.py +261 -0
- manigent/server/room_flow.py +139 -0
- manigent/server/routes/_batch.py +218 -0
- manigent/server/routes/_fd_routing.py +155 -0
- manigent/server/routes/_mentions.py +70 -0
- manigent/server/routes/agent_env.py +188 -0
- manigent/server/routes/agent_fs.py +450 -0
- manigent/server/routes/agents.py +1206 -0
- manigent/server/routes/announcements.py +79 -0
- manigent/server/routes/auth.py +387 -0
- manigent/server/routes/brief_tabs.py +404 -0
- manigent/server/routes/changelog.py +237 -0
- manigent/server/routes/channels.py +993 -0
- manigent/server/routes/chatrooms.py +871 -0
- manigent/server/routes/desk_labels.py +298 -0
- manigent/server/routes/desk_latest_messages.py +116 -0
- manigent/server/routes/desk_read_state.py +110 -0
- manigent/server/routes/desk_sign_off.py +88 -0
- manigent/server/routes/desk_sops.py +216 -0
- manigent/server/routes/desk_todos.py +692 -0
- manigent/server/routes/desk_tour.py +44 -0
- manigent/server/routes/files.py +572 -0
- manigent/server/routes/hosts.py +484 -0
- manigent/server/routes/hub.py +534 -0
- manigent/server/routes/hub_channels.py +234 -0
- manigent/server/routes/inbox.py +581 -0
- manigent/server/routes/install.ps1 +436 -0
- manigent/server/routes/install.py +324 -0
- manigent/server/routes/install.sh +566 -0
- manigent/server/routes/isolation_check.py +145 -0
- manigent/server/routes/knowledge_packs.py +477 -0
- manigent/server/routes/managed_jobs.py +196 -0
- manigent/server/routes/mcps.py +271 -0
- manigent/server/routes/messages.py +1972 -0
- manigent/server/routes/model_defaults.py +279 -0
- manigent/server/routes/oauth.py +237 -0
- manigent/server/routes/oauth_login.py +351 -0
- manigent/server/routes/owner_isolation.py +91 -0
- manigent/server/routes/project_plans.py +1521 -0
- manigent/server/routes/project_reports.py +235 -0
- manigent/server/routes/projects.py +2047 -0
- manigent/server/routes/public_agents.py +151 -0
- manigent/server/routes/public_requests.py +181 -0
- manigent/server/routes/reflection.py +93 -0
- manigent/server/routes/scheduled_messages.py +263 -0
- manigent/server/routes/search.py +94 -0
- manigent/server/routes/sharing.py +156 -0
- manigent/server/routes/skills.py +406 -0
- manigent/server/routes/templates.py +219 -0
- manigent/server/routes/turn_tokens.py +119 -0
- manigent/server/routes/webchat.py +406 -0
- manigent/server/routes/websocket.py +431 -0
- manigent/server/serving_only.py +200 -0
- manigent/server/signup_policy.py +120 -0
- manigent/server/skill_registry.py +164 -0
- manigent/server/socket_events.py +858 -0
- manigent/server/timeout_checker.py +446 -0
- manigent/server/tunnel_subscriber.py +1000 -0
- manigent/server/turn_tokens.py +285 -0
- manigent/server/ws_hub.py +556 -0
- manigent/server_cli.py +31 -0
- manigent/sync/changelog.py +885 -0
- manigent/sync/console_subscriber.py +222 -0
- manigent/sync/runloop.py +619 -0
- manigent/sync/runloop_manager.py +197 -0
- manigent/sync/subscriber.py +98 -0
- manigent/utils/agent_processes.py +276 -0
- manigent/utils/agent_storage.py +125 -0
- manigent/utils/email.py +563 -0
- manigent/utils/env_store.py +174 -0
- manigent/utils/extra_dirs.py +85 -0
- manigent/utils/file_io.py +485 -0
- manigent/utils/invoke_timeout.py +87 -0
- manigent/utils/jsonc.py +78 -0
- manigent/utils/knowledge_index.py +148 -0
- manigent/utils/nofollow_fs.py +279 -0
- manigent/utils/notification_center.py +67 -0
- manigent/utils/version.py +57 -0
- manigent/web/frontend/.design-sync-entry.tsx +74 -0
- manigent/web/frontend/.design-sync-provider.tsx +46 -0
- manigent/web/frontend/.eslintrc.cjs +183 -0
- manigent/web/frontend/.gitignore +6 -0
- manigent/web/frontend/app/page.tsx +39 -0
- manigent/web/frontend/hub-terms.html +192 -0
- manigent/web/frontend/index.html +15 -0
- manigent/web/frontend/landing.html +15 -0
- manigent/web/frontend/package-lock.json +8028 -0
- manigent/web/frontend/package.json +55 -0
- manigent/web/frontend/postcss.config.js +6 -0
- manigent/web/frontend/privacy.html +217 -0
- manigent/web/frontend/private-beta-announcement.html +19 -0
- manigent/web/frontend/public/apple-touch-icon.png +0 -0
- manigent/web/frontend/public/brand-hero-banner.png +0 -0
- manigent/web/frontend/public/brand-hero.png +0 -0
- manigent/web/frontend/public/favicon.png +0 -0
- manigent/web/frontend/public/favicon.svg +8 -0
- manigent/web/frontend/public/icon-transparent-sm.png +0 -0
- manigent/web/frontend/public/icon.png +0 -0
- manigent/web/frontend/public/manigent-mark.svg +7 -0
- manigent/web/frontend/public/vite.svg +5 -0
- manigent/web/frontend/public.html +15 -0
- manigent/web/frontend/src/App.activeAccountRedirect.test.tsx +236 -0
- manigent/web/frontend/src/App.hubHostDm.test.tsx +119 -0
- manigent/web/frontend/src/App.hubHostProject.test.tsx +142 -0
- manigent/web/frontend/src/App.hubRoutes.test.tsx +187 -0
- manigent/web/frontend/src/App.oauthAddCallback.test.tsx +263 -0
- manigent/web/frontend/src/App.tsx +246 -0
- manigent/web/frontend/src/api/attachments.ts +32 -0
- manigent/web/frontend/src/api/batchLoader.test.ts +212 -0
- manigent/web/frontend/src/api/batchLoader.ts +124 -0
- manigent/web/frontend/src/api/chatroomsBatch.test.tsx +392 -0
- manigent/web/frontend/src/api/client.ts +321 -0
- manigent/web/frontend/src/api/crossAccountAuth.test.ts +388 -0
- manigent/web/frontend/src/api/endpoints/agentEnv.ts +24 -0
- manigent/web/frontend/src/api/endpoints/agentFs.ts +125 -0
- manigent/web/frontend/src/api/endpoints/agentSearch.ts +19 -0
- manigent/web/frontend/src/api/endpoints/agents.ts +66 -0
- manigent/web/frontend/src/api/endpoints/announcements.ts +26 -0
- manigent/web/frontend/src/api/endpoints/auth.ts +361 -0
- manigent/web/frontend/src/api/endpoints/authLogin.test.ts +236 -0
- manigent/web/frontend/src/api/endpoints/batch.ts +64 -0
- manigent/web/frontend/src/api/endpoints/briefTabs.ts +81 -0
- manigent/web/frontend/src/api/endpoints/channels.ts +285 -0
- manigent/web/frontend/src/api/endpoints/computers.ts +212 -0
- manigent/web/frontend/src/api/endpoints/deskLabels.ts +151 -0
- manigent/web/frontend/src/api/endpoints/deskLatestMessages.ts +23 -0
- manigent/web/frontend/src/api/endpoints/deskReadState.ts +41 -0
- manigent/web/frontend/src/api/endpoints/deskSignOffs.ts +74 -0
- manigent/web/frontend/src/api/endpoints/deskSops.ts +53 -0
- manigent/web/frontend/src/api/endpoints/deskTodoAttachments.ts +69 -0
- manigent/web/frontend/src/api/endpoints/deskTodoProjects.test.ts +99 -0
- manigent/web/frontend/src/api/endpoints/deskTodoProjects.ts +114 -0
- manigent/web/frontend/src/api/endpoints/deskTodos.ts +164 -0
- manigent/web/frontend/src/api/endpoints/deskTour.ts +16 -0
- manigent/web/frontend/src/api/endpoints/dm.ts +137 -0
- manigent/web/frontend/src/api/endpoints/files.ts +55 -0
- manigent/web/frontend/src/api/endpoints/hub.contract.test.ts +94 -0
- manigent/web/frontend/src/api/endpoints/hub.keys.ts +260 -0
- manigent/web/frontend/src/api/endpoints/hub.test.ts +203 -0
- manigent/web/frontend/src/api/endpoints/hub.ts +654 -0
- manigent/web/frontend/src/api/endpoints/index.ts +15 -0
- manigent/web/frontend/src/api/endpoints/install.ts +74 -0
- manigent/web/frontend/src/api/endpoints/isolationCheck.ts +36 -0
- manigent/web/frontend/src/api/endpoints/knowledgePacks.ts +179 -0
- manigent/web/frontend/src/api/endpoints/mcps.ts +36 -0
- manigent/web/frontend/src/api/endpoints/messages.held.test.ts +43 -0
- manigent/web/frontend/src/api/endpoints/messages.ts +95 -0
- manigent/web/frontend/src/api/endpoints/modelConfigs.ts +232 -0
- manigent/web/frontend/src/api/endpoints/oauthApi.test.ts +110 -0
- manigent/web/frontend/src/api/endpoints/projectPlans.ts +608 -0
- manigent/web/frontend/src/api/endpoints/projectReports.ts +36 -0
- manigent/web/frontend/src/api/endpoints/projects.ts +124 -0
- manigent/web/frontend/src/api/endpoints/publicRequests.ts +75 -0
- manigent/web/frontend/src/api/endpoints/reflection.ts +32 -0
- manigent/web/frontend/src/api/endpoints/roomFlow.ts +14 -0
- manigent/web/frontend/src/api/endpoints/scheduledMessages.ts +60 -0
- manigent/web/frontend/src/api/endpoints/search.ts +27 -0
- manigent/web/frontend/src/api/endpoints/sharing.ts +42 -0
- manigent/web/frontend/src/api/endpoints/skills.ts +67 -0
- manigent/web/frontend/src/api/endpoints/templates.ts +72 -0
- manigent/web/frontend/src/api/loaders.ts +22 -0
- manigent/web/frontend/src/api/singleIssuer.test.ts +148 -0
- manigent/web/frontend/src/api/transientRetry.test.ts +176 -0
- manigent/web/frontend/src/api/transientRetry.ts +140 -0
- manigent/web/frontend/src/api/websocket.resync.test.ts +111 -0
- manigent/web/frontend/src/api/websocket.ts +335 -0
- manigent/web/frontend/src/components/agent/AgentNameLink.tsx +24 -0
- manigent/web/frontend/src/components/agent/AgentViewActions.test.tsx +41 -0
- manigent/web/frontend/src/components/agent/AgentViewActions.tsx +89 -0
- manigent/web/frontend/src/components/agent/CreateAgentPage.tsx +535 -0
- manigent/web/frontend/src/components/agent/JsonConfigEditor.tsx +33 -0
- manigent/web/frontend/src/components/agent/KnowledgePackList.tsx +103 -0
- manigent/web/frontend/src/components/agent/McpCatalog.tsx +261 -0
- manigent/web/frontend/src/components/agent/McpConfigModal.tsx +224 -0
- manigent/web/frontend/src/components/agent/PreConsentModal.tsx +172 -0
- manigent/web/frontend/src/components/agent/SkillCatalog.tsx +364 -0
- manigent/web/frontend/src/components/agent/SkillConfigModal.tsx +221 -0
- manigent/web/frontend/src/components/auth/AddAccountPage.test.tsx +181 -0
- manigent/web/frontend/src/components/auth/AddAccountPage.tsx +201 -0
- manigent/web/frontend/src/components/auth/AuthShell.tsx +462 -0
- manigent/web/frontend/src/components/auth/LoginPage.test.tsx +384 -0
- manigent/web/frontend/src/components/auth/LoginPage.tsx +129 -0
- manigent/web/frontend/src/components/auth/OAuthCallbackPage.test.tsx +185 -0
- manigent/web/frontend/src/components/auth/OAuthCallbackPage.tsx +154 -0
- manigent/web/frontend/src/components/auth/OAuthLinkedBanner.tsx +44 -0
- manigent/web/frontend/src/components/auth/ProviderButtons.tsx +94 -0
- manigent/web/frontend/src/components/auth/SignupPage.tsx +437 -0
- manigent/web/frontend/src/components/auth/StepProgress.tsx +60 -0
- manigent/web/frontend/src/components/auth/VerifyEmailPage.test.tsx +155 -0
- manigent/web/frontend/src/components/auth/VerifyEmailPage.tsx +211 -0
- manigent/web/frontend/src/components/auth/index.ts +3 -0
- manigent/web/frontend/src/components/auth/oauthErrors.test.ts +107 -0
- manigent/web/frontend/src/components/auth/oauthErrors.ts +82 -0
- manigent/web/frontend/src/components/auth/useUsernameCheck.test.tsx +68 -0
- manigent/web/frontend/src/components/auth/useUsernameCheck.ts +86 -0
- manigent/web/frontend/src/components/beta/BetaPage.tsx +21 -0
- manigent/web/frontend/src/components/beta/DayAtMyDesk.tsx +120 -0
- manigent/web/frontend/src/components/beta/Footer.tsx +82 -0
- manigent/web/frontend/src/components/beta/Hero.tsx +224 -0
- manigent/web/frontend/src/components/beta/Nav.tsx +51 -0
- manigent/web/frontend/src/components/beta/Pillars.tsx +172 -0
- manigent/web/frontend/src/components/beta/TwoModels.tsx +146 -0
- manigent/web/frontend/src/components/beta/constants.ts +3 -0
- manigent/web/frontend/src/components/briefing/BriefingFrame.test.tsx +208 -0
- manigent/web/frontend/src/components/briefing/BriefingFrame.tsx +151 -0
- manigent/web/frontend/src/components/briefing/BriefingPage.test.tsx +176 -0
- manigent/web/frontend/src/components/briefing/BriefingPage.tsx +157 -0
- manigent/web/frontend/src/components/briefing/BriefingPage.wsDelete.test.tsx +177 -0
- manigent/web/frontend/src/components/briefing/briefing.css +147 -0
- manigent/web/frontend/src/components/briefing/heightBootstrap.test.ts +121 -0
- manigent/web/frontend/src/components/briefing/heightBootstrap.ts +224 -0
- manigent/web/frontend/src/components/briefing/parseBriefMessage.test.ts +90 -0
- manigent/web/frontend/src/components/briefing/sampleBriefing.ts +148 -0
- manigent/web/frontend/src/components/channels/ChannelBadge.tsx +35 -0
- manigent/web/frontend/src/components/chatroom/ChannelThreadControls.tsx +127 -0
- manigent/web/frontend/src/components/chatroom/ChannelThreadNotice.test.tsx +207 -0
- manigent/web/frontend/src/components/chatroom/ChannelThreadNotice.tsx +80 -0
- manigent/web/frontend/src/components/chatroom/ChatroomView.channel.test.tsx +550 -0
- manigent/web/frontend/src/components/chatroom/ChatroomView.flow.test.tsx +186 -0
- manigent/web/frontend/src/components/chatroom/ChatroomView.isolation.test.tsx +70 -0
- manigent/web/frontend/src/components/chatroom/ChatroomView.tsx +450 -0
- manigent/web/frontend/src/components/chatroom/DelegationRow.test.tsx +170 -0
- manigent/web/frontend/src/components/chatroom/DelegationRow.tsx +217 -0
- manigent/web/frontend/src/components/chatroom/DeliveryStatusLine.test.tsx +33 -0
- manigent/web/frontend/src/components/chatroom/DeliveryStatusLine.tsx +46 -0
- manigent/web/frontend/src/components/chatroom/ForwardModal.test.tsx +109 -0
- manigent/web/frontend/src/components/chatroom/ForwardModal.tsx +304 -0
- manigent/web/frontend/src/components/chatroom/HeldNotice.tsx +77 -0
- manigent/web/frontend/src/components/chatroom/MentionDropdown.tsx +97 -0
- manigent/web/frontend/src/components/chatroom/MessageInput.tsx +408 -0
- manigent/web/frontend/src/components/chatroom/MessageItem.tsx +425 -0
- manigent/web/frontend/src/components/chatroom/MessageList.outside.test.tsx +98 -0
- manigent/web/frontend/src/components/chatroom/MessageList.test.tsx +245 -0
- manigent/web/frontend/src/components/chatroom/MessageList.tsx +406 -0
- manigent/web/frontend/src/components/chatroom/OfflineRemedyNote.test.tsx +211 -0
- manigent/web/frontend/src/components/chatroom/OfflineRemedyNote.tsx +182 -0
- manigent/web/frontend/src/components/chatroom/OutsideBadge.tsx +18 -0
- manigent/web/frontend/src/components/chatroom/RoomFlowControl.tsx +49 -0
- manigent/web/frontend/src/components/chatroom/RoomFlowStrip.test.tsx +47 -0
- manigent/web/frontend/src/components/chatroom/RoomFlowStrip.tsx +25 -0
- manigent/web/frontend/src/components/chatroom/SaveToPackModal.tsx +350 -0
- manigent/web/frontend/src/components/chatroom/StagedAttachments.test.tsx +56 -0
- manigent/web/frontend/src/components/chatroom/StagedAttachments.tsx +160 -0
- manigent/web/frontend/src/components/chatroom/SystemNote.tsx +18 -0
- manigent/web/frontend/src/components/chatroom/contactSender.test.tsx +130 -0
- manigent/web/frontend/src/components/chatroom/index.ts +3 -0
- manigent/web/frontend/src/components/chatroom/recipientStatus.test.ts +344 -0
- manigent/web/frontend/src/components/chatroom/recipientStatus.ts +197 -0
- manigent/web/frontend/src/components/common/AnnouncementBanners.test.tsx +221 -0
- manigent/web/frontend/src/components/common/AnnouncementBanners.tsx +180 -0
- manigent/web/frontend/src/components/common/Avatar.test.tsx +50 -0
- manigent/web/frontend/src/components/common/Avatar.tsx +102 -0
- manigent/web/frontend/src/components/common/Badge.tsx +30 -0
- manigent/web/frontend/src/components/common/BrandName.tsx +16 -0
- manigent/web/frontend/src/components/common/ClearHistoryButton.tsx +74 -0
- manigent/web/frontend/src/components/common/CollapsibleHeader.tsx +64 -0
- manigent/web/frontend/src/components/common/ConnectionStatus.test.tsx +56 -0
- manigent/web/frontend/src/components/common/ConnectionStatus.tsx +28 -0
- manigent/web/frontend/src/components/common/DropOverlay.tsx +27 -0
- manigent/web/frontend/src/components/common/InlineEditableTitle.test.tsx +369 -0
- manigent/web/frontend/src/components/common/InlineEditableTitle.tsx +287 -0
- manigent/web/frontend/src/components/common/IsolationUnavailablePanel.tsx +19 -0
- manigent/web/frontend/src/components/common/Loading.tsx +22 -0
- manigent/web/frontend/src/components/common/ModelSelector.tsx +248 -0
- manigent/web/frontend/src/components/common/Overlay.tsx +15 -0
- manigent/web/frontend/src/components/common/ResizeHandle.tsx +52 -0
- manigent/web/frontend/src/components/common/TagAutocompleteInput.test.tsx +92 -0
- manigent/web/frontend/src/components/common/TagAutocompleteInput.tsx +246 -0
- manigent/web/frontend/src/components/common/TagPillInput.tsx +181 -0
- manigent/web/frontend/src/components/common/TeamAndAgentPicker.tsx +83 -0
- manigent/web/frontend/src/components/common/Timestamp.tsx +61 -0
- manigent/web/frontend/src/components/common/VerifiedBadge.tsx +20 -0
- manigent/web/frontend/src/components/common/index.ts +8 -0
- manigent/web/frontend/src/components/composer/PhPopover.tsx +239 -0
- manigent/web/frontend/src/components/composer/PromptEditor.test.tsx +472 -0
- manigent/web/frontend/src/components/composer/PromptEditor.tsx +540 -0
- manigent/web/frontend/src/components/composer/caret.ts +159 -0
- manigent/web/frontend/src/components/composer/placeholders.test.ts +352 -0
- manigent/web/frontend/src/components/composer/placeholders.ts +354 -0
- manigent/web/frontend/src/components/composer/promptEditor.css +161 -0
- manigent/web/frontend/src/components/computer/ComputerPage.test.tsx +452 -0
- manigent/web/frontend/src/components/computer/ComputerPage.tsx +811 -0
- manigent/web/frontend/src/components/computer/ConnectComputerModal.tsx +135 -0
- manigent/web/frontend/src/components/computer/CopyCommand.tsx +77 -0
- manigent/web/frontend/src/components/computer/DisconnectComputerModal.tsx +121 -0
- manigent/web/frontend/src/components/computer/SoftwareCard.tsx +145 -0
- manigent/web/frontend/src/components/computer/TerminalCard.test.tsx +114 -0
- manigent/web/frontend/src/components/computer/TerminalCard.tsx +131 -0
- manigent/web/frontend/src/components/computer/TerminalPanel.tsx +226 -0
- manigent/web/frontend/src/components/computer/TrustPanel.test.tsx +58 -0
- manigent/web/frontend/src/components/computer/TrustPanel.tsx +143 -0
- manigent/web/frontend/src/components/computer/computerCopy.test.ts +322 -0
- manigent/web/frontend/src/components/computer/computerCopy.ts +413 -0
- manigent/web/frontend/src/components/computer/sections.ts +21 -0
- manigent/web/frontend/src/components/computer/terminalProtocol.test.ts +135 -0
- manigent/web/frontend/src/components/computer/terminalProtocol.ts +170 -0
- manigent/web/frontend/src/components/context/ContextGuide.test.tsx +26 -0
- manigent/web/frontend/src/components/context/ContextGuide.tsx +144 -0
- manigent/web/frontend/src/components/context/ContextLanding.tsx +46 -0
- manigent/web/frontend/src/components/desk/CardBand.a11y.test.tsx +138 -0
- manigent/web/frontend/src/components/desk/CardBand.tsx +132 -0
- manigent/web/frontend/src/components/desk/DashTile.tsx +81 -0
- manigent/web/frontend/src/components/desk/DeskAgentPicker.retained.test.tsx +79 -0
- manigent/web/frontend/src/components/desk/DeskAgentPicker.tsx +151 -0
- manigent/web/frontend/src/components/desk/DeskComposer.detachTodo.test.tsx +233 -0
- manigent/web/frontend/src/components/desk/DeskComposer.dispatch.test.tsx +208 -0
- manigent/web/frontend/src/components/desk/DeskComposer.loadTodoDraft.test.tsx +242 -0
- manigent/web/frontend/src/components/desk/DeskComposer.restage.test.tsx +258 -0
- manigent/web/frontend/src/components/desk/DeskComposer.saveTodo.test.tsx +265 -0
- manigent/web/frontend/src/components/desk/DeskComposer.tsx +828 -0
- manigent/web/frontend/src/components/desk/DeskPage.crossHighlight.test.tsx +427 -0
- manigent/web/frontend/src/components/desk/DeskPage.link.test.tsx +271 -0
- manigent/web/frontend/src/components/desk/DeskPage.tsx +1066 -0
- manigent/web/frontend/src/components/desk/DeskPage.welcomeTour.test.tsx +262 -0
- manigent/web/frontend/src/components/desk/DeskSideRail.tsx +100 -0
- manigent/web/frontend/src/components/desk/DeskWelcomeTour.tsx +513 -0
- manigent/web/frontend/src/components/desk/DeskZeroState.tsx +45 -0
- manigent/web/frontend/src/components/desk/LabelChip.tsx +147 -0
- manigent/web/frontend/src/components/desk/LabelFilter.tsx +474 -0
- manigent/web/frontend/src/components/desk/LabelInput.test.tsx +439 -0
- manigent/web/frontend/src/components/desk/LabelInput.tsx +477 -0
- manigent/web/frontend/src/components/desk/LabelManageSheet.test.tsx +384 -0
- manigent/web/frontend/src/components/desk/LabelManageSheet.tsx +498 -0
- manigent/web/frontend/src/components/desk/PhaseRail.test.tsx +170 -0
- manigent/web/frontend/src/components/desk/PhaseRail.tsx +120 -0
- manigent/web/frontend/src/components/desk/PlanBand.test.tsx +655 -0
- manigent/web/frontend/src/components/desk/PlanBand.tsx +216 -0
- manigent/web/frontend/src/components/desk/SaveTodoModal.tsx +126 -0
- manigent/web/frontend/src/components/desk/SopEditor.tsx +280 -0
- manigent/web/frontend/src/components/desk/SopItem.tsx +171 -0
- manigent/web/frontend/src/components/desk/SopRail.test.tsx +517 -0
- manigent/web/frontend/src/components/desk/SopRail.tsx +250 -0
- manigent/web/frontend/src/components/desk/TicketChip.tsx +51 -0
- manigent/web/frontend/src/components/desk/TodoItem.attachments.test.tsx +96 -0
- manigent/web/frontend/src/components/desk/TodoItem.menu.test.tsx +142 -0
- manigent/web/frontend/src/components/desk/TodoItem.tsx +573 -0
- manigent/web/frontend/src/components/desk/TodoRail.longpress.test.tsx +396 -0
- manigent/web/frontend/src/components/desk/TodoRail.test.tsx +1155 -0
- manigent/web/frontend/src/components/desk/TodoRail.tsx +918 -0
- manigent/web/frontend/src/components/desk/TodoRowMenu.tsx +147 -0
- manigent/web/frontend/src/components/desk/UpdateCard.bands.test.tsx +308 -0
- manigent/web/frontend/src/components/desk/UpdateCard.sendBack.test.tsx +444 -0
- manigent/web/frontend/src/components/desk/UpdateCard.tsx +943 -0
- manigent/web/frontend/src/components/desk/UpdateCard.untrusted.test.tsx +161 -0
- manigent/web/frontend/src/components/desk/desk.css +1921 -0
- manigent/web/frontend/src/components/desk/desk.css.test.ts +582 -0
- manigent/web/frontend/src/components/desk/deskBands.test.ts +389 -0
- manigent/web/frontend/src/components/desk/deskBands.ts +226 -0
- manigent/web/frontend/src/components/desk/m16Surfaces.test.ts +134 -0
- manigent/web/frontend/src/components/desk/sopSyntax.ts +73 -0
- manigent/web/frontend/src/components/discovery/AgentDirectory.tsx +71 -0
- manigent/web/frontend/src/components/discovery/AgentFilterBar.tsx +46 -0
- manigent/web/frontend/src/components/discovery/AgentSearchBar.tsx +56 -0
- manigent/web/frontend/src/components/dm/AgentSummaryCard.tsx +154 -0
- manigent/web/frontend/src/components/dm/ComposeFields.tsx +145 -0
- manigent/web/frontend/src/components/dm/DMChatView.flow.test.tsx +374 -0
- manigent/web/frontend/src/components/dm/DMChatView.tsx +841 -0
- manigent/web/frontend/src/components/dm/DMZeroState.tsx +204 -0
- manigent/web/frontend/src/components/dm/DmComposeModal.tsx +301 -0
- manigent/web/frontend/src/components/dm/PersonalizeModal.tsx +366 -0
- manigent/web/frontend/src/components/dm/index.ts +1 -0
- manigent/web/frontend/src/components/files/FileItem.tsx +138 -0
- manigent/web/frontend/src/components/files/FileList.outside.test.tsx +29 -0
- manigent/web/frontend/src/components/files/FileList.tsx +48 -0
- manigent/web/frontend/src/components/files/FilePreview.test.tsx +75 -0
- manigent/web/frontend/src/components/files/FilePreview.tsx +325 -0
- manigent/web/frontend/src/components/files/FileViewerModal.test.tsx +157 -0
- manigent/web/frontend/src/components/files/FileViewerModal.tsx +261 -0
- manigent/web/frontend/src/components/files/HighlightedCode.tsx +39 -0
- manigent/web/frontend/src/components/files/SaveToAgentPanel.test.tsx +156 -0
- manigent/web/frontend/src/components/files/SaveToAgentPanel.tsx +545 -0
- manigent/web/frontend/src/components/files/index.ts +3 -0
- manigent/web/frontend/src/components/hero/AgentAvatar.tsx +66 -0
- manigent/web/frontend/src/components/hero/Button.tsx +66 -0
- manigent/web/frontend/src/components/hero/Hero.tsx +133 -0
- manigent/web/frontend/src/components/homefs/HomeFolderBrowser.test.tsx +393 -0
- manigent/web/frontend/src/components/homefs/HomeFolderBrowser.tsx +792 -0
- manigent/web/frontend/src/components/hub/BridgeDeliveryLine.test.tsx +40 -0
- manigent/web/frontend/src/components/hub/BridgeDeliveryLine.tsx +36 -0
- manigent/web/frontend/src/components/hub/HubAvatar.test.tsx +93 -0
- manigent/web/frontend/src/components/hub/HubAvatar.tsx +33 -0
- manigent/web/frontend/src/components/hub/HubChatView.test.tsx +695 -0
- manigent/web/frontend/src/components/hub/HubChatView.tsx +504 -0
- manigent/web/frontend/src/components/hub/HubContactLabel.test.tsx +92 -0
- manigent/web/frontend/src/components/hub/HubContactLabel.tsx +47 -0
- manigent/web/frontend/src/components/hub/HubDeliveryLine.tsx +49 -0
- manigent/web/frontend/src/components/hub/HubDisclosure.tsx +49 -0
- manigent/web/frontend/src/components/hub/HubEnrollmentDialog.test.tsx +144 -0
- manigent/web/frontend/src/components/hub/HubEnrollmentDialog.tsx +244 -0
- manigent/web/frontend/src/components/hub/HubMessageBody.test.tsx +26 -0
- manigent/web/frontend/src/components/hub/HubMessageBody.tsx +14 -0
- manigent/web/frontend/src/components/hub/HubOfflineConfirm.tsx +45 -0
- manigent/web/frontend/src/components/hub/HubThreadBanner.tsx +33 -0
- manigent/web/frontend/src/components/hub/HubThreadGuard.tsx +59 -0
- manigent/web/frontend/src/components/hub/RemoteAgentCard.test.tsx +50 -0
- manigent/web/frontend/src/components/hub/RemoteAgentCard.tsx +174 -0
- manigent/web/frontend/src/components/hub/RemoteAgentSection.test.tsx +446 -0
- manigent/web/frontend/src/components/hub/RemoteAgentSection.tsx +219 -0
- manigent/web/frontend/src/components/hub/ReportDialog.test.tsx +96 -0
- manigent/web/frontend/src/components/hub/ReportDialog.tsx +162 -0
- manigent/web/frontend/src/components/hub/RetainButton.test.tsx +103 -0
- manigent/web/frontend/src/components/hub/RetainButton.tsx +114 -0
- manigent/web/frontend/src/components/hub/RetainDialog.test.tsx +68 -0
- manigent/web/frontend/src/components/hub/RetainDialog.tsx +115 -0
- manigent/web/frontend/src/components/hub/RetainedList.test.tsx +94 -0
- manigent/web/frontend/src/components/hub/RetainedList.tsx +32 -0
- manigent/web/frontend/src/components/hub/RetainedRow.tsx +129 -0
- manigent/web/frontend/src/components/hub/StandInChip.test.tsx +37 -0
- manigent/web/frontend/src/components/hub/StandInChip.tsx +43 -0
- manigent/web/frontend/src/components/hub/UnusualNameChip.test.tsx +81 -0
- manigent/web/frontend/src/components/hub/UnusualNameChip.tsx +22 -0
- manigent/web/frontend/src/components/hub/hubLint.test.ts +265 -0
- manigent/web/frontend/src/components/landing/ComparisonSection.tsx +92 -0
- manigent/web/frontend/src/components/landing/ConsoleSection.tsx +402 -0
- manigent/web/frontend/src/components/landing/CrewSection.tsx +224 -0
- manigent/web/frontend/src/components/landing/FAQ.tsx +68 -0
- manigent/web/frontend/src/components/landing/Footer.tsx +58 -0
- manigent/web/frontend/src/components/landing/HowItWorks.tsx +117 -0
- manigent/web/frontend/src/components/landing/KnowledgeSection.tsx +91 -0
- manigent/web/frontend/src/components/landing/LandingPage.test.tsx +134 -0
- manigent/web/frontend/src/components/landing/LearningSection.tsx +486 -0
- manigent/web/frontend/src/components/landing/Nav.tsx +68 -0
- manigent/web/frontend/src/components/landing/Pricing.tsx +263 -0
- manigent/web/frontend/src/components/landing/Section.tsx +98 -0
- manigent/web/frontend/src/components/landing/StaffingSection.tsx +122 -0
- manigent/web/frontend/src/components/landing/WhyNowSection.tsx +92 -0
- manigent/web/frontend/src/components/landing/WhyTeamSection.tsx +73 -0
- manigent/web/frontend/src/components/landing/earlyAccess.ts +23 -0
- manigent/web/frontend/src/components/layout/AppLayout.tsx +77 -0
- manigent/web/frontend/src/components/layout/Sidebar.tsx +172 -0
- manigent/web/frontend/src/components/layout/index.ts +2 -0
- manigent/web/frontend/src/components/project/ActivityFeed.tsx +247 -0
- manigent/web/frontend/src/components/project/CreateProjectPage.tsx +543 -0
- manigent/web/frontend/src/components/project/DeleteProjectButton.tsx +39 -0
- manigent/web/frontend/src/components/project/ProjectPlanTab.phase.test.tsx +107 -0
- manigent/web/frontend/src/components/project/ProjectPlanTab.test.tsx +994 -0
- manigent/web/frontend/src/components/project/ProjectPlanTab.tsx +166 -0
- manigent/web/frontend/src/components/project/ProjectReportTab.tsx +139 -0
- manigent/web/frontend/src/components/project/ProjectView.tsx +390 -0
- manigent/web/frontend/src/components/project/index.ts +2 -0
- manigent/web/frontend/src/components/project/plan/PlanAcceptance.test.tsx +460 -0
- manigent/web/frontend/src/components/project/plan/PlanAcceptance.tsx +111 -0
- manigent/web/frontend/src/components/project/plan/PlanBlockEdit.tsx +111 -0
- manigent/web/frontend/src/components/project/plan/PlanBlockEditing.test.tsx +1132 -0
- manigent/web/frontend/src/components/project/plan/PlanBody.test.tsx +495 -0
- manigent/web/frontend/src/components/project/plan/PlanBody.tsx +992 -0
- manigent/web/frontend/src/components/project/plan/PlanCollide.tsx +254 -0
- manigent/web/frontend/src/components/project/plan/PlanCommentList.test.tsx +420 -0
- manigent/web/frontend/src/components/project/plan/PlanCommentList.tsx +391 -0
- manigent/web/frontend/src/components/project/plan/PlanDecisionNudge.test.tsx +226 -0
- manigent/web/frontend/src/components/project/plan/PlanDecisionNudge.tsx +128 -0
- manigent/web/frontend/src/components/project/plan/PlanDestructiveAccept.test.tsx +209 -0
- manigent/web/frontend/src/components/project/plan/PlanDiff.test.tsx +126 -0
- manigent/web/frontend/src/components/project/plan/PlanDiff.tsx +131 -0
- manigent/web/frontend/src/components/project/plan/PlanDiffSeries.test.tsx +500 -0
- manigent/web/frontend/src/components/project/plan/PlanDiffSeries.tsx +125 -0
- manigent/web/frontend/src/components/project/plan/PlanEditor.mounts.test.tsx +504 -0
- manigent/web/frontend/src/components/project/plan/PlanEditor.tsx +2159 -0
- manigent/web/frontend/src/components/project/plan/PlanHistory.tsx +69 -0
- manigent/web/frontend/src/components/project/plan/PlanInlineNotes.test.tsx +2398 -0
- manigent/web/frontend/src/components/project/plan/PlanNoteBase.test.tsx +215 -0
- manigent/web/frontend/src/components/project/plan/PlanNoteRow.test.tsx +562 -0
- manigent/web/frontend/src/components/project/plan/PlanNoteRow.tsx +908 -0
- manigent/web/frontend/src/components/project/plan/PlanQuotePop.tsx +254 -0
- manigent/web/frontend/src/components/project/plan/PlanStaleReconcile.test.tsx +244 -0
- manigent/web/frontend/src/components/project/plan/PlanSubmitWindow.test.tsx +281 -0
- manigent/web/frontend/src/components/project/plan/PlanTray.tsx +184 -0
- manigent/web/frontend/src/components/project/plan/PlanTrayMirror.test.tsx +242 -0
- manigent/web/frontend/src/components/project/plan/plan.css +1151 -0
- manigent/web/frontend/src/components/project/plan/planAnchor.test.tsx +459 -0
- manigent/web/frontend/src/components/project/plan/planAnchor.tsx +277 -0
- manigent/web/frontend/src/components/project/plan/planBlocks.test.tsx +470 -0
- manigent/web/frontend/src/components/project/plan/planBlocks.ts +242 -0
- manigent/web/frontend/src/components/project/plan/planContrast.test.ts +229 -0
- manigent/web/frontend/src/components/project/plan/planDiffs.test.ts +455 -0
- manigent/web/frontend/src/components/project/plan/planDiffs.ts +358 -0
- manigent/web/frontend/src/components/project/plan/planTestServer.ts +741 -0
- manigent/web/frontend/src/components/project/plan/planTransport.test.ts +160 -0
- manigent/web/frontend/src/components/project/plan/planTrayLogic.test.ts +1201 -0
- manigent/web/frontend/src/components/project/plan/planTrayLogic.ts +1164 -0
- manigent/web/frontend/src/components/publicAgents/PublicAgentsAccount.tsx +162 -0
- manigent/web/frontend/src/components/publicAgents/api.ts +55 -0
- manigent/web/frontend/src/components/publicAgents/parts.tsx +54 -0
- manigent/web/frontend/src/components/publicAgents/publicAgents.css +53 -0
- manigent/web/frontend/src/components/publicAgents/publicAgents.test.tsx +86 -0
- manigent/web/frontend/src/components/publicAgents/widget.test.ts +148 -0
- manigent/web/frontend/src/components/publicAgents/widget.ts +40 -0
- manigent/web/frontend/src/components/publicRequests/AgentDrawer.tsx +101 -0
- manigent/web/frontend/src/components/publicRequests/AgentPanel.tsx +173 -0
- manigent/web/frontend/src/components/publicRequests/AgentRankList.tsx +61 -0
- manigent/web/frontend/src/components/publicRequests/MatchRetainButton.tsx +67 -0
- manigent/web/frontend/src/components/publicRequests/ProgressBoard.tsx +74 -0
- manigent/web/frontend/src/components/publicRequests/PublicRequestsPage.tsx +57 -0
- manigent/web/frontend/src/components/publicRequests/RequestHome.tsx +99 -0
- manigent/web/frontend/src/components/publicRequests/RequestRoom.tsx +126 -0
- manigent/web/frontend/src/components/publicRequests/agentView.ts +65 -0
- manigent/web/frontend/src/components/publicRequests/publicRequests.css +209 -0
- manigent/web/frontend/src/components/publicRequests/publicRequests.test.tsx +172 -0
- manigent/web/frontend/src/components/publicRequests/requestCopy.ts +121 -0
- manigent/web/frontend/src/components/sample-request/SampleIdeaList.test.tsx +190 -0
- manigent/web/frontend/src/components/sample-request/SampleIdeaList.tsx +180 -0
- manigent/web/frontend/src/components/sample-request/SampleRequestBody.tsx +276 -0
- manigent/web/frontend/src/components/sample-request/assistantStarterSamples.ts +62 -0
- manigent/web/frontend/src/components/sample-request/sampleIdeaList.css +106 -0
- manigent/web/frontend/src/components/scheduled/CronPicker.tsx +80 -0
- manigent/web/frontend/src/components/scheduled/ScheduleMessageModal.tsx +341 -0
- manigent/web/frontend/src/components/scheduled/ScheduledMessagesList.tsx +157 -0
- manigent/web/frontend/src/components/settings/AgentSettingsPage.tsx +366 -0
- manigent/web/frontend/src/components/settings/ConnectedAccounts.tsx +277 -0
- manigent/web/frontend/src/components/settings/DefaultModelSection.test.tsx +96 -0
- manigent/web/frontend/src/components/settings/DefaultModelSection.tsx +212 -0
- manigent/web/frontend/src/components/settings/DisconnectConfirmModal.tsx +93 -0
- manigent/web/frontend/src/components/settings/FrontDeskSettingsPage.isolation.test.tsx +66 -0
- manigent/web/frontend/src/components/settings/FrontDeskSettingsPage.tsx +134 -0
- manigent/web/frontend/src/components/settings/InvitableAgentsPicker.tsx +182 -0
- manigent/web/frontend/src/components/settings/KnowledgePacksSection.tsx +867 -0
- manigent/web/frontend/src/components/settings/ModelConfigDialog.catalogDriven.test.tsx +79 -0
- manigent/web/frontend/src/components/settings/ModelConfigDialog.tsx +343 -0
- manigent/web/frontend/src/components/settings/ModelConfigSection.smartRouting.test.tsx +109 -0
- manigent/web/frontend/src/components/settings/ModelConfigSection.tsx +599 -0
- manigent/web/frontend/src/components/settings/ReflectionScheduleSection.tsx +170 -0
- manigent/web/frontend/src/components/settings/UserSettingsPage.tsx +168 -0
- manigent/web/frontend/src/components/settings/agent/AgentStatusStrip.tsx +71 -0
- manigent/web/frontend/src/components/settings/agent/BlockedDeploymentsCard.test.tsx +81 -0
- manigent/web/frontend/src/components/settings/agent/BlockedDeploymentsCard.tsx +62 -0
- manigent/web/frontend/src/components/settings/agent/ChannelIsolationLine.tsx +21 -0
- manigent/web/frontend/src/components/settings/agent/ChannelsSection.test.tsx +879 -0
- manigent/web/frontend/src/components/settings/agent/ChannelsSection.tsx +1124 -0
- manigent/web/frontend/src/components/settings/agent/EnvVarsCard.test.ts +15 -0
- manigent/web/frontend/src/components/settings/agent/EnvVarsCard.tsx +301 -0
- manigent/web/frontend/src/components/settings/agent/ExtraDirsList.tsx +85 -0
- manigent/web/frontend/src/components/settings/agent/GeneralSection.tsx +88 -0
- manigent/web/frontend/src/components/settings/agent/HostDisclaimerSlot.test.tsx +32 -0
- manigent/web/frontend/src/components/settings/agent/HostDisclaimerSlot.tsx +30 -0
- manigent/web/frontend/src/components/settings/agent/HubChannelCard.test.tsx +449 -0
- manigent/web/frontend/src/components/settings/agent/HubChannelCard.tsx +312 -0
- manigent/web/frontend/src/components/settings/agent/HubInvitableAgentsCard.test.tsx +83 -0
- manigent/web/frontend/src/components/settings/agent/HubInvitableAgentsCard.tsx +64 -0
- manigent/web/frontend/src/components/settings/agent/HubSendUsageCard.test.tsx +69 -0
- manigent/web/frontend/src/components/settings/agent/HubSendUsageCard.tsx +42 -0
- manigent/web/frontend/src/components/settings/agent/HubTurnOffDialog.tsx +88 -0
- manigent/web/frontend/src/components/settings/agent/IsolationRecheckButton.test.tsx +26 -0
- manigent/web/frontend/src/components/settings/agent/IsolationRecheckButton.tsx +68 -0
- manigent/web/frontend/src/components/settings/agent/KnowledgeSection.tsx +68 -0
- manigent/web/frontend/src/components/settings/agent/LineChannelCard.test.tsx +428 -0
- manigent/web/frontend/src/components/settings/agent/LineChannelCard.tsx +343 -0
- manigent/web/frontend/src/components/settings/agent/RuntimeSection.test.tsx +164 -0
- manigent/web/frontend/src/components/settings/agent/RuntimeSection.tsx +118 -0
- manigent/web/frontend/src/components/settings/agent/StorageSection.tsx +78 -0
- manigent/web/frontend/src/components/settings/agent/WebChatChannelCard.test.tsx +253 -0
- manigent/web/frontend/src/components/settings/agent/WebChatChannelCard.tsx +401 -0
- manigent/web/frontend/src/components/settings/agent/WhatsAppChannelCard.test.tsx +462 -0
- manigent/web/frontend/src/components/settings/agent/WhatsAppChannelCard.tsx +289 -0
- manigent/web/frontend/src/components/settings/agent/agentSettings.test.tsx +109 -0
- manigent/web/frontend/src/components/settings/agent/channelSetupGuides.test.tsx +162 -0
- manigent/web/frontend/src/components/settings/agent/channelSetupGuides.tsx +119 -0
- manigent/web/frontend/src/components/settings/agent/channelsShared.ts +83 -0
- manigent/web/frontend/src/components/settings/agent/fields.tsx +67 -0
- manigent/web/frontend/src/components/settings/agent/sections.ts +36 -0
- manigent/web/frontend/src/components/settings/agent/useAgentSettingsDraft.ts +129 -0
- manigent/web/frontend/src/components/settings/agent/useInstallSelection.ts +38 -0
- manigent/web/frontend/src/components/settings/primitives.tsx +98 -0
- manigent/web/frontend/src/components/shared/ExpandToggle.tsx +45 -0
- manigent/web/frontend/src/components/shared/MarkdownBody.tsx +218 -0
- manigent/web/frontend/src/components/shared/MarkdownBody.untrusted.test.tsx +97 -0
- manigent/web/frontend/src/components/shared/RenderBody.tsx +90 -0
- manigent/web/frontend/src/components/shared/rehypeHideComments.test.tsx +115 -0
- manigent/web/frontend/src/components/shared/rehypeHideComments.ts +124 -0
- manigent/web/frontend/src/components/sharing/AcceptSharePage.tsx +141 -0
- manigent/web/frontend/src/components/sharing/ShareLandingPage.tsx +89 -0
- manigent/web/frontend/src/components/sidebar/AccountChip.test.tsx +337 -0
- manigent/web/frontend/src/components/sidebar/AccountChip.tsx +407 -0
- manigent/web/frontend/src/components/sidebar/ActiveWorkDot.tsx +9 -0
- manigent/web/frontend/src/components/sidebar/AgentProfile.tsx +44 -0
- manigent/web/frontend/src/components/sidebar/AgentRow.tsx +71 -0
- manigent/web/frontend/src/components/sidebar/AgentsPanel.retained.test.tsx +105 -0
- manigent/web/frontend/src/components/sidebar/AgentsPanel.tsx +231 -0
- manigent/web/frontend/src/components/sidebar/AssistantHero.tsx +48 -0
- manigent/web/frontend/src/components/sidebar/ChatroomItem.tsx +48 -0
- manigent/web/frontend/src/components/sidebar/CommandPalette.channelThreads.test.tsx +76 -0
- manigent/web/frontend/src/components/sidebar/CommandPalette.reopen.test.tsx +206 -0
- manigent/web/frontend/src/components/sidebar/CommandPalette.test.tsx +725 -0
- manigent/web/frontend/src/components/sidebar/CommandPalette.tsx +774 -0
- manigent/web/frontend/src/components/sidebar/ComputersPanel.tsx +144 -0
- manigent/web/frontend/src/components/sidebar/DmIcon.tsx +46 -0
- manigent/web/frontend/src/components/sidebar/DmsPanel.tsx +226 -0
- manigent/web/frontend/src/components/sidebar/FrontDeskPanel.channels.test.tsx +582 -0
- manigent/web/frontend/src/components/sidebar/FrontDeskPanel.test.tsx +151 -0
- manigent/web/frontend/src/components/sidebar/FrontDeskPanel.tsx +454 -0
- manigent/web/frontend/src/components/sidebar/HotkeysHelp.tsx +101 -0
- manigent/web/frontend/src/components/sidebar/MessageHitRow.test.tsx +84 -0
- manigent/web/frontend/src/components/sidebar/MessageHitRow.tsx +57 -0
- manigent/web/frontend/src/components/sidebar/MyDeskRailPanel.crossHighlight.test.tsx +247 -0
- manigent/web/frontend/src/components/sidebar/MyDeskRailPanel.delete.test.tsx +273 -0
- manigent/web/frontend/src/components/sidebar/MyDeskRailPanel.tsx +351 -0
- manigent/web/frontend/src/components/sidebar/PanelShell.tsx +48 -0
- manigent/web/frontend/src/components/sidebar/ProjectItem.tsx +161 -0
- manigent/web/frontend/src/components/sidebar/ProjectRow.tsx +151 -0
- manigent/web/frontend/src/components/sidebar/ProjectsPanel.tsx +80 -0
- manigent/web/frontend/src/components/sidebar/PublicPanel.counterpart.test.tsx +85 -0
- manigent/web/frontend/src/components/sidebar/PublicPanel.hub.test.tsx +147 -0
- manigent/web/frontend/src/components/sidebar/PublicPanel.tsx +271 -0
- manigent/web/frontend/src/components/sidebar/RecencyHeader.tsx +17 -0
- manigent/web/frontend/src/components/sidebar/ScheduledPanel.tsx +58 -0
- manigent/web/frontend/src/components/sidebar/SidebarAvatar.tsx +128 -0
- manigent/web/frontend/src/components/sidebar/SidebarRail.tsx +163 -0
- manigent/web/frontend/src/components/sidebar/TeamGroup.tsx +67 -0
- manigent/web/frontend/src/components/sidebar/dmPrefill.test.ts +69 -0
- manigent/web/frontend/src/components/sidebar/dmPrefill.ts +80 -0
- manigent/web/frontend/src/components/sidebar/index.ts +18 -0
- manigent/web/frontend/src/components/sidebar/railShortcuts.ts +18 -0
- manigent/web/frontend/src/components/today/lib.test.ts +70 -0
- manigent/web/frontend/src/components/today/lib.ts +296 -0
- manigent/web/frontend/src/components/today/today.css +113 -0
- manigent/web/frontend/src/components/welcome/RunnerSetup.css +253 -0
- manigent/web/frontend/src/components/welcome/RunnerSetup.tsx +148 -0
- manigent/web/frontend/src/components/welcome/WelcomePage.css +383 -0
- manigent/web/frontend/src/components/welcome/WelcomePage.tsx +329 -0
- manigent/web/frontend/src/components/welcome/welcomeCopy.test.ts +382 -0
- manigent/web/frontend/src/components/welcome/welcomeCopy.ts +313 -0
- manigent/web/frontend/src/config/llmProviders.test.ts +161 -0
- manigent/web/frontend/src/config/llmProviders.ts +109 -0
- manigent/web/frontend/src/config/providerIds.fixture.json +13 -0
- manigent/web/frontend/src/hooks/accountNavigation.test.tsx +138 -0
- manigent/web/frontend/src/hooks/index.ts +10 -0
- manigent/web/frontend/src/hooks/useActiveWorkBootstrap.ts +86 -0
- manigent/web/frontend/src/hooks/useAgentAccess.test.tsx +30 -0
- manigent/web/frontend/src/hooks/useAgentAccess.ts +204 -0
- manigent/web/frontend/src/hooks/useAgentSampleRequests.ts +27 -0
- manigent/web/frontend/src/hooks/useAgentSearch.ts +10 -0
- manigent/web/frontend/src/hooks/useAgents.ts +46 -0
- manigent/web/frontend/src/hooks/useAnnouncements.test.ts +112 -0
- manigent/web/frontend/src/hooks/useAnnouncements.ts +100 -0
- manigent/web/frontend/src/hooks/useAssistantAgent.ts +24 -0
- manigent/web/frontend/src/hooks/useAutoResizeTextarea.ts +18 -0
- manigent/web/frontend/src/hooks/useBridgeDeliveries.test.tsx +79 -0
- manigent/web/frontend/src/hooks/useBriefTabs.ts +122 -0
- manigent/web/frontend/src/hooks/useChannelThreads.ts +69 -0
- manigent/web/frontend/src/hooks/useComposeForm.ts +80 -0
- manigent/web/frontend/src/hooks/useComputers.ts +123 -0
- manigent/web/frontend/src/hooks/useContextFirstItem.ts +118 -0
- manigent/web/frontend/src/hooks/useCreateProject.ts +78 -0
- manigent/web/frontend/src/hooks/useDebouncedValue.ts +16 -0
- manigent/web/frontend/src/hooks/useDeleteProject.ts +27 -0
- manigent/web/frontend/src/hooks/useDeskDispatch.test.tsx +170 -0
- manigent/web/frontend/src/hooks/useDeskDispatch.ts +135 -0
- manigent/web/frontend/src/hooks/useDeskReadState.test.tsx +85 -0
- manigent/web/frontend/src/hooks/useDeskReadState.ts +150 -0
- manigent/web/frontend/src/hooks/useDeskRecentlyDone.test.tsx +222 -0
- manigent/web/frontend/src/hooks/useDeskRecentlyDone.ts +225 -0
- manigent/web/frontend/src/hooks/useDeskTour.ts +37 -0
- manigent/web/frontend/src/hooks/useDeskUpdates.channelThreads.test.tsx +91 -0
- manigent/web/frontend/src/hooks/useDeskUpdates.hubThreads.test.tsx +93 -0
- manigent/web/frontend/src/hooks/useDeskUpdates.ts +353 -0
- manigent/web/frontend/src/hooks/useDisconnectIntegration.ts +23 -0
- manigent/web/frontend/src/hooks/useDmThreads.ts +99 -0
- manigent/web/frontend/src/hooks/useFileDropzone.ts +93 -0
- manigent/web/frontend/src/hooks/useFileUpload.ts +38 -0
- manigent/web/frontend/src/hooks/useFiles.ts +98 -0
- manigent/web/frontend/src/hooks/useHub.test.tsx +237 -0
- manigent/web/frontend/src/hooks/useHub.ts +502 -0
- manigent/web/frontend/src/hooks/useInstall.ts +82 -0
- manigent/web/frontend/src/hooks/useLabels.test.tsx +294 -0
- manigent/web/frontend/src/hooks/useLabels.ts +287 -0
- manigent/web/frontend/src/hooks/useLogout.ts +49 -0
- manigent/web/frontend/src/hooks/useMentionDetection.ts +90 -0
- manigent/web/frontend/src/hooks/useMessageAttachments.deskLimit.test.ts +264 -0
- manigent/web/frontend/src/hooks/useMessageAttachments.ts +283 -0
- manigent/web/frontend/src/hooks/useMessageDeepLink.test.tsx +70 -0
- manigent/web/frontend/src/hooks/useMessageDeepLink.ts +32 -0
- manigent/web/frontend/src/hooks/useMessageSearch.ts +78 -0
- manigent/web/frontend/src/hooks/useModelConfigs.ts +178 -0
- manigent/web/frontend/src/hooks/useMyAgents.ts +18 -0
- manigent/web/frontend/src/hooks/usePointerReorder.ts +270 -0
- manigent/web/frontend/src/hooks/usePrefersReducedMotion.ts +18 -0
- manigent/web/frontend/src/hooks/useProjectPlan.ts +36 -0
- manigent/web/frontend/src/hooks/useProjectReport.ts +19 -0
- manigent/web/frontend/src/hooks/useProjects.ts +104 -0
- manigent/web/frontend/src/hooks/useProjectsWithChatrooms.ts +97 -0
- manigent/web/frontend/src/hooks/usePublicRequests.ts +89 -0
- manigent/web/frontend/src/hooks/useRecentAgents.ts +38 -0
- manigent/web/frontend/src/hooks/useRenameProject.test.tsx +185 -0
- manigent/web/frontend/src/hooks/useRenameProject.ts +192 -0
- manigent/web/frontend/src/hooks/useRoomTrust.ts +56 -0
- manigent/web/frontend/src/hooks/useSharing.ts +46 -0
- manigent/web/frontend/src/hooks/useSopRecents.ts +55 -0
- manigent/web/frontend/src/hooks/useSopSchedules.ts +25 -0
- manigent/web/frontend/src/hooks/useSops.ts +99 -0
- manigent/web/frontend/src/hooks/useSwitchAccount.ts +41 -0
- manigent/web/frontend/src/hooks/useTeamGroups.ts +48 -0
- manigent/web/frontend/src/hooks/useThreadOutbox.ts +68 -0
- manigent/web/frontend/src/hooks/useTodos.add.test.tsx +89 -0
- manigent/web/frontend/src/hooks/useTodos.linkProject.test.tsx +115 -0
- manigent/web/frontend/src/hooks/useTodos.saveDraft.test.tsx +188 -0
- manigent/web/frontend/src/hooks/useTodos.ts +396 -0
- manigent/web/frontend/src/hooks/useUntrustedBodies.test.tsx +87 -0
- manigent/web/frontend/src/hooks/useUntrustedBodies.ts +51 -0
- manigent/web/frontend/src/hooks/useWebSocket.briefTab.test.tsx +148 -0
- manigent/web/frontend/src/hooks/useWebSocket.channelThreads.test.tsx +82 -0
- manigent/web/frontend/src/hooks/useWebSocket.hostSync.test.tsx +92 -0
- manigent/web/frontend/src/hooks/useWebSocket.hub.test.tsx +114 -0
- manigent/web/frontend/src/hooks/useWebSocket.labelSync.test.tsx +168 -0
- manigent/web/frontend/src/hooks/useWebSocket.plan.test.tsx +168 -0
- manigent/web/frontend/src/hooks/useWebSocket.reconnect.test.tsx +166 -0
- manigent/web/frontend/src/hooks/useWebSocket.runnerVersions.test.tsx +167 -0
- manigent/web/frontend/src/hooks/useWebSocket.ts +495 -0
- manigent/web/frontend/src/hooks/useWindowFileDropGuard.ts +33 -0
- manigent/web/frontend/src/landing.tsx +11 -0
- manigent/web/frontend/src/main.tsx +17 -0
- manigent/web/frontend/src/private-beta.tsx +10 -0
- manigent/web/frontend/src/public.tsx +42 -0
- manigent/web/frontend/src/queryClient.ts +16 -0
- manigent/web/frontend/src/stores/activeWorkStore.ts +88 -0
- manigent/web/frontend/src/stores/announcementStore.test.ts +217 -0
- manigent/web/frontend/src/stores/announcementStore.ts +169 -0
- manigent/web/frontend/src/stores/authStore.multiSession.test.ts +304 -0
- manigent/web/frontend/src/stores/authStore.test.ts +235 -0
- manigent/web/frontend/src/stores/authStore.ts +693 -0
- manigent/web/frontend/src/stores/deskLabelViewStore.test.ts +162 -0
- manigent/web/frontend/src/stores/deskLabelViewStore.ts +234 -0
- manigent/web/frontend/src/stores/deskLinkStore.ts +54 -0
- manigent/web/frontend/src/stores/deskStore.test.ts +53 -0
- manigent/web/frontend/src/stores/deskStore.ts +93 -0
- manigent/web/frontend/src/stores/heldPostsStore.ts +78 -0
- manigent/web/frontend/src/stores/mcpAuthStore.ts +52 -0
- manigent/web/frontend/src/stores/modelSelectionStore.ts +33 -0
- manigent/web/frontend/src/stores/perUserStores.ts +79 -0
- manigent/web/frontend/src/stores/runnerVersionStore.test.ts +81 -0
- manigent/web/frontend/src/stores/runnerVersionStore.ts +60 -0
- manigent/web/frontend/src/stores/skillAuthStore.ts +54 -0
- manigent/web/frontend/src/stores/switchReset.test.ts +236 -0
- manigent/web/frontend/src/stores/tokenExp.ts +32 -0
- manigent/web/frontend/src/stores/uiStore.ts +186 -0
- manigent/web/frontend/src/stores/unreadStore.ts +204 -0
- manigent/web/frontend/src/stores/unsavedGuard.ts +22 -0
- manigent/web/frontend/src/styles/design/fonts/JetBrainsMono-Latin.woff2 +0 -0
- manigent/web/frontend/src/styles/design/fonts/Nunito-Latin.woff2 +0 -0
- manigent/web/frontend/src/styles/design/fonts/Nunito-LatinExt.woff2 +0 -0
- manigent/web/frontend/src/styles/design/tokens.css +160 -0
- manigent/web/frontend/src/styles/homepage.css +242 -0
- manigent/web/frontend/src/styles/index.css +126 -0
- manigent/web/frontend/src/styles/landing.css +52 -0
- manigent/web/frontend/src/test/authFixtures.ts +154 -0
- manigent/web/frontend/src/test/fetchHarness.ts +203 -0
- manigent/web/frontend/src/test/fixtures/channelThreads.smoke.json +42 -0
- manigent/web/frontend/src/test/hubFixtures.ts +212 -0
- manigent/web/frontend/src/test/queryWrapper.tsx +9 -0
- manigent/web/frontend/src/test/suiteHygiene.test.ts +212 -0
- manigent/web/frontend/src/types/channelThreadName.test.ts +16 -0
- manigent/web/frontend/src/types/index.ts +903 -0
- manigent/web/frontend/src/utils/agentAccessCopy.test.ts +53 -0
- manigent/web/frontend/src/utils/agentAccessCopy.ts +231 -0
- manigent/web/frontend/src/utils/agentDisplay.ts +81 -0
- manigent/web/frontend/src/utils/briefSchedule.ts +25 -0
- manigent/web/frontend/src/utils/channelThreads.test.ts +109 -0
- manigent/web/frontend/src/utils/channelThreads.ts +179 -0
- manigent/web/frontend/src/utils/chatroomDisplay.ts +11 -0
- manigent/web/frontend/src/utils/deskLinks.test.ts +155 -0
- manigent/web/frontend/src/utils/deskLinks.ts +115 -0
- manigent/web/frontend/src/utils/deskRecipient.ts +29 -0
- manigent/web/frontend/src/utils/formatDate.ts +102 -0
- manigent/web/frontend/src/utils/frontDesk.ts +65 -0
- manigent/web/frontend/src/utils/hubChannelView.test.ts +178 -0
- manigent/web/frontend/src/utils/hubChannelView.ts +307 -0
- manigent/web/frontend/src/utils/hubDelivery.test.ts +105 -0
- manigent/web/frontend/src/utils/hubDelivery.ts +137 -0
- manigent/web/frontend/src/utils/hubDisplay.test.ts +157 -0
- manigent/web/frontend/src/utils/hubDisplay.ts +221 -0
- manigent/web/frontend/src/utils/hubThread.test.ts +184 -0
- manigent/web/frontend/src/utils/hubThread.ts +247 -0
- manigent/web/frontend/src/utils/labelErrors.test.ts +127 -0
- manigent/web/frontend/src/utils/labelErrors.ts +123 -0
- manigent/web/frontend/src/utils/labelView.test.ts +846 -0
- manigent/web/frontend/src/utils/labelView.ts +760 -0
- manigent/web/frontend/src/utils/legalUrls.ts +11 -0
- manigent/web/frontend/src/utils/messageSender.test.ts +32 -0
- manigent/web/frontend/src/utils/messageSender.ts +29 -0
- manigent/web/frontend/src/utils/oauthScopeCopy.ts +73 -0
- manigent/web/frontend/src/utils/personalize.ts +49 -0
- manigent/web/frontend/src/utils/reachableAgents.test.ts +36 -0
- manigent/web/frontend/src/utils/reachableAgents.ts +24 -0
- manigent/web/frontend/src/utils/recencyBuckets.ts +61 -0
- manigent/web/frontend/src/utils/roomTrust.test.ts +94 -0
- manigent/web/frontend/src/utils/roomTrust.ts +111 -0
- manigent/web/frontend/src/utils/snippetHighlight.test.ts +63 -0
- manigent/web/frontend/src/utils/snippetHighlight.ts +42 -0
- manigent/web/frontend/src/utils/sopRecipient.ts +37 -0
- manigent/web/frontend/src/utils/sopRequest.test.ts +91 -0
- manigent/web/frontend/src/utils/sopRequest.ts +68 -0
- manigent/web/frontend/src/utils/sopSchedule.ts +26 -0
- manigent/web/frontend/src/utils/sopSection.test.ts +148 -0
- manigent/web/frontend/src/utils/sopSection.ts +143 -0
- manigent/web/frontend/src/utils/textSearch.test.ts +60 -0
- manigent/web/frontend/src/utils/textSearch.ts +43 -0
- manigent/web/frontend/src/utils/thoughtPartner.ts +26 -0
- manigent/web/frontend/src/utils/threadName.test.ts +131 -0
- manigent/web/frontend/src/utils/threadName.ts +122 -0
- manigent/web/frontend/src/utils/ticketView.test.ts +296 -0
- manigent/web/frontend/src/utils/ticketView.ts +175 -0
- manigent/web/frontend/src/utils/todoAttachments.desiredState.test.ts +180 -0
- manigent/web/frontend/src/utils/todoAttachments.ts +126 -0
- manigent/web/frontend/src/utils/todoDraft.test.ts +84 -0
- manigent/web/frontend/src/utils/todoDraft.ts +46 -0
- manigent/web/frontend/src/utils/todoSearch.test.ts +82 -0
- manigent/web/frontend/src/utils/todoSearch.ts +43 -0
- manigent/web/frontend/src/utils/versionMatch.test.ts +295 -0
- manigent/web/frontend/src/utils/versionMatch.ts +245 -0
- manigent/web/frontend/src/vite-env.d.ts +1 -0
- manigent/web/frontend/tailwind.config.js +86 -0
- manigent/web/frontend/tos.html +188 -0
- manigent/web/frontend/tsconfig.dts.json +25 -0
- manigent/web/frontend/tsconfig.json +26 -0
- manigent/web/frontend/tsconfig.node.json +11 -0
- manigent/web/frontend/vite.config.ts +41 -0
- manigent/web/frontend/vitest.config.ts +16 -0
- manigent/ws_edge/app.py +514 -0
- manigent/ws_edge/auth.py +104 -0
- manigent/ws_edge/link.py +282 -0
- manigent/ws_edge/registry.py +206 -0
- manigent/ws_edge/terminal_relay.py +269 -0
- manigent_server-0.1.0.dist-info/METADATA +138 -0
- manigent_server-0.1.0.dist-info/RECORD +1004 -0
- manigent_server-0.1.0.dist-info/WHEEL +4 -0
- manigent_server-0.1.0.dist-info/entry_points.txt +2 -0
- manigent_server-0.1.0.dist-info/licenses/LICENSE +68 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
"""
|
|
3
|
+
manigent/server/config.py
|
|
4
|
+
Env-driven server configuration.
|
|
5
|
+
|
|
6
|
+
The **CORS allowlist** — ``allow_origins=["*"]`` combined with
|
|
7
|
+
``allow_credentials=True`` is both unsafe and spec-incompatible.
|
|
8
|
+
``cors_allow_origins`` builds the explicit allowlist from the environment
|
|
9
|
+
(``MANIGENT_CORS_ORIGINS`` + ``MANIGENT_APP_URL``).
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def cors_allow_origins() -> list[str]:
|
|
17
|
+
"""Explicit CORS allowlist, replacing ``allow_origins=['*']``.
|
|
18
|
+
|
|
19
|
+
Order-preserving union of:
|
|
20
|
+
- ``MANIGENT_CORS_ORIGINS`` — comma-separated explicit origins (the public
|
|
21
|
+
app origin plus any extra, e.g. ``https://ics.manigent.ai``),
|
|
22
|
+
- ``MANIGENT_APP_URL`` — the public app origin.
|
|
23
|
+
|
|
24
|
+
De-duplicated. When nothing is configured, falls back to ``['*']`` so dev and
|
|
25
|
+
the test suite keep working unchanged; production is expected to set at least
|
|
26
|
+
one origin (``['*']`` + credentials cannot reject a cross-origin caller).
|
|
27
|
+
"""
|
|
28
|
+
origins: list[str] = []
|
|
29
|
+
|
|
30
|
+
def _add(value: str | None) -> None:
|
|
31
|
+
cleaned = (value or "").strip().rstrip("/")
|
|
32
|
+
if cleaned and cleaned not in origins:
|
|
33
|
+
origins.append(cleaned)
|
|
34
|
+
|
|
35
|
+
for item in os.environ.get("MANIGENT_CORS_ORIGINS", "").split(","):
|
|
36
|
+
_add(item)
|
|
37
|
+
_add(os.environ.get("MANIGENT_APP_URL"))
|
|
38
|
+
|
|
39
|
+
return origins or ["*"]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def public_app_url() -> str:
|
|
43
|
+
"""The origin a user's own machine should be told to talk to.
|
|
44
|
+
|
|
45
|
+
Needed by anything that hands a URL to something OUTSIDE this process — the
|
|
46
|
+
one-command installer bakes it into a script that a laptop will use for
|
|
47
|
+
weeks, so guessing it from an inbound ``Host`` header (which a proxy may have
|
|
48
|
+
rewritten) is not good enough.
|
|
49
|
+
|
|
50
|
+
Precedence mirrors ``server/email.APP_BASE_URL``, which has the same problem
|
|
51
|
+
for links in verification mail: ``MANIGENT_APP_URL`` first, then
|
|
52
|
+
``MANIGENT_VERIFICATION_URL``. Returns "" when neither is set rather than
|
|
53
|
+
inventing ``https://manigent.ai`` — a self-hosted deployment that forgot to
|
|
54
|
+
configure this must produce an obviously broken command, not one that
|
|
55
|
+
silently sends its users' tokens to someone else's server.
|
|
56
|
+
"""
|
|
57
|
+
for name in ("MANIGENT_APP_URL", "MANIGENT_VERIFICATION_URL"):
|
|
58
|
+
value = (os.environ.get(name) or "").strip().rstrip("/")
|
|
59
|
+
if value:
|
|
60
|
+
return value
|
|
61
|
+
return ""
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
"""
|
|
3
|
+
manigent/server/context.py
|
|
4
|
+
Server context holding shared dependencies.
|
|
5
|
+
|
|
6
|
+
The ServerContext provides access to all stores, services, and utilities
|
|
7
|
+
needed by route handlers. It's created once at app startup and passed
|
|
8
|
+
to route registration functions.
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from typing import TYPE_CHECKING
|
|
14
|
+
|
|
15
|
+
from manigent.server.signup_policy import SignupPolicy
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from manigent.server.isolation_gate import IsolationGate
|
|
19
|
+
from manigent.models.work_tracker import WorkTracker
|
|
20
|
+
from manigent.server.hub.runtime import HubRuntime
|
|
21
|
+
from manigent.server.ws_hub import Hub
|
|
22
|
+
from manigent.server.socket_events import SocketEvents
|
|
23
|
+
from manigent.server.auth import AuthService
|
|
24
|
+
from manigent.server.timeout_checker import BatchTimeoutChecker
|
|
25
|
+
from manigent.server.message_scheduler import MessageScheduler
|
|
26
|
+
from manigent.server.oauth_state import OAuthStateStore
|
|
27
|
+
from manigent.server.oauth_login.handoff import LoginHandoffStore
|
|
28
|
+
from manigent.server.oauth_login.cli_state import CliOAuthStateStore
|
|
29
|
+
from manigent.sync.runloop_manager import ChangelogRunloopManager
|
|
30
|
+
from manigent.models.context import ModelContext
|
|
31
|
+
from manigent.models.scheduled_message import ScheduledMessageStore
|
|
32
|
+
from manigent.models.reflection_schedule import ReflectionScheduleStore
|
|
33
|
+
from manigent.models.managed_job import ManagedJobStore
|
|
34
|
+
from manigent.server.reflection_scheduler import ReflectionScheduler
|
|
35
|
+
from manigent.server.chat_search_index import ChatSearchIndex
|
|
36
|
+
from manigent.ws_edge.terminal_relay import TerminalRelay
|
|
37
|
+
from manigent.server.home_fs_relay import HomeFsRelay
|
|
38
|
+
from manigent.server.channels.store import ChannelStore
|
|
39
|
+
from manigent.server.channels.gateway import ChannelGateway
|
|
40
|
+
from manigent.server.inspection import OutsideIngress
|
|
41
|
+
from manigent.server.room_flow import RoomFlowSwitch
|
|
42
|
+
from pathlib import Path
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class ServerContext:
|
|
47
|
+
"""
|
|
48
|
+
Shared server context holding all dependencies.
|
|
49
|
+
|
|
50
|
+
This replaces the closure-based approach in create_app, making
|
|
51
|
+
dependencies explicit and enabling easier route module splitting.
|
|
52
|
+
"""
|
|
53
|
+
# Stores
|
|
54
|
+
model_ctx: "ModelContext" # Server-wide file I/O layer
|
|
55
|
+
|
|
56
|
+
# Services
|
|
57
|
+
ws_hub: "Hub"
|
|
58
|
+
work_tracker: "WorkTracker"
|
|
59
|
+
auth: "AuthService"
|
|
60
|
+
runloop_manager: "ChangelogRunloopManager" # Per-project changelog handling
|
|
61
|
+
timeout_checker: "BatchTimeoutChecker" # Background batch timeout enforcement
|
|
62
|
+
scheduled_message_store: "ScheduledMessageStore" # Scheduled message persistence
|
|
63
|
+
message_scheduler: "MessageScheduler" # Background scheduled message firing
|
|
64
|
+
reflection_schedule_store: "ReflectionScheduleStore" # Per-user reflection schedule
|
|
65
|
+
reflection_scheduler: "ReflectionScheduler" # Background reflection fan-out
|
|
66
|
+
managed_job_store: "ManagedJobStore" # Durable background-job lifecycle state
|
|
67
|
+
oauth_state_store: "OAuthStateStore" # In-memory state store for the MCP OAuth relay flow
|
|
68
|
+
login_handoff_store: "LoginHandoffStore" # In-memory single-use OAuth-login exchange codes
|
|
69
|
+
cli_oauth_state_store: "CliOAuthStateStore" # In-memory single-use CLI OAuth pending-state + PKCE bindings
|
|
70
|
+
chat_search_index: "ChatSearchIndex" # Derived FTS5 index behind GET /me/search/messages
|
|
71
|
+
# Browser <-> computer terminal sessions. Optional so contexts built by
|
|
72
|
+
# hand in tests keep working; create_app always sets it.
|
|
73
|
+
terminal_relay: "TerminalRelay | None" = None
|
|
74
|
+
# Home-folder requests to agents' runners (server/home_fs_relay.py).
|
|
75
|
+
# Optional for the same reason; create_app always sets it.
|
|
76
|
+
home_fs_relay: "HomeFsRelay | None" = None
|
|
77
|
+
# What core does when a socket opens, closes or reports in
|
|
78
|
+
# (server/socket_events.py). Optional for the same reason; create_app
|
|
79
|
+
# always sets it, and the socket routes build one on first use otherwise.
|
|
80
|
+
socket_events: "SocketEvents | None" = None
|
|
81
|
+
# Channel records (server/channels/store.py). Open whether or not the
|
|
82
|
+
# gateway is on: the message write paths ask it whether a project is a
|
|
83
|
+
# channel thread. Optional so hand-built test contexts keep working.
|
|
84
|
+
channel_store: "ChannelStore | None" = None
|
|
85
|
+
# The channel gateway, or None while the kill switch is off
|
|
86
|
+
# (MANIGENT_CHANNELS_ENABLED) or its configuration is invalid.
|
|
87
|
+
channel_gateway: "ChannelGateway | None" = None
|
|
88
|
+
# The hub's one owner of "is it live" (server/hub/runtime.py): built
|
|
89
|
+
# whenever the gateway is, idle in hub mode off.
|
|
90
|
+
hub_runtime: "HubRuntime | None" = None
|
|
91
|
+
# Isolated projects reach only sandbox-capable runners, and are written to
|
|
92
|
+
# only under a live turn grant (server/isolation_gate.py). Optional so
|
|
93
|
+
# hand-built test contexts keep working; create_app always sets it.
|
|
94
|
+
isolation_gate: "IsolationGate | None" = None
|
|
95
|
+
#: The owner-isolation setting's server half (server/owner_isolation.py).
|
|
96
|
+
owner_isolation: object = None
|
|
97
|
+
# The message inspection hook every outside message passes before it is
|
|
98
|
+
# stored (server/inspection.py), and the per-room flow switch it checks
|
|
99
|
+
# first (server/room_flow.py). Optional so hand-built test contexts keep
|
|
100
|
+
# working; create_app always sets both and installs the append guard.
|
|
101
|
+
outside_ingress: "OutsideIngress | None" = None
|
|
102
|
+
room_flow: "RoomFlowSwitch | None" = None
|
|
103
|
+
# Hub send caps for agents and the per-user target cap (server/hub/agent_send_guard.py);
|
|
104
|
+
# built on first use from the channel store.
|
|
105
|
+
hub_send_guard: object = None
|
|
106
|
+
room_bridge_subscriber: object = None
|
|
107
|
+
|
|
108
|
+
# Who may create an account (MANIGENT_SIGNUP_MODE / _TRUSTED_DOMAINS),
|
|
109
|
+
# read once at boot. The default is invite-only, as before the setting.
|
|
110
|
+
signup_policy: "SignupPolicy" = field(default_factory=SignupPolicy)
|
|
111
|
+
|
|
112
|
+
# Config
|
|
113
|
+
batch_timeout: int = 1800 # Default 30 minutes
|
|
114
|
+
skills_dir: "Path | None" = None # Skills registry directory
|
|
115
|
+
mcps_dir: "Path | None" = None # MCP server registry directory
|
|
116
|
+
agent_pool_dir: "Path | None" = None # manigent-agents checkout (the agent catalog)
|
|
117
|
+
# announcements.json (optional). None => the repo-root default resolved by
|
|
118
|
+
# manigent/server/announcements.py. The config has no write surface — it
|
|
119
|
+
# stays a file on disk — so this override is how a test or a deployment
|
|
120
|
+
# points at a different one.
|
|
121
|
+
announcements_path: "Path | None" = None
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
"""The own-coordinator rule (plan-owner-isolation section 4).
|
|
3
|
+
|
|
4
|
+
A project's coordinator is either its owner (``coordinator_id ==
|
|
5
|
+
created_by``, a user) or an agent the owner registered. A hub stand-in (an id
|
|
6
|
+
with ``~``), another account's agent and an unknown id never are. Requester
|
|
7
|
+
ends name their outside party as ``counterpart_id`` instead.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from typing import TYPE_CHECKING, Optional
|
|
12
|
+
|
|
13
|
+
from manigent.models.agent import Agent
|
|
14
|
+
from manigent.models.project import STAND_IN_SEPARATOR
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from manigent.models.context import ModelContext
|
|
18
|
+
|
|
19
|
+
CODE = "foreign_coordinator"
|
|
20
|
+
MESSAGE = "Only this account's own agents can coordinate its projects."
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def is_own_coordinator(model_ctx: "ModelContext", *, project_owner_id: Optional[str],
|
|
24
|
+
coordinator_id: Optional[str]) -> bool:
|
|
25
|
+
"""True iff the coordinator is the project's owner or an agent the owner
|
|
26
|
+
registered. Pure over the registry."""
|
|
27
|
+
if not project_owner_id or not coordinator_id or STAND_IN_SEPARATOR in coordinator_id:
|
|
28
|
+
return False
|
|
29
|
+
if coordinator_id == project_owner_id:
|
|
30
|
+
return True
|
|
31
|
+
agent = Agent.get(coordinator_id, model_ctx)
|
|
32
|
+
return agent is not None and agent.registered_by == project_owner_id
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ForeignCoordinator(Exception):
|
|
36
|
+
"""An append that would make a stand-in, another account's agent or an
|
|
37
|
+
unknown id the coordinator of a project. Rendered ``foreign_coordinator``
|
|
38
|
+
[403] by the app's exception handler."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def foreign_coordinator(message: str = MESSAGE):
|
|
42
|
+
from manigent.server.hub.browser import HubError
|
|
43
|
+
|
|
44
|
+
return HubError(CODE, message)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def coordinator_guard(model_ctx: "ModelContext"):
|
|
48
|
+
"""The append-guard half the server installs on its runloops (never the
|
|
49
|
+
shared runloop class, so a runner replica replaying old entries never
|
|
50
|
+
raises): PROJECT_CREATED and PROJECT_COORDINATOR_REASSIGNED are refused
|
|
51
|
+
unless their coordinator is the project's owner or the owner's agent.
|
|
52
|
+
Covers ``append`` and ``append_batch`` (the tunnel's path) alike."""
|
|
53
|
+
from manigent.sync.changelog import ChangelogEntryType
|
|
54
|
+
|
|
55
|
+
def guard(project_id: str, entries, _ticket) -> None:
|
|
56
|
+
owner: Optional[str] = None
|
|
57
|
+
for entry_type, payload in entries:
|
|
58
|
+
if entry_type == ChangelogEntryType.PROJECT_CREATED:
|
|
59
|
+
owner = payload.created_by
|
|
60
|
+
elif entry_type == ChangelogEntryType.PROJECT_COORDINATOR_REASSIGNED:
|
|
61
|
+
from manigent.models.project import Project
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
owner = Project.get(project_id, model_ctx).created_by
|
|
65
|
+
except ValueError:
|
|
66
|
+
owner = None
|
|
67
|
+
else:
|
|
68
|
+
continue
|
|
69
|
+
if not is_own_coordinator(model_ctx, project_owner_id=owner, coordinator_id=payload.coordinator_id):
|
|
70
|
+
raise ForeignCoordinator(
|
|
71
|
+
f"{entry_type.value} in {project_id[:8]}: coordinator "
|
|
72
|
+
f"{(payload.coordinator_id or '')[:12]!r} is not the owner or the owner's agent"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return guard
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def compose_guards(*guards):
|
|
79
|
+
"""One append guard running each in turn (the ingress guard, then this)."""
|
|
80
|
+
def guard(project_id, entries, ticket) -> None:
|
|
81
|
+
for g in guards:
|
|
82
|
+
g(project_id, entries, ticket)
|
|
83
|
+
return guard
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def require_own_actor(model_ctx: "ModelContext", project) -> None:
|
|
87
|
+
"""Room create and invite: the coordinator token's holder must also be
|
|
88
|
+
the owner's agent (defence in depth: after the start-up migration and
|
|
89
|
+
with the append guard armed, no project has a foreign coordinator)."""
|
|
90
|
+
if not is_own_coordinator(model_ctx, project_owner_id=project.created_by,
|
|
91
|
+
coordinator_id=project.coordinator_id):
|
|
92
|
+
raise foreign_coordinator()
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def clamp_foreign_expects(model_ctx: "ModelContext", project, author_id: str, expects: list[str], *,
|
|
96
|
+
reply_to_author: Optional[str] = None) -> list[str]:
|
|
97
|
+
"""``expects_response_from`` on a row whose author is outside (another
|
|
98
|
+
account, a stand-in, a requester): it may name only the project's
|
|
99
|
+
coordinator, or ``reply_to_author`` (the own agent whose message this
|
|
100
|
+
replies to; on the tunnel, the binding's responder, which is the host
|
|
101
|
+
coordinator). The rest is dropped and logged. An inside author's list is
|
|
102
|
+
returned unchanged."""
|
|
103
|
+
import logging
|
|
104
|
+
|
|
105
|
+
from manigent.models.provenance import outside_author
|
|
106
|
+
|
|
107
|
+
if outside_author(project, author_id, model_ctx) is None:
|
|
108
|
+
return list(expects)
|
|
109
|
+
allowed = {project.coordinator_id, reply_to_author} - {None}
|
|
110
|
+
kept = [pid for pid in expects if pid in allowed]
|
|
111
|
+
if len(kept) != len(expects):
|
|
112
|
+
logging.getLogger("manigent.server.coordinator_rule").info(
|
|
113
|
+
"clamped expects of outside author %s in %s: dropped %d",
|
|
114
|
+
author_id[:12], project.id[:8], len(expects) - len(kept))
|
|
115
|
+
return kept
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
"""
|
|
3
|
+
manigent/server/desk_todo_notify.py
|
|
4
|
+
|
|
5
|
+
A project event moves this owner's to-dos.
|
|
6
|
+
|
|
7
|
+
Two halves, and the module header says so rather than leaving the next reader
|
|
8
|
+
to infer the remit from whatever happens to be in the file:
|
|
9
|
+
|
|
10
|
+
* **The notify half** (:func:`notify_plate_of_project_change`) — a project's
|
|
11
|
+
status moved or it was deleted, so the rows pointing at it derive a new
|
|
12
|
+
ticket state and the desk must refetch.
|
|
13
|
+
* **The write half** (:func:`mirror_plate_to_spawned_project`) — a project was
|
|
14
|
+
SPAWNED from a context a to-do already points at, so the to-do gains the new
|
|
15
|
+
project and keeps reading Working against the work that actually continued.
|
|
16
|
+
|
|
17
|
+
They share the one scan (``todos_referencing_project``), the one owner-addressed
|
|
18
|
+
envelope, and the rule that neither may ever fail the project event that caused
|
|
19
|
+
it.
|
|
20
|
+
|
|
21
|
+
**THE TRIGGER IS THE ROUTE, NOT THE STATE TRANSITION.** This paragraph is the
|
|
22
|
+
deliverable, not decoration. A project's status is flipped by the CHANGELOG —
|
|
23
|
+
``models/context.py::_handle_project_completed`` and
|
|
24
|
+
``_handle_project_reactivated`` — and that context has **no socket hub**. So the
|
|
25
|
+
broadcast cannot live where the status actually changes; it is added at each of
|
|
26
|
+
the ROUTES that cause the change instead.
|
|
27
|
+
|
|
28
|
+
The consequence is real and it is accepted rather than designed around: a
|
|
29
|
+
future non-HTTP producer of a completion or a reactivation silently misses this
|
|
30
|
+
sync, and the owner's desk holds a stale chip until something else makes it
|
|
31
|
+
refetch. Every producer known today is wired (see the call sites below), and
|
|
32
|
+
anyone adding a fourth must add a fifth line here — there is no hook that will
|
|
33
|
+
catch it for them.
|
|
34
|
+
|
|
35
|
+
**Addressed to the TO-DO'S OWNER, never** ``broadcast_to_project``. That is
|
|
36
|
+
AC-2.4 exactly: the triggering event happens inside *another* project's context
|
|
37
|
+
— a project the owner may not even be a participant of — and must still reach
|
|
38
|
+
their desk. ``broadcast_to_project`` would fan out to that project's
|
|
39
|
+
participants, which is the wrong set in both directions.
|
|
40
|
+
|
|
41
|
+
**Cheap by construction.** One plate read for the project's creator, an
|
|
42
|
+
in-memory scan, and at most one envelope. The overwhelmingly common case is an
|
|
43
|
+
owner whose plate does not reference the project at all, and that case sends
|
|
44
|
+
nothing and costs one small JSON read.
|
|
45
|
+
|
|
46
|
+
Never raises. A project event must not fail because a desk notification could
|
|
47
|
+
not be built — the completion already happened, and the owner's recourse for a
|
|
48
|
+
missed envelope is a page refresh.
|
|
49
|
+
"""
|
|
50
|
+
from __future__ import annotations
|
|
51
|
+
|
|
52
|
+
import logging
|
|
53
|
+
from typing import TYPE_CHECKING
|
|
54
|
+
|
|
55
|
+
from manigent.api.control import (
|
|
56
|
+
ControlEnvelope,
|
|
57
|
+
ControlMessageType,
|
|
58
|
+
DeskTodoSyncPayload,
|
|
59
|
+
)
|
|
60
|
+
from manigent.models.desk_todo import associate_todo
|
|
61
|
+
from manigent.models.desk_todo_link import (
|
|
62
|
+
AssociationRefused,
|
|
63
|
+
check_association_target,
|
|
64
|
+
plate_references_project,
|
|
65
|
+
todos_referencing_project,
|
|
66
|
+
)
|
|
67
|
+
from manigent.models.project import Project
|
|
68
|
+
|
|
69
|
+
if TYPE_CHECKING:
|
|
70
|
+
from manigent.server.context import ServerContext
|
|
71
|
+
|
|
72
|
+
logger = logging.getLogger("manigent.server")
|
|
73
|
+
|
|
74
|
+
# The action every project event carries. One member for all three events —
|
|
75
|
+
# completing, reactivating, deleting — because the desk ignores the payload and
|
|
76
|
+
# refetches the whole plate either way, so three actions would be three names
|
|
77
|
+
# for one behaviour.
|
|
78
|
+
PROJECT_ACTION = "project"
|
|
79
|
+
|
|
80
|
+
# The action a mirrored link carries. It is the SAME word
|
|
81
|
+
# ``POST /me/desk/todos/{id}/projects`` emits, and deliberately so: a to-do that
|
|
82
|
+
# gains a project this way must move on the owner's open plate exactly as one
|
|
83
|
+
# linked from the composer does, which means the same channel and the same
|
|
84
|
+
# action, not a second vocabulary the client would have to learn. That the two
|
|
85
|
+
# agree is asserted end to end rather than by reading this comment.
|
|
86
|
+
ASSOCIATE_ACTION = "associate"
|
|
87
|
+
|
|
88
|
+
# How a mirror reports itself on the create response. Two headers and no third,
|
|
89
|
+
# because there are only two things worth saying: it linked N to-dos, or it
|
|
90
|
+
# tried and could not.
|
|
91
|
+
#
|
|
92
|
+
# NEITHER IS EMITTED WHEN NOTHING MATCHED. That is what keeps the common path
|
|
93
|
+
# silent, and it is also what keeps the cross-owner decline indistinguishable
|
|
94
|
+
# from the not-matched case — see :func:`mirror_plate_to_spawned_project`.
|
|
95
|
+
#
|
|
96
|
+
# ``manigent/cli_client.py`` reads both off the response by literal string; it
|
|
97
|
+
# is MIT and ships in the runner wheel, which does not carry ``server/``, so it
|
|
98
|
+
# CANNOT import these names. A test asserts the two copies are equal rather than
|
|
99
|
+
# leaving the pair to drift.
|
|
100
|
+
MIRRORED_HEADER = "X-Desk-Todo-Mirrored"
|
|
101
|
+
MIRROR_ERROR_HEADER = "X-Desk-Todo-Mirror-Error"
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
async def notify_plate_of_project_change(
|
|
105
|
+
ctx: "ServerContext | None", project: "Project | None"
|
|
106
|
+
) -> None:
|
|
107
|
+
"""Push ``DESK_TODO_SYNC(action="project", id=None)`` to a project's creator
|
|
108
|
+
when their plate references it.
|
|
109
|
+
|
|
110
|
+
Called from the routes that cause a project's status to move, or that
|
|
111
|
+
destroy the project outright:
|
|
112
|
+
|
|
113
|
+
* ``routes/projects.py :: complete_project`` — after the changelog append.
|
|
114
|
+
* ``routes/projects.py :: _delete_project_in_place`` — **before** the
|
|
115
|
+
teardown, because ``project.created_by`` is unreadable once the directory
|
|
116
|
+
is gone.
|
|
117
|
+
* ``routes/messages.py`` — both ``PROJECT_REACTIVATED`` appends
|
|
118
|
+
(``send_message_as_user`` and the addressed-batch door).
|
|
119
|
+
* ``server/tunnel_subscriber.py :: _mirror`` — the auto-reactivate on the
|
|
120
|
+
far end of a cross-account tunnel.
|
|
121
|
+
|
|
122
|
+
``id`` is deliberately ``None``: one project event can move several rows at
|
|
123
|
+
once (an owner may have linked the same project to three to-dos), and the
|
|
124
|
+
desk's refetch is whole-plate regardless. A single row id would be a lie
|
|
125
|
+
about scope that the client would then have to ignore.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
ctx: The server context. Accepts ``None`` so a caller holding a
|
|
129
|
+
late-bound context — the tunnel subscriber does — can pass it
|
|
130
|
+
straight through without a guard of its own.
|
|
131
|
+
project: The project whose status moved, or which is about to be
|
|
132
|
+
deleted. ``None`` and a project with no ``created_by`` are both
|
|
133
|
+
no-ops.
|
|
134
|
+
"""
|
|
135
|
+
if ctx is None or project is None or not project.created_by:
|
|
136
|
+
return
|
|
137
|
+
try:
|
|
138
|
+
if not plate_references_project(
|
|
139
|
+
ctx.model_ctx.participants_dir, project.created_by, project.id
|
|
140
|
+
):
|
|
141
|
+
return
|
|
142
|
+
envelope = ControlEnvelope(
|
|
143
|
+
type=ControlMessageType.DESK_TODO_SYNC,
|
|
144
|
+
payload=DeskTodoSyncPayload(action=PROJECT_ACTION, id=None),
|
|
145
|
+
)
|
|
146
|
+
delivered = await ctx.ws_hub.send_to(project.created_by, envelope)
|
|
147
|
+
if delivered:
|
|
148
|
+
logger.info(
|
|
149
|
+
f"Sent DESK_TODO_SYNC(project) to user "
|
|
150
|
+
f"{project.created_by[:8]} for project {project.id[:8]}"
|
|
151
|
+
)
|
|
152
|
+
except Exception:
|
|
153
|
+
# A desk notification must never fail the project event that caused it.
|
|
154
|
+
logger.exception(
|
|
155
|
+
f"Failed to notify desk of project change for {project.id[:8]}"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
async def mirror_plate_to_spawned_project(
|
|
160
|
+
ctx: "ServerContext", spawned_from: str, project: "Project"
|
|
161
|
+
) -> int:
|
|
162
|
+
"""A project was spawned from a context some to-do already points at — give
|
|
163
|
+
the to-do the new project too. Returns HOW MANY to-dos were linked.
|
|
164
|
+
|
|
165
|
+
The case this exists for: an agent running in a DM thread the owner's
|
|
166
|
+
**command** button spawned is asked to turn that conversation into a real
|
|
167
|
+
project. Without this, the to-do keeps pointing at the thread alone, and the
|
|
168
|
+
moment the thread is archived or the work moves on the row falls back to
|
|
169
|
+
**New** — which is the one state it is certainly not in. Mirroring keeps it
|
|
170
|
+
reading Working against the work that actually continued.
|
|
171
|
+
|
|
172
|
+
**It goes through the association write, not into storage.** The sequence is
|
|
173
|
+
``check_association_target`` -> ``associate_todo`` -> the ``associate``
|
|
174
|
+
envelope, which is the same sequence
|
|
175
|
+
``POST /me/desk/todos/{id}/projects`` runs. The scoping predicate therefore
|
|
176
|
+
keeps exactly ONE implementation and this path cannot drift from the route
|
|
177
|
+
— the check passes trivially here (see below) and is made anyway for that
|
|
178
|
+
reason, not because it is in doubt.
|
|
179
|
+
|
|
180
|
+
**Why the scoping holds by construction.** ``create_project`` derives
|
|
181
|
+
``created_by`` from the credential: on the agent-token path it is
|
|
182
|
+
``coordinator_agent.registered_by``, and a coordinator with no owner is
|
|
183
|
+
refused outright. So a project an agent spawns is owned by *that agent's
|
|
184
|
+
owner*, which satisfies the rename predicate (``created_by == user.id``)
|
|
185
|
+
the same way ``_create_own_dm_thread_project`` satisfies it for the
|
|
186
|
+
composer's threads. A worker, a coordinator and an assistant all produce the
|
|
187
|
+
same ``created_by`` when the same user owns them, so this works for every
|
|
188
|
+
same-owner shape rather than for one of them.
|
|
189
|
+
|
|
190
|
+
**THE THREE SILENT RETURNS ARE ONE ANSWER ON PURPOSE, AND IT IS A SECURITY
|
|
191
|
+
PROPERTY.** An unresolvable ``spawned_from``, a cross-owner ``spawned_from``
|
|
192
|
+
and a resolvable one no to-do points at all return ``0`` and are
|
|
193
|
+
indistinguishable from outside — no header, no stderr line, nothing. If
|
|
194
|
+
declining were distinguishable from not-matching, an agent owned by A could
|
|
195
|
+
feed ids at ``spawned_from`` and learn which of them are real projects
|
|
196
|
+
belonging to someone else: the same existence oracle the association route's
|
|
197
|
+
404 refuses, arriving through a different door.
|
|
198
|
+
|
|
199
|
+
The cross-owner case is doubly closed, which is worth knowing because it is
|
|
200
|
+
what makes the indistinguishability structural rather than careful: a
|
|
201
|
+
project belonging to someone else could never be on this owner's plate in
|
|
202
|
+
the first place, because ``check_association_target`` would have refused the
|
|
203
|
+
link that put it there. The guard below and the empty scan reach ``0``
|
|
204
|
+
independently.
|
|
205
|
+
|
|
206
|
+
Cross-account threads therefore do not mirror, and that is the designed
|
|
207
|
+
outcome rather than a gap: an agent owned by A running in B's Front Desk
|
|
208
|
+
thread would otherwise put a link to *A's* project on *B's* plate, which B
|
|
209
|
+
could never have made themselves.
|
|
210
|
+
|
|
211
|
+
**Zero costs one small JSON read and says nothing.** That is the budget
|
|
212
|
+
:func:`notify_plate_of_project_change` already spends one lane over for the
|
|
213
|
+
same overwhelmingly-common shape, not a new one.
|
|
214
|
+
|
|
215
|
+
**N matches produce N envelopes**, one per to-do, each carrying its own
|
|
216
|
+
to-do id. Deliberately not one ``project``-with-``id: null``: the to-do
|
|
217
|
+
contract publishes ``associate`` as ALWAYS carrying a to-do id, and blurring
|
|
218
|
+
that to save an envelope in a case where N is almost always 1 or 2 trades a
|
|
219
|
+
contract for nothing. Two to-dos pointing at the same originating thread are
|
|
220
|
+
two real intentions and there is no principled way to pick between them, so
|
|
221
|
+
both are mirrored — "whichever the scan hit first" is a non-answer.
|
|
222
|
+
|
|
223
|
+
Idempotent, because ``associate_todo`` is: a to-do that already carries the
|
|
224
|
+
new id counts as mirrored and still broadcasts, matching the route's own
|
|
225
|
+
200 no-op.
|
|
226
|
+
|
|
227
|
+
Raises rather than swallowing. The CALLER owns the "never fail the create"
|
|
228
|
+
rule and holds the response it has to report the miss on; a failure
|
|
229
|
+
swallowed here would be a miss nobody could see.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
ctx: The server context.
|
|
233
|
+
spawned_from: The originating context's id, as the agent typed it —
|
|
234
|
+
the bare id or the ``{name}-{id}`` slug it sees as its synced
|
|
235
|
+
project directory. Both resolve; ``Project.get`` owns that.
|
|
236
|
+
project: The project just created.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
The number of to-dos linked. ``0`` for all three silent cases.
|
|
240
|
+
"""
|
|
241
|
+
origin_id = (spawned_from or "").strip()
|
|
242
|
+
if not origin_id or project is None or not project.created_by:
|
|
243
|
+
return 0
|
|
244
|
+
try:
|
|
245
|
+
origin = Project.get(origin_id, ctx.model_ctx)
|
|
246
|
+
except (ValueError, OSError):
|
|
247
|
+
# Unresolvable. Silent, and NOT an error the caller may report — see
|
|
248
|
+
# the oracle paragraph above.
|
|
249
|
+
#
|
|
250
|
+
# ``OSError`` and not just ``ValueError``: ``Project.get`` documents
|
|
251
|
+
# the ValueError, but its fallback ``(metadata_dir / project_id)
|
|
252
|
+
# .is_dir()`` is a bare ``stat()``, so an id longer than NAME_MAX
|
|
253
|
+
# raises ``OSError(ENAMETOOLONG)`` straight through. Uncaught, that
|
|
254
|
+
# reaches the caller's ``except Exception`` and comes back as
|
|
255
|
+
# ``X-Desk-Todo-Mirror-Error: OSError: [Errno 63] File name too long:
|
|
256
|
+
# /…/metadata/projects/…`` — which both publishes the server's
|
|
257
|
+
# absolute data directory to any agent that can create a project, and
|
|
258
|
+
# makes one unresolvable id distinguishable from another when the
|
|
259
|
+
# whole point of this arm is that they are not. An id that cannot name
|
|
260
|
+
# a directory cannot name a project; it is unresolvable, which is what
|
|
261
|
+
# this branch already means.
|
|
262
|
+
return 0
|
|
263
|
+
if origin.created_by != project.created_by:
|
|
264
|
+
return 0
|
|
265
|
+
|
|
266
|
+
owner = project.created_by
|
|
267
|
+
data_dir = ctx.model_ctx.participants_dir
|
|
268
|
+
# `origin.id` and not `origin_id`: the slug form resolved above, and the
|
|
269
|
+
# plate stores bare ids.
|
|
270
|
+
todo_ids = todos_referencing_project(data_dir, owner, origin.id)
|
|
271
|
+
if not todo_ids:
|
|
272
|
+
return 0
|
|
273
|
+
|
|
274
|
+
try:
|
|
275
|
+
check_association_target(project, owner, project.id)
|
|
276
|
+
except AssociationRefused:
|
|
277
|
+
# Unreachable while `created_by` is derived from the credential. Kept
|
|
278
|
+
# so the predicate has one implementation rather than a copy here that
|
|
279
|
+
# could silently come to disagree with the route's.
|
|
280
|
+
return 0
|
|
281
|
+
|
|
282
|
+
mirrored = 0
|
|
283
|
+
for todo_id in todo_ids:
|
|
284
|
+
todo = await associate_todo(data_dir, owner, todo_id, project.id)
|
|
285
|
+
if todo is None:
|
|
286
|
+
# Deleted between the scan and the write. Nothing to link and
|
|
287
|
+
# nothing to say.
|
|
288
|
+
continue
|
|
289
|
+
envelope = ControlEnvelope(
|
|
290
|
+
type=ControlMessageType.DESK_TODO_SYNC,
|
|
291
|
+
payload=DeskTodoSyncPayload(action=ASSOCIATE_ACTION, id=todo.id),
|
|
292
|
+
)
|
|
293
|
+
await ctx.ws_hub.send_to(owner, envelope)
|
|
294
|
+
mirrored += 1
|
|
295
|
+
if mirrored:
|
|
296
|
+
logger.info(
|
|
297
|
+
f"Mirrored project {project.id[:8]} onto {mirrored} to-do(s) of "
|
|
298
|
+
f"user {owner[:8]} spawned from {origin.id[:8]}"
|
|
299
|
+
)
|
|
300
|
+
return mirrored
|