@allbluecn/web-app 0.19.2 → 0.19.4
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 +45 -44
- package/public/fonts/Trap-font/Trap-Black.otf +0 -0
- package/public/fonts/Trap-font/Trap-Bold.otf +0 -0
- package/public/fonts/Trap-font/Trap-ExtraBold.otf +0 -0
- package/public/fonts/Trap-font/Trap-Light.otf +0 -0
- package/public/fonts/Trap-font/Trap-Medium.otf +0 -0
- package/public/fonts/Trap-font/Trap-Regular.otf +0 -0
- package/public/fonts/Trap-font/Trap-SemiBold.otf +0 -0
- package/public/fonts/buttersans-Rounded.otf +0 -0
- package/src/__tests__/desktop-connection-validate.test.ts +66 -0
- package/src/__tests__/knowledge/public/share-merge.test.ts +7 -1
- package/src/__tests__/security/xss-sanitize.test.ts +21 -0
- package/src/__tests__/setup.ts +5 -0
- package/src/__tests__/story-view.test.ts +24 -2
- package/src/components/agents/agent-bindings-tab.tsx +13 -7
- package/src/components/agents/agent-card.tsx +5 -10
- package/src/components/agents/agent-form-dialog.tsx +10 -3
- package/src/components/agents/agent-selector.tsx +6 -3
- package/src/components/agents/agents-page.tsx +5 -2
- package/src/components/agents/schemas/agent-form.ts +1 -1
- package/src/components/agents/skill-form-dialog.tsx +19 -5
- package/src/components/agents/use-agent-handlers.ts +3 -1
- package/src/components/ai/__tests__/ai-prompt-input-attach.test.tsx +0 -3
- package/src/components/ai/__tests__/web-search-card-url.test.tsx +87 -0
- package/src/components/ai/ai-chat-prompt.tsx +4 -13
- package/src/components/ai/ai-prompt-input/components/action-buttons.tsx +3 -18
- package/src/components/ai/ai-prompt-input/components/context-badge.tsx +1 -13
- package/src/components/ai/ai-prompt-input/components/kb-context-selector.tsx +15 -27
- package/src/components/ai/ai-prompt-input/components/model-select.tsx +21 -14
- package/src/components/ai/ai-prompt-input/constants.tsx +0 -18
- package/src/components/ai/ai-prompt-input/index.tsx +50 -113
- package/src/components/ai/ai-suggested-prompts.tsx +28 -15
- package/src/components/ai/global-harness-sidebar/index.tsx +42 -23
- package/src/components/ai/tool-cards/-shared.tsx +5 -1
- package/src/components/ai/tool-cards/fallback-tool-card.tsx +2 -2
- package/src/components/ai/tool-cards/knowledge-search-card.tsx +7 -53
- package/src/components/ai/tool-cards/web-search-card.tsx +29 -68
- package/src/components/anyhub/anyhub-app-card.tsx +53 -19
- package/src/components/anyhub/anyhub-app-runner.tsx +53 -20
- package/src/components/anyhub/anyhub-install-dialog.tsx +43 -15
- package/src/components/anyhub/anyhub-management-view.tsx +4 -3
- package/src/components/anyhub/anyhub-marketplace-view.tsx +16 -11
- package/src/components/anyhub/anyhub-permission-panel.tsx +50 -16
- package/src/components/anyhub/anyhub-top-nav.tsx +2 -2
- package/src/components/auth/auth-features.ts +32 -0
- package/src/components/auth/icon-input.tsx +3 -1
- package/src/components/auth/password-input.tsx +3 -2
- package/src/components/auth/session-guard.tsx +2 -1
- package/src/components/auth/sso-section.tsx +9 -4
- package/src/components/billing/__tests__/feature-label.test.ts +22 -0
- package/src/components/billing/billing-panel.tsx +8 -32
- package/src/components/billing/checkout-redirect.ts +3 -2
- package/src/components/billing/currency-toggle.tsx +62 -19
- package/src/components/billing/feature-gate.tsx +5 -0
- package/src/components/billing/feature-label.ts +51 -0
- package/src/components/billing/invoice-history.tsx +2 -2
- package/src/components/billing/login-prompt-dialog.tsx +5 -16
- package/src/components/billing/pricing-card.tsx +10 -11
- package/src/components/billing/pricing-page.tsx +26 -4
- package/src/components/billing/seats-manager.tsx +9 -2
- package/src/components/billing/subscription-card.tsx +5 -10
- package/src/components/billing/upgrade-prompt.tsx +2 -11
- package/src/components/billing/use-feature.ts +6 -1
- package/src/components/bug/__tests__/bug-display-dropdown.test.tsx +1 -1
- package/src/components/bug/__tests__/bug-list-loading-defer.test.tsx +1 -1
- package/src/components/bug/__tests__/saved-views.test.tsx +1 -1
- package/src/components/bug/__tests__/toolbar-shell.test.tsx +1 -1
- package/src/components/bug/__tests__/use-paged-bug-groups.test.tsx +1 -1
- package/src/components/bug/bug-list-view.tsx +31 -9
- package/src/components/bug/bug-panel-header.tsx +8 -3
- package/src/components/bug/bug-toolbar.tsx +1 -1
- package/src/components/bug/collect/collect-form.tsx +2 -0
- package/src/components/bug/create-bug-dialog.tsx +2 -1
- package/src/components/bug/detail/activity-tabs.tsx +12 -3
- package/src/components/bug/detail/bug-detail-body.tsx +2 -2
- package/src/components/bug/detail/comment-input.tsx +4 -2
- package/src/components/bug/detail/comment-item.tsx +5 -3
- package/src/components/bug/detail/comment-reactions.tsx +2 -1
- package/src/components/bug/detail/error-context.tsx +10 -0
- package/src/components/bug/detail/events-timeline.tsx +22 -6
- package/src/components/bug/detail/fix-timeline.tsx +20 -7
- package/src/components/bug/detail/props-section.tsx +2 -1
- package/src/components/bug/detail/repro-report-card.tsx +30 -9
- package/src/components/bug/detail/reproduce-steps-view.tsx +3 -2
- package/src/components/bug/display/constants.ts +1 -1
- package/src/components/bug/display/display-dropdown.tsx +1 -1
- package/src/components/bug/display/use-bug-display-options.ts +13 -7
- package/src/components/bug/display/use-paged-bug-groups.ts +16 -4
- package/src/components/bug/filters/field-configs.tsx +156 -174
- package/src/components/bug/inline-editors/assignee-editor.tsx +4 -1
- package/src/components/bug/inline-editors/date-editor.tsx +14 -5
- package/src/components/bug/inline-editors/severity-editor.tsx +14 -17
- package/src/components/bug/peek-panel.tsx +4 -1
- package/src/components/bug/select-bug-dialog.tsx +15 -1
- package/src/components/bug/settings/bug-settings-panel.tsx +24 -8
- package/src/components/bug/settings/collect-page-manager.tsx +10 -5
- package/src/components/bug/settings/webhook-manager.tsx +11 -0
- package/src/components/bug/story-bugs-panel.tsx +214 -227
- package/src/components/bug/views/board-view.tsx +2 -2
- package/src/components/bug/views/bug-list/group.tsx +1 -1
- package/src/components/bug/views/bug-list/index.tsx +1 -1
- package/src/components/bug/views/bug-list/inline-bug-creator.tsx +14 -10
- package/src/components/bug/views/bug-list/row.tsx +6 -3
- package/src/components/bug/views/view-types.ts +1 -1
- package/src/components/changelog/changelog-page.tsx +53 -38
- package/src/components/collab/__tests__/activity-attribution.test.tsx +25 -11
- package/src/components/collab/activity-attribution.tsx +27 -17
- package/src/components/command/command-palette.tsx +12 -4
- package/src/components/design/canvas/document/__tests__/ai.test.ts +71 -0
- package/src/components/design/canvas/document/__tests__/color-utils.test.ts +11 -0
- package/src/components/design/canvas/document/__tests__/frames.test.ts +13 -0
- package/src/components/design/canvas/document/__tests__/layer-order.test.ts +14 -1
- package/src/components/design/canvas/document/align.ts +1 -1
- package/src/components/design/canvas/document/constraints.ts +7 -1
- package/src/components/design/canvas/document/frames.ts +3 -2
- package/src/components/design/canvas/document/layer-order.ts +4 -0
- package/src/components/design/canvas/document/reconcile.ts +1 -5
- package/src/components/design/canvas/document/style/color-utils.ts +2 -2
- package/src/components/design/canvas/document/style/theme-color.ts +15 -0
- package/src/components/design/canvas/document/types.ts +6 -2
- package/src/components/design/canvas/panels/__tests__/color-paint-picker.test.tsx +77 -2
- package/src/components/design/canvas/panels/__tests__/number-drag-input.test.tsx +25 -0
- package/src/components/design/canvas/panels/__tests__/rows.test.tsx +1 -1
- package/src/components/design/canvas/panels/__tests__/toolbar.test.tsx +1 -2
- package/src/components/design/canvas/panels/component-library-data.ts +9 -1
- package/src/components/design/canvas/panels/controls/color-paint-picker.tsx +29 -14
- package/src/components/design/canvas/panels/controls/gradient-editor.tsx +34 -32
- package/src/components/design/canvas/panels/controls/number-drag-input.tsx +38 -53
- package/src/components/design/canvas/panels/controls/pattern-params.tsx +13 -2
- package/src/components/design/canvas/panels/controls/pointer-drag.ts +64 -0
- package/src/components/design/canvas/panels/controls/shader-picker-utils.ts +1 -1
- package/src/components/design/canvas/panels/controls/shader-picker.tsx +27 -4
- package/src/components/design/canvas/panels/controls/use-pointer-drag.ts +84 -0
- package/src/components/design/canvas/panels/frame-property-panel.tsx +60 -44
- package/src/components/design/canvas/panels/layer-panel.tsx +3 -18
- package/src/components/design/canvas/panels/paint-lists-panel.tsx +15 -6
- package/src/components/design/canvas/panels/panel-data.ts +1 -3
- package/src/components/design/canvas/panels/property-panel.tsx +19 -11
- package/src/components/design/canvas/panels/toolbar.tsx +4 -4
- package/src/components/design/canvas/panels/transform-layout-panel.tsx +14 -7
- package/src/components/design/canvas/plugins/geo/shift-by-world.ts +32 -0
- package/src/components/design/canvas/plugins/leafer-x-align/__tests__/align.test.ts +43 -0
- package/src/components/design/canvas/plugins/leafer-x-align/index.ts +23 -35
- package/src/components/design/canvas/plugins/leafer-x-clipboard/index.ts +5 -20
- package/src/components/design/canvas/plugins/leafer-x-history-lite/index.ts +17 -0
- package/src/components/design/canvas/react/__tests__/workbench.test.tsx +0 -2
- package/src/components/design/canvas/react/workbench.tsx +4 -7
- package/src/components/design/canvas/registry/__tests__/registry.test.ts +34 -6
- package/src/components/design/canvas/registry/builtin/button.ts +4 -2
- package/src/components/design/canvas/registry/builtin/card.ts +4 -2
- package/src/components/design/canvas/registry/builtin/default-labels.ts +22 -0
- package/src/components/design/canvas/registry/builtin/input.ts +4 -2
- package/src/components/design/canvas/registry/builtin/rect-shapes.ts +4 -2
- package/src/components/design/canvas/registry/builtin/text.ts +4 -2
- package/src/components/design/canvas/tools/__tests__/tools.test.ts +3 -3
- package/src/components/design/canvas/tools/frame-tool.ts +7 -2
- package/src/components/design/canvas/tools/pen-tool.ts +1 -4
- package/src/components/design/canvas/tools/polyline-tools.ts +1 -4
- package/src/components/design/canvas/tools/shape-tools.ts +7 -1
- package/src/components/design/canvas/tools/text-tool.ts +5 -3
- package/src/components/design/editor/annotation/annotation-node/annotation-node-view.tsx +62 -27
- package/src/components/design/editor/annotation/overlay/annotation-overlay.tsx +7 -5
- package/src/components/design/editor/collaboration/agent-input.tsx +28 -42
- package/src/components/design/editor/collaboration/design-agent-panel.tsx +97 -32
- package/src/components/design/editor/collaboration/design-comment-review-panel.tsx +77 -17
- package/src/components/design/editor/dashboard/create-design-dialog.tsx +13 -4
- package/src/components/design/editor/dashboard/design-dashboard.tsx +10 -14
- package/src/components/design/editor/dashboard/schemas/create-design.ts +1 -1
- package/src/components/design/editor/layout/__tests__/collab-param-wiring.test.tsx +7 -3
- package/src/components/design/editor/layout/design-doc-panel.tsx +21 -8
- package/src/components/design/editor/layout/design-editor-doc-utils.ts +9 -6
- package/src/components/design/editor/layout/design-editor-layout.tsx +1 -1
- package/src/components/design/editor/layout/design-left-sidebar.tsx +17 -10
- package/src/components/design/editor/layout/design-navigation.tsx +8 -1
- package/src/components/design/editor/layout/design-outline-tab.tsx +7 -4
- package/src/components/design/editor/layout/design-right-sidebar.tsx +31 -15
- package/src/components/design/editor/layout/hooks/use-design-auto-save.ts +12 -1
- package/src/components/design/editor/layout/hooks/use-design-page-load.ts +31 -6
- package/src/components/design/editor/pages/design-detail-page.tsx +2 -2
- package/src/components/design/editor/pages/share-design-page.tsx +3 -3
- package/src/components/design/editor/pages-tree/design-tree-page-tab.tsx +82 -46
- package/src/components/design/editor/pages-tree/design-tree-reducer.ts +3 -4
- package/src/components/design/editor/share/design-share-client.tsx +34 -42
- package/src/components/design/editor/share/design-share-panel/components/single-version-share-card.tsx +13 -14
- package/src/components/design/editor/share/design-share-panel/index.tsx +45 -46
- package/src/components/design/editor/share/design-share-panel/types.ts +30 -0
- package/src/components/design/editor/share/design-share-panel/utils.ts +28 -0
- package/src/components/design/editor/share/share-annotation-overlay.tsx +17 -4
- package/src/components/design/editor/share/share-comment-panel.tsx +11 -4
- package/src/components/design/editor/share/share-comment-review-panel.tsx +4 -2
- package/src/components/design/editor/share/share-directory-tree.tsx +14 -8
- package/src/components/design/editor/share/share-doc-view.tsx +16 -5
- package/src/components/design/editor/share/share-layout.tsx +47 -21
- package/src/components/design/editor/share/share-nav-bar.tsx +1 -2
- package/src/components/design/editor/share/share-password-gate.tsx +11 -5
- package/src/components/design/editor/share/share-review-panel.tsx +22 -4
- package/src/components/design/editor/share/share-sse-listener.tsx +6 -3
- package/src/components/design/editor/share/share-theme-toggle.tsx +6 -5
- package/src/components/design/editor/share/share-types.ts +38 -0
- package/src/components/design/editor/share/version-share-client.tsx +6 -4
- package/src/components/design/editor/versions/components/create-version-dialog.tsx +12 -3
- package/src/components/design/editor/versions/components/page-tree-selector.tsx +26 -10
- package/src/components/design/editor/versions/components/page-version-timeline.tsx +13 -9
- package/src/components/design/editor/versions/constants.tsx +3 -2
- package/src/components/design/editor/versions/hooks/use-design-versions.ts +21 -18
- package/src/components/design/editor/versions/hooks/use-page-tree-selection.ts +25 -6
- package/src/components/design/editor/versions/hooks/use-page-version-history.ts +51 -15
- package/src/components/design/editor/versions/lib/restore-version.ts +10 -14
- package/src/components/design/editor/versions/lib/semver.ts +25 -0
- package/src/components/design/editor/versions/page-version-panel.tsx +66 -51
- package/src/components/design/editor/versions/page-version-tree.tsx +30 -17
- package/src/components/error/global-error-boundary.tsx +12 -7
- package/src/components/forms/app-array-field.tsx +3 -1
- package/src/components/forms/app-combobox.tsx +41 -36
- package/src/components/forms/app-date-picker.tsx +25 -17
- package/src/components/forms/app-field-error.tsx +4 -1
- package/src/components/forms/app-field.tsx +15 -2
- package/src/components/forms/app-form-dialog.tsx +15 -3
- package/src/components/forms/app-submit.tsx +7 -10
- package/src/components/forms/hooks/use-form-submit.ts +2 -0
- package/src/components/forms/schemas/common.ts +2 -4
- package/src/components/harness/ai-chat-history/components/conversation-header.tsx +1 -0
- package/src/components/harness/ai-chat-history/components/conversation-item.tsx +24 -4
- package/src/components/harness/ai-chat-history/components/empty-state.tsx +1 -0
- package/src/components/harness/ai-chat-history/index.tsx +17 -7
- package/src/components/harness/ai-chat-history/utils/group-conversations.ts +11 -2
- package/src/components/harness/ai-citations/components/citation-item.tsx +4 -4
- package/src/components/harness/ai-citations/components/citations-list.tsx +5 -2
- package/src/components/harness/ai-citations/components/source-components.tsx +45 -16
- package/src/components/harness/ai-message/components/markdown-content.tsx +0 -1
- package/src/components/harness/ai-message/utils/__tests__/dom-utils.test.ts +38 -0
- package/src/components/harness/ai-message/utils/dom-utils.ts +7 -1
- package/src/components/harness/ai-thinking.tsx +8 -34
- package/src/components/harness/chat-ui.tsx +2 -1
- package/src/components/harness/code/changeset-panel.tsx +13 -4
- package/src/components/harness/code/code-workspace-sidebar.tsx +4 -6
- package/src/components/harness/code/file-tree.tsx +8 -10
- package/src/components/harness/code/preview-panel.tsx +2 -1
- package/src/components/harness/code/terminal-panel.tsx +19 -12
- package/src/components/harness/code/workspace-picker.tsx +4 -6
- package/src/components/harness/composer/attachments/attachment-policy.ts +4 -7
- package/src/components/harness/composer/attachments/attachment-tray.tsx +8 -4
- package/src/components/harness/composer/attachments/use-attachments.ts +42 -13
- package/src/components/harness/composer/composer-editor.tsx +9 -5
- package/src/components/harness/composer/context-meter.tsx +21 -12
- package/src/components/harness/composer/harness-composer.tsx +28 -6
- package/src/components/harness/composer/mention/mention-suggestion-menu.tsx +4 -2
- package/src/components/harness/composer/mention/use-mention-sources.ts +5 -4
- package/src/components/harness/composer/use-composer-submit.ts +2 -1
- package/src/components/harness/composer/use-drafts.ts +22 -2
- package/src/components/harness/dock/dock-panel-container.tsx +27 -10
- package/src/components/harness/dock/dock-registry.ts +7 -1
- package/src/components/harness/dock/resource-preview.tsx +74 -144
- package/src/components/{tiptap/notion-like/setup-error-message/index.tsx → harness/flatten-content.ts} +28 -2
- package/src/components/harness/gallery/gallery-card.tsx +4 -0
- package/src/components/harness/gallery/gallery-grid.tsx +15 -3
- package/src/components/harness/gallery/retranscribe-dialog.tsx +9 -8
- package/src/components/harness/harness-chat-slots.ts +41 -5
- package/src/components/harness/harness-layout.tsx +11 -0
- package/src/components/harness/harness-message.tsx +25 -6
- package/src/components/harness/harness-workbench-page.tsx +39 -7
- package/src/components/harness/image-lightbox.tsx +9 -3
- package/src/components/harness/plugin-mention-menu.tsx +5 -21
- package/src/components/harness/plugin-panel.tsx +27 -21
- package/src/components/harness/queue-bar.tsx +1 -19
- package/src/components/harness/queue-item.tsx +1 -25
- package/src/components/harness/transcript-width-handle.tsx +4 -24
- package/src/components/harness/turn-navigator.tsx +7 -4
- package/src/components/harness/use-column-resize.ts +64 -0
- package/src/components/harness/workbench/use-track-columns.ts +12 -3
- package/src/components/harness/workbench/workbench-shell.tsx +25 -44
- package/src/components/hextaui/ai-citations.tsx +39 -16
- package/src/components/hextaui/ai-file-upload.tsx +43 -20
- package/src/components/hextaui/ai-message.tsx +32 -13
- package/src/components/hextaui/ai-thinking.tsx +10 -115
- package/src/components/hextaui/command-menu.tsx +9 -2
- package/src/components/hotkeys/shortcuts-panel.tsx +4 -3
- package/src/components/iteration/auto-schedule-dialog.tsx +14 -8
- package/src/components/iteration/burndown-chart.tsx +1 -1
- package/src/components/iteration/create-iteration-dialog.tsx +2 -2
- package/src/components/iteration/iteration-card.tsx +3 -1
- package/src/components/iteration/iteration-editor.tsx +24 -10
- package/src/components/kibo-ui/contribution-graph/index.tsx +20 -4
- package/src/components/knowledge/dialog/knowledge-form-dialog.tsx +3 -2
- package/src/components/knowledge/doc-properties.tsx +9 -2
- package/src/components/knowledge/doc-type-meta.ts +47 -0
- package/src/components/knowledge/editor/knowledge-doc-editor.tsx +30 -58
- package/src/components/knowledge/editor/use-auto-save-channels.ts +93 -0
- package/src/components/knowledge/knowledge-homepage.tsx +11 -3
- package/src/components/knowledge/knowledge-tree-item.tsx +16 -28
- package/src/components/knowledge/knowledge-tree.tsx +18 -22
- package/src/components/knowledge/public/bookmark-card.tsx +10 -2
- package/src/components/knowledge/public/industry-options.ts +36 -0
- package/src/components/knowledge/public/legal-detail-actions.tsx +286 -0
- package/src/components/layout/sidebar-03/nav-main.tsx +2 -2
- package/src/components/magicui/__tests__/word-rotate.test.tsx +28 -0
- package/src/components/magicui/primitives/animate/slot.tsx +17 -9
- package/src/components/magicui/primitives/animate/tooltip.tsx +10 -0
- package/src/components/magicui/sparkles-text.tsx +17 -2
- package/src/components/magicui/word-rotate.tsx +7 -1
- package/src/components/react-bits/light-rays.jsx +8 -1
- package/src/components/settings/personal-team/account/account-client.tsx +1 -1
- package/src/components/settings/personal-team/account/avatar/notion-avatar-editor.tsx +1 -1
- package/src/components/settings/personal-team/account/settings-profile.tsx +1 -1
- package/src/components/share/public-doc-share-page.tsx +122 -0
- package/src/components/shared-kit/list-kit/display/__tests__/dropdown.test.tsx +1 -1
- package/src/components/shared-kit/list-kit/display/dropdown.tsx +1 -1
- package/src/components/shared-kit/list-kit/kanban/manual-order.ts +1 -1
- package/src/components/{testcase/views → shared-kit/list-kit}/move.ts +3 -2
- package/src/components/shared-kit/timezone/timezone-bootstrap.tsx +0 -1
- package/src/components/story/detail/story-detail-toolbar/associated-attachments-panel.tsx +10 -10
- package/src/components/story/display/types.ts +2 -2
- package/src/components/story/filters/filter-check-popover.tsx +104 -0
- package/src/components/story/inline-editors/state-editor.tsx +19 -17
- package/src/components/story/inline-editors/story-select-dialog.tsx +113 -134
- package/src/components/story/peek-panel.tsx +20 -12
- package/src/components/story/relations/attachment-manage-dialog.tsx +31 -19
- package/src/components/story/relations/design-select-dialog.tsx +28 -40
- package/src/components/story/relations/file-preview.tsx +8 -6
- package/src/components/story/relations/format.ts +70 -14
- package/src/components/story/relations/knowledge-select-dialog.tsx +41 -39
- package/src/components/story/relations/link-manage-dialog.tsx +25 -6
- package/src/components/story/relations/story-ref-row.tsx +4 -5
- package/src/components/story/relations/use-linked-selection.ts +72 -0
- package/src/components/story/search-popover.tsx +20 -5
- package/src/components/story/story-list-view.tsx +69 -28
- package/src/components/story/story-panel-header.tsx +9 -3
- package/src/components/story/story-toolbar.tsx +30 -11
- package/src/components/story/transfer-story-popover.tsx +17 -10
- package/src/components/story/types.ts +4 -1
- package/src/components/story/views/calendar-view.tsx +96 -99
- package/src/components/story/views/create-view-dialog.tsx +10 -6
- package/src/components/story/views/story-list/__tests__/move.test.ts +1 -1
- package/src/components/story/views/story-list/batch-preview-dialog.tsx +77 -117
- package/src/components/story/views/story-list/group.tsx +27 -23
- package/src/components/story/views/story-list/index.tsx +84 -52
- package/src/components/story/views/story-list/inline-story-creator.tsx +10 -2
- package/src/components/story/views/story-list/row.tsx +1 -2
- package/src/components/story/views/story-list/use-flat-rows.ts +10 -12
- package/src/components/story/views/timeline-view.tsx +11 -15
- package/src/components/story/views/view-list-section.tsx +59 -37
- package/src/components/testcase/__tests__/manual-move.test.ts +1 -1
- package/src/components/testcase/__tests__/step-stream.test.tsx +30 -0
- package/src/components/testcase/list-view.tsx +1 -1
- package/src/components/testcase/runs/run-matrix.tsx +36 -8
- package/src/components/testcase/runs/step-stream.tsx +24 -8
- package/src/components/testcase/testcase-toolbar.tsx +6 -2
- package/src/components/testcase/views/board-view.tsx +25 -9
- package/src/components/testcase/views/create-view-dialog.tsx +3 -1
- package/src/components/testcase/views/view-selector-button.tsx +33 -19
- package/src/components/tiptap/__tests__/audit-fixes.test.ts +147 -0
- package/src/components/tiptap/extensions/ai-extension.ts +110 -25
- package/src/components/tiptap/extensions/ai-suggestion-mark.ts +6 -2
- package/src/components/tiptap/extensions/local-file/local-file-node.ts +19 -15
- package/src/components/tiptap/extensions/node-background-extension.ts +21 -3
- package/src/components/tiptap/lib/advanced-utils.ts +6 -8
- package/src/components/tiptap/lib/collab-utils.ts +27 -23
- package/src/components/tiptap/lib/doc-group.ts +62 -0
- package/src/components/tiptap/lib/utils/platform.ts +10 -9
- package/src/components/tiptap/lib/utils/selection.ts +3 -3
- package/src/components/tiptap/lib/utils/url.ts +25 -11
- package/src/components/tiptap/mindmap/lib/menu-actions.ts +14 -2
- package/src/components/tiptap/mindmap/mind-map.tsx +42 -10
- package/src/components/tiptap/node/doc-card-node-view.tsx +35 -15
- package/src/components/tiptap/node/image-node/image-node-extension.ts +27 -8
- package/src/components/tiptap/node/image-node/image-node-view.tsx +7 -2
- package/src/components/tiptap/node/image-upload-node/image-upload-node.tsx +25 -20
- package/src/components/tiptap/node/mention-extension.ts +3 -9
- package/src/components/tiptap/node/table-node/extensions/table-handle/table-handle-plugin.ts +61 -40
- package/src/components/tiptap/node/table-node/extensions/table-node-extension.ts +7 -6
- package/src/components/tiptap/node/table-node/lib/table-dom.ts +4 -0
- package/src/components/tiptap/node/table-node/ui/table-handle/table-handle.tsx +2 -2
- package/src/components/tiptap/node/table-node/ui/table-handle-menu/table-handle-menu.tsx +4 -3
- package/src/components/tiptap/node/table-node/ui/table-selection-overlay/table-selection-overlay.tsx +16 -1
- package/src/components/tiptap/node/table-node/ui/table-sort-row-column-button/use-table-sort-row-column.ts +3 -7
- package/src/components/tiptap/node/toc-node/toc-node.tsx +4 -2
- package/src/components/tiptap/notion-like/editor-extensions.ts +11 -2
- package/src/components/tiptap/notion-like/notion-like-editor-header.tsx +2 -10
- package/src/components/tiptap/notion-like/notion-like-editor-toolbar-floating.tsx +9 -23
- package/src/components/tiptap/notion-like/notion-like-editor.tsx +66 -63
- package/src/components/tiptap/ui/ai-menu/ai-menu-hooks.ts +12 -0
- package/src/components/tiptap/ui/ai-menu/ai-menu-items/ai-menu-items.tsx +51 -129
- package/src/components/tiptap/ui/ai-menu/ai-menu-utils.ts +1 -1
- package/src/components/tiptap/ui/ai-menu/ai-menu.tsx +50 -30
- package/src/components/tiptap/ui/copy-anchor-link-button/use-scroll-to-hash.ts +6 -3
- package/src/components/tiptap/ui/doc-reference-floating/doc-reference-floating.tsx +4 -11
- package/src/components/tiptap/ui/drag-context-menu/drag-context-menu.tsx +11 -12
- package/src/components/tiptap/ui/image-download-button/use-image-download.ts +2 -1
- package/src/components/tiptap/ui/improve-dropdown/use-improve-dropdown.ts +15 -23
- package/src/components/tiptap/ui/link-popover/link-popover.tsx +19 -23
- package/src/components/tiptap/ui/link-popover/use-link-popover.ts +12 -2
- package/src/components/tiptap/ui/slash-dropdown-menu/use-slash-dropdown-menu.ts +9 -0
- package/src/components/workspace/dialogs/create-workspace-dialog.tsx +20 -13
- package/src/components/workspace/dialogs/delete-workspace-options.tsx +0 -3
- package/src/components/workspace/dialogs/edit-workspace-dialog.tsx +20 -13
- package/src/components/workspace/header/workspace-header.tsx +1 -1
- package/src/components/workspace/kb/workspace-kb-card.tsx +12 -4
- package/src/components/workspace/kb/workspace-kb-manage-dialog.tsx +8 -1
- package/src/components/workspace/kb/workspace-quick-doc-dialog.tsx +24 -7
- package/src/components/workspace/members/workspace-member-item.tsx +8 -12
- package/src/components/workspace/members/workspace-members-manager.tsx +38 -25
- package/src/components/workspace/projects/workspace-project-list.tsx +47 -63
- package/src/components/workspace/schemas/create-workspace.ts +14 -5
- package/src/config/sidebar-routes.tsx +2 -10
- package/src/design-engine/ai/ai.ts +75 -5
- package/src/design-engine/ai/server-registry.ts +8 -0
- package/src/design-engine/document/serialize-leafer-json.ts +17 -7
- package/src/design-engine/document/serialize-sanitize.ts +21 -3
- package/src/design-engine/engine/__tests__/app-commands.test.ts +156 -0
- package/src/design-engine/engine/__tests__/path-anchors.test.ts +43 -0
- package/src/design-engine/engine/app.ts +1 -0
- package/src/design-engine/engine/boolean-ops.ts +28 -8
- package/src/design-engine/engine/engine-actions.ts +13 -3
- package/src/design-engine/engine/engine-decor.ts +42 -21
- package/src/design-engine/engine/engine-doc.ts +21 -5
- package/src/design-engine/engine/engine-path.ts +29 -25
- package/src/design-engine/engine/export-node.ts +26 -4
- package/src/design-engine/engine/path-anchors.ts +88 -25
- package/src/devframe-docks/session-iframe.tsx +4 -0
- package/src/hooks/__tests__/use-entity-subscription.test.ts +39 -1
- package/src/hooks/use-entity-subscription.ts +36 -5
- package/src/hooks/use-load-more.ts +16 -6
- package/src/hooks/use-notifications.ts +6 -3
- package/src/hooks/use-paged-groups.ts +3 -2
- package/src/hooks/use-popover-outside-close.ts +46 -0
- package/src/hooks/use-scrolling.ts +18 -10
- package/src/hooks/use-translator.ts +45 -28
- package/src/lib/__tests__/ai-adapter.test.ts +40 -39
- package/src/lib/__tests__/annotation-prompt.test.ts +6 -2
- package/src/lib/__tests__/datetime.test.ts +6 -0
- package/src/lib/__tests__/github.test.ts +87 -0
- package/src/lib/__tests__/login-redirect.test.ts +80 -0
- package/src/lib/__tests__/project-display-id.test.ts +5 -4
- package/src/lib/__tests__/safe-url.test.ts +84 -0
- package/src/lib/__tests__/sse-transport.test.ts +20 -2
- package/src/lib/agents/skill-errors.ts +12 -0
- package/src/lib/ai/__tests__/story-jsonl.test.ts +15 -3
- package/src/lib/ai/chat-handoff.ts +63 -45
- package/src/lib/ai/default-model.ts +9 -0
- package/src/lib/ai/story-jsonl.ts +39 -6
- package/src/lib/ai/use-knowledge-bases.ts +20 -13
- package/src/lib/ai/use-selected-model.ts +72 -22
- package/src/lib/anyhub/anyhub-message-bridge.ts +83 -30
- package/src/lib/anyhub/anyhub-store.ts +11 -6
- package/src/lib/{pgvector.ts → anyhub/base-dir.ts} +10 -4
- package/src/lib/anyhub/capabilities.ts +34 -15
- package/src/lib/anyhub/local-path.ts +1 -1
- package/src/lib/anyhub/permissions.ts +18 -6
- package/src/lib/anyhub/proxy.ts +26 -4
- package/src/lib/anyhub/types.ts +3 -6
- package/src/lib/app-version.ts +8 -1
- package/src/lib/auth/__tests__/auth-config-profile-cache.test.ts +32 -4
- package/src/lib/auth/auth.config.ts +219 -94
- package/src/lib/auth/sso-authorize.ts +12 -3
- package/src/lib/auth/submit-credentials.ts +60 -0
- package/src/lib/changelog/sdk-versions.ts +8 -6
- package/src/lib/collab/__tests__/presence-store.test.ts +9 -0
- package/src/lib/collab/bindings/__tests__/canvas-tree-perf.test.ts +6 -2
- package/src/lib/collab/bindings/canvas-local.ts +22 -25
- package/src/lib/collab/bindings/canvas-presence.ts +11 -26
- package/src/lib/collab/bindings/canvas-remote.ts +9 -18
- package/src/lib/collab/bindings/steps.ts +6 -2
- package/src/lib/collab/module-map.ts +2 -1
- package/src/lib/collab/provider.ts +9 -6
- package/src/lib/collab/throttle-core.ts +87 -0
- package/src/lib/collab/use-collab-doc.ts +5 -0
- package/src/lib/collab/use-presence-report.ts +11 -4
- package/src/lib/collab/use-self-profile-broadcast.ts +13 -0
- package/src/lib/collab/use-share-presence.ts +14 -14
- package/src/lib/collections/reference/users-brief-collection.ts +5 -2
- package/src/lib/commands/registry.ts +3 -1
- package/src/lib/comment-utils.ts +8 -6
- package/src/lib/crypto/api-key-cipher.ts +5 -0
- package/src/lib/datetime.ts +17 -7
- package/src/lib/deploy-region.ts +12 -3
- package/src/lib/design-tree-utils.ts +30 -0
- package/src/lib/form/standard-schema-validator.ts +44 -0
- package/src/lib/fsap.ts +16 -8
- package/src/lib/github.ts +33 -59
- package/src/lib/hooks/use-story-panel-open.ts +79 -14
- package/src/lib/hotkeys/registry.ts +35 -26
- package/src/lib/hotkeys/types.ts +4 -2
- package/src/{server/serverFns/iteration/__tests__/burndown-core.test.ts → lib/iteration/__tests__/burndown.test.ts} +1 -1
- package/src/{server/serverFns/iteration/burndown-core.ts → lib/iteration/burndown.ts} +5 -0
- package/src/lib/knowledge/share-result-message.ts +26 -0
- package/src/lib/layout.shared.tsx +14 -2
- package/src/lib/login-redirect.ts +65 -0
- package/src/lib/optimistic/use-optimistic-mutation.ts +14 -3
- package/src/lib/outline-utils.ts +7 -0
- package/src/lib/plugin-runtime/bridge.ts +53 -7
- package/src/lib/plugin-runtime/plugin-client-tools.ts +37 -14
- package/src/lib/plugin-runtime/plugin-client.ts +45 -28
- package/src/lib/plugin-runtime/worker-realm-source.ts +51 -15
- package/src/lib/project-display-id.ts +7 -3
- package/src/lib/project-module-meta.ts +34 -11
- package/src/lib/query-client-seam.test.ts +6 -4
- package/src/lib/query-client-seam.ts +8 -0
- package/src/lib/redis.ts +14 -2
- package/src/lib/restore-version.ts +3 -0
- package/src/lib/router-context.ts +3 -0
- package/src/lib/safe-url.ts +91 -0
- package/src/lib/sanitize.ts +35 -2
- package/src/lib/share-events.ts +18 -2
- package/src/lib/sse-transport.ts +14 -6
- package/src/lib/story/description-diff.ts +12 -11
- package/src/lib/story/video-embed.ts +7 -2
- package/src/lib/tiptap/__tests__/link-policy.test.ts +35 -0
- package/src/lib/tiptap/link-policy.ts +25 -0
- package/src/lib/vector-store/allowlist.ts +33 -0
- package/src/lib/vector-store/pg-vector-store.ts +13 -6
- package/src/lib/vector-store/sqlite-vec-store.ts +87 -42
- package/src/providers/index.tsx +16 -1
- package/src/providers/theme-mode-provider.tsx +3 -2
- package/src/routes/-tests/attachments-content.test.ts +125 -0
- package/src/routes/__desktop/onboarding/route.lazy.tsx +45 -15
- package/src/routes/__root.tsx +8 -6
- package/src/routes/_login/changelog/confirm/route.tsx +2 -1
- package/src/routes/_login/email-unsubscribe/route.tsx +2 -1
- package/src/routes/_login/forgot-password/route.lazy.tsx +4 -8
- package/src/routes/_login/login/route.lazy.tsx +17 -73
- package/src/routes/_login/login/route.tsx +4 -3
- package/src/routes/_login/register/route.lazy.tsx +5 -9
- package/src/routes/_login/reset-password/route.lazy.tsx +4 -8
- package/src/routes/_login/schemas/-auth.ts +21 -0
- package/src/routes/_login/verify-email/route.lazy.tsx +33 -3
- package/src/routes/_login/verify-email/route.tsx +2 -1
- package/src/routes/_nav/-components/nav-not-found.tsx +19 -13
- package/src/routes/_nav/apps/anyhub/$id/route.lazy.tsx +1 -0
- package/src/routes/_nav/apps/anyhub/route.tsx +5 -3
- package/src/routes/_nav/bugs/$bugId/route.lazy.tsx +4 -4
- package/src/routes/_nav/bugs/$bugId/route.tsx +1 -1
- package/src/routes/_nav/changelog/route.tsx +5 -4
- package/src/routes/_nav/dashboard/-components/avatar-group.tsx +9 -5
- package/src/routes/_nav/dashboard/route.lazy.tsx +6 -18
- package/src/routes/_nav/dashboard/route.tsx +3 -1
- package/src/routes/_nav/design/canvas/$id/route.tsx +2 -1
- package/src/routes/_nav/harness/$threadId.lazy.tsx +3 -0
- package/src/routes/_nav/knowledge/$kbId/doc/$docId/route.lazy.tsx +3 -0
- package/src/routes/_nav/knowledge/$kbId/index.tsx +4 -1
- package/src/routes/_nav/knowledge/$kbId/route.lazy.tsx +44 -41
- package/src/routes/_nav/knowledge/$kbId/route.tsx +6 -2
- package/src/routes/_nav/knowledge/bookmarks/$id.lazy.tsx +15 -2
- package/src/routes/_nav/knowledge/bookmarks/index.lazy.tsx +9 -4
- package/src/routes/_nav/knowledge/compliance/$id.lazy.tsx +59 -148
- package/src/routes/_nav/knowledge/compliance/index.lazy.tsx +15 -21
- package/src/routes/_nav/knowledge/dictionaries/$id.lazy.tsx +45 -13
- package/src/routes/_nav/knowledge/dictionaries/index.lazy.tsx +6 -17
- package/src/routes/_nav/knowledge/index.lazy.tsx +14 -7
- package/src/routes/_nav/knowledge/laws/$id.lazy.tsx +59 -149
- package/src/routes/_nav/knowledge/laws/index.lazy.tsx +14 -6
- package/src/routes/_nav/knowledge/summary/index.lazy.tsx +23 -13
- package/src/routes/_nav/notifications/route.tsx +2 -1
- package/src/routes/_nav/notion-like/route.tsx +1 -1
- package/src/routes/_nav/pricing-02/route.tsx +1 -1
- package/src/routes/_nav/projects/$projectId/$storyId/route.lazy.tsx +2 -1
- package/src/routes/_nav/projects/$projectId/index.lazy.tsx +1 -1
- package/src/routes/_nav/projects/$projectId/iterations/$iterationId/route.lazy.tsx +55 -30
- package/src/routes/_nav/projects/$projectId/iterations/$iterationId/route.tsx +5 -2
- package/src/routes/_nav/projects/$projectId/settings/route.lazy.tsx +17 -9
- package/src/routes/_nav/route.lazy.tsx +2 -0
- package/src/routes/_nav/settings/-settings-tabs.tsx +7 -3
- package/src/routes/_nav/settings/account/route.lazy.tsx +11 -2
- package/src/routes/_nav/settings/account/route.tsx +17 -10
- package/src/routes/_nav/settings/ai/hosted/route.lazy.tsx +10 -3
- package/src/routes/_nav/settings/ai/hosted/route.tsx +3 -3
- package/src/routes/_nav/settings/ai/index/route.lazy.tsx +2 -1
- package/src/routes/_nav/settings/ai/providers/$providerId/route.lazy.tsx +5 -5
- package/src/routes/_nav/settings/ai/providers/$providerId/route.tsx +5 -2
- package/src/routes/_nav/settings/ai/route.tsx +7 -5
- package/src/routes/_nav/settings/billing/route.lazy.tsx +16 -3
- package/src/routes/_nav/settings/billing/route.tsx +6 -3
- package/src/routes/_nav/settings/privacy/route.lazy.tsx +6 -4
- package/src/routes/_nav/settings/route.tsx +0 -5
- package/src/routes/_nav/settings/team/route.lazy.tsx +11 -2
- package/src/routes/_nav/settings/team/route.tsx +13 -7
- package/src/routes/_nav/stories/$storyId/route.lazy.tsx +2 -1
- package/src/routes/_nav/stories/$storyId/route.tsx +5 -1
- package/src/routes/_nav/tasks/-components/ai-task-detail.tsx +2 -8
- package/src/routes/_nav/tasks/-components/ai-task-list.tsx +3 -9
- package/src/routes/_nav/tasks/-components/source-ai-exec-dialog.tsx +2 -8
- package/src/routes/_nav/tasks/-components/task-constants.ts +15 -0
- package/src/routes/_nav/test-cases/runs/$runId/route.lazy.tsx +2 -1
- package/src/routes/_nav/workspaces/$workspaceId/activities/route.lazy.tsx +3 -17
- package/src/routes/_nav/workspaces/$workspaceId/route.lazy.tsx +17 -44
- package/src/routes/_nav/workspaces/$workspaceId/route.tsx +0 -1
- package/src/routes/_nav/workspaces/$workspaceId/settings/route.lazy.tsx +7 -17
- package/src/routes/_nav/workspaces/index.lazy.tsx +16 -16
- package/src/routes/_public/pricing/route.tsx +5 -3
- package/src/routes/api/attachments/$id/content.ts +55 -11
- package/src/routes/api/attachments/upload.ts +72 -38
- package/src/routes/api/auth/desktop-callback.ts +46 -10
- package/src/routes/api/billing-webhook.ts +8 -4
- package/src/routes/api/blob/$id.ts +6 -1
- package/src/routes/api/cron/changelog-release.ts +6 -2
- package/src/routes/api/cron/subscription-reminders.ts +21 -14
- package/src/routes/api/design/prototype/route.ts +7 -4
- package/src/routes/api/license/activate/route.ts +24 -1
- package/src/routes/api/license/heartbeat/route.ts +14 -1
- package/src/routes/api/notifications/stream.ts +22 -15
- package/src/routes/api/share/design/$designId/events.ts +13 -0
- package/src/routes/api/story-ai.ts +11 -0
- package/src/routes/api/test-runs/$runId/events.ts +11 -7
- package/src/routes/design-files/$projectId/$artboardId/$filename.ts +22 -3
- package/src/routes/invite/$token/route.lazy.tsx +8 -7
- package/src/routes/server/ai-stream.ts +6 -0
- package/src/routes/server/ws.ts +11 -2
- package/src/routes/share/$versionId/route.lazy.tsx +3 -7
- package/src/routes/share/compliance/$id/route.lazy.tsx +13 -64
- package/src/routes/share/compliance/$id/route.tsx +6 -1
- package/src/routes/share/law/$id/route.lazy.tsx +13 -64
- package/src/routes/share/law/$id/route.tsx +6 -1
- package/src/server/__tests__/agent-crud.test.ts +8 -0
- package/src/server/__tests__/chat-conversations.test.ts +1 -0
- package/src/server/__tests__/fetch-guard.test.ts +67 -0
- package/src/{lib → server}/__tests__/rag.test.ts +1 -1
- package/src/server/__tests__/resources.license.test.ts +3 -2
- package/src/server/__tests__/resources.test.ts +29 -4
- package/src/server/__tests__/share-version.test.ts +64 -12
- package/src/server/__tests__/skill-crud.test.ts +9 -2
- package/src/server/__tests__/sso-domain.test.ts +1 -1
- package/src/server/__tests__/sso-tokens.test.ts +23 -3
- package/src/server/ai-gateway/__tests__/agent-runtime.test.ts +14 -11
- package/src/server/ai-gateway/__tests__/chat-handler-prompt-key.test.ts +1 -1
- package/src/server/ai-gateway/__tests__/chat-stream-builder-code-mode.test.ts +1 -1
- package/src/server/ai-gateway/__tests__/chat-stream-builder-memory.test.ts +1 -1
- package/src/server/ai-gateway/__tests__/chat-stream-builder-sandbox.test.ts +30 -6
- package/src/server/ai-gateway/__tests__/chat-stream-builder-skills.test.ts +1 -1
- package/src/server/ai-gateway/__tests__/code-mode-stack.test.ts +59 -8
- package/src/server/ai-gateway/__tests__/consume-attachments.test.ts +1 -1
- package/src/server/ai-gateway/__tests__/create-pr.test.ts +169 -0
- package/src/server/ai-gateway/__tests__/delegate-task.test.ts +121 -0
- package/src/server/ai-gateway/__tests__/embedding-request.test.ts +17 -1
- package/src/server/ai-gateway/__tests__/embedding.test.ts +23 -0
- package/src/server/ai-gateway/__tests__/interrupt-store.test.ts +98 -85
- package/src/server/ai-gateway/__tests__/knowledge-search-fence.test.ts +2 -2
- package/src/server/ai-gateway/__tests__/message-store.test.ts +53 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-adapter.test.ts +40 -39
- package/src/server/ai-gateway/__tests__/prompt-vars-contract.test.ts +1 -1
- package/src/server/ai-gateway/__tests__/provider-adapter.test.ts +56 -0
- package/src/server/ai-gateway/__tests__/run-store.test.ts +51 -15
- package/src/server/ai-gateway/__tests__/skills-resource-tool.test.ts +56 -0
- package/src/server/ai-gateway/__tests__/todo-plan-tools.test.ts +17 -4
- package/src/server/ai-gateway/__tests__/tool-error-sanitize.test.ts +119 -0
- package/src/server/ai-gateway/__tests__/tools-authorization.test.ts +211 -0
- package/src/server/ai-gateway/adapter.ts +35 -9
- package/src/server/ai-gateway/chat-handler.ts +81 -46
- package/src/server/ai-gateway/chat-stream-builder.ts +37 -4
- package/src/server/ai-gateway/code-mode/index.ts +11 -7
- package/src/server/ai-gateway/code-mode/sandbox.ts +59 -17
- package/src/server/ai-gateway/code-mode/vm-driver.ts +15 -16
- package/src/server/ai-gateway/durability/pg-stream.ts +10 -9
- package/src/server/ai-gateway/durability/reaper-driver.ts +3 -0
- package/src/server/ai-gateway/embedding.ts +22 -2
- package/src/server/ai-gateway/label-suggest.ts +14 -3
- package/src/server/ai-gateway/log-redact.ts +61 -0
- package/src/server/ai-gateway/media/adapters.ts +19 -0
- package/src/server/ai-gateway/media/index.ts +19 -0
- package/src/server/ai-gateway/media/recorder.ts +3 -1
- package/src/server/ai-gateway/memory/pgvector-adapter.ts +12 -24
- package/src/server/ai-gateway/middlewares/logger.ts +4 -1
- package/src/server/ai-gateway/middlewares/plan-approval.ts +33 -14
- package/src/server/ai-gateway/middlewares/rate-limit.ts +15 -0
- package/src/server/ai-gateway/middlewares/usage-log.ts +17 -1
- package/src/server/ai-gateway/model-fetch.ts +3 -0
- package/src/server/ai-gateway/persistence/interrupt-store.ts +42 -32
- package/src/server/ai-gateway/persistence/message-store.ts +30 -10
- package/src/server/ai-gateway/persistence/metadata-store.ts +13 -2
- package/src/server/ai-gateway/persistence/run-store.ts +25 -3
- package/src/server/ai-gateway/prompts/index.ts +1 -1
- package/src/server/ai-gateway/prompts/registry.ts +24 -2
- package/src/server/ai-gateway/prompts/seed.ts +22 -12
- package/src/server/ai-gateway/provider-router.ts +32 -32
- package/src/server/ai-gateway/rerank.ts +20 -1
- package/src/server/ai-gateway/runs/agent-runtime.ts +17 -50
- package/src/server/ai-gateway/runs/resolve-overrides.ts +10 -26
- package/src/server/ai-gateway/runs/user-agent.ts +75 -0
- package/src/server/ai-gateway/sandbox/__tests__/harness-sandbox.test.ts +136 -0
- package/src/server/ai-gateway/sandbox/__tests__/local-process.test.ts +144 -1
- package/src/server/ai-gateway/sandbox/__tests__/policy.test.ts +47 -0
- package/src/server/ai-gateway/sandbox/browser-policy.ts +45 -9
- package/src/server/ai-gateway/sandbox/harness-sandbox.ts +76 -10
- package/src/server/ai-gateway/sandbox/local-process.ts +212 -21
- package/src/server/ai-gateway/sandbox/policy.ts +39 -7
- package/src/server/ai-gateway/skills/builtin-source.ts +10 -0
- package/src/server/ai-gateway/skills/index.ts +6 -4
- package/src/server/ai-gateway/source-mode.ts +8 -2
- package/src/server/ai-gateway/storage/__tests__/blob-store.test.ts +17 -0
- package/src/server/ai-gateway/storage/db-blob-store.ts +16 -1
- package/src/server/ai-gateway/story-handler.ts +2 -1
- package/src/server/ai-gateway/story-prompt.ts +3 -1
- package/src/server/ai-gateway/tools/create-pr.ts +92 -55
- package/src/server/ai-gateway/tools/definitions.ts +2 -2
- package/src/server/ai-gateway/tools/delegate-task.ts +38 -18
- package/src/server/ai-gateway/tools/delete-project.ts +7 -1
- package/src/server/ai-gateway/tools/plan-submit.ts +12 -8
- package/src/server/ai-gateway/tools/plugin-lifecycle-server.ts +24 -3
- package/src/server/ai-gateway/tools/plugin-tools.ts +15 -4
- package/src/server/ai-gateway/tools/select.ts +8 -4
- package/src/server/ai-gateway/tools/server.ts +91 -19
- package/src/server/ai-gateway/tools/todo-write.ts +4 -3
- package/src/server/ai-gateway/tools/tool-errors.ts +38 -0
- package/src/server/ai-gateway/unified-router.ts +64 -54
- package/src/server/ai-ports.ts +22 -3
- package/src/server/ai-task/executor.ts +49 -27
- package/src/server/audit.ts +5 -2
- package/src/server/auth-helpers.ts +37 -4
- package/src/server/billing-email.ts +9 -1
- package/src/server/bug/bug-permissions.ts +15 -8
- package/src/server/bug-collect/collect-handler.ts +65 -51
- package/src/server/bug-report/report-handler.ts +131 -125
- package/src/server/bug-report/repro-runner.ts +5 -15
- package/src/server/bug-report/webhook-out.ts +13 -1
- package/src/server/bug-screenshot/screenshot-handler.ts +7 -3
- package/src/server/builtin-project.ts +43 -18
- package/src/server/collab/reindex-endpoint.ts +20 -0
- package/src/server/collab/seed.ts +20 -4
- package/src/server/collab/write-guard.ts +5 -0
- package/src/server/csv.ts +6 -3
- package/src/server/design/__tests__/share-access.test.ts +128 -0
- package/src/server/design/access.ts +136 -0
- package/src/server/design/annotation-prompt.ts +7 -1
- package/src/server/design/share-access.ts +109 -0
- package/src/server/design/share-generate.ts +42 -0
- package/src/server/desktop-guest.ts +3 -2
- package/src/server/email/deliverability.ts +9 -1
- package/src/server/email/drivers/resend.ts +8 -1
- package/src/server/email/drivers/smtp.ts +32 -18
- package/src/server/email/templates/product/changelog-release.tsx +1 -1
- package/src/server/email/templates/team/invite.tsx +1 -1
- package/src/server/entitlements-token.ts +8 -1
- package/src/server/entitlements.ts +7 -2
- package/src/server/fetch-guard.ts +67 -0
- package/src/server/iteration/auto-schedule-internal.ts +19 -8
- package/src/server/iteration/permissions.ts +40 -0
- package/src/server/iteration/transfer-internal.ts +19 -12
- package/src/server/keepalive/middleware.ts +12 -2
- package/src/server/knowledge/kb-doc-search.ts +20 -3
- package/src/server/knowledge/knowledge-index-utils.ts +21 -8
- package/src/server/knowledge/public/favicon.ts +24 -6
- package/src/server/knowledge/public/github-sync.ts +24 -4
- package/src/server/knowledge/public/share-merge.ts +51 -18
- package/src/server/lib/api-key-cipher.ts +2 -1
- package/src/server/lib/bug-sequence.ts +67 -0
- package/src/server/lib/cron-auth.ts +7 -3
- package/src/server/lib/display-options-schema.ts +52 -0
- package/src/server/lib/fixed-window-rate-limit.ts +105 -0
- package/src/server/lib/image-magic.ts +44 -0
- package/src/{components/design/editor/pages/design-layout.tsx → server/lib/prisma-json.ts} +12 -9
- package/src/server/lib/project-membership.ts +60 -0
- package/src/server/lib/rate-limit.ts +38 -5
- package/src/{lib/annotation-template.ts → server/lib/sse-chunk.ts} +10 -12
- package/src/server/lib/text-truncate.ts +51 -0
- package/src/{config/sidebar-teams.ts → server/lib/user-brief.ts} +11 -14
- package/src/server/lib/validate-assignee.ts +19 -0
- package/src/server/lib/validators.ts +16 -0
- package/src/server/lib/webhook-secret.ts +45 -0
- package/src/server/mcp/__tests__/json-rpc.test.ts +57 -5
- package/src/server/mcp/__tests__/tools.test.ts +12 -3
- package/src/server/mcp/json-rpc.ts +12 -0
- package/src/server/mcp/protocol.ts +50 -3
- package/src/server/mcp/tool-schemas.ts +8 -2
- package/src/server/mcp/tools.ts +28 -18
- package/src/server/middlewares/audit-recorder.ts +11 -3
- package/src/server/middlewares/audit.ts +33 -12
- package/src/server/middlewares/auth-rate-limit.ts +25 -39
- package/src/server/middlewares/rate-limit.ts +42 -15
- package/src/server/middlewares/security-headers.ts +14 -16
- package/src/server/notifications/__tests__/notification-service.test.ts +4 -0
- package/src/server/notifications/notification-service.ts +144 -59
- package/src/server/notifications/verify-reminder.ts +2 -0
- package/src/server/permissions.ts +17 -1
- package/src/{lib → server}/rag.ts +3 -1
- package/src/server/references/access.ts +117 -0
- package/src/server/references/engine.ts +46 -27
- package/src/server/remote-auth.ts +17 -3
- package/src/server/resources.ts +55 -43
- package/src/server/serverFns/__tests__/auth-server-schemas.test.ts +51 -9
- package/src/server/serverFns/__tests__/collab.test.ts +21 -0
- package/src/server/serverFns/__tests__/compliance.test.ts +31 -2
- package/src/server/serverFns/__tests__/knowledge-index.test.ts +1 -0
- package/src/server/serverFns/__tests__/knowledge-kb-projects.test.ts +141 -0
- package/src/server/serverFns/__tests__/knowledge-public-compliance.test.ts +163 -0
- package/src/server/serverFns/__tests__/knowledge-readable-kb.test.ts +194 -0
- package/src/server/serverFns/__tests__/legal-public.test.ts +91 -0
- package/src/server/serverFns/__tests__/notifications-list.test.ts +130 -0
- package/src/server/serverFns/__tests__/ownership-merge.test.ts +12 -4
- package/src/server/serverFns/__tests__/project-delete-transaction.test.ts +128 -0
- package/src/server/serverFns/__tests__/project-kb.test.ts +18 -0
- package/src/server/serverFns/__tests__/read-path-permissions.test.ts +107 -0
- package/src/server/serverFns/__tests__/read-write-merge.test.ts +29 -1
- package/src/server/serverFns/__tests__/references-access.test.ts +117 -0
- package/src/server/serverFns/__tests__/story-crud-labels-users.test.ts +18 -4
- package/src/server/serverFns/__tests__/story-links.test.ts +7 -5
- package/src/server/serverFns/__tests__/story-tree.test.ts +57 -121
- package/src/server/serverFns/__tests__/story-types.test.ts +4 -48
- package/src/server/serverFns/__tests__/update-page-guard.test.ts +2 -0
- package/src/server/serverFns/__tests__/workspace-kb.test.ts +63 -3
- package/src/server/serverFns/__tests__/workspace.test.ts +2 -1
- package/src/server/serverFns/activity.ts +26 -9
- package/src/server/serverFns/agents/agent-crud.ts +61 -61
- package/src/server/serverFns/agents/bindings.ts +21 -22
- package/src/server/serverFns/agents/skill-crud.ts +48 -45
- package/src/server/serverFns/ai/code-mode-readiness.ts +8 -2
- package/src/server/serverFns/ai/search-capability.ts +8 -2
- package/src/server/serverFns/analytics.ts +7 -3
- package/src/server/serverFns/anyhub/app.ts +31 -14
- package/src/server/serverFns/anyhub/index.ts +48 -32
- package/src/server/serverFns/anyhub/install.ts +21 -7
- package/src/server/serverFns/anyhub/permissions.ts +25 -4
- package/src/server/serverFns/anyhub/proxy.ts +1 -1
- package/src/server/serverFns/auth/email-verification.ts +8 -1
- package/src/server/serverFns/auth/forgot-password.ts +7 -2
- package/src/server/serverFns/auth/providers.ts +2 -0
- package/src/server/serverFns/auth/register.ts +1 -1
- package/src/server/serverFns/auth/registration-mode.ts +2 -0
- package/src/server/serverFns/auth/reset-password.ts +28 -17
- package/src/server/serverFns/auth/session.ts +30 -14
- package/src/server/serverFns/auth/setup.ts +2 -0
- package/src/server/serverFns/billing.ts +20 -14
- package/src/server/serverFns/blob-upload.ts +12 -1
- package/src/server/serverFns/bug/__tests__/bug-access-tokens.test.ts +1 -0
- package/src/server/serverFns/bug/__tests__/bug-activities.test.ts +30 -3
- package/src/server/serverFns/bug/__tests__/bug-collect.test.ts +47 -12
- package/src/server/serverFns/bug/__tests__/bug-comments.test.ts +47 -16
- package/src/server/serverFns/bug/__tests__/bug-groups.test.ts +2 -2
- package/src/server/serverFns/bug/__tests__/bug-list-query.test.ts +10 -0
- package/src/server/serverFns/bug/__tests__/bug-reactions.test.ts +21 -11
- package/src/server/serverFns/bug/__tests__/bug-webhooks.test.ts +13 -10
- package/src/server/serverFns/bug/bug-access-tokens.ts +13 -5
- package/src/server/serverFns/bug/bug-activities.ts +36 -5
- package/src/server/serverFns/bug/bug-collect-tokens.ts +4 -4
- package/src/server/serverFns/bug/bug-collect.ts +4 -2
- package/src/server/serverFns/bug/bug-comments.ts +55 -32
- package/src/server/serverFns/bug/bug-crud/detail.ts +3 -3
- package/src/server/serverFns/bug/bug-crud.ts +31 -29
- package/src/server/serverFns/bug/bug-display-options.ts +7 -11
- package/src/server/serverFns/bug/bug-export.ts +10 -1
- package/src/server/serverFns/bug/bug-fix.ts +3 -3
- package/src/server/serverFns/bug/bug-group-query.ts +1 -1
- package/src/server/serverFns/bug/bug-groups.ts +4 -4
- package/src/server/serverFns/bug/bug-list-query.ts +7 -3
- package/src/server/serverFns/bug/bug-reactions.ts +19 -6
- package/src/server/serverFns/bug/bug-reorder.ts +2 -5
- package/src/server/serverFns/bug/bug-repro.ts +2 -2
- package/src/server/serverFns/bug/bug-story-bulk.ts +7 -16
- package/src/server/serverFns/bug/bug-story.ts +3 -3
- package/src/server/serverFns/bug/bug-views.ts +27 -18
- package/src/server/serverFns/bug/bug-webhooks.ts +8 -5
- package/src/server/serverFns/bug/test-bug-confirm.ts +2 -2
- package/src/server/serverFns/changelog/__tests__/fetch.test.ts +80 -0
- package/src/server/serverFns/changelog/__tests__/subscribe.test.ts +4 -2
- package/src/server/serverFns/changelog/fetch.ts +12 -1
- package/src/server/serverFns/changelog/subscribe.ts +17 -3
- package/src/server/serverFns/chat/conversations.ts +11 -5
- package/src/server/serverFns/collab-presence.ts +1 -1
- package/src/server/serverFns/collab-snapshot.ts +1 -1
- package/src/server/serverFns/collab.ts +5 -0
- package/src/server/serverFns/compliance.ts +11 -8
- package/src/server/serverFns/design/__tests__/comments.test.ts +222 -0
- package/src/server/serverFns/design/__tests__/designs.test.ts +3 -1
- package/src/server/serverFns/design/__tests__/page-versions.test.ts +177 -0
- package/src/server/serverFns/design/__tests__/shares-password.test.ts +12 -6
- package/src/server/serverFns/design/ai/__tests__/agent-conversations.test.ts +131 -0
- package/src/server/serverFns/design/ai/__tests__/providers.test.ts +187 -0
- package/src/server/serverFns/design/ai/agent-conversations.ts +27 -7
- package/src/server/serverFns/design/ai/fill-annotation.ts +27 -17
- package/src/server/serverFns/design/ai/generate-prototype.ts +8 -3
- package/src/server/serverFns/design/ai/providers.ts +74 -36
- package/src/server/serverFns/design/comments.ts +51 -12
- package/src/server/serverFns/design/designs.ts +9 -7
- package/src/server/serverFns/design/detail.ts +12 -11
- package/src/server/serverFns/design/page-versions.ts +39 -23
- package/src/server/serverFns/design/pages.ts +15 -37
- package/src/server/serverFns/design/reviews.ts +17 -7
- package/src/server/serverFns/design/share/__tests__/share-metadata.test.ts +105 -0
- package/src/server/serverFns/design/share/__tests__/share-versions.test.ts +148 -0
- package/src/server/serverFns/design/share/__tests__/verify-password.test.ts +14 -3
- package/src/server/serverFns/design/share/verify-password.ts +4 -0
- package/src/server/serverFns/design/share/versions.ts +14 -30
- package/src/server/serverFns/design/share.ts +50 -5
- package/src/server/serverFns/design/shares-password.ts +28 -18
- package/src/server/serverFns/design/shares.ts +38 -39
- package/src/server/serverFns/design/versions.ts +14 -56
- package/src/server/serverFns/harness/__tests__/attach-to-kb.spec.ts +9 -9
- package/src/server/serverFns/harness/__tests__/attach-to-story.spec.ts +2 -1
- package/src/server/serverFns/harness/__tests__/extract-attachment.spec.ts +40 -0
- package/src/server/serverFns/harness/__tests__/github-workspace.spec.ts +107 -0
- package/src/server/serverFns/harness/attach-prototype.ts +5 -5
- package/src/server/serverFns/harness/attach-to-kb.ts +6 -9
- package/src/server/serverFns/harness/attach-to-story.ts +3 -3
- package/src/server/serverFns/harness/extract-attachment.ts +9 -1
- package/src/server/serverFns/harness/gallery.ts +2 -0
- package/src/server/serverFns/harness/github-workspace.ts +18 -11
- package/src/server/serverFns/harness/media.ts +7 -3
- package/src/server/serverFns/harness/sandbox-policy.ts +1 -2
- package/src/server/serverFns/harness/search-mention-candidates.ts +1 -1
- package/src/server/serverFns/iteration/__tests__/iteration-crud.test.ts +30 -1
- package/src/server/serverFns/iteration/__tests__/iteration-stories.test.ts +51 -4
- package/src/server/serverFns/iteration/__tests__/iteration-transfer.test.ts +9 -0
- package/src/server/serverFns/iteration/iteration-auto-schedule.ts +4 -13
- package/src/server/serverFns/iteration/iteration-burndown.ts +7 -3
- package/src/server/serverFns/iteration/iteration-crud.ts +16 -24
- package/src/server/serverFns/iteration/iteration-stories.ts +57 -54
- package/src/server/serverFns/iteration/iteration-transfer.ts +1 -1
- package/src/server/serverFns/knowledge/public/bookmarks/categories.ts +18 -14
- package/src/server/serverFns/knowledge/public/bookmarks/create.ts +35 -5
- package/src/server/serverFns/knowledge/public/bookmarks/delete.ts +2 -2
- package/src/server/serverFns/knowledge/public/bookmarks/detail.ts +1 -1
- package/src/server/serverFns/knowledge/public/bookmarks/favorite.ts +13 -3
- package/src/server/serverFns/knowledge/public/bookmarks/list.ts +5 -2
- package/src/server/serverFns/knowledge/public/bookmarks/refresh-favicon.ts +10 -4
- package/src/server/serverFns/knowledge/public/bookmarks/share.ts +4 -7
- package/src/server/serverFns/knowledge/public/bookmarks/sync-github.ts +12 -1
- package/src/server/serverFns/knowledge/public/bookmarks/unshare.ts +1 -1
- package/src/server/serverFns/knowledge/public/bookmarks/update.ts +52 -29
- package/src/server/serverFns/knowledge/public/compliance/create.ts +3 -2
- package/src/server/serverFns/knowledge/public/compliance/delete.ts +2 -2
- package/src/server/serverFns/knowledge/public/compliance/detail.ts +1 -1
- package/src/server/serverFns/knowledge/public/compliance/list.ts +6 -3
- package/src/server/serverFns/knowledge/public/compliance/public.ts +9 -5
- package/src/server/serverFns/knowledge/public/compliance/share.ts +4 -7
- package/src/server/serverFns/knowledge/public/compliance/unshare.ts +14 -1
- package/src/server/serverFns/knowledge/public/compliance/update.ts +10 -5
- package/src/server/serverFns/knowledge/public/dictionary/create.ts +5 -3
- package/src/server/serverFns/knowledge/public/dictionary/delete.ts +2 -2
- package/src/server/serverFns/knowledge/public/dictionary/detail.ts +1 -1
- package/src/server/serverFns/knowledge/public/dictionary/list.ts +3 -2
- package/src/server/serverFns/knowledge/public/dictionary/share.ts +4 -7
- package/src/server/serverFns/knowledge/public/dictionary/unshare.ts +1 -1
- package/src/server/serverFns/knowledge/public/dictionary/update.ts +4 -3
- package/src/server/serverFns/knowledge/public/entity-tags.ts +19 -13
- package/src/server/serverFns/knowledge/public/favorite.ts +17 -2
- package/src/server/serverFns/knowledge/public/legal/create.ts +3 -2
- package/src/server/serverFns/knowledge/public/legal/delete.ts +2 -2
- package/src/server/serverFns/knowledge/public/legal/detail.ts +1 -1
- package/src/server/serverFns/knowledge/public/legal/list.ts +6 -3
- package/src/server/serverFns/knowledge/public/legal/public.ts +12 -5
- package/src/server/serverFns/knowledge/public/legal/share.ts +4 -7
- package/src/server/serverFns/knowledge/public/legal/unshare.ts +1 -1
- package/src/server/serverFns/knowledge/public/legal/update.ts +10 -3
- package/src/server/serverFns/knowledge-index.ts +34 -9
- package/src/server/serverFns/knowledge.ts +143 -166
- package/src/server/serverFns/notifications.ts +30 -22
- package/src/server/serverFns/plugins/harness-plugins.ts +31 -26
- package/src/server/serverFns/plugins/plugin-precheck.ts +40 -23
- package/src/server/serverFns/project/module-overview.ts +7 -3
- package/src/server/serverFns/project.ts +48 -39
- package/src/server/serverFns/references/create.ts +17 -4
- package/src/server/serverFns/references/resolve.ts +10 -2
- package/src/server/serverFns/references/search.ts +9 -2
- package/src/server/serverFns/settings/account-team.ts +1 -1
- package/src/server/serverFns/share/design/[designId]/events.ts +6 -1
- package/src/server/serverFns/share/version.ts +44 -16
- package/src/server/serverFns/sso.ts +16 -0
- package/src/server/serverFns/story/__tests__/story-assoc.test.ts +17 -2
- package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +8 -0
- package/src/server/serverFns/story/__tests__/story-read-path-authz.test.ts +141 -0
- package/src/server/serverFns/story/index.ts +1 -3
- package/src/server/serverFns/story/kb-scope.ts +9 -0
- package/src/server/serverFns/story/link-preview.ts +2 -1
- package/src/server/serverFns/story/story-assoc.ts +10 -30
- package/src/server/serverFns/story/story-attachments.ts +6 -13
- package/src/server/serverFns/story/story-children.ts +4 -1
- package/src/server/serverFns/story/story-comments.ts +7 -27
- package/src/server/serverFns/story/story-crud/activities.ts +3 -1
- package/src/server/serverFns/story/story-crud/archive.ts +4 -25
- package/src/server/serverFns/story/story-crud/bulk.ts +3 -3
- package/src/server/serverFns/story/story-crud/detail.ts +7 -2
- package/src/server/serverFns/story/story-crud/labels.ts +1 -58
- package/src/server/serverFns/story/story-crud/user-brief.ts +69 -0
- package/src/server/serverFns/story/story-crud.ts +9 -27
- package/src/server/serverFns/story/story-dependencies.ts +7 -28
- package/src/server/serverFns/story/story-groups.ts +5 -5
- package/src/server/serverFns/story/story-links.ts +9 -28
- package/src/server/serverFns/story/story-list-query.ts +1 -1
- package/src/server/serverFns/story/story-reactions.ts +7 -27
- package/src/server/serverFns/story/story-search.ts +2 -2
- package/src/server/serverFns/story/story-transfer.ts +7 -14
- package/src/server/serverFns/story/story-tree.ts +6 -58
- package/src/server/serverFns/story-display-options.ts +9 -32
- package/src/server/serverFns/story-view.ts +20 -17
- package/src/server/serverFns/tasks/task-crud.ts +3 -3
- package/src/server/serverFns/tasks/task-queries.ts +3 -3
- package/src/server/serverFns/team.ts +42 -18
- package/src/server/serverFns/testcase/__tests__/generation.test.ts +9 -4
- package/src/server/serverFns/testcase/__tests__/plans.test.ts +1 -0
- package/src/server/serverFns/testcase/__tests__/regression.test.ts +15 -0
- package/src/server/serverFns/testcase/__tests__/run-cases.test.ts +11 -6
- package/src/server/serverFns/testcase/__tests__/runs.test.ts +2 -0
- package/src/server/serverFns/testcase/__tests__/testgen-output.test.ts +3 -3
- package/src/server/serverFns/testcase/automation.ts +8 -15
- package/src/server/serverFns/testcase/bulk.ts +3 -3
- package/src/server/serverFns/testcase/generation.ts +26 -20
- package/src/server/serverFns/testcase/plans.ts +18 -40
- package/src/server/serverFns/testcase/regression.ts +12 -7
- package/src/server/serverFns/testcase/run-cases.ts +6 -15
- package/src/server/serverFns/testcase/runs.ts +17 -35
- package/src/server/serverFns/testcase/stats.ts +7 -18
- package/src/server/serverFns/testcase/testcase-activities.ts +3 -1
- package/src/server/serverFns/testcase/testcase-board.ts +6 -22
- package/src/server/serverFns/testcase/testcase-crud.ts +114 -150
- package/src/server/serverFns/testcase/testcase-display-options.ts +2 -2
- package/src/server/serverFns/testcase/testcase-export.ts +1 -1
- package/src/server/serverFns/testcase/testcase-filter-views.ts +4 -4
- package/src/server/serverFns/testcase/testcase-folders.ts +13 -23
- package/src/server/serverFns/testcase/testcase-groups.ts +1 -1
- package/src/server/serverFns/testcase/testcase-reorder.ts +1 -1
- package/src/server/serverFns/translation.ts +4 -1
- package/src/server/serverFns/user/avatar.ts +1 -1
- package/src/server/serverFns/user/settings.ts +1 -1
- package/src/server/serverFns/user/update-locale.ts +1 -1
- package/src/server/serverFns/workspace-kb.ts +84 -27
- package/src/server/serverFns/workspace.ts +41 -38
- package/src/server/serverFns/ws.ts +1 -1
- package/src/server/sso/tokens.ts +15 -3
- package/src/server/story/permissions.ts +56 -0
- package/src/server/story/types.ts +7 -33
- package/src/server/team-access.ts +5 -8
- package/src/server/testcase/__tests__/auto-bug.test.ts +5 -2
- package/src/server/testcase/__tests__/automation-rerun.test.ts +18 -0
- package/src/server/testcase/__tests__/builtin-executor.test.ts +43 -6
- package/src/server/testcase/__tests__/list-query.test.ts +11 -0
- package/src/server/testcase/__tests__/run-summary.test.ts +47 -15
- package/src/server/testcase/__tests__/sandbox-runner.test.ts +27 -1
- package/src/server/testcase/__tests__/triage.test.ts +17 -0
- package/src/server/testcase/auto-bug.ts +6 -6
- package/src/server/testcase/automation-rerun.ts +45 -8
- package/src/server/testcase/builtin-executor.ts +19 -0
- package/src/server/testcase/list-query.ts +18 -3
- package/src/server/testcase/permissions.ts +64 -0
- package/src/server/testcase/run-finalize.ts +19 -2
- package/src/server/testcase/run-webhook.ts +13 -1
- package/src/server/testcase/sandbox-runner.ts +21 -1
- package/src/server/testcase/triage.ts +38 -15
- package/src/server/web-search.ts +85 -0
- package/src/server-entry.ts +7 -1
- package/src/shared/ai-cli/__tests__/adapter.test.ts +39 -17
- package/src/shared/ai-cli/__tests__/cli-detector.test.ts +44 -13
- package/src/shared/ai-cli/adapter.ts +38 -15
- package/src/shared/ai-cli/cli-detector.ts +41 -16
- package/src/{components/bug/display/types.ts → shared/bug/display-types.ts} +1 -1
- package/src/shared/design-ai/ndjson.ts +13 -0
- package/src/{components/shared-kit/list-kit/display/types.ts → shared/list-kit/display-types.ts} +1 -1
- package/src/{components/shared-kit/list-kit/display/values.ts → shared/list-kit/display-values.ts} +1 -1
- package/src/start.ts +26 -10
- package/src/styles/globals.css +11 -0
- package/vite.shared.ts +39 -25
- package/LICENSE +0 -661
- package/src/components/ai/ai-prompt-input/components/page-user-context-selector.tsx +0 -183
- package/src/components/harness/turn-usage-pill.tsx +0 -60
- package/src/components/story/views/story-list/move.ts +0 -55
- package/src/components/tiptap/notion-like/notion-like-editor-theme-toggle.tsx +0 -63
- package/src/components/tiptap/notion-like/setup-error-message/setup-error-message.scss +0 -108
- package/src/components/tiptap/notion-like/setup-error-message/setup-error-message.tsx +0 -115
- package/src/lib/__tests__/pgvector.test.ts +0 -94
- package/src/lib/__tests__/rate-limit.test.ts +0 -80
- package/src/lib/analytics.ts +0 -78
- package/src/lib/collections/ai/index.ts +0 -17
- package/src/lib/plugin-runtime/worker-realm.ts +0 -225
- package/src/lib/prisma.ts +0 -18
- package/src/lib/rate-limit.ts +0 -70
- package/src/paraglide/.gitignore +0 -3
- package/src/paraglide/.prettierignore +0 -3
- package/src/paraglide/README.md +0 -162
- package/src/paraglide/messages/_index.js +0 -83424
- package/src/paraglide/messages/en.js +0 -26715
- package/src/paraglide/messages/zh.js +0 -26713
- package/src/paraglide/messages.js +0 -4
- package/src/paraglide/registry.js +0 -46
- package/src/paraglide/runtime.js +0 -2311
- package/src/paraglide/server.js +0 -294
- package/src/routes/_nav/dashboard/-components/quick-actions.tsx +0 -48
- /package/src/{components/settings/personal-team/account → lib}/avatar/avatar-config.ts +0 -0
|
@@ -129,7 +129,7 @@ export const listFilterViewsFn = createServerFn({ method: "GET" }).handler(async
|
|
|
129
129
|
const prisma = await getPrisma();
|
|
130
130
|
const request = getRequest();
|
|
131
131
|
const session = await requireAuth(request);
|
|
132
|
-
const userId = session.user
|
|
132
|
+
const userId = session.user.id;
|
|
133
133
|
const rows = await prisma.testCaseFilterView.findMany({
|
|
134
134
|
where: { userId, ...NOT_RESERVED },
|
|
135
135
|
orderBy: { sortOrder: "asc" },
|
|
@@ -158,7 +158,7 @@ export const createFilterViewFn = createServerFn({ method: "POST" })
|
|
|
158
158
|
const prisma = await getPrisma();
|
|
159
159
|
const request = getRequest();
|
|
160
160
|
const session = await requireAuth(request);
|
|
161
|
-
const userId = session.user
|
|
161
|
+
const userId = session.user.id;
|
|
162
162
|
const row = await prisma.testCaseFilterView.create({
|
|
163
163
|
data: {
|
|
164
164
|
userId,
|
|
@@ -193,7 +193,7 @@ export const updateFilterViewFn = createServerFn({ method: "POST" })
|
|
|
193
193
|
const prisma = await getPrisma();
|
|
194
194
|
const request = getRequest();
|
|
195
195
|
const session = await requireAuth(request);
|
|
196
|
-
const userId = session.user
|
|
196
|
+
const userId = session.user.id;
|
|
197
197
|
const { id, ...patch } = data;
|
|
198
198
|
const updates: Record<string, unknown> = {};
|
|
199
199
|
if (patch.name !== undefined) updates.name = patch.name;
|
|
@@ -219,7 +219,7 @@ export const deleteFilterViewFn = createServerFn({ method: "POST" })
|
|
|
219
219
|
const prisma = await getPrisma();
|
|
220
220
|
const request = getRequest();
|
|
221
221
|
const session = await requireAuth(request);
|
|
222
|
-
const userId = session.user
|
|
222
|
+
const userId = session.user.id;
|
|
223
223
|
await prisma.testCaseFilterView.delete({
|
|
224
224
|
// userId + 非保留名限定:他人视图与显示选项保留行均删不到(照 bug-views.ts)
|
|
225
225
|
where: { id: data.id, userId, ...NOT_RESERVED },
|
|
@@ -25,18 +25,7 @@ import { getRequest } from "@tanstack/react-start/server";
|
|
|
25
25
|
import { z } from "zod";
|
|
26
26
|
import { requireAuth } from "@/server/auth-helpers";
|
|
27
27
|
import { ensureBuiltinIndependentProject, resolveStoryScopeProjectId } from "@/server/builtin-project";
|
|
28
|
-
|
|
29
|
-
/** 项目有效成员校验(R 口径同 deleteBugFn:suspended 视同无权限) */
|
|
30
|
-
async function assertProjectMembership(projectId: string, userId: string) {
|
|
31
|
-
const prisma = await getPrisma();
|
|
32
|
-
const membership = await prisma.projectMember.findUnique({
|
|
33
|
-
where: { projectId_userId: { projectId, userId } },
|
|
34
|
-
select: { status: true },
|
|
35
|
-
});
|
|
36
|
-
if (!membership || membership.status === "suspended") {
|
|
37
|
-
throw new Error("无权限操作该项目的测试模块");
|
|
38
|
-
}
|
|
39
|
-
}
|
|
28
|
+
import { assertTestProjectMembership as assertProjectMembership } from "@/server/testcase/permissions";
|
|
40
29
|
|
|
41
30
|
// ── 列表:按 projectId 树序返回(parentId + position 升序的扁平列表,客户端组树)──
|
|
42
31
|
|
|
@@ -48,7 +37,7 @@ export const listFoldersFn = createServerFn({ method: "GET" })
|
|
|
48
37
|
const prisma = await getPrisma();
|
|
49
38
|
const request = getRequest();
|
|
50
39
|
const session = await requireAuth(request);
|
|
51
|
-
const userId = session.user
|
|
40
|
+
const userId = session.user.id;
|
|
52
41
|
|
|
53
42
|
const projectId = await resolveStoryScopeProjectId(data.projectId, userId);
|
|
54
43
|
|
|
@@ -74,7 +63,7 @@ export const createFolderFn = createServerFn({ method: "POST" })
|
|
|
74
63
|
const prisma = await getPrisma();
|
|
75
64
|
const request = getRequest();
|
|
76
65
|
const session = await requireAuth(request);
|
|
77
|
-
const userId = session.user
|
|
66
|
+
const userId = session.user.id;
|
|
78
67
|
|
|
79
68
|
let projectId = data.projectId;
|
|
80
69
|
if (projectId) {
|
|
@@ -137,7 +126,7 @@ export const renameFolderFn = createServerFn({ method: "POST" })
|
|
|
137
126
|
const prisma = await getPrisma();
|
|
138
127
|
const request = getRequest();
|
|
139
128
|
const session = await requireAuth(request);
|
|
140
|
-
const userId = session.user
|
|
129
|
+
const userId = session.user.id;
|
|
141
130
|
|
|
142
131
|
await getFolderWithMembership(data.id, userId);
|
|
143
132
|
|
|
@@ -155,17 +144,18 @@ export const deleteFolderFn = createServerFn({ method: "POST" })
|
|
|
155
144
|
const prisma = await getPrisma();
|
|
156
145
|
const request = getRequest();
|
|
157
146
|
const session = await requireAuth(request);
|
|
158
|
-
const userId = session.user
|
|
147
|
+
const userId = session.user.id;
|
|
159
148
|
|
|
160
149
|
const folder = await getFolderWithMembership(data.id, userId);
|
|
161
150
|
|
|
162
|
-
// 有子模块或用例时拒绝(model 层 Cascade 只在删父模块时生效,此处防误删整棵子树)
|
|
163
|
-
const childCount = await prisma.testCaseFolder.count({ where: { parentId: folder.id } });
|
|
164
|
-
if (childCount > 0) throw new Error("该模块存在子模块,请先删除或移出子模块");
|
|
165
|
-
const caseCount = await prisma.testCase.count({ where: { folderId: folder.id } });
|
|
166
|
-
if (caseCount > 0) throw new Error("该模块下存在用例,请先移出用例后再删除");
|
|
167
|
-
|
|
168
151
|
await prisma.$transaction(async (tx) => {
|
|
152
|
+
// 子模块/用例计数守卫入事务(审计 🟡 TOCTOU:count 与 delete 间隙写入的
|
|
153
|
+
// 子模块/用例此前会被级联删除;事务内重查对账)
|
|
154
|
+
const childCount = await tx.testCaseFolder.count({ where: { parentId: folder.id } });
|
|
155
|
+
if (childCount > 0) throw new Error("该模块存在子模块,请先删除或移出子模块");
|
|
156
|
+
const caseCount = await tx.testCase.count({ where: { folderId: folder.id } });
|
|
157
|
+
if (caseCount > 0) throw new Error("该模块下存在用例,请先移出用例后再删除");
|
|
158
|
+
|
|
169
159
|
await tx.testCaseFolder.delete({ where: { id: folder.id } });
|
|
170
160
|
await tx.projectActivity.create({
|
|
171
161
|
data: {
|
|
@@ -192,7 +182,7 @@ export const reorderFolderFn = createServerFn({ method: "POST" })
|
|
|
192
182
|
const prisma = await getPrisma();
|
|
193
183
|
const request = getRequest();
|
|
194
184
|
const session = await requireAuth(request);
|
|
195
|
-
const userId = session.user
|
|
185
|
+
const userId = session.user.id;
|
|
196
186
|
|
|
197
187
|
const folder = await getFolderWithMembership(data.id, userId);
|
|
198
188
|
|
|
@@ -97,7 +97,7 @@ export const listGroupsFn = createServerFn({ method: "GET" })
|
|
|
97
97
|
const prisma = await getPrisma();
|
|
98
98
|
const request = getRequest();
|
|
99
99
|
const session = await requireAuth(request);
|
|
100
|
-
const userId = session.user
|
|
100
|
+
const userId = session.user.id;
|
|
101
101
|
|
|
102
102
|
// scope 解析与列表一致(同 story/story-groups 与 bug 域):未传 → 成员关系
|
|
103
103
|
// 全部项目聚合;单项目经鉴权(无效/非成员 → 静默回退独立项目),防越权查询
|
|
@@ -48,7 +48,7 @@ export const reorderTestCasesFn = createServerFn({ method: "POST" })
|
|
|
48
48
|
// 可见性过滤进 where(SEC-03:防跨项目改他人用例排序);updateMany 对
|
|
49
49
|
// 越权/不存在 id 静默跳过,不中断整批合法排序
|
|
50
50
|
const memberships = await prisma.projectMember.findMany({
|
|
51
|
-
where: { userId: session.user
|
|
51
|
+
where: { userId: session.user.id, status: { not: "suspended" } },
|
|
52
52
|
select: { projectId: true },
|
|
53
53
|
});
|
|
54
54
|
const visibleProjectIds = memberships.map((m) => m.projectId);
|
|
@@ -19,6 +19,7 @@ import { createServerFn } from '@tanstack/react-start'
|
|
|
19
19
|
import { getRequest } from '@tanstack/react-start/server'
|
|
20
20
|
import { z } from 'zod'
|
|
21
21
|
import { requireAuth } from '@/server/auth-helpers'
|
|
22
|
+
import { checkAiRateLimit } from '@/server/lib/rate-limit'
|
|
22
23
|
import { hasAiKey } from "@/server/ai-gateway/adapter"
|
|
23
24
|
import { runChatAsAgent } from "@/server/ai-gateway/runs/agent-runtime"
|
|
24
25
|
|
|
@@ -33,7 +34,9 @@ export const translateFn = createServerFn({ method: 'POST' })
|
|
|
33
34
|
.handler(async ({ data }) => {
|
|
34
35
|
const request = getRequest()
|
|
35
36
|
const session = await requireAuth(request)
|
|
36
|
-
const userId = session.user
|
|
37
|
+
const userId = session.user.id
|
|
38
|
+
// AI 昂贵调用独立限流(审计 🟠:对照 startGenerationFn 同款;先于 hasAiKey 消耗配额)
|
|
39
|
+
await checkAiRateLimit(userId, "translation")
|
|
37
40
|
if (!(await hasAiKey(userId))) throw new Error('AI 未配置')
|
|
38
41
|
|
|
39
42
|
const translated = await runChatAsAgent(
|
|
@@ -34,7 +34,7 @@ export const updateAvatarFn = createServerFn({ method: 'POST' })
|
|
|
34
34
|
const request = getRequest()
|
|
35
35
|
const session = await requireAuth(request)
|
|
36
36
|
const user = await prisma.user.update({
|
|
37
|
-
where: { id: session.user
|
|
37
|
+
where: { id: session.user.id },
|
|
38
38
|
data: { ...data, avatarConfig: data.avatarConfig as object },
|
|
39
39
|
})
|
|
40
40
|
return { avatarConfig: user.avatarConfig, bgShape: user.bgShape, bgColor: user.bgColor }
|
|
@@ -32,7 +32,7 @@ export const updateUserTimezoneFn = createServerFn({ method: 'POST' })
|
|
|
32
32
|
const request = getRequest()
|
|
33
33
|
const session = await requireAuth(request)
|
|
34
34
|
await prisma.user.update({
|
|
35
|
-
where: { id: session.user
|
|
35
|
+
where: { id: session.user.id },
|
|
36
36
|
data: { timezone: data.timezone },
|
|
37
37
|
})
|
|
38
38
|
return { success: true }
|
|
@@ -12,7 +12,7 @@ export const updateLocaleFn = createServerFn({ method: 'POST' })
|
|
|
12
12
|
const request = getRequest()
|
|
13
13
|
const session = await requireAuth(request)
|
|
14
14
|
await prisma.user.update({
|
|
15
|
-
where: { id: session.user
|
|
15
|
+
where: { id: session.user.id },
|
|
16
16
|
data: { locale: data.locale },
|
|
17
17
|
})
|
|
18
18
|
return { success: true }
|
|
@@ -23,7 +23,7 @@ import { createServerFn } from "@tanstack/react-start";
|
|
|
23
23
|
import { getRequest } from "@tanstack/react-start/server";
|
|
24
24
|
import { requireAuth } from "@/server/auth-helpers";
|
|
25
25
|
import { GENERAL_GROUP_TABLES, GENERAL_GROUPS, type GeneralGroup } from "@/server/knowledge/kb-general";
|
|
26
|
-
import type { QuickDocRow, WorkspaceKbCardData
|
|
26
|
+
import type { QuickDocRow, WorkspaceKbCardData } from "./workspace-kb-utils";
|
|
27
27
|
import {
|
|
28
28
|
searchGeneralGroupDocs,
|
|
29
29
|
listUserTeamKbIds,
|
|
@@ -43,13 +43,45 @@ async function requireWorkspaceMember(workspaceId: string, userId: string) {
|
|
|
43
43
|
if (ws.ownerId !== userId && ws.members.length === 0) throw new Error("仅工作空间成员可访问");
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* 通用组表动态访问的单点 cast 收口(审计 ⚪:替代调用点散落的 as unknown as 双 cast)。
|
|
48
|
+
* 仅暴露 findMany 最小面,行形状由调用方泛型声明。
|
|
49
|
+
*/
|
|
50
|
+
async function findGeneralGroupRows<R>(
|
|
51
|
+
group: Exclude<GeneralGroup, "summary">,
|
|
52
|
+
args: { where: Record<string, unknown>; select: Record<string, boolean> },
|
|
53
|
+
): Promise<R[]> {
|
|
54
|
+
const prisma = await getPrisma();
|
|
55
|
+
const model = prisma[GENERAL_GROUP_TABLES[group]] as unknown as {
|
|
56
|
+
findMany: (a: typeof args) => Promise<R[]>;
|
|
57
|
+
};
|
|
58
|
+
return model.findMany(args);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 通用组条目的用户可访问范围(审计 🟠:对齐 searchGeneralGroupDocs 候选侧归属口径
|
|
63
|
+
* ——本人创建 ∪ 本人收藏),防把他人条目挂成快捷文档后标题跨用户回显。
|
|
64
|
+
*/
|
|
65
|
+
async function generalGroupVisibleFilter(
|
|
66
|
+
group: Exclude<GeneralGroup, "summary">,
|
|
67
|
+
userId: string,
|
|
68
|
+
): Promise<Record<string, unknown>> {
|
|
69
|
+
const prisma = await getPrisma();
|
|
70
|
+
const favoriteIds = await prisma.articleFavorite
|
|
71
|
+
.findMany({ where: { entityType: group, userId }, select: { entityId: true } })
|
|
72
|
+
.then((r) => r.map((f) => f.entityId));
|
|
73
|
+
return {
|
|
74
|
+
OR: [{ userId }, ...(favoriteIds.length > 0 ? [{ id: { in: favoriteIds } }] : [])],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
46
78
|
export const getWorkspaceKbCardFn = createServerFn({ method: "GET" })
|
|
47
79
|
.validator(z.object({ workspaceId: z.string() }))
|
|
48
80
|
.handler(async ({ data }): Promise<WorkspaceKbCardData> => {
|
|
49
81
|
const prisma = await getPrisma()
|
|
50
82
|
const request = getRequest();
|
|
51
83
|
const session = await requireAuth(request);
|
|
52
|
-
const userId = session.user
|
|
84
|
+
const userId = session.user.id;
|
|
53
85
|
await requireWorkspaceMember(data.workspaceId, userId);
|
|
54
86
|
|
|
55
87
|
const [linkRows, quickRows] = await Promise.all([
|
|
@@ -89,11 +121,15 @@ export const getWorkspaceKbCardFn = createServerFn({ method: "GET" })
|
|
|
89
121
|
}
|
|
90
122
|
}
|
|
91
123
|
for (const [group, ids] of byGroup) {
|
|
92
|
-
const rows = await
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
124
|
+
const rows = await findGeneralGroupRows<{
|
|
125
|
+
id: string;
|
|
126
|
+
title: string;
|
|
127
|
+
faviconUrl?: string | null;
|
|
128
|
+
url?: string | null;
|
|
129
|
+
}>(group, {
|
|
130
|
+
where: { id: { in: ids } },
|
|
131
|
+
select: { id: true, title: true, faviconUrl: true, url: true },
|
|
132
|
+
});
|
|
97
133
|
const map = new Map(rows.map((r) => [r.id, r.title]));
|
|
98
134
|
const faviconMap = new Map(rows.map((r) => [r.id, r.faviconUrl ?? null]));
|
|
99
135
|
const urlMap = new Map(rows.map((r) => [r.id, (r.url as string | null) ?? null]));
|
|
@@ -138,7 +174,7 @@ export const listWorkspaceAvailableKbsFn = createServerFn({ method: "GET" })
|
|
|
138
174
|
const prisma = await getPrisma()
|
|
139
175
|
const request = getRequest();
|
|
140
176
|
const session = await requireAuth(request);
|
|
141
|
-
const userId = session.user
|
|
177
|
+
const userId = session.user.id;
|
|
142
178
|
await requireWorkspaceMember(data.workspaceId, userId);
|
|
143
179
|
|
|
144
180
|
const linked = await prisma.workspaceKnowledgeBase.findMany({
|
|
@@ -164,11 +200,23 @@ export const setWorkspaceKbsFn = createServerFn({ method: "POST" })
|
|
|
164
200
|
const prisma = await getPrisma()
|
|
165
201
|
const request = getRequest();
|
|
166
202
|
const session = await requireAuth(request);
|
|
167
|
-
await requireWorkspaceMember(data.workspaceId, session.user
|
|
203
|
+
await requireWorkspaceMember(data.workspaceId, session.user.id);
|
|
168
204
|
|
|
205
|
+
// 校验与候选清单(listWorkspaceAvailableKbsFn)同口径(审计 🟡):
|
|
206
|
+
// 本空间已关联 ∪ 本人 team 库——防凭 id 把任意他人 team 库挂入自己空间
|
|
207
|
+
const linked = await prisma.workspaceKnowledgeBase.findMany({
|
|
208
|
+
where: { workspaceId: data.workspaceId },
|
|
209
|
+
select: { kbId: true },
|
|
210
|
+
});
|
|
211
|
+
const linkedIds = linked.map((l) => l.kbId);
|
|
169
212
|
if (data.kbIds.length > 0) {
|
|
170
213
|
const valid = await prisma.knowledgeBase.findMany({
|
|
171
|
-
where: {
|
|
214
|
+
where: {
|
|
215
|
+
id: { in: data.kbIds },
|
|
216
|
+
visibility: "team",
|
|
217
|
+
isDeleted: false,
|
|
218
|
+
OR: [{ id: { in: linkedIds } }, { userId: session.user.id }],
|
|
219
|
+
},
|
|
172
220
|
select: { id: true },
|
|
173
221
|
});
|
|
174
222
|
if (valid.length !== data.kbIds.length) {
|
|
@@ -202,7 +250,7 @@ export const searchQuickDocCandidatesFn = createServerFn({ method: "GET" })
|
|
|
202
250
|
const prisma = await getPrisma()
|
|
203
251
|
const request = getRequest();
|
|
204
252
|
const session = await requireAuth(request);
|
|
205
|
-
const userId = session.user
|
|
253
|
+
const userId = session.user.id;
|
|
206
254
|
await requireWorkspaceMember(data.workspaceId, userId);
|
|
207
255
|
|
|
208
256
|
if (data.generalGroup) {
|
|
@@ -247,7 +295,7 @@ export const addQuickDocsFn = createServerFn({ method: "POST" })
|
|
|
247
295
|
const prisma = await getPrisma()
|
|
248
296
|
const request = getRequest();
|
|
249
297
|
const session = await requireAuth(request);
|
|
250
|
-
const userId = session.user
|
|
298
|
+
const userId = session.user.id;
|
|
251
299
|
await requireWorkspaceMember(data.workspaceId, userId);
|
|
252
300
|
|
|
253
301
|
// DB-01:批量快捷文档原每项 2~3 次串行查询(存在性 findFirst + 查重 findFirst + create)。
|
|
@@ -271,19 +319,22 @@ export const addQuickDocsFn = createServerFn({ method: "POST" })
|
|
|
271
319
|
}
|
|
272
320
|
|
|
273
321
|
// 预取存在性:知识库文档一次 in 查询;通用组表按出现的分组各一次 in 查询
|
|
274
|
-
const docIds = [...new Set(
|
|
322
|
+
const docIds = [...new Set(data.items.map((i) => i.docId).filter((id): id is string => !!id))];
|
|
323
|
+
// 存在性校验限定可访问范围(审计 🟠):对齐候选侧 listUserTeamKbIds 口径,
|
|
324
|
+
// 防把他人私有/团队库文档挂成快捷文档后标题与库名跨用户回显
|
|
325
|
+
const teamKbIds = docIds.length > 0 ? await listUserTeamKbIds(userId) : [];
|
|
275
326
|
const existingDocIds = docIds.length
|
|
276
327
|
? new Set(
|
|
277
328
|
(
|
|
278
329
|
await prisma.knowledgeDocument.findMany({
|
|
279
|
-
where: { id: { in: docIds }, isDeleted: false },
|
|
330
|
+
where: { id: { in: docIds }, isDeleted: false, kb: { id: { in: teamKbIds } } },
|
|
280
331
|
select: { id: true },
|
|
281
332
|
})
|
|
282
333
|
).map((d) => d.id),
|
|
283
334
|
)
|
|
284
335
|
: new Set<string>();
|
|
285
336
|
const externalIdsByGroup = new Map<Exclude<GeneralGroup, "summary">, string[]>();
|
|
286
|
-
for (const item of data.items
|
|
337
|
+
for (const item of data.items) {
|
|
287
338
|
if (item.docId || !item.externalGroup || item.externalGroup === "summary") continue;
|
|
288
339
|
const ids = externalIdsByGroup.get(item.externalGroup) ?? [];
|
|
289
340
|
if (item.externalId) ids.push(item.externalId);
|
|
@@ -291,11 +342,14 @@ export const addQuickDocsFn = createServerFn({ method: "POST" })
|
|
|
291
342
|
}
|
|
292
343
|
const existingExternalIds = new Map<string, Set<string>>();
|
|
293
344
|
for (const [group, ids] of externalIdsByGroup) {
|
|
294
|
-
const rows = await (
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
345
|
+
const rows = await findGeneralGroupRows<{ id: string }>(group, {
|
|
346
|
+
where: {
|
|
347
|
+
id: { in: [...new Set(ids)] },
|
|
348
|
+
isDeleted: false,
|
|
349
|
+
...(await generalGroupVisibleFilter(group, userId)),
|
|
350
|
+
},
|
|
351
|
+
select: { id: true },
|
|
352
|
+
});
|
|
299
353
|
existingExternalIds.set(group, new Set(rows.map((r) => r.id)));
|
|
300
354
|
}
|
|
301
355
|
|
|
@@ -303,7 +357,7 @@ export const addQuickDocsFn = createServerFn({ method: "POST" })
|
|
|
303
357
|
const failed: Array<{ key: string; reason: "outOfScope" | "duplicate" }> = [];
|
|
304
358
|
const rowsToCreate: Array<Record<string, unknown>> = [];
|
|
305
359
|
|
|
306
|
-
for (const item of data.items
|
|
360
|
+
for (const item of data.items) {
|
|
307
361
|
const key = quickDocItemKey(item);
|
|
308
362
|
const targetCol = counts.indexOf(Math.min(...counts));
|
|
309
363
|
const order = maxOrder[targetCol] + 1;
|
|
@@ -374,7 +428,7 @@ export const renameQuickDocFn = createServerFn({ method: "POST" })
|
|
|
374
428
|
select: { workspaceId: true },
|
|
375
429
|
});
|
|
376
430
|
if (!row) throw new Error("快捷文档不存在");
|
|
377
|
-
await requireWorkspaceMember(row.workspaceId, session.user
|
|
431
|
+
await requireWorkspaceMember(row.workspaceId, session.user.id);
|
|
378
432
|
await prisma.workspaceQuickDoc.update({
|
|
379
433
|
where: { id: data.quickDocId },
|
|
380
434
|
data: {
|
|
@@ -396,7 +450,7 @@ export const removeQuickDocFn = createServerFn({ method: "POST" })
|
|
|
396
450
|
select: { workspaceId: true },
|
|
397
451
|
});
|
|
398
452
|
if (!row) throw new Error("快捷文档不存在");
|
|
399
|
-
await requireWorkspaceMember(row.workspaceId, session.user
|
|
453
|
+
await requireWorkspaceMember(row.workspaceId, session.user.id);
|
|
400
454
|
await prisma.workspaceQuickDoc.delete({ where: { id: data.quickDocId } });
|
|
401
455
|
return { ok: true };
|
|
402
456
|
});
|
|
@@ -405,16 +459,19 @@ export const reorderQuickDocsFn = createServerFn({ method: "POST" })
|
|
|
405
459
|
.validator(
|
|
406
460
|
z.object({
|
|
407
461
|
workspaceId: z.string(),
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
462
|
+
// 上限 500 与 reorderTestCasesFn 同字段口径对齐(审计 🟡:防超大数组生成等量 update 事务)
|
|
463
|
+
items: z
|
|
464
|
+
.array(
|
|
465
|
+
z.object({ id: z.string(), columnIndex: z.number().int().min(0), sortOrder: z.number().int().min(0) }),
|
|
466
|
+
)
|
|
467
|
+
.max(500),
|
|
411
468
|
}),
|
|
412
469
|
)
|
|
413
470
|
.handler(async ({ data }) => {
|
|
414
471
|
const prisma = await getPrisma()
|
|
415
472
|
const request = getRequest();
|
|
416
473
|
const session = await requireAuth(request);
|
|
417
|
-
await requireWorkspaceMember(data.workspaceId, session.user
|
|
474
|
+
await requireWorkspaceMember(data.workspaceId, session.user.id);
|
|
418
475
|
const ids = data.items.map((item) => item.id);
|
|
419
476
|
const owned = await prisma.workspaceQuickDoc.findMany({
|
|
420
477
|
where: { id: { in: ids }, workspaceId: data.workspaceId },
|
|
@@ -22,18 +22,9 @@ import { z } from "zod";
|
|
|
22
22
|
import { requireAuth } from "@/server/auth-helpers";
|
|
23
23
|
import { migrateStoriesToIndependentProject } from "@/server/builtin-project";
|
|
24
24
|
import { requireResource } from "@/server/resources";
|
|
25
|
+
import { USER_BRIEF_SELECT } from "@/server/story/types";
|
|
25
26
|
import { startOfMonth, endOfMonth, subMonths, eachDayOfInterval } from "date-fns";
|
|
26
27
|
import { formatInTimeZone } from "date-fns-tz";
|
|
27
|
-
import type { Prisma } from "@allbluecn/database";
|
|
28
|
-
|
|
29
|
-
const USER_BRIEF_SELECT = {
|
|
30
|
-
id: true,
|
|
31
|
-
username: true,
|
|
32
|
-
email: true,
|
|
33
|
-
avatarConfig: true,
|
|
34
|
-
bgShape: true,
|
|
35
|
-
bgColor: true,
|
|
36
|
-
} satisfies Prisma.UserDefaultArgs["select"];
|
|
37
28
|
|
|
38
29
|
async function requireWorkspaceOwner(workspaceId: string, userId: string) {
|
|
39
30
|
const prisma = await getPrisma();
|
|
@@ -51,7 +42,7 @@ export const listWorkspacesFn = createServerFn({ method: "GET" }).handler(
|
|
|
51
42
|
const prisma = await getPrisma()
|
|
52
43
|
const request = getRequest();
|
|
53
44
|
const session = await requireAuth(request);
|
|
54
|
-
const userId = session.user
|
|
45
|
+
const userId = session.user.id;
|
|
55
46
|
|
|
56
47
|
return prisma.workspace.findMany({
|
|
57
48
|
where: { ownerId: userId },
|
|
@@ -77,7 +68,7 @@ export const listWorkspacesBriefFn = createServerFn({ method: "GET" }).handler(
|
|
|
77
68
|
const prisma = await getPrisma()
|
|
78
69
|
const request = getRequest();
|
|
79
70
|
const session = await requireAuth(request);
|
|
80
|
-
const userId = session.user
|
|
71
|
+
const userId = session.user.id;
|
|
81
72
|
|
|
82
73
|
return prisma.workspace.findMany({
|
|
83
74
|
where: { ownerId: userId },
|
|
@@ -92,7 +83,7 @@ export const listPinnedWorkspacesBriefFn = createServerFn({ method: "GET" }).han
|
|
|
92
83
|
const prisma = await getPrisma()
|
|
93
84
|
const request = getRequest();
|
|
94
85
|
const session = await requireAuth(request);
|
|
95
|
-
const userId = session.user
|
|
86
|
+
const userId = session.user.id;
|
|
96
87
|
|
|
97
88
|
return prisma.workspace.findMany({
|
|
98
89
|
where: { ownerId: userId, pinnedToSidebar: true },
|
|
@@ -113,7 +104,7 @@ export const toggleWorkspacePinFn = createServerFn({ method: "POST" })
|
|
|
113
104
|
const prisma = await getPrisma()
|
|
114
105
|
const request = getRequest();
|
|
115
106
|
const session = await requireAuth(request);
|
|
116
|
-
const userId = session.user
|
|
107
|
+
const userId = session.user.id;
|
|
117
108
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
118
109
|
|
|
119
110
|
await prisma.workspace.update({
|
|
@@ -135,7 +126,7 @@ export const createWorkspaceFn = createServerFn({ method: "POST" })
|
|
|
135
126
|
const prisma = await getPrisma()
|
|
136
127
|
const request = getRequest();
|
|
137
128
|
const session = await requireAuth(request);
|
|
138
|
-
const userId = session.user
|
|
129
|
+
const userId = session.user.id;
|
|
139
130
|
|
|
140
131
|
await requireResource(request, "workspaces", 1);
|
|
141
132
|
|
|
@@ -174,7 +165,7 @@ export const getWorkspaceDetailFn = createServerFn({ method: "GET" })
|
|
|
174
165
|
const prisma = await getPrisma()
|
|
175
166
|
const request = getRequest();
|
|
176
167
|
const session = await requireAuth(request);
|
|
177
|
-
const userId = session.user
|
|
168
|
+
const userId = session.user.id;
|
|
178
169
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
179
170
|
|
|
180
171
|
const workspace = await prisma.workspace.findUnique({
|
|
@@ -201,7 +192,7 @@ export const listWorkspaceProjectsFn = createServerFn({ method: "GET" })
|
|
|
201
192
|
const prisma = await getPrisma()
|
|
202
193
|
const request = getRequest();
|
|
203
194
|
const session = await requireAuth(request);
|
|
204
|
-
const userId = session.user
|
|
195
|
+
const userId = session.user.id;
|
|
205
196
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
206
197
|
|
|
207
198
|
return prisma.project.findMany({
|
|
@@ -236,7 +227,7 @@ export const updateWorkspaceFn = createServerFn({ method: "POST" })
|
|
|
236
227
|
const prisma = await getPrisma()
|
|
237
228
|
const request = getRequest();
|
|
238
229
|
const session = await requireAuth(request);
|
|
239
|
-
const userId = session.user
|
|
230
|
+
const userId = session.user.id;
|
|
240
231
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
241
232
|
|
|
242
233
|
const { workspaceId, ...rest } = data;
|
|
@@ -261,7 +252,7 @@ export const deleteWorkspaceFn = createServerFn({ method: "POST" })
|
|
|
261
252
|
const prisma = await getPrisma()
|
|
262
253
|
const request = getRequest();
|
|
263
254
|
const session = await requireAuth(request);
|
|
264
|
-
const userId = session.user
|
|
255
|
+
const userId = session.user.id;
|
|
265
256
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
266
257
|
|
|
267
258
|
const projectCount = await prisma.project.count({
|
|
@@ -283,18 +274,21 @@ export const deleteWorkspaceFn = createServerFn({ method: "POST" })
|
|
|
283
274
|
}
|
|
284
275
|
|
|
285
276
|
// 清空模式下需求(stories)的处理与删除项目逻辑保持一致:
|
|
286
|
-
// transfer → 迁移到用户「独立需求」内置项目;clear →
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
where: { project: { workspaceId: data.workspaceId } },
|
|
291
|
-
select: { id: true },
|
|
292
|
-
})
|
|
293
|
-
).map((s) => s.id);
|
|
294
|
-
await migrateStoriesToIndependentProject(userId, storyIds);
|
|
295
|
-
}
|
|
296
|
-
|
|
277
|
+
// transfer → 迁移到用户「独立需求」内置项目;clear → 直接删除。
|
|
278
|
+
// 迁移与下方删除同事务执行(审计 🟡:此前迁移在事务外,迁移成功而后续
|
|
279
|
+
// 事务失败会留下「需求已迁走、空间未删」的半迁移状态且不可回滚;
|
|
280
|
+
// migrateStoriesToIndependentProject 已支持 tx 参数——deleteProjectFn 先例)
|
|
297
281
|
await prisma.$transaction(async (tx) => {
|
|
282
|
+
if (projectCount > 0 && mode === "clear" && (data.storyMode ?? "transfer") === "transfer") {
|
|
283
|
+
const storyIds = (
|
|
284
|
+
await tx.story.findMany({
|
|
285
|
+
where: { project: { workspaceId: data.workspaceId } },
|
|
286
|
+
select: { id: true },
|
|
287
|
+
})
|
|
288
|
+
).map((s) => s.id);
|
|
289
|
+
await migrateStoriesToIndependentProject(userId, storyIds, tx);
|
|
290
|
+
}
|
|
291
|
+
|
|
298
292
|
if (projectCount > 0) {
|
|
299
293
|
if (mode === "clear") {
|
|
300
294
|
// Story 对 project 为 Restrict 外键,storyMode=transfer 时需求已迁走,此处兜底清空残留
|
|
@@ -362,7 +356,7 @@ export const listWorkspaceActivitiesFn = createServerFn({ method: "GET" })
|
|
|
362
356
|
const prisma = await getPrisma()
|
|
363
357
|
const request = getRequest();
|
|
364
358
|
const session = await requireAuth(request);
|
|
365
|
-
const userId = session.user
|
|
359
|
+
const userId = session.user.id;
|
|
366
360
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
367
361
|
|
|
368
362
|
const projects = await prisma.project.findMany({
|
|
@@ -404,7 +398,7 @@ export const getWorkspaceActivityDataFn = createServerFn({ method: "GET" })
|
|
|
404
398
|
const prisma = await getPrisma()
|
|
405
399
|
const request = getRequest();
|
|
406
400
|
const session = await requireAuth(request);
|
|
407
|
-
const userId = session.user
|
|
401
|
+
const userId = session.user.id;
|
|
408
402
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
409
403
|
|
|
410
404
|
const projects = await prisma.project.findMany({
|
|
@@ -426,12 +420,17 @@ export const getWorkspaceActivityDataFn = createServerFn({ method: "GET" })
|
|
|
426
420
|
dateMap.set(key, 0);
|
|
427
421
|
}
|
|
428
422
|
|
|
423
|
+
// 防御性 take 上限(审计 ⚪:活跃空间 12 个月活动可达数万行,全量拉内存仅
|
|
424
|
+
// 为 JS 侧按日计数;SQL date_trunc 按用户任意时区表达式聚合有注入面/无效
|
|
425
|
+
// 时区报错风险,故先以行数上限兜底,DB 侧聚合为后续增强点)
|
|
426
|
+
const ACTIVITY_DATA_MAX_ROWS = 50_000;
|
|
429
427
|
const activities = await prisma.projectActivity.findMany({
|
|
430
428
|
where: {
|
|
431
429
|
projectId: { in: projectIds },
|
|
432
430
|
createdAt: { gte: rangeStart, lte: monthEnd },
|
|
433
431
|
},
|
|
434
432
|
select: { createdAt: true },
|
|
433
|
+
take: ACTIVITY_DATA_MAX_ROWS,
|
|
435
434
|
});
|
|
436
435
|
|
|
437
436
|
for (const a of activities) {
|
|
@@ -459,7 +458,7 @@ export const listWorkspaceMembersFn = createServerFn({ method: "GET" })
|
|
|
459
458
|
const prisma = await getPrisma()
|
|
460
459
|
const request = getRequest();
|
|
461
460
|
const session = await requireAuth(request);
|
|
462
|
-
const userId = session.user
|
|
461
|
+
const userId = session.user.id;
|
|
463
462
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
464
463
|
|
|
465
464
|
const [members, owner] = await Promise.all([
|
|
@@ -477,7 +476,9 @@ export const listWorkspaceMembersFn = createServerFn({ method: "GET" })
|
|
|
477
476
|
}),
|
|
478
477
|
prisma.workspace.findUnique({
|
|
479
478
|
where: { id: data.workspaceId },
|
|
480
|
-
|
|
479
|
+
// createdAt 作 owner joinedAt(审计 ⚪:合成 new Date() 每次请求漂移,
|
|
480
|
+
// 前端展示会跳动)
|
|
481
|
+
select: { ownerId: true, createdAt: true, owner: { select: USER_BRIEF_SELECT } },
|
|
481
482
|
}),
|
|
482
483
|
]);
|
|
483
484
|
|
|
@@ -487,12 +488,14 @@ export const listWorkspaceMembersFn = createServerFn({ method: "GET" })
|
|
|
487
488
|
userId: owner.ownerId,
|
|
488
489
|
role: "owner",
|
|
489
490
|
status: "active",
|
|
490
|
-
joinedAt:
|
|
491
|
+
joinedAt: owner.createdAt,
|
|
491
492
|
user: owner.owner,
|
|
492
493
|
}
|
|
493
494
|
: null;
|
|
494
495
|
|
|
495
|
-
return [ownerMember, ...members.filter((m) => m.userId !== owner?.ownerId)].filter(
|
|
496
|
+
return [ownerMember, ...members.filter((m) => m.userId !== owner?.ownerId)].filter(
|
|
497
|
+
(m): m is NonNullable<typeof m> => m !== null,
|
|
498
|
+
);
|
|
496
499
|
});
|
|
497
500
|
|
|
498
501
|
const addWorkspaceMemberSchema = z.object({
|
|
@@ -507,7 +510,7 @@ export const addWorkspaceMemberFn = createServerFn({ method: "POST" })
|
|
|
507
510
|
const prisma = await getPrisma()
|
|
508
511
|
const request = getRequest();
|
|
509
512
|
const session = await requireAuth(request);
|
|
510
|
-
const currentUserId = session.user
|
|
513
|
+
const currentUserId = session.user.id;
|
|
511
514
|
await requireWorkspaceOwner(data.workspaceId, currentUserId);
|
|
512
515
|
|
|
513
516
|
const workspace = await prisma.workspace.findUnique({
|
|
@@ -554,7 +557,7 @@ export const removeWorkspaceMemberFn = createServerFn({ method: "POST" })
|
|
|
554
557
|
const prisma = await getPrisma()
|
|
555
558
|
const request = getRequest();
|
|
556
559
|
const session = await requireAuth(request);
|
|
557
|
-
const currentUserId = session.user
|
|
560
|
+
const currentUserId = session.user.id;
|
|
558
561
|
await requireWorkspaceOwner(data.workspaceId, currentUserId);
|
|
559
562
|
|
|
560
563
|
if (data.userId === (await prisma.workspace.findUnique({
|
|
@@ -32,7 +32,7 @@ export const wsStreamFn = createServerFn({ method: 'GET' })
|
|
|
32
32
|
if (!data.ids.length) throw new Error('Missing ids parameter')
|
|
33
33
|
return {
|
|
34
34
|
message: 'SSE stream endpoint',
|
|
35
|
-
userId: session.user
|
|
35
|
+
userId: session.user.id,
|
|
36
36
|
entityIds: data.ids,
|
|
37
37
|
}
|
|
38
38
|
})
|