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,162 @@
|
|
|
1
|
+
import { MouseEvent, useEffect, useMemo, useState } from 'react'
|
|
2
|
+
import { PublicAgent, PublicDirectory, chatUrl, fetchDirectory } from './api'
|
|
3
|
+
import { Avatar, Icon, PoweredBy, Unavailable } from './parts'
|
|
4
|
+
import { addChat, loadWidget, openChat } from './widget'
|
|
5
|
+
|
|
6
|
+
/** An account's public agents: /users/:account/agents/. Chats open in the web
|
|
7
|
+
* chat widget's dock (several side by side, Messenger-style); each card still
|
|
8
|
+
* links to the agent's full-page chat for a new tab or no JavaScript. */
|
|
9
|
+
|
|
10
|
+
type Filter = 'all' | 'direct'
|
|
11
|
+
|
|
12
|
+
const plural = (n: number, one: string) => `${n} ${one}${n === 1 ? '' : 's'}`
|
|
13
|
+
|
|
14
|
+
export function matches(agent: PublicAgent, query: string, filter: Filter): boolean {
|
|
15
|
+
if (filter === 'direct' && !agent.takes_direct_requests) return false
|
|
16
|
+
const q = query.trim().toLowerCase()
|
|
17
|
+
if (!q) return true
|
|
18
|
+
return [agent.display_name, agent.id, agent.description, ...agent.skills]
|
|
19
|
+
.join(' ').toLowerCase().includes(q)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default function PublicAgentsAccount({ username }: { username: string }) {
|
|
23
|
+
const [dir, setDir] = useState<PublicDirectory | null>(null)
|
|
24
|
+
const [missing, setMissing] = useState(false)
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
fetchDirectory(username).then(setDir).catch(() => setMissing(true))
|
|
28
|
+
}, [username])
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!dir) return
|
|
32
|
+
document.title = `${dir.account.display_name} — Public agents · Manigent`
|
|
33
|
+
loadWidget('dock')
|
|
34
|
+
// Every public agent goes in the dock's picker; heads appear as they're opened.
|
|
35
|
+
dir.agents.forEach((a) => addChat(a.chat_key))
|
|
36
|
+
}, [dir])
|
|
37
|
+
|
|
38
|
+
if (missing) return <Unavailable text="This account has no public agents." />
|
|
39
|
+
if (!dir) return <div className="pa2-page" aria-busy />
|
|
40
|
+
return <AccountView dir={dir} />
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function AccountView({ dir }: { dir: PublicDirectory }) {
|
|
44
|
+
const { account, teams, agents } = dir
|
|
45
|
+
const [query, setQuery] = useState('')
|
|
46
|
+
const [filter, setFilter] = useState<Filter>('all')
|
|
47
|
+
const defaultAgent = agents.find((a) => a.id === dir.default_agent)
|
|
48
|
+
|
|
49
|
+
const groups = useMemo(() => {
|
|
50
|
+
const hits = agents.filter((a) => matches(a, query, filter))
|
|
51
|
+
if (teams.length === 0) return hits.length ? [{ id: '', name: '', description: '', agents: hits }] : []
|
|
52
|
+
const known = new Set(teams.map((t) => t.id))
|
|
53
|
+
return [
|
|
54
|
+
...teams.map((t) => ({ ...t, agents: hits.filter((a) => a.team_id === t.id) })),
|
|
55
|
+
{
|
|
56
|
+
id: '', name: 'Other agents', description: '',
|
|
57
|
+
agents: hits.filter((a) => !a.team_id || !known.has(a.team_id)),
|
|
58
|
+
},
|
|
59
|
+
].filter((g) => g.agents.length > 0)
|
|
60
|
+
}, [agents, teams, query, filter])
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<>
|
|
64
|
+
<div className="pa2-page">
|
|
65
|
+
<section className="pa2-prof">
|
|
66
|
+
<Avatar name={account.display_name} seed={account.handle} size="xl" src={account.avatar_url} />
|
|
67
|
+
<div className="info">
|
|
68
|
+
<h1>{account.display_name}</h1>
|
|
69
|
+
<div className="pc-mono pa2-handle">@{account.handle}</div>
|
|
70
|
+
{account.bio && <p>{account.bio}</p>}
|
|
71
|
+
<div className="pa2-meta">
|
|
72
|
+
<span>{plural(agents.length, 'public agent')}</span>
|
|
73
|
+
{teams.length > 0 && <span>{plural(teams.length, 'team')}</span>}
|
|
74
|
+
{account.website && (
|
|
75
|
+
<a href={account.website} target="_blank" rel="noopener noreferrer nofollow">
|
|
76
|
+
{account.website.replace(/^https?:\/\//, '').replace(/\/$/, '')}
|
|
77
|
+
</a>
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
{defaultAgent && (
|
|
82
|
+
<a
|
|
83
|
+
className="pc-btn pri"
|
|
84
|
+
href={chatUrl(account.handle, defaultAgent.id)}
|
|
85
|
+
onClick={(e) => openInDock(e, defaultAgent.chat_key)}
|
|
86
|
+
>
|
|
87
|
+
Ask {account.display_name}
|
|
88
|
+
</a>
|
|
89
|
+
)}
|
|
90
|
+
</section>
|
|
91
|
+
|
|
92
|
+
<div className="pa2-bar">
|
|
93
|
+
<label className="pa2-search">
|
|
94
|
+
<Icon name="search" />
|
|
95
|
+
<input
|
|
96
|
+
value={query}
|
|
97
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
98
|
+
placeholder="Search agents by name or skill"
|
|
99
|
+
aria-label="Search agents"
|
|
100
|
+
/>
|
|
101
|
+
</label>
|
|
102
|
+
<div className="pa2-tabs" role="tablist" aria-label="Filter agents">
|
|
103
|
+
{(['all', 'direct'] as const).map((f) => (
|
|
104
|
+
<button
|
|
105
|
+
key={f}
|
|
106
|
+
type="button"
|
|
107
|
+
role="tab"
|
|
108
|
+
aria-selected={filter === f}
|
|
109
|
+
className={filter === f ? 'on' : ''}
|
|
110
|
+
onClick={() => setFilter(f)}
|
|
111
|
+
>
|
|
112
|
+
{f === 'all' ? 'All' : 'Takes requests'}
|
|
113
|
+
</button>
|
|
114
|
+
))}
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
{groups.length === 0 && <div className="pa2-empty">No agents match.</div>}
|
|
119
|
+
{groups.map((g) => (
|
|
120
|
+
<section className="pa2-team" key={g.id || '_other'}>
|
|
121
|
+
{g.name && <h2>{g.name}</h2>}
|
|
122
|
+
{g.description && <div className="d">{g.description}</div>}
|
|
123
|
+
<div className="pa2-grid">
|
|
124
|
+
{g.agents.map((a) => <AgentCard key={a.id} username={account.handle} agent={a} />)}
|
|
125
|
+
</div>
|
|
126
|
+
</section>
|
|
127
|
+
))}
|
|
128
|
+
</div>
|
|
129
|
+
<PoweredBy />
|
|
130
|
+
</>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** A plain click opens the chat in the dock; a modified click (new tab or
|
|
135
|
+
* window) follows the link to the full-page chat. */
|
|
136
|
+
export function openInDock(e: MouseEvent, key: string) {
|
|
137
|
+
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return
|
|
138
|
+
e.preventDefault()
|
|
139
|
+
openChat(key)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function AgentCard({ username, agent }: { username: string; agent: PublicAgent }) {
|
|
143
|
+
return (
|
|
144
|
+
<a className="pa2-card" href={chatUrl(username, agent.id)} onClick={(e) => openInDock(e, agent.chat_key)}>
|
|
145
|
+
<div className="top">
|
|
146
|
+
<Avatar name={agent.display_name} seed={agent.id} />
|
|
147
|
+
<div className="t">
|
|
148
|
+
<b>{agent.display_name}</b>
|
|
149
|
+
<span className="pc-mono">{agent.id}</span>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
{agent.description && <p className="desc">{agent.description}</p>}
|
|
153
|
+
{agent.skills.length > 0 && <div className="pa2-sk">{agent.skills.join(' · ')}</div>}
|
|
154
|
+
<div className="pa2-cf">
|
|
155
|
+
{agent.takes_direct_requests
|
|
156
|
+
? <span className="pc-badge go"><i />Takes requests</span>
|
|
157
|
+
: <span className="pc-badge">Answers questions</span>}
|
|
158
|
+
<span className="go">Chat<Icon name="arrow" size={14} stroke={2.4} /></span>
|
|
159
|
+
</div>
|
|
160
|
+
</a>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The account page's server calls: the account's public directory
|
|
3
|
+
* (`/api/public/users/…`, served by `server/routes/public_agents.py`). Chats
|
|
4
|
+
* themselves run in the web chat widget (`widget.ts`). No auth, no cookies.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const BASE = import.meta.env.DEV ? '/api' : ''
|
|
8
|
+
|
|
9
|
+
export interface PublicAccount {
|
|
10
|
+
handle: string
|
|
11
|
+
display_name: string
|
|
12
|
+
bio: string
|
|
13
|
+
website: string | null
|
|
14
|
+
avatar_url: string | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface PublicTeam {
|
|
18
|
+
id: string
|
|
19
|
+
name: string
|
|
20
|
+
description: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PublicAgent {
|
|
24
|
+
id: string
|
|
25
|
+
display_name: string
|
|
26
|
+
team_id: string | null
|
|
27
|
+
description: string
|
|
28
|
+
skills: string[]
|
|
29
|
+
takes_direct_requests: boolean
|
|
30
|
+
online: boolean
|
|
31
|
+
starter_questions: string[]
|
|
32
|
+
/** The widget key this page chats with (it lists this server; public by design). */
|
|
33
|
+
chat_key: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface PublicDirectory {
|
|
37
|
+
account: PublicAccount
|
|
38
|
+
teams: PublicTeam[]
|
|
39
|
+
agents: PublicAgent[]
|
|
40
|
+
default_agent: string | null
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function fetchDirectory(username: string): Promise<PublicDirectory> {
|
|
44
|
+
const r = await fetch(`${BASE}/api/public/users/${encodeURIComponent(username)}/agents`, {
|
|
45
|
+
credentials: 'omit',
|
|
46
|
+
})
|
|
47
|
+
if (!r.ok) throw new Error(`http_${r.status}`)
|
|
48
|
+
return r.json()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Account page and chat URLs — root-relative, outside the `/app` SPA. */
|
|
52
|
+
const enc = encodeURIComponent
|
|
53
|
+
export const accountUrl = (username: string) => `/users/${enc(username)}/agents/`
|
|
54
|
+
export const chatUrl = (username: string, agent: string) =>
|
|
55
|
+
`/users/${enc(username)}/agents/${enc(agent)}/chat`
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { colorFor } from '../sidebar/SidebarAvatar'
|
|
2
|
+
|
|
3
|
+
/** Shared bits of the two public agent pages. */
|
|
4
|
+
|
|
5
|
+
export function Avatar({ name, seed, size = '', src }: {
|
|
6
|
+
name: string
|
|
7
|
+
/** What the color hashes on — the handle, so a rename keeps the color. */
|
|
8
|
+
seed: string
|
|
9
|
+
size?: '' | 'xl'
|
|
10
|
+
src?: string | null
|
|
11
|
+
}) {
|
|
12
|
+
const cls = 'pc-av' + (size ? ` ${size}` : '')
|
|
13
|
+
if (src) return <img className={cls} src={src} alt="" />
|
|
14
|
+
return (
|
|
15
|
+
<div className={cls} style={{ background: colorFor(seed) }} aria-hidden>
|
|
16
|
+
{(name.trim()[0] || '?').toUpperCase()}
|
|
17
|
+
</div>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const PATHS = {
|
|
22
|
+
arrow: 'M5 12h14M13 6l6 6-6 6',
|
|
23
|
+
search: 'M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM21 21l-4.3-4.3',
|
|
24
|
+
} as const
|
|
25
|
+
|
|
26
|
+
export function Icon({ name, size = 16, stroke = 2 }: {
|
|
27
|
+
name: keyof typeof PATHS
|
|
28
|
+
size?: number
|
|
29
|
+
stroke?: number
|
|
30
|
+
}) {
|
|
31
|
+
return (
|
|
32
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
33
|
+
strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round" aria-hidden>
|
|
34
|
+
<path d={PATHS[name]} />
|
|
35
|
+
</svg>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function PoweredBy() {
|
|
40
|
+
return (
|
|
41
|
+
<div className="pc-foot">
|
|
42
|
+
Powered by <a href="/" target="_top">Manigent</a>
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function Unavailable({ text }: { text: string }) {
|
|
48
|
+
return (
|
|
49
|
+
<div className="pc-unavailable">
|
|
50
|
+
<p>{text}</p>
|
|
51
|
+
<PoweredBy />
|
|
52
|
+
</div>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* The public account page (public.html). Chats are drawn by the web chat widget.
|
|
2
|
+
Values lifted from the design handoff; tokens from styles/design/tokens.css. */
|
|
3
|
+
|
|
4
|
+
*{box-sizing:border-box}
|
|
5
|
+
body{margin:0;background:var(--bg-canvas);color:var(--ink-1);font-family:var(--font-sans);font-size:14px;line-height:1.45;font-weight:500;-webkit-font-smoothing:antialiased}
|
|
6
|
+
button{font-family:inherit}
|
|
7
|
+
a{color:var(--accent-deep)}a:hover{color:var(--accent)}
|
|
8
|
+
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
|
|
9
|
+
|
|
10
|
+
.pc-av{width:36px;height:36px;border-radius:11px;color:#fff;font-weight:800;font-size:15px;display:flex;align-items:center;justify-content:center;flex:none;object-fit:cover}
|
|
11
|
+
.pc-av.xl{width:72px;height:72px;border-radius:20px;font-size:28px}
|
|
12
|
+
.pc-mono{font-family:var(--font-mono);font-size:12px;color:var(--ink-3)}
|
|
13
|
+
.pc-badge{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:700;border-radius:999px;padding:2px 9px;background:var(--bg-pill-muted);color:var(--ink-2);white-space:nowrap}
|
|
14
|
+
.pc-badge.go{background:var(--prio-quick-bg);color:var(--prio-quick-fg)}
|
|
15
|
+
.pc-badge i{width:7px;height:7px;border-radius:50%;background:currentColor}
|
|
16
|
+
.pc-btn{border:1px solid var(--line-2);background:#fff;color:var(--ink-1);font-weight:700;font-size:13px;border-radius:9px;padding:7px 13px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;text-decoration:none;white-space:nowrap}
|
|
17
|
+
.pc-btn:hover{border-color:var(--line-strong);color:var(--ink-1)}
|
|
18
|
+
.pc-btn.pri{background:var(--accent);border-color:var(--accent);color:#fff}.pc-btn.pri:hover{background:var(--accent-deep);color:#fff}
|
|
19
|
+
.pc-foot{text-align:center;font-size:11.5px;color:var(--ink-3);padding:6px 0 12px}.pc-foot a{color:var(--ink-2);font-weight:700;text-decoration:none}
|
|
20
|
+
.pc-unavailable{min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px}
|
|
21
|
+
.pc-unavailable p{margin:0;font-size:15px;color:var(--ink-2)}
|
|
22
|
+
|
|
23
|
+
/* account */
|
|
24
|
+
.pa2-page{max-width:1000px;margin:0 auto;padding:44px 28px 30px}
|
|
25
|
+
.pa2-prof{display:flex;gap:20px;align-items:flex-start;flex-wrap:wrap}
|
|
26
|
+
.pa2-prof .info{flex:1;min-width:260px}
|
|
27
|
+
.pa2-prof h1{font-size:28px;font-weight:800;letter-spacing:-.02em;margin:0}
|
|
28
|
+
.pa2-handle{margin-top:3px}
|
|
29
|
+
.pa2-prof p{margin:8px 0 0;font-size:14.5px;color:var(--ink-2);line-height:1.55;max-width:600px}
|
|
30
|
+
.pa2-meta{display:flex;gap:14px;flex-wrap:wrap;margin-top:10px;font-size:13px;color:var(--ink-3)}
|
|
31
|
+
.pa2-bar{display:flex;gap:10px;align-items:center;margin:32px 0 6px;flex-wrap:wrap}
|
|
32
|
+
.pa2-search{flex:1;min-width:220px;display:flex;align-items:center;gap:8px;border:1px solid var(--line-2);background:#fff;border-radius:10px;padding:0 12px;color:var(--ink-3)}
|
|
33
|
+
.pa2-search:focus-within{border-color:var(--accent)}
|
|
34
|
+
.pa2-search input{flex:1;border:0;outline:0;font:inherit;font-size:14px;padding:9px 0;background:transparent;color:var(--ink-1)}
|
|
35
|
+
.pa2-search input:focus-visible{outline:0}
|
|
36
|
+
.pa2-tabs{display:flex;gap:4px;background:var(--bg-pill-muted);border-radius:10px;padding:3px}
|
|
37
|
+
.pa2-tabs button{border:0;background:transparent;font-size:13px;font-weight:700;color:var(--ink-2);padding:6px 11px;border-radius:8px;cursor:pointer}.pa2-tabs button.on{background:#fff;color:var(--ink-1);box-shadow:var(--shadow-1)}
|
|
38
|
+
.pa2-team{margin-top:28px}
|
|
39
|
+
.pa2-team h2{font-size:16px;font-weight:800;margin:0 0 12px}
|
|
40
|
+
.pa2-team h2:has(+ .d){margin-bottom:0}
|
|
41
|
+
.pa2-team .d{font-size:13px;color:var(--ink-3);margin:2px 0 12px}
|
|
42
|
+
.pa2-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:12px}
|
|
43
|
+
.pa2-card{border:1px solid var(--line-2);background:#fff;border-radius:var(--r-lg);padding:16px;display:flex;flex-direction:column;gap:10px;text-decoration:none;color:inherit;transition:border-color .15s,box-shadow .15s}
|
|
44
|
+
.pa2-card:hover{border-color:var(--accent-soft);box-shadow:var(--shadow-2);color:inherit}
|
|
45
|
+
.pa2-card .top{display:flex;gap:12px;align-items:center}
|
|
46
|
+
.pa2-card .top .t{flex:1;min-width:0}.pa2-card b{display:block;font-size:15px;font-weight:800}
|
|
47
|
+
.pa2-card .desc{font-size:13.5px;color:var(--ink-2);line-height:1.5;margin:0;flex:1;text-wrap:pretty}
|
|
48
|
+
.pa2-sk{font-size:12px;color:var(--ink-3)}
|
|
49
|
+
.pa2-cf{display:flex;justify-content:space-between;align-items:center;gap:8px;border-top:1px solid var(--line-1);padding-top:10px;margin-top:auto}
|
|
50
|
+
.pa2-cf .go{font-size:13px;font-weight:800;color:var(--accent-deep);display:inline-flex;gap:5px;align-items:center}
|
|
51
|
+
.pa2-empty{padding:40px;text-align:center;color:var(--ink-3);font-size:14px}
|
|
52
|
+
|
|
53
|
+
@media (max-width:600px){.pa2-page{padding:28px 16px}}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
|
|
3
|
+
import PublicAgentsAccount, { matches } from './PublicAgentsAccount'
|
|
4
|
+
import type { PublicAgent, PublicDirectory } from './api'
|
|
5
|
+
|
|
6
|
+
const agent = (over: Partial<PublicAgent>): PublicAgent => ({
|
|
7
|
+
id: 'a', display_name: 'A', team_id: null, description: '', skills: [],
|
|
8
|
+
takes_direct_requests: true, online: true, starter_questions: [], chat_key: 'cmw_a', ...over,
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const DIR: PublicDirectory = {
|
|
12
|
+
account: { handle: 'chu', display_name: "Chu's Wine", bio: '', website: null, avatar_url: null },
|
|
13
|
+
teams: [{ id: 'video', name: 'video', description: '' }],
|
|
14
|
+
agents: [
|
|
15
|
+
agent({ id: 'assets', display_name: 'Asset Producer', team_id: 'video', takes_direct_requests: false,
|
|
16
|
+
skills: ['voiceover'], chat_key: 'cmw_assets' }),
|
|
17
|
+
agent({ id: 'coord', display_name: 'Production Coordinator', team_id: 'video', chat_key: 'cmw_coord' }),
|
|
18
|
+
agent({ id: 'support', display_name: 'Customer Support', chat_key: 'cmw_support' }),
|
|
19
|
+
],
|
|
20
|
+
default_agent: 'support',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
cleanup()
|
|
25
|
+
vi.unstubAllGlobals()
|
|
26
|
+
delete window.ManigentChat
|
|
27
|
+
document.querySelectorAll('script[data-manigent-widget]').forEach((s) => s.remove())
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
function mockDirectory(dir: PublicDirectory | null) {
|
|
31
|
+
vi.stubGlobal('fetch', vi.fn(async () => dir
|
|
32
|
+
? new Response(JSON.stringify(dir), { status: 200 })
|
|
33
|
+
: new Response('{}', { status: 404 })))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('matches', () => {
|
|
37
|
+
it('searches name, handle, description and skills', () => {
|
|
38
|
+
expect(matches(DIR.agents[0], 'VOICE', 'all')).toBe(true)
|
|
39
|
+
expect(matches(DIR.agents[0], 'assets', 'all')).toBe(true)
|
|
40
|
+
expect(matches(DIR.agents[0], '', 'direct')).toBe(false)
|
|
41
|
+
expect(matches(DIR.agents[0], 'nothing', 'all')).toBe(false)
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
describe('PublicAgentsAccount', () => {
|
|
46
|
+
it('groups by team, filters, and searches', async () => {
|
|
47
|
+
mockDirectory(DIR)
|
|
48
|
+
render(<PublicAgentsAccount username="chu" />)
|
|
49
|
+
expect(await screen.findByRole('heading', { name: "Chu's Wine" })).toBeTruthy()
|
|
50
|
+
expect(screen.getByRole('heading', { name: 'video' })).toBeTruthy()
|
|
51
|
+
expect(screen.getByRole('heading', { name: 'Other agents' })).toBeTruthy()
|
|
52
|
+
fireEvent.click(screen.getByRole('tab', { name: 'Takes requests' }))
|
|
53
|
+
expect(screen.queryByText('Asset Producer')).toBeNull()
|
|
54
|
+
fireEvent.change(screen.getByLabelText('Search agents'), { target: { value: 'zzz' } })
|
|
55
|
+
expect(screen.getByText('No agents match.')).toBeTruthy()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('loads the widget dock, lists every agent, and opens chats in it', async () => {
|
|
59
|
+
mockDirectory(DIR)
|
|
60
|
+
render(<PublicAgentsAccount username="chu" />)
|
|
61
|
+
await screen.findByRole('heading', { name: "Chu's Wine" })
|
|
62
|
+
const script = document.querySelector('script[data-manigent-widget]')!
|
|
63
|
+
expect(script.getAttribute('src')).toContain('/api/channels/widget.js')
|
|
64
|
+
expect(script.getAttribute('data-mode')).toBe('dock')
|
|
65
|
+
// The widget is not loaded in jsdom, so calls sit in its queue.
|
|
66
|
+
const queue = () => window.ManigentChat as unknown as unknown[][]
|
|
67
|
+
expect(queue()).toEqual(expect.arrayContaining([['add', 'cmw_assets'], ['add', 'cmw_coord'], ['add', 'cmw_support']]))
|
|
68
|
+
|
|
69
|
+
const card = screen.getByText('Asset Producer').closest('a')!
|
|
70
|
+
expect(card.getAttribute('href')).toBe('/users/chu/agents/assets/chat')
|
|
71
|
+
fireEvent.click(card)
|
|
72
|
+
expect(queue().at(-1)).toEqual(['open', 'cmw_assets'])
|
|
73
|
+
fireEvent.click(screen.getByRole('link', { name: "Ask Chu's Wine" }))
|
|
74
|
+
expect(queue().at(-1)).toEqual(['open', 'cmw_support'])
|
|
75
|
+
// A modified click follows the link to the full-page chat instead.
|
|
76
|
+
const before = queue().length
|
|
77
|
+
fireEvent.click(card, { metaKey: true })
|
|
78
|
+
expect(queue().length).toBe(before)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('says so when the account has no public agents', async () => {
|
|
82
|
+
mockDirectory(null)
|
|
83
|
+
render(<PublicAgentsAccount username="nobody" />)
|
|
84
|
+
expect(await screen.findByText('This account has no public agents.')).toBeTruthy()
|
|
85
|
+
})
|
|
86
|
+
})
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { readFileSync } from 'fs'
|
|
2
|
+
import { resolve } from 'path'
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
4
|
+
import { fireEvent, waitFor } from '@testing-library/dom'
|
|
5
|
+
|
|
6
|
+
// The embeddable widget is plain JavaScript served by the server
|
|
7
|
+
// (manigent/server/channels/webchat_widget.js); load the real file.
|
|
8
|
+
const SRC = readFileSync(
|
|
9
|
+
resolve(__dirname, '../../../../../server/channels/webchat_widget.js'), 'utf8',
|
|
10
|
+
)
|
|
11
|
+
const BASE = 'https://cm.example'
|
|
12
|
+
|
|
13
|
+
const profile = (handle: string, over: Record<string, unknown> = {}) => ({
|
|
14
|
+
display_name: handle[0].toUpperCase() + handle.slice(1), handle, description: `${handle} help`,
|
|
15
|
+
online: true, takes_direct_requests: true, starter_questions: [],
|
|
16
|
+
account: { handle: 'olivia', display_name: 'Olivia', url: `${BASE}/users/olivia/agents/` },
|
|
17
|
+
request_taker: null, ...over,
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
let failSend = false
|
|
21
|
+
const fetchMock = vi.fn(async (input: string, init?: RequestInit) => {
|
|
22
|
+
const url = new URL(input)
|
|
23
|
+
const key = url.searchParams.get('key') || JSON.parse(String(init?.body || '{}')).key
|
|
24
|
+
const handle = String(key).replace('cmw_', '')
|
|
25
|
+
const ok = (body: unknown) => new Response(JSON.stringify(body), { status: 200 })
|
|
26
|
+
if (url.pathname.endsWith('/profile')) return ok({ profile: profile(handle), max_chars: 4000 })
|
|
27
|
+
if (url.pathname.endsWith('/session')) {
|
|
28
|
+
return ok({ visitor: 'v_aaaaaaaaaaaaaaaaaaaa', token: 't', profile: profile(handle), max_chars: 4000 })
|
|
29
|
+
}
|
|
30
|
+
if (init?.method === 'POST') {
|
|
31
|
+
return failSend ? new Response('{}', { status: 500 }) : ok({ ok: true })
|
|
32
|
+
}
|
|
33
|
+
return ok({ messages: [] })
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
interface Api {
|
|
37
|
+
open: (k: string) => void
|
|
38
|
+
minimize: (k: string) => void
|
|
39
|
+
close: (k: string) => void
|
|
40
|
+
add: (k: string) => void
|
|
41
|
+
list: () => { key: string; state: string; name: string }[]
|
|
42
|
+
__markdown: (t: string) => DocumentFragment
|
|
43
|
+
__manager: { chats: Record<string, { receive: (m: unknown) => void; stop: () => void }> }
|
|
44
|
+
}
|
|
45
|
+
const api = () => (window as unknown as { ManigentChat: Api }).ManigentChat
|
|
46
|
+
|
|
47
|
+
function boot(attrs: Record<string, string>) {
|
|
48
|
+
const s = document.createElement('script')
|
|
49
|
+
s.setAttribute('src', `${BASE}/api/channels/widget.js`)
|
|
50
|
+
s.setAttribute('data-test-open-shadow', '')
|
|
51
|
+
Object.entries(attrs).forEach(([k, v]) => s.setAttribute(k, v))
|
|
52
|
+
Object.defineProperty(document, 'currentScript', { configurable: true, get: () => s })
|
|
53
|
+
;(0, eval)(SRC)
|
|
54
|
+
delete (document as unknown as { currentScript?: unknown }).currentScript
|
|
55
|
+
return document.querySelector('[data-manigent-webchat]')!.shadowRoot!
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
failSend = false
|
|
60
|
+
vi.stubGlobal('fetch', fetchMock)
|
|
61
|
+
})
|
|
62
|
+
afterEach(() => {
|
|
63
|
+
const m = api()?.__manager
|
|
64
|
+
if (m) Object.values(m.chats).forEach((c) => c.stop())
|
|
65
|
+
delete (window as unknown as { ManigentChat?: unknown }).ManigentChat
|
|
66
|
+
document.querySelectorAll('[data-manigent-webchat]').forEach((el) => el.remove())
|
|
67
|
+
localStorage.clear()
|
|
68
|
+
vi.unstubAllGlobals()
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('markdown', () => {
|
|
72
|
+
it('renders formatting as nodes and never HTML or unsafe links', () => {
|
|
73
|
+
boot({ 'data-mode': 'dock' })
|
|
74
|
+
const div = document.createElement('div')
|
|
75
|
+
div.appendChild(api().__markdown(
|
|
76
|
+
'**Hi** <img src=x onerror=alert(1)>\n\n- one `code`\n- [ok](https://a.example) [bad](javascript:alert(1))',
|
|
77
|
+
))
|
|
78
|
+
expect(div.querySelector('strong')!.textContent).toBe('Hi')
|
|
79
|
+
expect(div.querySelector('img')).toBeNull()
|
|
80
|
+
expect(div.textContent).toContain('<img src=x onerror=alert(1)>')
|
|
81
|
+
expect(div.querySelectorAll('li')).toHaveLength(2)
|
|
82
|
+
expect(div.querySelector('code')!.textContent).toBe('code')
|
|
83
|
+
const links = Array.from(div.querySelectorAll('a')).map((a) => a.getAttribute('href'))
|
|
84
|
+
expect(links).toEqual(['https://a.example'])
|
|
85
|
+
expect(div.querySelector('a')!.getAttribute('target')).toBe('_blank')
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
describe('dock', () => {
|
|
90
|
+
it('shows one chat head per key, sharing one dock', async () => {
|
|
91
|
+
const root = boot({ 'data-keys': 'cmw_alpha, cmw_beta' })
|
|
92
|
+
await waitFor(() => expect(root.querySelector('[aria-label="Alpha"]')).toBeTruthy())
|
|
93
|
+
expect(root.querySelector('[aria-label="Beta"]')).toBeTruthy()
|
|
94
|
+
expect(root.querySelector('[aria-label="Start a chat"]')).toBeTruthy()
|
|
95
|
+
expect(document.querySelectorAll('[data-manigent-webchat]')).toHaveLength(1)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('opens windows side by side up to the limit, minimising the oldest', async () => {
|
|
99
|
+
const root = boot({ 'data-mode': 'dock' })
|
|
100
|
+
;['cmw_a1', 'cmw_a2', 'cmw_a3'].forEach((k) => api().add(k))
|
|
101
|
+
;['cmw_a1', 'cmw_a2', 'cmw_a3'].forEach((k) => api().open(k))
|
|
102
|
+
// jsdom is 1024px wide: room for two windows.
|
|
103
|
+
expect(root.querySelectorAll('.wins > .chat')).toHaveLength(2)
|
|
104
|
+
const states = Object.fromEntries(api().list().map((c) => [c.key, c.state]))
|
|
105
|
+
expect(states).toEqual({ cmw_a1: 'min', cmw_a2: 'open', cmw_a3: 'open' })
|
|
106
|
+
|
|
107
|
+
api().minimize('cmw_a3')
|
|
108
|
+
api().close('cmw_a2')
|
|
109
|
+
expect(root.querySelectorAll('.wins > .chat')).toHaveLength(0)
|
|
110
|
+
const after = Object.fromEntries(api().list().map((c) => [c.key, c.state]))
|
|
111
|
+
expect(after).toEqual({ cmw_a1: 'min', cmw_a2: 'listed', cmw_a3: 'min' })
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('counts unread replies on a minimised head', async () => {
|
|
115
|
+
const root = boot({ 'data-key': 'cmw_alpha' })
|
|
116
|
+
await waitFor(() => expect(root.querySelector('[aria-label="Alpha"]')).toBeTruthy())
|
|
117
|
+
api().__manager.chats.cmw_alpha.receive({ seq: 1, text: 'hello', at: 1 })
|
|
118
|
+
expect(root.querySelector('.hw .un')!.textContent).toBe('1')
|
|
119
|
+
api().open('cmw_alpha')
|
|
120
|
+
expect(root.querySelector('.hw .un')).toBeNull()
|
|
121
|
+
expect(root.querySelector('.md')!.textContent).toContain('hello')
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('keeps the visitor message and says so when a send fails', async () => {
|
|
125
|
+
failSend = true
|
|
126
|
+
const root = boot({ 'data-key': 'cmw_alpha', 'data-open': '' })
|
|
127
|
+
const ta = await waitFor(() => {
|
|
128
|
+
const el = root.querySelector('textarea')
|
|
129
|
+
expect(el).toBeTruthy()
|
|
130
|
+
return el as HTMLTextAreaElement
|
|
131
|
+
})
|
|
132
|
+
fireEvent.input(ta, { target: { value: 'hi **there**' } })
|
|
133
|
+
fireEvent.keyDown(ta, { key: 'Enter' })
|
|
134
|
+
await waitFor(() => expect(root.textContent).toContain('couldn’t reply just now'))
|
|
135
|
+
expect(root.querySelector('.me')!.textContent).toBe('hi **there**')
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
describe('fullpage', () => {
|
|
140
|
+
it('fills the page with one chat and its intro', async () => {
|
|
141
|
+
const root = boot({ 'data-key': 'cmw_alpha', 'data-mode': 'fullpage' })
|
|
142
|
+
await waitFor(() => expect(root.querySelector('.intro h1')!.textContent).toBe('Alpha'))
|
|
143
|
+
expect(root.querySelector('.full .chat')).toBeTruthy()
|
|
144
|
+
expect(root.querySelector('.heads')).toBeNull()
|
|
145
|
+
expect(root.querySelectorAll('.starters button').length).toBe(3)
|
|
146
|
+
expect(document.title).toBe('Alpha · Olivia')
|
|
147
|
+
})
|
|
148
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BASE } from './api'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The public pages run chats in the web chat widget
|
|
5
|
+
* (`server/channels/webchat_widget.js`) — the same script customer sites
|
|
6
|
+
* embed — and drive it through `window.ManigentChat`. Calls made before the
|
|
7
|
+
* script loads are queued (the widget drains the array when it boots).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
type Command = [string, ...unknown[]]
|
|
11
|
+
interface ChatApi {
|
|
12
|
+
push: (cmd: Command) => void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare global {
|
|
16
|
+
interface Window {
|
|
17
|
+
ManigentChat?: ChatApi | Command[]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function chatApi(): ChatApi {
|
|
22
|
+
if (!window.ManigentChat) window.ManigentChat = []
|
|
23
|
+
return window.ManigentChat as ChatApi
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Load the widget once. `fullpage` mounts one chat filling the page; `dock`
|
|
27
|
+
* starts an empty dock that `addChat` / `openChat` fill. */
|
|
28
|
+
export function loadWidget(mode: 'dock' | 'fullpage', key?: string) {
|
|
29
|
+
if (document.querySelector('script[data-manigent-widget]')) return
|
|
30
|
+
const s = document.createElement('script')
|
|
31
|
+
s.src = `${BASE}/api/channels/widget.js`
|
|
32
|
+
s.async = true
|
|
33
|
+
s.setAttribute('data-manigent-widget', '')
|
|
34
|
+
s.setAttribute('data-mode', mode)
|
|
35
|
+
if (key) s.setAttribute('data-key', key)
|
|
36
|
+
document.body.appendChild(s)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const addChat = (key: string) => chatApi().push(['add', key])
|
|
40
|
+
export const openChat = (key: string) => chatApi().push(['open', key])
|