@allbluecn/web-app 0.22.4 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -14
- package/src/__tests__/integration/login-email-acceptance.test.ts +16 -0
- package/src/__tests__/story-view.test.ts +33 -1
- package/src/components/agents/__tests__/agent-bindings-tab.test.tsx +221 -0
- package/src/components/agents/__tests__/agents-page.test.tsx +284 -0
- package/src/components/agents/agent-bindings-tab.tsx +59 -45
- package/src/components/agents/agent-form-dialog.tsx +3 -3
- package/src/components/agents/agent-selector.tsx +2 -3
- package/src/components/agents/agents-page.tsx +66 -31
- package/src/components/agents/slash-skill-menu.tsx +2 -3
- package/src/components/auth/__tests__/session-guard.test.tsx +74 -0
- package/src/components/auth/session-guard.tsx +8 -0
- package/src/components/billing/login-prompt-dialog.tsx +1 -1
- package/src/components/billing/subscription-provider.tsx +2 -16
- package/src/components/bug/__tests__/peek-modes.test.tsx +8 -0
- package/src/components/bug/__tests__/subgroup-header.test.tsx +202 -40
- package/src/components/bug/peek-panel.tsx +5 -3
- package/src/components/bug/views/bug-list/group.tsx +12 -2
- package/src/components/bug/views/bug-list/index.tsx +94 -67
- package/src/components/command/command-palette.tsx +10 -9
- package/src/components/design/canvas/document/frame-custom-presets.ts +9 -1
- package/src/components/design/canvas/panels/toolbar.tsx +21 -22
- package/src/components/design/canvas/react/__tests__/canvas-context-load-echo.test.tsx +199 -0
- package/src/components/design/canvas/react/__tests__/hooks.test.tsx +17 -3
- package/src/components/design/canvas/react/canvas-context.tsx +47 -26
- package/src/components/design/canvas/react/hooks.ts +39 -34
- package/src/components/design/editor/layout/__tests__/collab-param-wiring.test.tsx +17 -0
- package/src/components/design/editor/layout/__tests__/context-menu.test.tsx +17 -1
- package/src/components/design/editor/layout/__tests__/no-page-save-toast.test.tsx +17 -0
- package/src/components/design/editor/layout/__tests__/persistence-restore.test.tsx +17 -1
- package/src/components/design/editor/layout/__tests__/ssr-localstorage-smoke.test.tsx +17 -1
- package/src/components/design/editor/layout/design-editor-layout.tsx +13 -2
- package/src/components/design/editor/layout/hooks/use-design-auto-save.ts +3 -19
- package/src/components/devtools/devtools-panel.tsx +56 -0
- package/src/components/forms/__tests__/create-app-form.test.tsx +131 -0
- package/src/components/forms/app-field-error.tsx +21 -1
- package/src/components/forms/app-field.tsx +8 -8
- package/src/components/forms/app-submit.tsx +12 -9
- package/src/components/forms/create-app-form.tsx +124 -0
- package/src/components/forms/index.ts +2 -3
- package/src/components/harness/__tests__/gallery-behavior.test.tsx +37 -1
- package/src/components/harness/__tests__/harness-workbench-first-send.test.tsx +4 -1
- package/src/components/harness/__tests__/message-actions.test.tsx +7 -6
- package/src/components/harness/__tests__/use-video-generation.test.tsx +165 -0
- package/src/components/harness/ai-chat-history/index.tsx +5 -3
- package/src/components/harness/gallery/gallery-card.tsx +57 -35
- package/src/components/harness/gallery/gallery-grid.tsx +32 -15
- package/src/components/harness/gallery/gallery-types.ts +19 -0
- package/src/components/harness/gallery/gallery-video-card.tsx +54 -0
- package/src/components/harness/gallery/types.ts +2 -0
- package/src/components/harness/gallery/use-video-generation.ts +95 -0
- package/src/components/harness/harness-workbench-page.tsx +2 -3
- package/src/components/harness/message-actions.tsx +5 -3
- package/src/components/hotkeys/shortcuts-panel.tsx +28 -13
- package/src/components/iteration/__tests__/burndown-chart.test.tsx +118 -0
- package/src/components/iteration/burndown-chart.tsx +54 -23
- package/src/components/knowledge/editor/__tests__/knowledge-doc-editor-collab.test.tsx +96 -0
- package/src/components/knowledge/editor/knowledge-doc-editor.tsx +56 -1
- package/src/components/knowledge/editor/mindmap-doc-editor.tsx +12 -0
- package/src/components/knowledge/editor/use-auto-save-channels.ts +3 -1
- package/src/components/layout/sidebar-03/__tests__/nav-workspace.test.tsx +0 -4
- package/src/components/layout/sidebar-03/nav-knowledge.tsx +11 -11
- package/src/components/layout/sidebar-03/nav-main.tsx +12 -15
- package/src/components/layout/sidebar-03/nav-notifications.tsx +5 -8
- package/src/components/layout/sidebar-03/nav-workspace.tsx +11 -9
- package/src/components/notifications/__tests__/settings-notifications.test.tsx +158 -0
- package/src/components/notifications/settings-notifications.tsx +37 -13
- package/src/components/notifications/team-notifications.tsx +10 -14
- package/src/components/settings/personal-team/account/__tests__/account-client.test.tsx +170 -0
- package/src/components/settings/personal-team/account/account-client.tsx +44 -7
- package/src/components/settings/personal-team/team/team-client.tsx +17 -19
- package/src/components/shared-kit/list-kit/__tests__/frozen-header.test.ts +210 -41
- package/src/components/shared-kit/list-kit/frozen-header.ts +134 -21
- package/src/components/shared-kit/list-kit/kanban/frozen-header.ts +20 -27
- package/src/components/story/__tests__/peek-panel-patch-sync.test.tsx +8 -0
- package/src/components/story/__tests__/story-list-table.test.tsx +214 -0
- package/src/components/story/columns.tsx +11 -2
- package/src/components/story/peek-panel.tsx +4 -2
- package/src/components/story/story-list-table.tsx +16 -1
- package/src/components/story/views/story-list/__tests__/frozen-headers.test.tsx +186 -0
- package/src/components/story/views/story-list/group.tsx +12 -1
- package/src/components/story/views/story-list/index.tsx +101 -68
- package/src/components/testcase/__tests__/case-row.test.tsx +134 -2
- package/src/components/testcase/__tests__/peek-panel.test.tsx +8 -0
- package/src/components/testcase/__tests__/step-editor.test.tsx +106 -0
- package/src/components/testcase/list/grouped-list.tsx +50 -22
- package/src/components/testcase/peek-panel.tsx +7 -4
- package/src/components/testcase/step-editor.tsx +196 -150
- package/src/components/tiptap/notion-like/editor-extensions.ts +0 -3
- package/src/components/tiptap/notion-like/notion-like-editor-header.tsx +1 -31
- package/src/components/tiptap/notion-like/notion-like-editor.tsx +32 -1
- package/src/components/workspace/__tests__/dialogs/create-workspace-dialog.test.tsx +2 -28
- package/src/components/workspace/__tests__/dialogs/edit-workspace-dialog.test.tsx +2 -28
- package/src/components/workspace/dialogs/create-workspace-dialog.tsx +45 -43
- package/src/components/workspace/dialogs/edit-workspace-dialog.tsx +38 -36
- package/src/design-engine/engine/engine-decor.ts +2 -0
- package/src/design-engine/engine/engine-path.ts +2 -0
- package/src/hooks/__tests__/use-unsaved-guard.test.tsx +180 -0
- package/src/hooks/use-notifications.ts +9 -16
- package/src/hooks/use-unsaved-guard.tsx +87 -0
- package/src/lib/__tests__/pacer.test.ts +33 -96
- package/src/lib/__tests__/query-defaults.test.ts +169 -0
- package/src/lib/__tests__/query-global-error.test.ts +256 -0
- package/src/lib/anyhub/anyhub-store.ts +2 -2
- package/src/lib/changelog/sdk-versions.ts +2 -10
- package/src/lib/collab/presence-store.ts +5 -5
- package/src/lib/collab/use-presence-list-refresh.ts +2 -2
- package/src/lib/collab/use-share-presence.ts +2 -2
- package/src/lib/collections/query-keys.ts +7 -2
- package/src/lib/commands/__tests__/command-palette-state.test.ts +12 -14
- package/src/lib/commands/__tests__/registry.test.ts +6 -3
- package/src/lib/commands/command-palette-state.ts +8 -31
- package/src/lib/hotkeys/__tests__/registry.test.ts +71 -18
- package/src/lib/hotkeys/registry.ts +188 -85
- package/src/lib/hotkeys/types.ts +1 -13
- package/src/lib/pacer.ts +1 -79
- package/src/lib/queries/README.md +67 -0
- package/src/lib/queries/__tests__/agents-queries.test.ts +101 -0
- package/src/lib/queries/__tests__/compliance-queries.test.ts +136 -0
- package/src/lib/queries/__tests__/notifications-queries.test.ts +175 -0
- package/src/lib/queries/__tests__/team-queries.test.ts +87 -0
- package/src/lib/queries/agents.ts +40 -0
- package/src/lib/queries/compliance.ts +69 -0
- package/src/lib/queries/notifications.ts +63 -0
- package/src/lib/queries/team.ts +39 -0
- package/src/lib/query-defaults.ts +8 -0
- package/src/lib/query-global-error.ts +128 -0
- package/src/lib/remote-auth-client.ts +16 -0
- package/src/paraglide/README.md +1 -1
- package/src/paraglide/messages/_index.d.ts +11 -0
- package/src/paraglide/messages/_index.js +5659 -88285
- package/src/paraglide/messages/common_error_generic.d.ts +16 -0
- package/src/paraglide/messages/common_error_generic.js +29 -0
- package/src/paraglide/messages/common_unsaved_body.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_body.js +29 -0
- package/src/paraglide/messages/common_unsaved_leave.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_leave.js +29 -0
- package/src/paraglide/messages/common_unsaved_stay.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_stay.js +29 -0
- package/src/paraglide/messages/common_unsaved_title.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_title.js +29 -0
- package/src/paraglide/messages/gallery_videofailed1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videofailed1.js +30 -0
- package/src/paraglide/messages/gallery_videogenerating1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videogenerating1.js +30 -0
- package/src/paraglide/messages/gallery_videomissingprompt2.d.ts +17 -0
- package/src/paraglide/messages/gallery_videomissingprompt2.js +30 -0
- package/src/paraglide/messages/gallery_videoprogress1.d.ts +19 -0
- package/src/paraglide/messages/gallery_videoprogress1.js +30 -0
- package/src/paraglide/messages/gallery_videostop1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videostop1.js +30 -0
- package/src/paraglide/messages/story_table_resizecolumn1.d.ts +17 -0
- package/src/paraglide/messages/story_table_resizecolumn1.js +30 -0
- package/src/providers/index.tsx +5 -50
- package/src/routeTree.gen.ts +21 -0
- package/src/router.tsx +21 -8
- package/src/routes/__root.tsx +2 -1
- package/src/routes/__tests__/-edition-routing.test.tsx +6 -1
- package/src/routes/_login/forgot-password/route.lazy.tsx +7 -6
- package/src/routes/_login/login/route.lazy.tsx +10 -9
- package/src/routes/_login/register/route.lazy.tsx +19 -18
- package/src/routes/_login/reset-password/route.lazy.tsx +10 -9
- package/src/routes/_nav/knowledge/compliance/$id.lazy.tsx +9 -12
- package/src/routes/_nav/knowledge/compliance/index.lazy.tsx +16 -13
- package/src/routes/_nav/knowledge/laws/$id.lazy.tsx +1 -1
- package/src/routes/_nav/notifications/route.tsx +6 -16
- package/src/routes/_nav/settings/-settings-tabs.tsx +9 -12
- package/src/routes/api/generate/__tests__/media.test.ts +378 -0
- package/src/routes/api/generate/media.ts +179 -0
- package/src/server/__tests__/agent-client-graph.test.ts +0 -1
- package/src/server/__tests__/agent-crud.test.ts +37 -4
- package/src/server/__tests__/bug-groups-two-level.test.ts +34 -1
- package/src/server/__tests__/chat-conversations.test.ts +37 -4
- package/src/server/__tests__/chat-list-messages.test.ts +40 -7
- package/src/server/__tests__/csv-export.test.ts +36 -3
- package/src/server/__tests__/desktop-bootstrap.test.ts +189 -0
- package/src/server/__tests__/remote-auth.test.ts +72 -0
- package/src/server/__tests__/skill-crud.test.ts +37 -4
- package/src/server/__tests__/sso-domain.test.ts +1 -1
- package/src/server/__tests__/sso-rate-limit-singleton.test.ts +123 -0
- package/src/server/__tests__/task-serverfn-crud.test.ts +35 -2
- package/src/server/__tests__/task-serverfn-queries.test.ts +35 -2
- package/src/server/__tests__/testcase-board.test.ts +38 -5
- package/src/server/__tests__/testcase-bulk.test.ts +38 -5
- package/src/server/__tests__/testcase-list-scope.test.ts +38 -5
- package/src/server/ai-gateway/__tests__/ai-output-guard.test.ts +126 -2
- package/src/server/ai-gateway/__tests__/chat-stream-builder-code-mode.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-memory.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-sandbox.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-skills.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-adapter.test.ts +30 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-conformance.test.ts +92 -0
- package/src/server/ai-gateway/__tests__/source-mode.test.ts +49 -8
- package/src/server/ai-gateway/ai-output-guard.ts +50 -2
- package/src/server/ai-gateway/chat-stream-builder.ts +3 -0
- package/src/server/ai-gateway/media/index.ts +36 -29
- package/src/server/ai-gateway/media/trim-input.ts +52 -0
- package/src/server/ai-gateway/memory/pgvector-adapter.ts +27 -13
- package/src/server/ai-gateway/sandbox/__tests__/harness-sandbox.test.ts +252 -41
- package/src/server/ai-gateway/sandbox/harness-sandbox.ts +6 -67
- package/src/server/ai-gateway/source-mode.ts +24 -8
- package/src/server/desktop-bootstrap.ts +74 -0
- package/src/server/lib/__tests__/rate-limit.test.ts +0 -1
- package/src/server/lib/rate-limit.ts +0 -2
- package/src/server/middlewares/__tests__/auth-context.test.ts +156 -0
- package/src/server/middlewares/auth-context.ts +62 -0
- package/src/server/remote-auth.ts +58 -31
- package/src/server/serverFns/__tests__/ai-hosted-models.test.ts +47 -15
- package/src/server/serverFns/__tests__/ai-source-mode.test.ts +45 -15
- package/src/server/serverFns/__tests__/billing.test.ts +37 -2
- package/src/server/serverFns/__tests__/collab-snapshot.test.ts +41 -14
- package/src/server/serverFns/__tests__/collab.test.ts +41 -14
- package/src/server/serverFns/__tests__/compliance.test.ts +33 -1
- package/src/server/serverFns/__tests__/email-verification.test.ts +35 -1
- package/src/server/serverFns/__tests__/knowledge-breadcrumb.test.ts +46 -6
- package/src/server/serverFns/__tests__/knowledge-delete.test.ts +42 -14
- package/src/server/serverFns/__tests__/knowledge-kb-projects.test.ts +46 -6
- package/src/server/serverFns/__tests__/knowledge-public-compliance.test.ts +36 -2
- package/src/server/serverFns/__tests__/knowledge-readable-kb.test.ts +42 -10
- package/src/server/serverFns/__tests__/knowledge-search.test.ts +45 -9
- package/src/server/serverFns/__tests__/legal-code-canonical.test.ts +36 -2
- package/src/server/serverFns/__tests__/link-preview.test.ts +38 -4
- package/src/server/serverFns/__tests__/notifications-list.test.ts +36 -3
- package/src/server/serverFns/__tests__/ownership-merge.test.ts +38 -4
- package/src/server/serverFns/__tests__/project-delete-transaction.test.ts +39 -2
- package/src/server/serverFns/__tests__/project-kb.test.ts +34 -1
- package/src/server/serverFns/__tests__/project-member-idor.test.ts +34 -1
- package/src/server/serverFns/__tests__/project-team-assign.test.ts +34 -1
- package/src/server/serverFns/__tests__/read-write-merge.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-comments.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-crud-archive-detail.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-crud-labels-users.test.ts +37 -3
- package/src/server/serverFns/__tests__/story-crud.test.ts +36 -3
- package/src/server/serverFns/__tests__/story-links.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-reactions.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-tree.test.ts +38 -4
- package/src/server/serverFns/__tests__/team-accept.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-invitation.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-join-request.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-members.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-ownership-merge.test.ts +34 -1
- package/src/server/serverFns/__tests__/update-bug-guard.test.ts +37 -3
- package/src/server/serverFns/__tests__/update-document-guard.test.ts +38 -4
- package/src/server/serverFns/__tests__/update-page-guard.test.ts +40 -4
- package/src/server/serverFns/__tests__/update-seats.test.ts +33 -1
- package/src/server/serverFns/__tests__/update-story-guard.test.ts +36 -3
- package/src/server/serverFns/__tests__/update-testcase-guard.test.ts +37 -3
- package/src/server/serverFns/__tests__/workspace-kb-idor.test.ts +36 -2
- package/src/server/serverFns/__tests__/workspace-kb.test.ts +36 -2
- package/src/server/serverFns/__tests__/workspace.test.ts +34 -1
- package/src/server/serverFns/activity.ts +10 -14
- package/src/server/serverFns/agents/agent-crud.ts +16 -15
- package/src/server/serverFns/agents/bindings.ts +12 -13
- package/src/server/serverFns/agents/skill-crud.ts +16 -15
- package/src/server/serverFns/ai/code-mode-readiness.ts +3 -4
- package/src/server/serverFns/ai/search-capability.ts +3 -4
- package/src/server/serverFns/anyhub/app.ts +10 -14
- package/src/server/serverFns/anyhub/index.ts +7 -10
- package/src/server/serverFns/anyhub/install.ts +4 -4
- package/src/server/serverFns/anyhub/permissions.ts +10 -14
- package/src/server/serverFns/anyhub/proxy.ts +4 -6
- package/src/server/serverFns/auth/email-verification.ts +4 -5
- package/src/server/serverFns/auth/session.ts +9 -0
- package/src/server/serverFns/billing.ts +18 -28
- package/src/server/serverFns/blob-upload.ts +6 -9
- package/src/server/serverFns/bug/__tests__/bug-access-tokens.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-activities.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-comments.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-crud.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-fix.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-groups.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-reactions.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-reorder.test.ts +39 -5
- package/src/server/serverFns/bug/__tests__/bug-repro.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-story.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-webhooks.test.ts +34 -1
- package/src/server/serverFns/bug/bug-access-tokens.ts +16 -22
- package/src/server/serverFns/bug/bug-activities.ts +4 -6
- package/src/server/serverFns/bug/bug-collect-tokens.ts +13 -18
- package/src/server/serverFns/bug/bug-comments.ts +13 -18
- package/src/server/serverFns/bug/bug-crud/detail.ts +10 -14
- package/src/server/serverFns/bug/bug-crud.ts +28 -38
- package/src/server/serverFns/bug/bug-display-options.ts +8 -11
- package/src/server/serverFns/bug/bug-export.ts +5 -7
- package/src/server/serverFns/bug/bug-fix.ts +10 -14
- package/src/server/serverFns/bug/bug-groups.ts +10 -14
- package/src/server/serverFns/bug/bug-reactions.ts +10 -14
- package/src/server/serverFns/bug/bug-reorder.ts +4 -6
- package/src/server/serverFns/bug/bug-repro.ts +8 -11
- package/src/server/serverFns/bug/bug-story-bulk.ts +13 -18
- package/src/server/serverFns/bug/bug-story.ts +10 -14
- package/src/server/serverFns/bug/bug-views.ts +12 -18
- package/src/server/serverFns/bug/bug-webhooks.ts +13 -18
- package/src/server/serverFns/bug/test-bug-confirm.ts +7 -10
- package/src/server/serverFns/changelog/__tests__/fetch.test.ts +40 -1
- package/src/server/serverFns/changelog/fetch.ts +4 -6
- package/src/server/serverFns/chat/conversations.ts +17 -28
- package/src/server/serverFns/chat/list-messages.ts +4 -7
- package/src/server/serverFns/collab-presence.ts +11 -13
- package/src/server/serverFns/collab-snapshot.ts +6 -7
- package/src/server/serverFns/collab.ts +7 -7
- package/src/server/serverFns/compliance.ts +8 -8
- package/src/server/serverFns/design/__tests__/comments.test.ts +54 -10
- package/src/server/serverFns/design/__tests__/designs.test.ts +39 -16
- package/src/server/serverFns/design/__tests__/page-versions.test.ts +52 -14
- package/src/server/serverFns/design/__tests__/shares-password.test.ts +44 -14
- package/src/server/serverFns/design/__tests__/shares.test.ts +44 -14
- package/src/server/serverFns/design/__tests__/versions.test.ts +44 -14
- package/src/server/serverFns/design/ai/__tests__/agent-conversations.test.ts +50 -21
- package/src/server/serverFns/design/ai/__tests__/providers.test.ts +42 -8
- package/src/server/serverFns/design/ai/agent-conversations.ts +19 -26
- package/src/server/serverFns/design/ai/fill-annotation.ts +5 -7
- package/src/server/serverFns/design/ai/generate-prototype.ts +5 -7
- package/src/server/serverFns/design/ai/hosted-models.ts +4 -5
- package/src/server/serverFns/design/ai/providers.ts +30 -39
- package/src/server/serverFns/design/ai/source-mode.ts +10 -12
- package/src/server/serverFns/design/comments.ts +14 -13
- package/src/server/serverFns/design/designs.ts +13 -19
- package/src/server/serverFns/design/page-versions.ts +17 -18
- package/src/server/serverFns/design/pages.ts +17 -18
- package/src/server/serverFns/design/reviews.ts +8 -9
- package/src/server/serverFns/design/shares-password.ts +13 -19
- package/src/server/serverFns/design/shares.ts +22 -31
- package/src/server/serverFns/design/versions.ts +8 -9
- package/src/server/serverFns/harness/__tests__/attach-prototype.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-kb.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-story-ssrf.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-story.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/cancel-run.test.ts +40 -15
- package/src/server/serverFns/harness/__tests__/extract-attachment.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/gallery.spec.ts +76 -12
- package/src/server/serverFns/harness/__tests__/github-workspace.spec.ts +38 -6
- package/src/server/serverFns/harness/__tests__/media-prototype.spec.ts +50 -6
- package/src/server/serverFns/harness/__tests__/media.spec.ts +55 -11
- package/src/server/serverFns/harness/__tests__/sandbox-policy.test.ts +41 -16
- package/src/server/serverFns/harness/__tests__/workspace-files.test.ts +41 -16
- package/src/server/serverFns/harness/attach-prototype.ts +4 -4
- package/src/server/serverFns/harness/attach-to-kb.ts +4 -4
- package/src/server/serverFns/harness/attach-to-story.ts +4 -4
- package/src/server/serverFns/harness/cancel-run.ts +4 -6
- package/src/server/serverFns/harness/extract-attachment.ts +3 -4
- package/src/server/serverFns/harness/gallery.ts +19 -23
- package/src/server/serverFns/harness/github-workspace.ts +14 -21
- package/src/server/serverFns/harness/media.ts +18 -117
- package/src/server/serverFns/harness/sandbox-policy.ts +11 -10
- package/src/server/serverFns/harness/search-mention-candidates.ts +4 -6
- package/src/server/serverFns/harness/workspace-files.ts +19 -26
- package/src/server/serverFns/iteration/__tests__/iteration-auto-schedule.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-crud.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-stories.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-transfer.test.ts +35 -3
- package/src/server/serverFns/iteration/iteration-auto-schedule.ts +7 -10
- package/src/server/serverFns/iteration/iteration-burndown.ts +4 -6
- package/src/server/serverFns/iteration/iteration-crud.ts +26 -35
- package/src/server/serverFns/iteration/iteration-stories.ts +10 -14
- package/src/server/serverFns/iteration/iteration-transfer.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/categories.ts +11 -15
- package/src/server/serverFns/knowledge/public/bookmarks/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/bookmarks/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/favorite.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/refresh-favicon.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/sync-github.ts +5 -7
- package/src/server/serverFns/knowledge/public/bookmarks/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/update.ts +6 -8
- package/src/server/serverFns/knowledge/public/compliance/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/compliance/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/update.ts +5 -7
- package/src/server/serverFns/knowledge/public/dictionary/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/dictionary/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/update.ts +5 -7
- package/src/server/serverFns/knowledge/public/entity-tags.ts +4 -6
- package/src/server/serverFns/knowledge/public/favorite.ts +7 -10
- package/src/server/serverFns/knowledge/public/legal/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/legal/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/update.ts +5 -7
- package/src/server/serverFns/knowledge-index.ts +12 -16
- package/src/server/serverFns/knowledge.ts +50 -67
- package/src/server/serverFns/notifications.ts +25 -34
- package/src/server/serverFns/plugins/harness-plugins.ts +16 -23
- package/src/server/serverFns/project/module-overview.ts +7 -10
- package/src/server/serverFns/project.ts +48 -68
- package/src/server/serverFns/references/create.ts +4 -6
- package/src/server/serverFns/references/resolve.ts +4 -6
- package/src/server/serverFns/references/search.ts +4 -6
- package/src/server/serverFns/share/design/[designId]/events.ts +4 -6
- package/src/server/serverFns/sso.ts +1 -1
- package/src/server/serverFns/story/__tests__/bulk.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-assoc.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-attachments.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-crud-date-key.test.ts +42 -17
- package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-gantt-deps.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-groups.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-read-path-authz.test.ts +40 -4
- package/src/server/serverFns/story/__tests__/story-search.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-transfer.test.ts +34 -1
- package/src/server/serverFns/story/link-preview.ts +5 -7
- package/src/server/serverFns/story/story-assoc.ts +28 -38
- package/src/server/serverFns/story/story-attachments.ts +7 -10
- package/src/server/serverFns/story/story-children.ts +4 -6
- package/src/server/serverFns/story/story-comments.ts +13 -18
- package/src/server/serverFns/story/story-crud/activities.ts +4 -6
- package/src/server/serverFns/story/story-crud/archive.ts +7 -10
- package/src/server/serverFns/story/story-crud/bulk.ts +10 -14
- package/src/server/serverFns/story/story-crud/detail.ts +7 -10
- package/src/server/serverFns/story/story-crud/label-suggest.ts +4 -6
- package/src/server/serverFns/story/story-crud/labels.ts +6 -9
- package/src/server/serverFns/story/story-crud/user-brief.ts +4 -6
- package/src/server/serverFns/story/story-crud.ts +13 -18
- package/src/server/serverFns/story/story-dependencies.ts +16 -22
- package/src/server/serverFns/story/story-groups.ts +10 -14
- package/src/server/serverFns/story/story-links.ts +13 -18
- package/src/server/serverFns/story/story-reactions.ts +13 -18
- package/src/server/serverFns/story/story-search.ts +7 -10
- package/src/server/serverFns/story/story-transfer.ts +10 -14
- package/src/server/serverFns/story/story-tree.ts +7 -10
- package/src/server/serverFns/story-display-options.ts +7 -8
- package/src/server/serverFns/story-view.ts +12 -18
- package/src/server/serverFns/tasks/task-crud.ts +13 -17
- package/src/server/serverFns/tasks/task-queries.ts +12 -18
- package/src/server/serverFns/team.ts +46 -66
- package/src/server/serverFns/testcase/__tests__/automation.test.ts +38 -5
- package/src/server/serverFns/testcase/__tests__/evidence-upload.test.ts +37 -3
- package/src/server/serverFns/testcase/__tests__/generation.test.ts +38 -5
- package/src/server/serverFns/testcase/__tests__/plans.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/regression.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/run-cases.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/runs.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/stats.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-board.test.ts +39 -5
- package/src/server/serverFns/testcase/__tests__/testcase-crud.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-folders.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-groups.test.ts +38 -5
- package/src/server/serverFns/testcase/automation.ts +13 -17
- package/src/server/serverFns/testcase/bulk.ts +10 -14
- package/src/server/serverFns/testcase/evidence-upload.ts +5 -7
- package/src/server/serverFns/testcase/generation.ts +10 -13
- package/src/server/serverFns/testcase/plans.ts +23 -31
- package/src/server/serverFns/testcase/regression.ts +7 -10
- package/src/server/serverFns/testcase/run-cases.ts +13 -18
- package/src/server/serverFns/testcase/runs.ts +13 -18
- package/src/server/serverFns/testcase/stats.ts +13 -18
- package/src/server/serverFns/testcase/testcase-activities.ts +4 -6
- package/src/server/serverFns/testcase/testcase-board.ts +4 -6
- package/src/server/serverFns/testcase/testcase-crud.ts +20 -27
- package/src/server/serverFns/testcase/testcase-display-options.ts +8 -11
- package/src/server/serverFns/testcase/testcase-export.ts +5 -7
- package/src/server/serverFns/testcase/testcase-filter-views.ts +12 -18
- package/src/server/serverFns/testcase/testcase-folders.ts +16 -22
- package/src/server/serverFns/testcase/testcase-groups.ts +4 -6
- package/src/server/serverFns/testcase/testcase-reorder.ts +4 -6
- package/src/server/serverFns/translation.ts +4 -6
- package/src/server/serverFns/user/avatar.ts +4 -6
- package/src/server/serverFns/user/settings.ts +4 -6
- package/src/server/serverFns/user/update-locale.ts +4 -6
- package/src/server/serverFns/workspace-kb.ts +26 -35
- package/src/server/serverFns/workspace.ts +43 -59
- package/src/server/serverFns/ws.ts +4 -6
- package/src/server/serverfn-public-allowlist.ts +117 -0
- package/src/server/story/types.ts +0 -1
- package/src/server/sync/__tests__/scopes.test.ts +64 -0
- package/src/server/sync/scopes.ts +7 -0
- package/src/server/testcase/__tests__/auto-bug.test.ts +44 -12
- package/src/__tests__/bench/baselines/format-timestamp.json +0 -44
- package/src/__typeprobe__.d.ts +0 -4
- package/src/components/forms/app-form-dialog.tsx +0 -126
- package/src/components/forms/hooks/use-form-submit.ts +0 -57
- package/src/components/forms/types.ts +0 -34
- package/src/components/harness/code/workspace-picker.tsx +0 -239
- package/src/components/tiptap/extensions/local-file/insert-local-file.ts +0 -35
- package/src/components/tiptap/extensions/local-file/local-file-node.ts +0 -71
- package/src/devframe-docks/ai-chat-iframe.tsx +0 -29
- package/src/devframe-docks/session-iframe.tsx +0 -90
- package/src/lib/__tests__/desktop-detect.test.ts +0 -19
- package/src/lib/collections/index.ts +0 -22
- package/src/lib/collections/knowledge/index.ts +0 -18
- package/src/lib/collections/knowledge/knowledge-bases-collection.ts +0 -34
- package/src/lib/collections/reference/bookmark-categories-collection.ts +0 -31
- package/src/lib/collections/reference/labels-collection.ts +0 -31
- package/src/lib/collections/reference/projects-collection.ts +0 -31
- package/src/lib/collections/reference/users-brief-collection.ts +0 -35
- package/src/lib/collections/reference/workspaces-collection.ts +0 -34
- package/src/lib/desktop-detect.ts +0 -29
- package/src/paraglide/messages/en.js +0 -28260
- package/src/paraglide/messages/zh.js +0 -28258
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import { useEffect, useState } from "react"
|
|
19
|
-
import type { ReactNode } from "react"
|
|
20
|
-
import { useForm, type AnyReactFormApi } from "@tanstack/react-form"
|
|
21
|
-
import {
|
|
22
|
-
Dialog,
|
|
23
|
-
DialogContent,
|
|
24
|
-
DialogDescription,
|
|
25
|
-
DialogFooter,
|
|
26
|
-
DialogHeader,
|
|
27
|
-
DialogTitle,
|
|
28
|
-
} from "@/components/ui/dialog"
|
|
29
|
-
import { Button } from "@/components/ui/button"
|
|
30
|
-
import { toast } from "@/components/ui/toast"
|
|
31
|
-
import { AppSubmit } from "./app-submit"
|
|
32
|
-
import { m } from "@/paraglide/messages.js";
|
|
33
|
-
|
|
34
|
-
export interface AppFormDialogProps<TValue> {
|
|
35
|
-
open: boolean
|
|
36
|
-
onOpenChange: (open: boolean) => void
|
|
37
|
-
title: string
|
|
38
|
-
description?: string
|
|
39
|
-
defaultValues: TValue
|
|
40
|
-
// TanStack Form v2(alpha)validators 泛型未稳定,经 unknown 通道透传
|
|
41
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
-
validators?: any
|
|
43
|
-
onSubmit?: (values: TValue) => Promise<void>
|
|
44
|
-
submitLabel?: string
|
|
45
|
-
cancelLabel?: string
|
|
46
|
-
children: (
|
|
47
|
-
form: AnyReactFormApi,
|
|
48
|
-
) => ReactNode
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function AppFormDialog<TValue>({
|
|
52
|
-
open,
|
|
53
|
-
onOpenChange,
|
|
54
|
-
title,
|
|
55
|
-
description,
|
|
56
|
-
defaultValues,
|
|
57
|
-
validators,
|
|
58
|
-
onSubmit,
|
|
59
|
-
submitLabel,
|
|
60
|
-
cancelLabel,
|
|
61
|
-
children,
|
|
62
|
-
}: AppFormDialogProps<TValue>) {
|
|
63
|
-
const displaySubmitLabel = submitLabel ?? m.common_form_submit()
|
|
64
|
-
const displayCancelLabel = cancelLabel ?? m.common_form_cancel()
|
|
65
|
-
const [isSaving, setIsSaving] = useState(false)
|
|
66
|
-
|
|
67
|
-
const form = useForm({
|
|
68
|
-
defaultValues: defaultValues as any,
|
|
69
|
-
validators: validators as any,
|
|
70
|
-
onSubmit: async ({ value }) => {
|
|
71
|
-
if (onSubmit) {
|
|
72
|
-
setIsSaving(true)
|
|
73
|
-
try {
|
|
74
|
-
await onSubmit(value as TValue)
|
|
75
|
-
} catch (err) {
|
|
76
|
-
console.error(err instanceof Error ? err.message : "unknown")
|
|
77
|
-
toast.error(m.common_form_operationFailed())
|
|
78
|
-
} finally {
|
|
79
|
-
setIsSaving(false)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
// 对话框复用(不 remount)编辑不同实体时随 open 重置表单值;
|
|
86
|
-
// 刻意只依赖 open(defaultValues 变化不重置,避免打断输入)
|
|
87
|
-
useEffect(() => {
|
|
88
|
-
if (open) form.reset(defaultValues as any)
|
|
89
|
-
}, [open])
|
|
90
|
-
|
|
91
|
-
return (
|
|
92
|
-
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
93
|
-
<DialogContent>
|
|
94
|
-
<DialogHeader>
|
|
95
|
-
<DialogTitle>{title}</DialogTitle>
|
|
96
|
-
{description && <DialogDescription>{description}</DialogDescription>}
|
|
97
|
-
</DialogHeader>
|
|
98
|
-
<form
|
|
99
|
-
onSubmit={(e) => {
|
|
100
|
-
e.preventDefault()
|
|
101
|
-
e.stopPropagation()
|
|
102
|
-
form.handleSubmit()
|
|
103
|
-
}}
|
|
104
|
-
className="space-y-4"
|
|
105
|
-
>
|
|
106
|
-
{children(form)}
|
|
107
|
-
</form>
|
|
108
|
-
<DialogFooter>
|
|
109
|
-
<Button
|
|
110
|
-
type="button"
|
|
111
|
-
variant="outline"
|
|
112
|
-
onClick={() => {
|
|
113
|
-
form.reset()
|
|
114
|
-
onOpenChange(false)
|
|
115
|
-
}}
|
|
116
|
-
>
|
|
117
|
-
{displayCancelLabel}
|
|
118
|
-
</Button>
|
|
119
|
-
<AppSubmit form={form} isSubmitting={isSaving} disabled={isSaving}>
|
|
120
|
-
{displaySubmitLabel}
|
|
121
|
-
</AppSubmit>
|
|
122
|
-
</DialogFooter>
|
|
123
|
-
</DialogContent>
|
|
124
|
-
</Dialog>
|
|
125
|
-
)
|
|
126
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import { useState, useCallback } from "react"
|
|
19
|
-
import { useQueryClient } from "@tanstack/react-query"
|
|
20
|
-
import { toast } from "@/components/ui/toast"
|
|
21
|
-
import { m } from '@/paraglide/messages.js'
|
|
22
|
-
import type { FormSubmitConfig } from "../types"
|
|
23
|
-
|
|
24
|
-
export function useFormSubmit<TData, TResult>(
|
|
25
|
-
serverFn: (data: { data: TData }) => Promise<TResult>,
|
|
26
|
-
config?: FormSubmitConfig,
|
|
27
|
-
) {
|
|
28
|
-
const queryClient = useQueryClient()
|
|
29
|
-
const [isSubmitting, setIsSubmitting] = useState(false)
|
|
30
|
-
|
|
31
|
-
const submit = useCallback(
|
|
32
|
-
async (data: TData) => {
|
|
33
|
-
setIsSubmitting(true)
|
|
34
|
-
try {
|
|
35
|
-
await serverFn({ data })
|
|
36
|
-
if (config?.toastSuccess) toast.success(config.toastSuccess)
|
|
37
|
-
if (config?.invalidateQueries) {
|
|
38
|
-
for (const queryKey of config.invalidateQueries) {
|
|
39
|
-
queryClient.invalidateQueries({ queryKey })
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return true
|
|
43
|
-
} catch (err) {
|
|
44
|
-
// 真实错误留痕(自定义 toastError 文案会掩盖原始信息,线上排障需要)
|
|
45
|
-
console.error(err instanceof Error ? err.message : "unknown")
|
|
46
|
-
const msg = err instanceof Error ? err.message : m.common_form_operationFailed()
|
|
47
|
-
toast.error(config?.toastError ?? msg)
|
|
48
|
-
return false
|
|
49
|
-
} finally {
|
|
50
|
-
setIsSubmitting(false)
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
[serverFn, config, queryClient],
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
return { submit, isSubmitting }
|
|
57
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
export interface FormSubmitConfig {
|
|
19
|
-
toastSuccess?: string
|
|
20
|
-
toastError?: string
|
|
21
|
-
resetOnSuccess?: boolean
|
|
22
|
-
redirectTo?: string
|
|
23
|
-
invalidateQueries?: string[][]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface FieldError {
|
|
27
|
-
message: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type ValidationError = string | null | undefined
|
|
31
|
-
|
|
32
|
-
export type AsyncValidator<T> = (
|
|
33
|
-
input: { value: T },
|
|
34
|
-
) => Promise<ValidationError>
|
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
import { useState } from "react"
|
|
20
|
-
import { FolderOpen, GitBranch, Loader2, Check } from "lucide-react"
|
|
21
|
-
import { Button } from "@/components/ui/button"
|
|
22
|
-
import {
|
|
23
|
-
Select,
|
|
24
|
-
SelectContent,
|
|
25
|
-
SelectItem,
|
|
26
|
-
SelectTrigger,
|
|
27
|
-
SelectValue,
|
|
28
|
-
} from "@/components/ui/select"
|
|
29
|
-
import { listGithubReposFn, listGithubBranchesFn, getGithubConnectionFn } from "@/server/serverFns/harness/github-workspace"
|
|
30
|
-
import { useQuery } from "@tanstack/react-query"
|
|
31
|
-
import { m } from "@/paraglide/messages.js"
|
|
32
|
-
import { isDesktop, getTauriInvoke } from "@/lib/desktop-detect"
|
|
33
|
-
import { toast } from "@/components/ui/toast"
|
|
34
|
-
import { hasFileSystemAccess, pickLocalDirectory } from "@/lib/fsap"
|
|
35
|
-
|
|
36
|
-
// S27:类型从 workspace-context 单一来源导入(删除同名异构副本)
|
|
37
|
-
import type { WorkspaceSource } from "./workspace-context";
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
interface WorkspacePickerProps {
|
|
41
|
-
value?: WorkspaceSource
|
|
42
|
-
onChange: (source: WorkspaceSource | undefined) => void
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interface GithubRepo {
|
|
46
|
-
id: number
|
|
47
|
-
owner: string
|
|
48
|
-
name: string
|
|
49
|
-
full_name: string
|
|
50
|
-
private: boolean
|
|
51
|
-
default_branch: string
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function WorkspacePicker({ value, onChange }: WorkspacePickerProps) {
|
|
55
|
-
const [mode, setMode] = useState<"local" | "github">("local")
|
|
56
|
-
|
|
57
|
-
const { data: repos, isLoading: loadingRepos } = useQuery({
|
|
58
|
-
queryKey: ["github-repos"],
|
|
59
|
-
queryFn: async () => {
|
|
60
|
-
const result = await listGithubReposFn()
|
|
61
|
-
return result as { repos: GithubRepo[] }
|
|
62
|
-
},
|
|
63
|
-
enabled: mode === "github",
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
// S27:连接状态显式取自 serverFn(token 不出服务端),未连接给可操作提示而非空列表
|
|
67
|
-
const { data: connection } = useQuery({
|
|
68
|
-
queryKey: ["github-connection"],
|
|
69
|
-
queryFn: async () => {
|
|
70
|
-
const result = await getGithubConnectionFn()
|
|
71
|
-
return result as { connected: boolean; source: "saved" | "session" | null }
|
|
72
|
-
},
|
|
73
|
-
enabled: mode === "github",
|
|
74
|
-
staleTime: 30_000,
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
const selectedRepo = repos?.repos.find((r) => {
|
|
78
|
-
if (value?.type !== "github") return false
|
|
79
|
-
return r.owner === value.owner && r.name === value.repo
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
const { data: branches, isLoading: loadingBranches } = useQuery({
|
|
83
|
-
queryKey: ["github-branches", selectedRepo?.owner, selectedRepo?.name],
|
|
84
|
-
queryFn: async () => {
|
|
85
|
-
if (!selectedRepo) return { branches: [] }
|
|
86
|
-
const result = await listGithubBranchesFn({ data: { owner: selectedRepo.owner, repo: selectedRepo.name } })
|
|
87
|
-
return result as { branches: Array<{ name: string; protected: boolean }> }
|
|
88
|
-
},
|
|
89
|
-
enabled: mode === "github" && !!selectedRepo,
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
const handleSelectLocal = async () => {
|
|
93
|
-
if (isDesktop()) {
|
|
94
|
-
const invoke = await getTauriInvoke()
|
|
95
|
-
if (!invoke) {
|
|
96
|
-
toast.error(m.chat_workspace_selectFolderError())
|
|
97
|
-
return
|
|
98
|
-
}
|
|
99
|
-
const result = (await invoke("open_directory")) as string | null | undefined
|
|
100
|
-
if (result) {
|
|
101
|
-
onChange({ type: "local", path: result })
|
|
102
|
-
} else {
|
|
103
|
-
// 用户取消对话框,静默忽略
|
|
104
|
-
}
|
|
105
|
-
} else if (hasFileSystemAccess()) {
|
|
106
|
-
const handle = await pickLocalDirectory()
|
|
107
|
-
if (handle) {
|
|
108
|
-
// S27:dirHandle 必须随选入 context(此前仅传 name,文件树拿到 undefined 句柄)
|
|
109
|
-
onChange({ type: "local-fsap", dirHandle: handle, path: handle.name })
|
|
110
|
-
}
|
|
111
|
-
} else {
|
|
112
|
-
// Firefox/Safari 降级:提示上传到云工作区
|
|
113
|
-
toast.info(m.chat_workspace_fsapUnavailable())
|
|
114
|
-
setMode("github")
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const hasGithubToken = (repos?.repos?.length ?? 0) > 0
|
|
119
|
-
|
|
120
|
-
return (
|
|
121
|
-
<div className="space-y-4">
|
|
122
|
-
<div className="flex gap-2">
|
|
123
|
-
<Button
|
|
124
|
-
variant={mode === "local" ? "default" : "outline"}
|
|
125
|
-
size="sm"
|
|
126
|
-
onClick={() => setMode("local")}
|
|
127
|
-
type="button"
|
|
128
|
-
>
|
|
129
|
-
<FolderOpen className="size-4 mr-2" />
|
|
130
|
-
{m.chat_workspace_local()}
|
|
131
|
-
</Button>
|
|
132
|
-
<Button
|
|
133
|
-
variant={mode === "github" ? "default" : "outline"}
|
|
134
|
-
size="sm"
|
|
135
|
-
onClick={() => setMode("github")}
|
|
136
|
-
type="button"
|
|
137
|
-
>
|
|
138
|
-
<GitBranch className="size-4 mr-2" />
|
|
139
|
-
{m.chat_workspace_github()}
|
|
140
|
-
</Button>
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
{mode === "local" && (
|
|
144
|
-
<div className="space-y-2">
|
|
145
|
-
<p className="text-sm text-muted-foreground">{m.chat_workspace_localHint()}</p>
|
|
146
|
-
<Button
|
|
147
|
-
variant="outline"
|
|
148
|
-
size="sm"
|
|
149
|
-
onClick={handleSelectLocal}
|
|
150
|
-
type="button"
|
|
151
|
-
>
|
|
152
|
-
{m.chat_workspace_selectFolder()}
|
|
153
|
-
</Button>
|
|
154
|
-
{(value?.type === "local" || value?.type === "local-fsap") && (
|
|
155
|
-
<div className="flex items-center gap-2 text-sm text-green-600">
|
|
156
|
-
<Check className="size-4" />
|
|
157
|
-
<span>{value.path}</span>
|
|
158
|
-
</div>
|
|
159
|
-
)}
|
|
160
|
-
</div>
|
|
161
|
-
)}
|
|
162
|
-
|
|
163
|
-
{mode === "github" && (
|
|
164
|
-
<div className="space-y-4">
|
|
165
|
-
{!hasGithubToken ? (
|
|
166
|
-
<div className="space-y-2">
|
|
167
|
-
<p className="text-sm text-muted-foreground">{m.chat_workspace_githubConnect()}</p>
|
|
168
|
-
{/* 真实 OAuth 发起端点未接线:裸 authorize URL 缺 client_id/redirect_uri
|
|
169
|
-
打开即 GitHub 报错页,先禁用并提示(接入后端 OAuth 后替换) */}
|
|
170
|
-
<Button variant="outline" size="sm" disabled type="button">
|
|
171
|
-
{m.chat_workspace_connectGithub()}
|
|
172
|
-
</Button>
|
|
173
|
-
<p className="text-xs text-muted-foreground">{m.chat_workspace_githubNotWired()}</p>
|
|
174
|
-
</div>
|
|
175
|
-
) : (
|
|
176
|
-
<>
|
|
177
|
-
<div className="space-y-2">
|
|
178
|
-
<label className="text-sm font-medium">{m.chat_workspace_selectRepo()}</label>
|
|
179
|
-
{loadingRepos ? (
|
|
180
|
-
<Loader2 className="size-4 animate-spin" />
|
|
181
|
-
) : connection && !connection.connected ? (
|
|
182
|
-
<p className="text-xs text-muted-foreground">{m.chat_workspace_githubNotConnected()}</p>
|
|
183
|
-
) : (
|
|
184
|
-
<Select
|
|
185
|
-
value={selectedRepo?.full_name}
|
|
186
|
-
onValueChange={(val) => {
|
|
187
|
-
const repo = repos?.repos.find((r) => r.full_name === val)
|
|
188
|
-
if (repo) {
|
|
189
|
-
onChange({ type: "github", owner: repo.owner, repo: repo.name, branch: repo.default_branch })
|
|
190
|
-
}
|
|
191
|
-
}}
|
|
192
|
-
>
|
|
193
|
-
<SelectTrigger>
|
|
194
|
-
<SelectValue placeholder={m.chat_workspace_selectRepo()} />
|
|
195
|
-
</SelectTrigger>
|
|
196
|
-
<SelectContent>
|
|
197
|
-
{repos?.repos.map((repo) => (
|
|
198
|
-
<SelectItem key={repo.id} value={repo.full_name}>
|
|
199
|
-
{repo.full_name}{repo.private ? ` (${m.chat_workspace_private()})` : ""}
|
|
200
|
-
</SelectItem>
|
|
201
|
-
))}
|
|
202
|
-
</SelectContent>
|
|
203
|
-
</Select>
|
|
204
|
-
)}
|
|
205
|
-
</div>
|
|
206
|
-
|
|
207
|
-
{selectedRepo && (
|
|
208
|
-
<div className="space-y-2">
|
|
209
|
-
<label className="text-sm font-medium">{m.chat_workspace_selectBranch()}</label>
|
|
210
|
-
{loadingBranches ? (
|
|
211
|
-
<Loader2 className="size-4 animate-spin" />
|
|
212
|
-
) : (
|
|
213
|
-
<Select
|
|
214
|
-
value={value?.type === "github" ? value.branch : selectedRepo.default_branch}
|
|
215
|
-
onValueChange={(branch) => {
|
|
216
|
-
onChange({ type: "github", owner: selectedRepo.owner, repo: selectedRepo.name, branch: branch ?? "" })
|
|
217
|
-
}}
|
|
218
|
-
>
|
|
219
|
-
<SelectTrigger>
|
|
220
|
-
<SelectValue />
|
|
221
|
-
</SelectTrigger>
|
|
222
|
-
<SelectContent>
|
|
223
|
-
{branches?.branches.map((b) => (
|
|
224
|
-
<SelectItem key={b.name} value={b.name}>
|
|
225
|
-
{b.name}{b.protected ? ` (${m.chat_workspace_branch()})` : ""}
|
|
226
|
-
</SelectItem>
|
|
227
|
-
))}
|
|
228
|
-
</SelectContent>
|
|
229
|
-
</Select>
|
|
230
|
-
)}
|
|
231
|
-
</div>
|
|
232
|
-
)}
|
|
233
|
-
</>
|
|
234
|
-
)}
|
|
235
|
-
</div>
|
|
236
|
-
)}
|
|
237
|
-
</div>
|
|
238
|
-
)
|
|
239
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { Editor } from '@tiptap/core'
|
|
2
|
-
import { getTauriInvoke } from '@/lib/desktop-detect'
|
|
3
|
-
|
|
4
|
-
interface LocalFilePayload {
|
|
5
|
-
path: string
|
|
6
|
-
mime: string
|
|
7
|
-
base64: string
|
|
8
|
-
size: number
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Open native file picker (Tauri) and insert into editor.
|
|
13
|
-
* No-op if not in desktop environment.
|
|
14
|
-
*/
|
|
15
|
-
export async function insertLocalFile(editor: Editor): Promise<void> {
|
|
16
|
-
const invoke = await getTauriInvoke()
|
|
17
|
-
if (!invoke) return // web 端不显示此按钮
|
|
18
|
-
|
|
19
|
-
const payload = (await invoke('open_local_file', {
|
|
20
|
-
filter: {
|
|
21
|
-
name: 'Images and Documents',
|
|
22
|
-
extensions: ['png', 'jpg', 'jpeg', 'gif', 'webp', 'pdf', 'docx', 'xlsx', 'epub', 'mobi', 'azw3'],
|
|
23
|
-
},
|
|
24
|
-
})) as LocalFilePayload | null
|
|
25
|
-
|
|
26
|
-
if (!payload) return // 用户取消
|
|
27
|
-
|
|
28
|
-
const name = payload.path.split('/').pop() ?? payload.path
|
|
29
|
-
editor.commands.insertLocalFile({
|
|
30
|
-
path: payload.path,
|
|
31
|
-
mime: payload.mime,
|
|
32
|
-
base64: payload.base64,
|
|
33
|
-
name,
|
|
34
|
-
})
|
|
35
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
|
|
5
|
-
import { Node } from '@tiptap/core'
|
|
6
|
-
|
|
7
|
-
export interface LocalFileOptions {
|
|
8
|
-
HTMLAttributes: Record<string, unknown>
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
declare module '@tiptap/core' {
|
|
12
|
-
interface Commands<ReturnType> {
|
|
13
|
-
localFile: {
|
|
14
|
-
insertLocalFile: (attrs: {
|
|
15
|
-
path: string
|
|
16
|
-
mime: string
|
|
17
|
-
base64: string
|
|
18
|
-
name: string
|
|
19
|
-
}) => ReturnType
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const LocalFile = Node.create<LocalFileOptions>({
|
|
25
|
-
name: 'localFile',
|
|
26
|
-
group: 'block',
|
|
27
|
-
atom: true,
|
|
28
|
-
selectable: true,
|
|
29
|
-
draggable: true,
|
|
30
|
-
|
|
31
|
-
addAttributes() {
|
|
32
|
-
return {
|
|
33
|
-
path: { default: null },
|
|
34
|
-
mime: { default: null },
|
|
35
|
-
base64: { default: null },
|
|
36
|
-
name: { default: null },
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
parseHTML() {
|
|
41
|
-
return [{ tag: 'local-file' }]
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
// 审计 🟡:禁止整包 merge HTMLAttributes——base64/mime/path 会被原样输出为
|
|
45
|
-
// 无效 DOM 属性(<img base64="...">),同一份 base64 在 DOM 出现两份。
|
|
46
|
-
// 这里显式挑拣输出字段。
|
|
47
|
-
renderHTML({ node }) {
|
|
48
|
-
const { path, mime, base64, name } = node.attrs as {
|
|
49
|
-
path: string | null
|
|
50
|
-
mime: string | null
|
|
51
|
-
base64: string | null
|
|
52
|
-
name: string | null
|
|
53
|
-
}
|
|
54
|
-
const isImage = mime?.startsWith('image/')
|
|
55
|
-
if (isImage) {
|
|
56
|
-
const src = base64 ? `data:${mime};base64,${base64}` : path
|
|
57
|
-
return ['img', { src: src ?? undefined, alt: name ?? '' }]
|
|
58
|
-
}
|
|
59
|
-
return ['a', { href: path ?? undefined, download: name ?? undefined }, `📎 ${name ?? ''}`]
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
addCommands() {
|
|
63
|
-
return {
|
|
64
|
-
insertLocalFile:
|
|
65
|
-
(attrs) =>
|
|
66
|
-
({ commands }) => {
|
|
67
|
-
return commands.insertContent({ type: 'localFile', attrs })
|
|
68
|
-
},
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
})
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import { createRoot } from 'react-dom/client'
|
|
19
|
-
import { StrictMode } from 'react'
|
|
20
|
-
import { AiDevtoolsPanel } from '@tanstack/react-ai-devtools'
|
|
21
|
-
|
|
22
|
-
const container = document.getElementById('root')
|
|
23
|
-
if (container) {
|
|
24
|
-
createRoot(container).render(
|
|
25
|
-
<StrictMode>
|
|
26
|
-
<AiDevtoolsPanel />
|
|
27
|
-
</StrictMode>,
|
|
28
|
-
)
|
|
29
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
// ⚠ devframe 专用 dock(@devframes/vite 独立 iframe 产物,仅本地开发期可见):
|
|
19
|
-
// 不在主应用 bundle 内、无 paraglide/theme 上下文,故中文文案与硬编码色值为
|
|
20
|
-
// 该隔离环境的刻意豁免,不适用「i18n + CSS 变量」主应用规范。
|
|
21
|
-
|
|
22
|
-
import { createRoot } from 'react-dom/client'
|
|
23
|
-
import { StrictMode, useEffect, useState } from 'react'
|
|
24
|
-
|
|
25
|
-
type UserInfo = {
|
|
26
|
-
id: string
|
|
27
|
-
email: string
|
|
28
|
-
name: string | null
|
|
29
|
-
role: string
|
|
30
|
-
aiProvider?: string | null
|
|
31
|
-
aiModel?: string | null
|
|
32
|
-
hasAiKey?: boolean | null
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function SessionPanel() {
|
|
36
|
-
const [user, setUser] = useState<UserInfo | null>(null)
|
|
37
|
-
const [loading, setLoading] = useState(true)
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
fetch('/api/auth/session', { credentials: 'include' })
|
|
41
|
-
.then((res) => (res.ok ? res.json() : null))
|
|
42
|
-
.then((data) => {
|
|
43
|
-
setUser(data?.user ?? null)
|
|
44
|
-
setLoading(false)
|
|
45
|
-
})
|
|
46
|
-
.catch(() => setLoading(false))
|
|
47
|
-
}, [])
|
|
48
|
-
|
|
49
|
-
if (loading) {
|
|
50
|
-
return (
|
|
51
|
-
<div style={{ display: 'flex', height: '100%', alignItems: 'center', justifyContent: 'center', color: '#888' }}>
|
|
52
|
-
加载中…
|
|
53
|
-
</div>
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (!user) {
|
|
58
|
-
return (
|
|
59
|
-
<div style={{ display: 'flex', height: '100%', alignItems: 'center', justifyContent: 'center', color: '#888' }}>
|
|
60
|
-
未登录
|
|
61
|
-
</div>
|
|
62
|
-
)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const row: React.CSSProperties = { display: 'grid', gridTemplateColumns: '80px 1fr', gap: '6px', fontSize: '12px', padding: '4px 0', borderBottom: '1px solid #00000010' }
|
|
66
|
-
const labelStyle: React.CSSProperties = { color: '#888' }
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<div style={{ padding: 12, fontFamily: 'ui-sans-serif, system-ui, -apple-system, sans-serif', color: '#222' }}>
|
|
70
|
-
<h4 style={{ margin: '0 0 8px', fontSize: 13 }}>当前用户</h4>
|
|
71
|
-
<div style={row}><span style={labelStyle}>ID</span><code>{user.id}</code></div>
|
|
72
|
-
<div style={row}><span style={labelStyle}>Email</span><span>{user.email}</span></div>
|
|
73
|
-
<div style={row}><span style={labelStyle}>Name</span><span>{user.name || '-'}</span></div>
|
|
74
|
-
<div style={row}><span style={labelStyle}>Role</span><span style={{ fontWeight: 600 }}>{user.role}</span></div>
|
|
75
|
-
<h4 style={{ margin: '16px 0 8px', fontSize: 13 }}>AI 配置</h4>
|
|
76
|
-
<div style={row}><span style={labelStyle}>Provider</span><span>{user.aiProvider || '未配置'}</span></div>
|
|
77
|
-
<div style={row}><span style={labelStyle}>Model</span><span>{user.aiModel || '未配置'}</span></div>
|
|
78
|
-
<div style={row}><span style={labelStyle}>Has Key</span><span>{user.hasAiKey ? '是' : '否'}</span></div>
|
|
79
|
-
</div>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const container = document.getElementById('root')
|
|
84
|
-
if (container) {
|
|
85
|
-
createRoot(container).render(
|
|
86
|
-
<StrictMode>
|
|
87
|
-
<SessionPanel />
|
|
88
|
-
</StrictMode>,
|
|
89
|
-
)
|
|
90
|
-
}
|