@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
|
@@ -27,20 +27,13 @@ import { resolveStoryScopeProjectId } from "@/server/builtin-project";
|
|
|
27
27
|
import { withCollabGuard } from "@/server/collab/write-guard";
|
|
28
28
|
import { STORY_LIST_SELECT, castStoryUsers, castUserBrief, USER_BRIEF_SELECT, checkDescendant } from "@/server/story/types";
|
|
29
29
|
import { withSequenceNumberRetry } from "@/server/lib/sequence-number-retry";
|
|
30
|
+
import { assertProjectMembership as assertProjectMembershipShared } from "@/server/lib/project-membership";
|
|
30
31
|
|
|
31
32
|
type StoryTx = Parameters<Parameters<typeof import("@allbluecn/database").prisma.$transaction>[0]>[0];
|
|
32
33
|
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const membership = await prisma.projectMember.findUnique({
|
|
37
|
-
where: { projectId_userId: { projectId, userId } },
|
|
38
|
-
select: { status: true },
|
|
39
|
-
});
|
|
40
|
-
if (!membership || membership.status === "suspended") {
|
|
41
|
-
throw new Error("无权限操作该项目的需求");
|
|
42
|
-
}
|
|
43
|
-
}
|
|
34
|
+
/** 项目有效成员校验(共享口径见 server/lib/project-membership:suspended 视同无权限) */
|
|
35
|
+
const assertProjectMembership = (projectId: string, userId: string) =>
|
|
36
|
+
assertProjectMembershipShared(projectId, userId, "无权限操作该项目的需求");
|
|
44
37
|
|
|
45
38
|
async function collectDescendantIds(storyId: string): Promise<Set<string>> {
|
|
46
39
|
const prisma = await getPrisma();
|
|
@@ -150,7 +143,7 @@ export const transferStoryToProjectFn = createServerFn({ method: "POST" })
|
|
|
150
143
|
const prisma = await getPrisma()
|
|
151
144
|
const request = getRequest();
|
|
152
145
|
const session = await requireAuth(request);
|
|
153
|
-
const userId = session.user
|
|
146
|
+
const userId = session.user.id;
|
|
154
147
|
|
|
155
148
|
return runTransferWithIdentifierRetry(async (tx) => {
|
|
156
149
|
const existing = await tx.story.findUnique({
|
|
@@ -237,7 +230,7 @@ export const transferStoryAsChildFn = createServerFn({ method: "POST" })
|
|
|
237
230
|
const prisma = await getPrisma()
|
|
238
231
|
const request = getRequest();
|
|
239
232
|
const session = await requireAuth(request);
|
|
240
|
-
const userId = session.user
|
|
233
|
+
const userId = session.user.id;
|
|
241
234
|
|
|
242
235
|
if (data.storyId === data.parentStoryId) {
|
|
243
236
|
throw new Error("不能将需求设为自身的子需求");
|
|
@@ -443,7 +436,7 @@ export const listProjectStoriesFn = createServerFn({ method: "GET" })
|
|
|
443
436
|
const prisma = await getPrisma()
|
|
444
437
|
const request = getRequest();
|
|
445
438
|
const session = await requireAuth(request);
|
|
446
|
-
const userId = session.user
|
|
439
|
+
const userId = session.user.id;
|
|
447
440
|
|
|
448
441
|
// 读门槛与列表 scope 同口径(SEC-03):传 projectId 走 resolveStoryScopeProjectId
|
|
449
442
|
// (非成员静默回退独立项目);不传(「全部项目」选择器)只返回用户为有效成员的项目
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
// You should have received a copy of the GNU Affero General Public License
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
|
+
// getStoryTreeFn / getChildrenCountFn 已删除(审计 2026-10-25):零 UI 引用的死 GET 通道,且前者
|
|
19
|
+
// 无 rootId 时返回全部项目的根需求全字段(跨项目泄露)、二者均无成员校验。可从 git 恢复。
|
|
18
20
|
import { getPrisma } from "@allbluecn/database/get-prisma"
|
|
19
21
|
import { createServerFn } from "@tanstack/react-start";
|
|
20
22
|
import { getRequest } from "@tanstack/react-start/server";
|
|
@@ -22,48 +24,8 @@ import { z } from "zod";
|
|
|
22
24
|
import { buildRoomName } from "@allbluecn/collab-core/rooms";
|
|
23
25
|
import { requireAuth } from "@/server/auth-helpers";
|
|
24
26
|
import { withCollabGuard } from "@/server/collab/write-guard";
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
/** 项目有效成员校验(口径同 testcase-crud / deleteBugFn:suspended 视同无权限) */
|
|
28
|
-
async function assertProjectMembership(projectId: string, userId: string) {
|
|
29
|
-
const prisma = await getPrisma();
|
|
30
|
-
const membership = await prisma.projectMember.findUnique({
|
|
31
|
-
where: { projectId_userId: { projectId, userId } },
|
|
32
|
-
select: { status: true },
|
|
33
|
-
});
|
|
34
|
-
if (!membership || membership.status === "suspended") {
|
|
35
|
-
throw new Error("无权限操作该项目的需求");
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const getStoryTreeFn = createServerFn({ method: "GET" })
|
|
40
|
-
.validator(z.object({ rootId: z.string().optional() }))
|
|
41
|
-
.handler(async ({ data }) => {
|
|
42
|
-
const prisma = await getPrisma()
|
|
43
|
-
const request = getRequest();
|
|
44
|
-
await requireAuth(request);
|
|
45
|
-
|
|
46
|
-
const rootStories = await prisma.story.findMany({
|
|
47
|
-
where: data.rootId ? { id: data.rootId } : { parentId: null },
|
|
48
|
-
include: {
|
|
49
|
-
children: {
|
|
50
|
-
include: {
|
|
51
|
-
children: {
|
|
52
|
-
include: {
|
|
53
|
-
children: true,
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
const tree = await Promise.all(
|
|
62
|
-
rootStories.map(async (story) => buildStoryTree(story)),
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
return tree;
|
|
66
|
-
});
|
|
27
|
+
import { checkDescendant } from "@/server/story/types";
|
|
28
|
+
import { assertStoryProjectMembership as assertProjectMembership } from "@/server/story/permissions";
|
|
67
29
|
|
|
68
30
|
export const addChildFn = createServerFn({ method: "POST" })
|
|
69
31
|
.validator(z.object({ parentId: z.string(), childId: z.string() }))
|
|
@@ -71,7 +33,7 @@ export const addChildFn = createServerFn({ method: "POST" })
|
|
|
71
33
|
const prisma = await getPrisma()
|
|
72
34
|
const request = getRequest();
|
|
73
35
|
const session = await requireAuth(request);
|
|
74
|
-
const userId = session.user
|
|
36
|
+
const userId = session.user.id;
|
|
75
37
|
|
|
76
38
|
const existingChild = await prisma.story.findUnique({
|
|
77
39
|
where: { id: data.childId },
|
|
@@ -162,7 +124,7 @@ export const removeChildFn = createServerFn({ method: "POST" })
|
|
|
162
124
|
const prisma = await getPrisma()
|
|
163
125
|
const request = getRequest();
|
|
164
126
|
const session = await requireAuth(request);
|
|
165
|
-
const userId = session.user
|
|
127
|
+
const userId = session.user.id;
|
|
166
128
|
|
|
167
129
|
const existing = await prisma.story.findUnique({
|
|
168
130
|
where: { id: data.childId },
|
|
@@ -200,17 +162,3 @@ export const removeChildFn = createServerFn({ method: "POST" })
|
|
|
200
162
|
|
|
201
163
|
return child;
|
|
202
164
|
});
|
|
203
|
-
|
|
204
|
-
export const getChildrenCountFn = createServerFn({ method: "GET" })
|
|
205
|
-
.validator(z.object({ parentId: z.string() }))
|
|
206
|
-
.handler(async ({ data }) => {
|
|
207
|
-
const prisma = await getPrisma()
|
|
208
|
-
const request = getRequest();
|
|
209
|
-
await requireAuth(request);
|
|
210
|
-
|
|
211
|
-
const count = await prisma.story.count({
|
|
212
|
-
where: { parentId: data.parentId },
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
return { count };
|
|
216
|
-
});
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
import { getPrisma } from "@allbluecn/database/get-prisma"
|
|
20
20
|
import { createServerFn } from "@tanstack/react-start"
|
|
21
21
|
import { getRequest } from "@tanstack/react-start/server"
|
|
22
|
-
import { z } from "zod"
|
|
23
22
|
import { requireAuth } from "@/server/auth-helpers"
|
|
24
23
|
import { requireFeature } from "@/server/entitlements"
|
|
25
24
|
import { isProEdition } from "@/server/pro-services"
|
|
26
|
-
import
|
|
25
|
+
import { toJsonInput } from "@/server/lib/prisma-json"
|
|
26
|
+
import { displayOptionsSchema } from "@/server/lib/display-options-schema"
|
|
27
27
|
import {
|
|
28
28
|
DEFAULT_DISPLAY_OPTIONS,
|
|
29
29
|
GROUP_KEYS,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
ORDER_DIRECTIONS,
|
|
32
32
|
ALL_DISPLAY_PROPERTIES,
|
|
33
33
|
PAGE_SIZE_OPTIONS,
|
|
34
|
-
} from "@/
|
|
34
|
+
} from "@/shared/list-kit/display-values"
|
|
35
35
|
import type {
|
|
36
36
|
DisplayOptions,
|
|
37
37
|
DisplayProperty,
|
|
@@ -39,12 +39,7 @@ import type {
|
|
|
39
39
|
OrderKey,
|
|
40
40
|
OrderDirection,
|
|
41
41
|
PageSize,
|
|
42
|
-
} from "@/
|
|
43
|
-
|
|
44
|
-
/** Prisma Json 字段不接受强类型对象(缺 index signature),统一 cast */
|
|
45
|
-
function toJson<T>(value: T): Prisma.InputJsonValue {
|
|
46
|
-
return value as unknown as Prisma.InputJsonValue
|
|
47
|
-
}
|
|
42
|
+
} from "@/shared/list-kit/display-types"
|
|
48
43
|
|
|
49
44
|
/** 解析存储的 JSON 偏好,非法/缺失字段回退默认值 */
|
|
50
45
|
function parseStoredOptions(raw: unknown): DisplayOptions {
|
|
@@ -103,26 +98,8 @@ function parseStoredOptions(raw: unknown): DisplayOptions {
|
|
|
103
98
|
}
|
|
104
99
|
}
|
|
105
100
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const orderBySchema = z.enum(ORDER_KEYS)
|
|
109
|
-
const orderDirSchema = z.enum(ORDER_DIRECTIONS)
|
|
110
|
-
const propertySchema = z.enum(ALL_DISPLAY_PROPERTIES)
|
|
111
|
-
const pageSizeSchema = z.union([z.literal(100), z.literal(200), z.literal(500), z.literal(1000)])
|
|
112
|
-
|
|
113
|
-
// 模块私有:serverFn 文件只准导出 createServerFn(客户端 split 会保留普通导出,
|
|
114
|
-
// 与本文件顶层 @/server/* import 叠加会把服务端依赖拉进浏览器 bundle)
|
|
115
|
-
const displayOptionsSchema = z.object({
|
|
116
|
-
groupBy: groupBySchema,
|
|
117
|
-
subGroupBy: subGroupBySchema,
|
|
118
|
-
orderBy: orderBySchema,
|
|
119
|
-
orderDir: orderDirSchema,
|
|
120
|
-
properties: z.array(propertySchema),
|
|
121
|
-
showEmptyGroups: z.boolean(),
|
|
122
|
-
showSubItems: z.boolean(),
|
|
123
|
-
pageSize: pageSizeSchema,
|
|
124
|
-
columnOrder: z.array(z.string().min(1)).optional(),
|
|
125
|
-
})
|
|
101
|
+
// 写入侧校验 schema 已收敛到 @/server/lib/display-options-schema(与
|
|
102
|
+
// story-view.ts 共用单一来源,审计 🔵/🟡 2026-10-25)
|
|
126
103
|
|
|
127
104
|
/** 获取当前用户持久化的 Display Options(非法/缺失字段已回退默认值) */
|
|
128
105
|
export const getStoryDisplayOptionsFn = createServerFn({ method: "GET" }).handler(
|
|
@@ -130,7 +107,7 @@ export const getStoryDisplayOptionsFn = createServerFn({ method: "GET" }).handle
|
|
|
130
107
|
const prisma = await getPrisma()
|
|
131
108
|
const request = getRequest()
|
|
132
109
|
const session = await requireAuth(request)
|
|
133
|
-
const userId = session.user
|
|
110
|
+
const userId = session.user.id
|
|
134
111
|
|
|
135
112
|
const user = await prisma.user.findUnique({
|
|
136
113
|
where: { id: userId },
|
|
@@ -162,7 +139,7 @@ export const updateStoryDisplayOptionsFn = createServerFn({ method: "POST" })
|
|
|
162
139
|
const prisma = await getPrisma()
|
|
163
140
|
const request = getRequest()
|
|
164
141
|
const session = await requireAuth(request)
|
|
165
|
-
const userId = session.user
|
|
142
|
+
const userId = session.user.id
|
|
166
143
|
|
|
167
144
|
// 服务端强制校验:pageSize > 200(500/1000)为 Pro 专属,前端锁定只是 UX
|
|
168
145
|
// OSS 环境直接 cap 到 200;Pro 环境走 feature gate
|
|
@@ -177,7 +154,7 @@ export const updateStoryDisplayOptionsFn = createServerFn({ method: "POST" })
|
|
|
177
154
|
const options: DisplayOptions = data
|
|
178
155
|
await prisma.user.update({
|
|
179
156
|
where: { id: userId },
|
|
180
|
-
data: { storyDisplayOptions:
|
|
157
|
+
data: { storyDisplayOptions: toJsonInput(options) },
|
|
181
158
|
})
|
|
182
159
|
return options
|
|
183
160
|
})
|
|
@@ -20,15 +20,12 @@ import { createServerFn } from "@tanstack/react-start";
|
|
|
20
20
|
import { getRequest } from "@tanstack/react-start/server";
|
|
21
21
|
import { z } from "zod";
|
|
22
22
|
import { requireAuth } from "@/server/auth-helpers";
|
|
23
|
-
import {
|
|
23
|
+
import { toJsonInput } from "@/server/lib/prisma-json";
|
|
24
|
+
import { displayOptionsSchema } from "@/server/lib/display-options-schema";
|
|
25
|
+
import { toSavedView } from "@/components/story/views/view-types";
|
|
24
26
|
import type { FilterCondition } from "@/components/story/filters/field-configs";
|
|
25
|
-
import type { DisplayOptions } from "@/components/shared-kit/list-kit/display/types";
|
|
26
27
|
import type { Prisma } from "@allbluecn/database";
|
|
27
28
|
|
|
28
|
-
function toJson<T>(value: T): Prisma.InputJsonValue {
|
|
29
|
-
return value as unknown as Prisma.InputJsonValue;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
29
|
const SELECT = {
|
|
33
30
|
id: true,
|
|
34
31
|
userId: true,
|
|
@@ -47,13 +44,13 @@ export const listStoryViewsFn = createServerFn({ method: "GET" }).handler(async
|
|
|
47
44
|
const prisma = await getPrisma()
|
|
48
45
|
const request = getRequest();
|
|
49
46
|
const session = await requireAuth(request);
|
|
50
|
-
const userId = session.user
|
|
47
|
+
const userId = session.user.id;
|
|
51
48
|
const rows = await prisma.storyFilterView.findMany({
|
|
52
49
|
where: { userId },
|
|
53
50
|
orderBy: { sortOrder: "asc" },
|
|
54
51
|
select: SELECT,
|
|
55
52
|
});
|
|
56
|
-
return rows.map((r
|
|
53
|
+
return rows.map((r) => toSavedView(r));
|
|
57
54
|
});
|
|
58
55
|
|
|
59
56
|
const filterConditionSchema = z.object({
|
|
@@ -69,6 +66,10 @@ const createSchema = z.object({
|
|
|
69
66
|
icon: z.string().default("list"),
|
|
70
67
|
projectId: z.string().optional(),
|
|
71
68
|
filters: z.array(filterConditionSchema),
|
|
69
|
+
// 审计 🟡(2026-10-25):displayOptions 曾 z.unknown() 任意 JSON 直通入库;
|
|
70
|
+
// 写入侧在 handler 内按 displayOptionsSchema.parse 强校验(放 validator 会把
|
|
71
|
+
// 完整 DisplayOptionsInput 泄漏成客户端 RPC 参数类型,迫使 story-list-view
|
|
72
|
+
// 等消费方改类型——该文件属并行组件批次范围,故校验收敛在 handler)
|
|
72
73
|
displayOptions: z.unknown(),
|
|
73
74
|
});
|
|
74
75
|
|
|
@@ -78,7 +79,9 @@ export const createStoryViewFn = createServerFn({ method: "POST" })
|
|
|
78
79
|
const prisma = await getPrisma()
|
|
79
80
|
const request = getRequest();
|
|
80
81
|
const session = await requireAuth(request);
|
|
81
|
-
const userId = session.user
|
|
82
|
+
const userId = session.user.id;
|
|
83
|
+
// 写入闸门:非法形状(缺 orderDir/pageSize 等)在落库前被拒
|
|
84
|
+
const displayOptions = displayOptionsSchema.parse(data.displayOptions);
|
|
82
85
|
const row = await prisma.storyFilterView.create({
|
|
83
86
|
data: {
|
|
84
87
|
userId,
|
|
@@ -86,8 +89,8 @@ export const createStoryViewFn = createServerFn({ method: "POST" })
|
|
|
86
89
|
description: data.description ?? null,
|
|
87
90
|
icon: data.icon,
|
|
88
91
|
projectId: data.projectId ?? null,
|
|
89
|
-
filters:
|
|
90
|
-
displayOptions:
|
|
92
|
+
filters: toJsonInput(data.filters as FilterCondition[]),
|
|
93
|
+
displayOptions: toJsonInput(displayOptions),
|
|
91
94
|
},
|
|
92
95
|
select: SELECT,
|
|
93
96
|
});
|
|
@@ -110,15 +113,17 @@ export const updateStoryViewFn = createServerFn({ method: "POST" })
|
|
|
110
113
|
const prisma = await getPrisma()
|
|
111
114
|
const request = getRequest();
|
|
112
115
|
const session = await requireAuth(request);
|
|
113
|
-
const userId = session.user
|
|
116
|
+
const userId = session.user.id;
|
|
114
117
|
const { id, ...patch } = data;
|
|
115
118
|
const data2: Record<string, unknown> = {};
|
|
116
119
|
if (patch.name !== undefined) data2.name = patch.name;
|
|
117
120
|
if (patch.description !== undefined) data2.description = patch.description;
|
|
118
121
|
if (patch.icon !== undefined) data2.icon = patch.icon;
|
|
119
122
|
if (patch.projectId !== undefined) data2.projectId = patch.projectId;
|
|
120
|
-
if (patch.filters !== undefined) data2.filters =
|
|
121
|
-
if (patch.displayOptions !== undefined)
|
|
123
|
+
if (patch.filters !== undefined) data2.filters = toJsonInput(patch.filters as FilterCondition[]);
|
|
124
|
+
if (patch.displayOptions !== undefined) {
|
|
125
|
+
data2.displayOptions = toJsonInput(displayOptionsSchema.parse(patch.displayOptions));
|
|
126
|
+
}
|
|
122
127
|
const row = await prisma.storyFilterView.update({
|
|
123
128
|
where: { id, userId },
|
|
124
129
|
data: data2,
|
|
@@ -135,9 +140,7 @@ export const deleteStoryViewFn = createServerFn({ method: "POST" })
|
|
|
135
140
|
const prisma = await getPrisma()
|
|
136
141
|
const request = getRequest();
|
|
137
142
|
const session = await requireAuth(request);
|
|
138
|
-
const userId = session.user
|
|
143
|
+
const userId = session.user.id;
|
|
139
144
|
await prisma.storyFilterView.delete({ where: { id: data.id, userId } });
|
|
140
145
|
return { success: true };
|
|
141
146
|
});
|
|
142
|
-
|
|
143
|
-
export type { SavedView };
|
|
@@ -156,7 +156,7 @@ export const createAiTaskFn = createServerFn({ method: "POST" })
|
|
|
156
156
|
.handler(async ({ data }): Promise<{ id: string; runId?: string }> => {
|
|
157
157
|
const request = getRequest();
|
|
158
158
|
const session = await requireAuth(request);
|
|
159
|
-
const userId = session.user
|
|
159
|
+
const userId = session.user.id;
|
|
160
160
|
|
|
161
161
|
assertPgOnlyMutation();
|
|
162
162
|
|
|
@@ -228,7 +228,7 @@ export const runAiTaskFn = createServerFn({ method: "POST" })
|
|
|
228
228
|
.handler(async ({ data }): Promise<{ runId: string }> => {
|
|
229
229
|
const request = getRequest();
|
|
230
230
|
const session = await requireAuth(request);
|
|
231
|
-
const userId = session.user
|
|
231
|
+
const userId = session.user.id;
|
|
232
232
|
|
|
233
233
|
assertPgOnlyMutation();
|
|
234
234
|
await checkAiRateLimit(userId, "aiTask");
|
|
@@ -243,7 +243,7 @@ export const deleteAiTaskFn = createServerFn({ method: "POST" })
|
|
|
243
243
|
.handler(async ({ data }): Promise<{ ok: true }> => {
|
|
244
244
|
const request = getRequest();
|
|
245
245
|
const session = await requireAuth(request);
|
|
246
|
-
const userId = session.user
|
|
246
|
+
const userId = session.user.id;
|
|
247
247
|
|
|
248
248
|
assertPgOnlyMutation();
|
|
249
249
|
|
|
@@ -68,7 +68,7 @@ export const listAssignedToMeFn = createServerFn({ method: "GET" }).handler(
|
|
|
68
68
|
async (): Promise<AssignedResult> => {
|
|
69
69
|
const request = getRequest();
|
|
70
70
|
const session = await requireAuth(request);
|
|
71
|
-
const userId = session.user
|
|
71
|
+
const userId = session.user.id;
|
|
72
72
|
|
|
73
73
|
return fetchAssignedToMe(userId);
|
|
74
74
|
},
|
|
@@ -80,7 +80,7 @@ export const listAiTasksFn = createServerFn({ method: "GET" }).handler(
|
|
|
80
80
|
async () => {
|
|
81
81
|
const request = getRequest();
|
|
82
82
|
const session = await requireAuth(request);
|
|
83
|
-
const userId = session.user
|
|
83
|
+
const userId = session.user.id;
|
|
84
84
|
|
|
85
85
|
// 桌面端 SQLite 无 aiTask 表(pg-only):降级空列表并声明 degraded,不触 DB
|
|
86
86
|
if (getDatabaseProvider() === "sqlite") {
|
|
@@ -132,7 +132,7 @@ export const getAiTaskFn = createServerFn({ method: "GET" })
|
|
|
132
132
|
}> => {
|
|
133
133
|
const request = getRequest();
|
|
134
134
|
const session = await requireAuth(request);
|
|
135
|
-
const userId = session.user
|
|
135
|
+
const userId = session.user.id;
|
|
136
136
|
|
|
137
137
|
const prisma = await getPrisma();
|
|
138
138
|
|
|
@@ -9,6 +9,8 @@ import { requireTeamSeats } from '@/server/resources'
|
|
|
9
9
|
import { auditLog } from '@/server/audit'
|
|
10
10
|
import { sendTemplateEmail } from '@/server/email'
|
|
11
11
|
import { USER_BRIEF_SELECT } from '@/server/team-access'
|
|
12
|
+
import { getClientIp } from '@allbluecn/kernel'
|
|
13
|
+
import { checkRateLimit, RateLimitExceededError } from '@/server/lib/rate-limit'
|
|
12
14
|
|
|
13
15
|
const INVITE_EXPIRES_DAYS = 7
|
|
14
16
|
const OWNER_SELECT = { id: true, username: true, email: true, avatarConfig: true, bgShape: true, bgColor: true } as const
|
|
@@ -34,7 +36,7 @@ export const createTeamInvitationFn = createServerFn({ method: 'POST' })
|
|
|
34
36
|
const prisma = await getPrisma()
|
|
35
37
|
const request = getRequest()
|
|
36
38
|
const session = await requireAuth(request)
|
|
37
|
-
const ownerId = session.user
|
|
39
|
+
const ownerId = session.user.id
|
|
38
40
|
|
|
39
41
|
const email = data.channel === 'email' ? data.email!.toLowerCase() : null
|
|
40
42
|
|
|
@@ -132,7 +134,7 @@ export const listTeamInvitationsFn = createServerFn({ method: 'GET' }).handler(a
|
|
|
132
134
|
try {
|
|
133
135
|
const request = getRequest()
|
|
134
136
|
const session = await requireAuth(request)
|
|
135
|
-
const ownerId = session.user
|
|
137
|
+
const ownerId = session.user.id
|
|
136
138
|
const now = new Date()
|
|
137
139
|
|
|
138
140
|
await prisma.teamInvitation.updateMany({
|
|
@@ -190,7 +192,7 @@ export const clearExpiredInvitationsFn = createServerFn({ method: 'POST' })
|
|
|
190
192
|
const prisma = await getPrisma()
|
|
191
193
|
const request = getRequest()
|
|
192
194
|
const session = await requireAuth(request)
|
|
193
|
-
const ownerId = session.user
|
|
195
|
+
const ownerId = session.user.id
|
|
194
196
|
const res = await prisma.teamInvitation.deleteMany({
|
|
195
197
|
where: { ownerId, status: 'expired', channel: 'email' },
|
|
196
198
|
})
|
|
@@ -211,7 +213,7 @@ export const revokeTeamInvitationFn = createServerFn({ method: 'POST' })
|
|
|
211
213
|
const prisma = await getPrisma()
|
|
212
214
|
const request = getRequest()
|
|
213
215
|
const session = await requireAuth(request)
|
|
214
|
-
const ownerId = session.user
|
|
216
|
+
const ownerId = session.user.id
|
|
215
217
|
// DB-03:属主校验并入单次 findFirst(消除查后比对二次往返与 TOCTOU),文案保持
|
|
216
218
|
const inv = await assertOwned(prisma.teamInvitation, { where: { id: data.invitationId, ownerId } }, '邀请不存在')
|
|
217
219
|
if (inv.status !== 'pending' && inv.status !== 'pending_approval') throw new Error('仅待处理/待批准邀请可撤销')
|
|
@@ -241,7 +243,7 @@ export const resendTeamInvitationFn = createServerFn({ method: 'POST' })
|
|
|
241
243
|
const prisma = await getPrisma()
|
|
242
244
|
const request = getRequest()
|
|
243
245
|
const session = await requireAuth(request)
|
|
244
|
-
const ownerId = session.user
|
|
246
|
+
const ownerId = session.user.id
|
|
245
247
|
// DB-03:属主校验并入单次 findFirst(消除查后比对二次往返与 TOCTOU),文案保持
|
|
246
248
|
const inv = await assertOwned(prisma.teamInvitation, { where: { id: data.invitationId, ownerId } }, '邀请不存在')
|
|
247
249
|
if (inv.status !== 'pending' && inv.status !== 'expired') {
|
|
@@ -285,7 +287,7 @@ export const refreshTeamInvitationLinkFn = createServerFn({ method: 'POST' })
|
|
|
285
287
|
const prisma = await getPrisma()
|
|
286
288
|
const request = getRequest()
|
|
287
289
|
const session = await requireAuth(request)
|
|
288
|
-
const ownerId = session.user
|
|
290
|
+
const ownerId = session.user.id
|
|
289
291
|
|
|
290
292
|
await requireTeamSeats(ownerId, 'member', 1)
|
|
291
293
|
|
|
@@ -335,7 +337,7 @@ export const listTeamMembersFn = createServerFn({ method: 'GET' }).handler(async
|
|
|
335
337
|
const prisma = await getPrisma()
|
|
336
338
|
const request = getRequest()
|
|
337
339
|
const session = await requireAuth(request)
|
|
338
|
-
const ownerId = session.user
|
|
340
|
+
const ownerId = session.user.id
|
|
339
341
|
|
|
340
342
|
// 以 memberId 判当前用户的归属:避免为已是别家成员的账号创建自引用 owner 记录(P2002)
|
|
341
343
|
const ownEntry = await prisma.teamMembership.findUnique({
|
|
@@ -381,7 +383,7 @@ export const removeTeamMemberFn = createServerFn({ method: 'POST' })
|
|
|
381
383
|
const prisma = await getPrisma()
|
|
382
384
|
const request = getRequest()
|
|
383
385
|
const session = await requireAuth(request)
|
|
384
|
-
const ownerId = session.user
|
|
386
|
+
const ownerId = session.user.id
|
|
385
387
|
const m = await prisma.teamMembership.findUnique({ where: { id: data.membershipId } })
|
|
386
388
|
if (!m) throw new Error('成员不存在')
|
|
387
389
|
if (m.ownerId !== ownerId) throw new Error('权限不足:仅团队所有者可移除成员')
|
|
@@ -403,7 +405,7 @@ export const leaveTeamFn = createServerFn({ method: 'POST' }).validator(z.object
|
|
|
403
405
|
const prisma = await getPrisma()
|
|
404
406
|
const request = getRequest()
|
|
405
407
|
const session = await requireAuth(request)
|
|
406
|
-
const userId = session.user
|
|
408
|
+
const userId = session.user.id
|
|
407
409
|
const m = await prisma.teamMembership.findUnique({ where: { memberId: userId } })
|
|
408
410
|
if (!m) throw new Error('你未加入任何团队')
|
|
409
411
|
await prisma.$transaction(async (tx) => {
|
|
@@ -433,7 +435,7 @@ export const approveTeamJoinRequestFn = createServerFn({ method: 'POST' })
|
|
|
433
435
|
const prisma = await getPrisma()
|
|
434
436
|
const request = getRequest()
|
|
435
437
|
const session = await requireAuth(request)
|
|
436
|
-
const ownerId = session.user
|
|
438
|
+
const ownerId = session.user.id
|
|
437
439
|
|
|
438
440
|
// DB-03:属主校验并入单次 findFirst(include 关系一并取回)。
|
|
439
441
|
// 此处内联 findFirst 而非 assertOwned:include 投影类型(reqRow.invitation)需走
|
|
@@ -502,7 +504,7 @@ export const rejectTeamJoinRequestFn = createServerFn({ method: 'POST' })
|
|
|
502
504
|
const prisma = await getPrisma()
|
|
503
505
|
const request = getRequest()
|
|
504
506
|
const session = await requireAuth(request)
|
|
505
|
-
const ownerId = session.user
|
|
507
|
+
const ownerId = session.user.id
|
|
506
508
|
|
|
507
509
|
// DB-03:属主校验并入单次 findFirst
|
|
508
510
|
const reqRow = await assertOwned(prisma.teamJoinRequest, { where: { id: data.requestId, ownerId } }, '申请不存在')
|
|
@@ -530,7 +532,7 @@ export const deleteTeamInvitationFn = createServerFn({ method: 'POST' })
|
|
|
530
532
|
const prisma = await getPrisma()
|
|
531
533
|
const request = getRequest()
|
|
532
534
|
const session = await requireAuth(request)
|
|
533
|
-
const ownerId = session.user
|
|
535
|
+
const ownerId = session.user.id
|
|
534
536
|
|
|
535
537
|
// DB-03:属主校验并入单次 findFirst
|
|
536
538
|
const invRow = await assertOwned(prisma.teamInvitation, { where: { id: data.invitationId, ownerId } }, '邀请不存在')
|
|
@@ -556,7 +558,7 @@ export const deleteTeamJoinRequestFn = createServerFn({ method: 'POST' })
|
|
|
556
558
|
const prisma = await getPrisma()
|
|
557
559
|
const request = getRequest()
|
|
558
560
|
const session = await requireAuth(request)
|
|
559
|
-
const ownerId = session.user
|
|
561
|
+
const ownerId = session.user.id
|
|
560
562
|
|
|
561
563
|
// DB-03:属主校验并入单次 findFirst
|
|
562
564
|
const reqRow = await assertOwned(prisma.teamJoinRequest, { where: { id: data.requestId, ownerId } }, '申请不存在')
|
|
@@ -578,7 +580,7 @@ export const listTeamUsersFn = createServerFn({ method: 'GET' }).handler(async (
|
|
|
578
580
|
const prisma = await getPrisma()
|
|
579
581
|
const request = getRequest()
|
|
580
582
|
const session = await requireAuth(request)
|
|
581
|
-
const userId = session.user
|
|
583
|
+
const userId = session.user.id
|
|
582
584
|
const joined = await prisma.teamMembership.findUnique({ where: { memberId: userId } })
|
|
583
585
|
const ownerId = joined ? joined.ownerId : userId
|
|
584
586
|
const [owner, members] = await Promise.all([
|
|
@@ -678,9 +680,31 @@ export const getTeamInvitationByTokenFn = createServerFn({ method: 'GET' })
|
|
|
678
680
|
})
|
|
679
681
|
|
|
680
682
|
export const checkInviteEmailRegisteredFn = createServerFn({ method: 'POST' })
|
|
681
|
-
|
|
683
|
+
// 审计 A5x-5 🟠:无鉴权端点曾可任意枚举注册邮箱——现绑定有效邀请 token + IP 限流
|
|
684
|
+
.validator(z.object({ token: z.string().min(1), email: z.string().email() }))
|
|
682
685
|
.handler(async ({ data }) => {
|
|
683
686
|
const prisma = await getPrisma()
|
|
687
|
+
let ip: string | null = null
|
|
688
|
+
try {
|
|
689
|
+
ip = getClientIp(getRequest())
|
|
690
|
+
} catch {
|
|
691
|
+
// IP 取不到归入 unknown 桶,仍受限流保护
|
|
692
|
+
}
|
|
693
|
+
const rl = checkRateLimit(
|
|
694
|
+
`invite-email-check:${ip ?? 'unknown'}`,
|
|
695
|
+
{ max: 30, windowMs: 15 * 60 * 1000 },
|
|
696
|
+
)
|
|
697
|
+
if (!rl.allowed) throw new RateLimitExceededError(rl.retryAfterMs, 'inviteEmailCheck')
|
|
698
|
+
|
|
699
|
+
const inv = await prisma.teamInvitation.findUnique({
|
|
700
|
+
where: { token: data.token },
|
|
701
|
+
select: { status: true, channel: true, expiresAt: true },
|
|
702
|
+
})
|
|
703
|
+
const invValid = inv
|
|
704
|
+
&& (inv.status === 'pending' || (inv.channel === 'email' && inv.status === 'pending_approval'))
|
|
705
|
+
&& (!inv.expiresAt || inv.expiresAt > new Date())
|
|
706
|
+
if (!invValid) throw new Error('邀请链接无效或已过期')
|
|
707
|
+
|
|
684
708
|
const user = await prisma.user.findUnique({
|
|
685
709
|
where: { email: data.email.toLowerCase() },
|
|
686
710
|
select: { id: true },
|
|
@@ -777,12 +801,12 @@ export const acceptTeamInvitationFn = createServerFn({ method: 'POST' })
|
|
|
777
801
|
const prisma = await getPrisma()
|
|
778
802
|
const request = getRequest()
|
|
779
803
|
const session = await requireAuth(request)
|
|
780
|
-
const userId = session.user
|
|
804
|
+
const userId = session.user.id
|
|
781
805
|
const currentUser = await prisma.user.findUnique({
|
|
782
806
|
where: { id: userId },
|
|
783
807
|
select: { email: true },
|
|
784
808
|
})
|
|
785
|
-
const email = (currentUser?.email ?? session.user
|
|
809
|
+
const email = (currentUser?.email ?? session.user.email ?? '').toLowerCase()
|
|
786
810
|
if (!email) throw new Error('当前账号缺少邮箱,无法申请')
|
|
787
811
|
|
|
788
812
|
const inv = await prisma.teamInvitation.findUnique({ where: { token: data.token } })
|
|
@@ -845,7 +869,7 @@ export const approveTeamInvitationFn = createServerFn({ method: 'POST' })
|
|
|
845
869
|
const prisma = await getPrisma()
|
|
846
870
|
const request = getRequest()
|
|
847
871
|
const session = await requireAuth(request)
|
|
848
|
-
const ownerId = session.user
|
|
872
|
+
const ownerId = session.user.id
|
|
849
873
|
|
|
850
874
|
// DB-03:属主校验并入单次 findFirst
|
|
851
875
|
const inv = await assertOwned(prisma.teamInvitation, { where: { id: data.invitationId, ownerId } }, '邀请不存在')
|
|
@@ -305,7 +305,7 @@ describe("startGenerationFn", () => {
|
|
|
305
305
|
expect(opts.promptVars.storyContext).toContain("AC1");
|
|
306
306
|
});
|
|
307
307
|
|
|
308
|
-
it("kbDocIds 组装 kbContext(docId+excerpt
|
|
308
|
+
it("kbDocIds 组装 kbContext(docId+excerpt 截断),归属过滤下推 DB(kb.userId)", async () => {
|
|
309
309
|
DB.storyFindUnique.mockResolvedValue({
|
|
310
310
|
id: "s-1",
|
|
311
311
|
projectId: P,
|
|
@@ -313,14 +313,13 @@ describe("startGenerationFn", () => {
|
|
|
313
313
|
description: STORY_DESC,
|
|
314
314
|
});
|
|
315
315
|
DB.caseFindMany.mockResolvedValue([]);
|
|
316
|
+
// 过滤在 where 内完成(mock 模拟 DB 行为):仅返回本人 KB 文档
|
|
316
317
|
DB.kbDocFindMany.mockResolvedValue([
|
|
317
318
|
{
|
|
318
319
|
id: "kbdoc-1",
|
|
319
320
|
title: "API 约定",
|
|
320
321
|
content: { markdown: "接口鉴权使用 Bearer Token".repeat(3000) },
|
|
321
|
-
kb: { userId: U },
|
|
322
322
|
},
|
|
323
|
-
{ id: "kbdoc-2", title: "他人文档", content: { markdown: "秘密" }, kb: { userId: "other" } },
|
|
324
323
|
]);
|
|
325
324
|
DB.runCreate.mockResolvedValue(runRow());
|
|
326
325
|
M.runChatAsAgent.mockResolvedValue(JSON.stringify(validOutput()));
|
|
@@ -328,9 +327,15 @@ describe("startGenerationFn", () => {
|
|
|
328
327
|
|
|
329
328
|
await startGenerationFn({ data: { storyId: "s-1", kbDocIds: ["kbdoc-1", "kbdoc-2"] } });
|
|
330
329
|
|
|
330
|
+
// 归属过滤下推 DB(审计 ⚪):where 含 kb.userId,他人文档整行不再进内存
|
|
331
331
|
expect(DB.kbDocFindMany).toHaveBeenCalledWith(
|
|
332
332
|
expect.objectContaining({
|
|
333
|
-
where: {
|
|
333
|
+
where: {
|
|
334
|
+
id: { in: ["kbdoc-1", "kbdoc-2"] },
|
|
335
|
+
isDeleted: false,
|
|
336
|
+
kb: { userId: U },
|
|
337
|
+
},
|
|
338
|
+
select: { id: true, title: true, content: true },
|
|
334
339
|
}),
|
|
335
340
|
);
|
|
336
341
|
const createdInput = DB.runCreate.mock.calls[0]![0]!.data.input as {
|
|
@@ -226,6 +226,21 @@ describe("getBugRegressionStatusFn", () => {
|
|
|
226
226
|
expect(res.regression!.completedAt).toBe("2026-03-01T00:00:00.000Z");
|
|
227
227
|
});
|
|
228
228
|
|
|
229
|
+
it("completed 但 completedAt=null 的脏数据 → regression null(审计 🟡:不产出 null 完成时间)", async () => {
|
|
230
|
+
DB.runCaseFindMany.mockResolvedValue([linkedCase("c1")]);
|
|
231
|
+
DB.runFindFirst.mockResolvedValue({
|
|
232
|
+
id: "run-dirty-time",
|
|
233
|
+
name: "回归验证:登录页空指针",
|
|
234
|
+
completedAt: null,
|
|
235
|
+
summary: { total: 3, passed: 3, failed: 0 },
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const res = (await getBugRegressionStatusFn({ data: { bugId: BUG } })) as {
|
|
239
|
+
regression: unknown;
|
|
240
|
+
};
|
|
241
|
+
expect(res.regression).toBeNull();
|
|
242
|
+
});
|
|
243
|
+
|
|
229
244
|
it("最近 completed Run 有失败(passed < total)→ regression null(失败覆盖旧绿)", async () => {
|
|
230
245
|
DB.runCaseFindMany.mockResolvedValue([linkedCase("c1")]);
|
|
231
246
|
DB.runFindFirst.mockResolvedValue({
|