@jingyi0605/codingns 0.9.0 → 0.9.6
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/bin/codingns.mjs +75 -0
- package/dist/public/assets/{AdaptiveButlerPage-B17QiMyT.js → AdaptiveButlerPage-khJQh6a_.js} +2 -2
- package/dist/public/assets/{App-CFBwDUNA.js → App-If9gThKM.js} +6 -6
- package/dist/public/assets/{BootstrapPage-W5wU3BPh.js → BootstrapPage-DcfYtoLC.js} +1 -1
- package/dist/public/assets/{ConversationPage-DQLX1bUh.js → ConversationPage-Bfb7GLTM.js} +1 -1
- package/dist/public/assets/{DesktopDetachPreviewPage-DTPeuAW-.js → DesktopDetachPreviewPage-CXUPMcBz.js} +1 -1
- package/dist/public/assets/{DesktopModal-6ii53_Y9.js → DesktopModal-bMdI1jEe.js} +1 -1
- package/dist/public/assets/DesktopWindowPage-D1xwgS-7.js +2 -0
- package/dist/public/assets/FileContextPanel-C4syif3B.js +1 -0
- package/dist/public/assets/GitSidebar-DduL9aTV.js +6 -0
- package/dist/public/assets/MobileCreateSessionSheet-DWPBsEx8.js +1 -0
- package/dist/public/assets/{MobileSheet-opTWyRe1.js → MobileSheet-BXvQPkxt.js} +1 -1
- package/dist/public/assets/{MobileTopHeaderFrame-BbNON3Y4.js → MobileTopHeaderFrame-vdYOyaaB.js} +1 -1
- package/dist/public/assets/{MobileWorkspaceSwitcherHeader-BZEzPeMj.js → MobileWorkspaceSwitcherHeader-DT330cAx.js} +1 -1
- package/dist/public/assets/{PluginAccessOverview-mQDmAljp.js → PluginAccessOverview-C77TeZTK.js} +1 -1
- package/dist/public/assets/{PluginContainerPage-CcxUJpM4.js → PluginContainerPage-DdSwOCw-.js} +1 -1
- package/dist/public/assets/{PluginDetailPage-D5--ACIt.js → PluginDetailPage-BK1yTzvO.js} +1 -1
- package/dist/public/assets/{PluginsListPage-D_oJxYXT.js → PluginsListPage-DAAwSc6W.js} +1 -1
- package/dist/public/assets/{RelayConnectEntryPage-DROxpnkv.js → RelayConnectEntryPage-4Yyo2p8b.js} +1 -1
- package/dist/public/assets/{ServerSettingsModal-CUUOPqSe.js → ServerSettingsModal-C_DEisHs.js} +1 -1
- package/dist/public/assets/{SessionIndexPage-C2Jxh6Gp.js → SessionIndexPage-DyMikN_x.js} +1 -1
- package/dist/public/assets/SettingsPage-CDAVsPr3.js +2 -0
- package/dist/public/assets/TerminalManagerPanel-4OR47vcf.js +1 -0
- package/dist/public/assets/{TerminalPage-CwWyFDj8.js → TerminalPage-Pvx396YX.js} +1 -1
- package/dist/public/assets/{TerminalRuntimeFallbackModal-CSVVbO8r.js → TerminalRuntimeFallbackModal-KvG6k4AQ.js} +1 -1
- package/dist/public/assets/{ToolFilesPage-QBEY8oCf.js → ToolFilesPage-DrYHk0N-.js} +1 -1
- package/dist/public/assets/{ToolGitPage-BKoZ2l9v.js → ToolGitPage-Dz1q-Ns_.js} +1 -1
- package/dist/public/assets/{ToolProcessesPage-BOH0ib4G.js → ToolProcessesPage-CRhphOmM.js} +1 -1
- package/dist/public/assets/{ToolsHomePage-BcMZ3BCQ.js → ToolsHomePage-BJSDLR6T.js} +1 -1
- package/dist/public/assets/{WorkbenchLandingPage-B5zoppEl.js → WorkbenchLandingPage-BlkxdOLC.js} +1 -1
- package/dist/public/assets/WorkbenchLayout-D-U7ghT0.js +1022 -0
- package/dist/public/assets/{WorkbenchModal-NGmPgqaE.js → WorkbenchModal-xbx1o6MO.js} +1 -1
- package/dist/public/assets/WorkbenchShellRoute-DyWSCHz_.js +1 -0
- package/dist/public/assets/WorkbenchShellRoute-htbkGbtW.css +1 -0
- package/dist/public/assets/WorkspaceDebugDetailPage-B4ol2_a5.js +1 -0
- package/dist/public/assets/WorkspaceDetailPage-DMakfmHR.js +1 -0
- package/dist/public/assets/WorkspaceHomePage-tmCafatd.js +1 -0
- package/dist/public/assets/{client-runtime-manager-DXbI9K1K.js → client-runtime-manager-Bwau7p1v.js} +1 -1
- package/dist/public/assets/index-DmUJ8tIw.css +1 -0
- package/dist/public/assets/index-_OCkVmfl.js +50 -0
- package/dist/public/assets/{login-direct-candidate-resolver-DkKyFtQJ.js → login-direct-candidate-resolver-CKUQ07IA.js} +1 -1
- package/dist/public/assets/{plugin-permission-copy-CzN269Bk.js → plugin-permission-copy-DIVk5jNp.js} +1 -1
- package/dist/public/assets/{plugins-api-Bv9DHpLF.js → plugins-api-DHJVvPZw.js} +1 -1
- package/dist/public/assets/{preferences-service-D2ISL2Zz.js → preferences-service-CyxxeBmS.js} +1 -1
- package/dist/public/assets/{relay-entry-Bg0OisQy.js → relay-entry-B5GmiOrR.js} +1 -1
- package/dist/public/assets/{terminal-runtime-meta-C8t-CIDF.js → terminal-runtime-meta-DBsyT35T.js} +1 -1
- package/dist/public/assets/useRegisteredDebugTemplates-wCGD2SLW.js +1 -0
- package/dist/public/assets/workbench-navigation-RyUjchbD.js +1 -0
- package/dist/public/index.html +2 -2
- package/dist/server/config/env.d.ts +1 -0
- package/dist/server/config/env.js +3 -0
- package/dist/server/config/env.js.map +1 -1
- package/dist/server/modules/affairs-indexer/core/src/parser/parser-skip-repository.js.map +1 -1
- package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-repository.d.ts +1 -0
- package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-repository.js +31 -0
- package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-repository.js.map +1 -1
- package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-write-repository.js.map +1 -1
- package/dist/server/modules/affairs-indexer/core/src/services/dirty/dirty-scope-resolver.d.ts +1 -0
- package/dist/server/modules/affairs-indexer/core/src/services/dirty/dirty-scope-resolver.js +1 -0
- package/dist/server/modules/affairs-indexer/core/src/services/dirty/dirty-scope-resolver.js.map +1 -1
- package/dist/server/modules/affairs-indexer/core/src/services/export/export-builder.js +4 -1
- package/dist/server/modules/affairs-indexer/core/src/services/export/export-builder.js.map +1 -1
- package/dist/server/modules/affairs-indexer/core/src/services/search/search-index-builder.js +140 -16
- package/dist/server/modules/affairs-indexer/core/src/services/search/search-index-builder.js.map +1 -1
- package/dist/server/modules/affairs-indexer/core/src/sqlite/detect-catalog-schema.js +2 -2
- package/dist/server/modules/affairs-indexer/core/src/sqlite/detect-catalog-schema.js.map +1 -1
- package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.d.ts +20 -3
- package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.js +3 -3
- package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.js.map +1 -1
- package/dist/server/modules/assistant-capability/assistant-capability-controller.d.ts +1 -1
- package/dist/server/modules/assistant-capability/assistant-capability-controller.js +8 -7
- package/dist/server/modules/assistant-capability/assistant-capability-controller.js.map +1 -1
- package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +14 -13
- package/dist/server/modules/assistant-capability/assistant-capability-service.js +27 -24
- package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -1
- package/dist/server/modules/auth/auth-controller.d.ts +27 -1
- package/dist/server/modules/auth/auth-controller.js +20 -0
- package/dist/server/modules/auth/auth-controller.js.map +1 -1
- package/dist/server/modules/auth/auth-service.d.ts +32 -1
- package/dist/server/modules/auth/auth-service.js +217 -2
- package/dist/server/modules/auth/auth-service.js.map +1 -1
- package/dist/server/modules/bootstrap/bootstrap-service.js +1 -0
- package/dist/server/modules/bootstrap/bootstrap-service.js.map +1 -1
- package/dist/server/modules/butler/assistant-automation-service.d.ts +1 -1
- package/dist/server/modules/butler/assistant-automation-service.js +9 -10
- package/dist/server/modules/butler/assistant-automation-service.js.map +1 -1
- package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.d.ts +32 -0
- package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.js +93 -0
- package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.js.map +1 -0
- package/dist/server/modules/butler/assistant-sandbox-service.d.ts +69 -0
- package/dist/server/modules/butler/assistant-sandbox-service.js +399 -0
- package/dist/server/modules/butler/assistant-sandbox-service.js.map +1 -0
- package/dist/server/modules/butler/butler-action-context-service.js +2 -2
- package/dist/server/modules/butler/butler-action-context-service.js.map +1 -1
- package/dist/server/modules/butler/butler-control-action-service.d.ts +5 -5
- package/dist/server/modules/butler/butler-control-action-service.js +19 -19
- package/dist/server/modules/butler/butler-control-action-service.js.map +1 -1
- package/dist/server/modules/butler/butler-control-session-service.d.ts +1 -1
- package/dist/server/modules/butler/butler-control-session-service.js +27 -26
- package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
- package/dist/server/modules/butler/butler-control-timer-service.js +4 -5
- package/dist/server/modules/butler/butler-control-timer-service.js.map +1 -1
- package/dist/server/modules/butler/butler-controller.d.ts +2 -2
- package/dist/server/modules/butler/butler-controller.js +19 -17
- package/dist/server/modules/butler/butler-controller.js.map +1 -1
- package/dist/server/modules/butler/butler-follow-up-service.d.ts +3 -0
- package/dist/server/modules/butler/butler-follow-up-service.js +11 -1
- package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -1
- package/dist/server/modules/butler/butler-inbox-service.d.ts +3 -0
- package/dist/server/modules/butler/butler-inbox-service.js +14 -2
- package/dist/server/modules/butler/butler-inbox-service.js.map +1 -1
- package/dist/server/modules/butler/butler-profile-service.d.ts +5 -5
- package/dist/server/modules/butler/butler-profile-service.js +17 -16
- package/dist/server/modules/butler/butler-profile-service.js.map +1 -1
- package/dist/server/modules/butler/butler-project-service.d.ts +7 -6
- package/dist/server/modules/butler/butler-project-service.js +35 -21
- package/dist/server/modules/butler/butler-project-service.js.map +1 -1
- package/dist/server/modules/butler/butler-session-service.d.ts +5 -2
- package/dist/server/modules/butler/butler-session-service.js +51 -27
- package/dist/server/modules/butler/butler-session-service.js.map +1 -1
- package/dist/server/modules/butler/butler-session-summary-service.d.ts +2 -2
- package/dist/server/modules/butler/butler-session-summary-service.js +23 -9
- package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -1
- package/dist/server/modules/butler/context-aggregator.js +9 -9
- package/dist/server/modules/butler/context-aggregator.js.map +1 -1
- package/dist/server/modules/butler/patrol-execution-service.d.ts +0 -1
- package/dist/server/modules/butler/patrol-execution-service.js +6 -12
- package/dist/server/modules/butler/patrol-execution-service.js.map +1 -1
- package/dist/server/modules/channels/wechat-claw-client.d.ts +51 -0
- package/dist/server/modules/channels/wechat-claw-client.js +245 -0
- package/dist/server/modules/channels/wechat-claw-client.js.map +1 -0
- package/dist/server/modules/file/file-controller.d.ts +11 -2
- package/dist/server/modules/file/file-controller.js +404 -17
- package/dist/server/modules/file/file-controller.js.map +1 -1
- package/dist/server/modules/file/file-search-service.js +200 -12
- package/dist/server/modules/file/file-search-service.js.map +1 -1
- package/dist/server/modules/file/runtime/codingns-workspace-bridge.js +18 -5
- package/dist/server/modules/file/workspace-file-bridge-service.d.ts +9 -0
- package/dist/server/modules/file/workspace-file-bridge-service.js +3 -0
- package/dist/server/modules/file/workspace-file-bridge-service.js.map +1 -1
- package/dist/server/modules/file/workspace-file-bridge-watch-service.d.ts +9 -0
- package/dist/server/modules/file/workspace-file-bridge-watch-service.js +28 -0
- package/dist/server/modules/file/workspace-file-bridge-watch-service.js.map +1 -1
- package/dist/server/modules/sessions/session-controller.js +3 -3
- package/dist/server/modules/sessions/session-controller.js.map +1 -1
- package/dist/server/modules/sessions/session-history-service.d.ts +8 -3
- package/dist/server/modules/sessions/session-history-service.js +126 -11
- package/dist/server/modules/sessions/session-history-service.js.map +1 -1
- package/dist/server/modules/sessions/session-live-runtime-service.js +25 -15
- package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
- package/dist/server/modules/sessions/session-permission-request-service.js +28 -15
- package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -1
- package/dist/server/modules/tasks/task-types.d.ts +1 -0
- package/dist/server/modules/tasks/task-types.js +1 -0
- package/dist/server/modules/tasks/task-types.js.map +1 -1
- package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.d.ts +1 -1
- package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.js +22 -5
- package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.js.map +1 -1
- package/dist/server/modules/workbench/workbench-controller.d.ts +5 -0
- package/dist/server/modules/workbench/workbench-controller.js +20 -0
- package/dist/server/modules/workbench/workbench-controller.js.map +1 -1
- package/dist/server/modules/workbench/workbench-service.d.ts +6 -6
- package/dist/server/modules/workbench/workbench-service.js +42 -45
- package/dist/server/modules/workbench/workbench-service.js.map +1 -1
- package/dist/server/modules/workspace/affairs-library-controller.d.ts +8 -0
- package/dist/server/modules/workspace/affairs-library-controller.js +11 -0
- package/dist/server/modules/workspace/affairs-library-controller.js.map +1 -1
- package/dist/server/modules/workspace/affairs-library-preview-link-service.d.ts +6 -0
- package/dist/server/modules/workspace/affairs-library-preview-link-service.js +12 -2
- package/dist/server/modules/workspace/affairs-library-preview-link-service.js.map +1 -1
- package/dist/server/modules/workspace/affairs-library-service.d.ts +12 -1
- package/dist/server/modules/workspace/affairs-library-service.js +294 -96
- package/dist/server/modules/workspace/affairs-library-service.js.map +1 -1
- package/dist/server/modules/workspace/affairs-lightweight-session-controller.d.ts +8 -0
- package/dist/server/modules/workspace/affairs-lightweight-session-controller.js +55 -8
- package/dist/server/modules/workspace/affairs-lightweight-session-controller.js.map +1 -1
- package/dist/server/modules/workspace/affairs-lightweight-session-service.d.ts +13 -0
- package/dist/server/modules/workspace/affairs-lightweight-session-service.js +167 -21
- package/dist/server/modules/workspace/affairs-lightweight-session-service.js.map +1 -1
- package/dist/server/modules/workspace/affairs-tag-controller.d.ts +3 -0
- package/dist/server/modules/workspace/affairs-tag-controller.js +5 -0
- package/dist/server/modules/workspace/affairs-tag-controller.js.map +1 -1
- package/dist/server/modules/workspace/affairs-tag-service.d.ts +34 -1
- package/dist/server/modules/workspace/affairs-tag-service.js +568 -4
- package/dist/server/modules/workspace/affairs-tag-service.js.map +1 -1
- package/dist/server/modules/workspace/teable-api-client.d.ts +118 -0
- package/dist/server/modules/workspace/teable-api-client.js +142 -0
- package/dist/server/modules/workspace/teable-api-client.js.map +1 -0
- package/dist/server/modules/workspace/teable-catalog-controller.d.ts +18 -0
- package/dist/server/modules/workspace/teable-catalog-controller.js +17 -0
- package/dist/server/modules/workspace/teable-catalog-controller.js.map +1 -0
- package/dist/server/modules/workspace/teable-catalog-service.d.ts +36 -0
- package/dist/server/modules/workspace/teable-catalog-service.js +124 -0
- package/dist/server/modules/workspace/teable-catalog-service.js.map +1 -0
- package/dist/server/modules/workspace/teable-credential-service.d.ts +8 -0
- package/dist/server/modules/workspace/teable-credential-service.js +37 -0
- package/dist/server/modules/workspace/teable-credential-service.js.map +1 -0
- package/dist/server/modules/workspace/teable-field-mapping-controller.d.ts +25 -0
- package/dist/server/modules/workspace/teable-field-mapping-controller.js +31 -0
- package/dist/server/modules/workspace/teable-field-mapping-controller.js.map +1 -0
- package/dist/server/modules/workspace/teable-field-mapping-service.d.ts +38 -0
- package/dist/server/modules/workspace/teable-field-mapping-service.js +215 -0
- package/dist/server/modules/workspace/teable-field-mapping-service.js.map +1 -0
- package/dist/server/modules/workspace/teable-global-binding-controller.d.ts +22 -0
- package/dist/server/modules/workspace/teable-global-binding-controller.js +25 -0
- package/dist/server/modules/workspace/teable-global-binding-controller.js.map +1 -0
- package/dist/server/modules/workspace/teable-global-binding-service.d.ts +35 -0
- package/dist/server/modules/workspace/teable-global-binding-service.js +151 -0
- package/dist/server/modules/workspace/teable-global-binding-service.js.map +1 -0
- package/dist/server/modules/workspace/teable-mirror-sync-controller.d.ts +29 -0
- package/dist/server/modules/workspace/teable-mirror-sync-controller.js +50 -0
- package/dist/server/modules/workspace/teable-mirror-sync-controller.js.map +1 -0
- package/dist/server/modules/workspace/teable-mirror-sync-service.d.ts +157 -0
- package/dist/server/modules/workspace/teable-mirror-sync-service.js +917 -0
- package/dist/server/modules/workspace/teable-mirror-sync-service.js.map +1 -0
- package/dist/server/modules/workspace/teable-runtime-controller.d.ts +58 -0
- package/dist/server/modules/workspace/teable-runtime-controller.js +60 -0
- package/dist/server/modules/workspace/teable-runtime-controller.js.map +1 -0
- package/dist/server/modules/workspace/teable-runtime-service.d.ts +96 -0
- package/dist/server/modules/workspace/teable-runtime-service.js +362 -0
- package/dist/server/modules/workspace/teable-runtime-service.js.map +1 -0
- package/dist/server/modules/workspace/teable-workbench-sync-config-controller.d.ts +22 -0
- package/dist/server/modules/workspace/teable-workbench-sync-config-controller.js +20 -0
- package/dist/server/modules/workspace/teable-workbench-sync-config-controller.js.map +1 -0
- package/dist/server/modules/workspace/teable-workbench-sync-config-service.d.ts +22 -0
- package/dist/server/modules/workspace/teable-workbench-sync-config-service.js +159 -0
- package/dist/server/modules/workspace/teable-workbench-sync-config-service.js.map +1 -0
- package/dist/server/modules/workspace/workspace-controller.d.ts +1 -1
- package/dist/server/modules/workspace/workspace-controller.js +7 -7
- package/dist/server/modules/workspace/workspace-controller.js.map +1 -1
- package/dist/server/modules/workspace/workspace-service.d.ts +7 -0
- package/dist/server/modules/workspace/workspace-service.js +151 -10
- package/dist/server/modules/workspace/workspace-service.js.map +1 -1
- package/dist/server/routes/affairs.d.ts +9 -1
- package/dist/server/routes/affairs.js +120 -1
- package/dist/server/routes/affairs.js.map +1 -1
- package/dist/server/routes/auth.js +6 -0
- package/dist/server/routes/auth.js.map +1 -1
- package/dist/server/routes/workbench.js +15 -0
- package/dist/server/routes/workbench.js.map +1 -1
- package/dist/server/routes/workspaces.js +51 -41
- package/dist/server/routes/workspaces.js.map +1 -1
- package/dist/server/server/create-server.d.ts +18 -0
- package/dist/server/server/create-server.js +99 -7
- package/dist/server/server/create-server.js.map +1 -1
- package/dist/server/server/start-host.js +20 -0
- package/dist/server/server/start-host.js.map +1 -1
- package/dist/server/shared/http/request-diagnostics.d.ts +56 -0
- package/dist/server/shared/http/request-diagnostics.js +256 -0
- package/dist/server/shared/http/request-diagnostics.js.map +1 -0
- package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.d.ts +18 -0
- package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js +191 -0
- package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js.map +1 -0
- package/dist/server/storage/repositories/auth-token-repository.d.ts +1 -0
- package/dist/server/storage/repositories/auth-token-repository.js +8 -0
- package/dist/server/storage/repositories/auth-token-repository.js.map +1 -1
- package/dist/server/storage/repositories/auth-user-repository.d.ts +50 -0
- package/dist/server/storage/repositories/auth-user-repository.js +198 -27
- package/dist/server/storage/repositories/auth-user-repository.js.map +1 -1
- package/dist/server/storage/repositories/butler-control-session-repository.d.ts +4 -1
- package/dist/server/storage/repositories/butler-control-session-repository.js +55 -8
- package/dist/server/storage/repositories/butler-control-session-repository.js.map +1 -1
- package/dist/server/storage/repositories/butler-profile-repository.d.ts +2 -1
- package/dist/server/storage/repositories/butler-profile-repository.js +35 -6
- package/dist/server/storage/repositories/butler-profile-repository.js.map +1 -1
- package/dist/server/storage/repositories/butler-project-repository.d.ts +2 -0
- package/dist/server/storage/repositories/butler-project-repository.js +38 -4
- package/dist/server/storage/repositories/butler-project-repository.js.map +1 -1
- package/dist/server/storage/repositories/butler-session-repository.d.ts +2 -1
- package/dist/server/storage/repositories/butler-session-repository.js +35 -6
- package/dist/server/storage/repositories/butler-session-repository.js.map +1 -1
- package/dist/server/storage/repositories/session-binding-repository.d.ts +3 -0
- package/dist/server/storage/repositories/session-binding-repository.js +70 -2
- package/dist/server/storage/repositories/session-binding-repository.js.map +1 -1
- package/dist/server/storage/repositories/session-index-repository.js +7 -5
- package/dist/server/storage/repositories/session-index-repository.js.map +1 -1
- package/dist/server/storage/repositories/user-affairs-library-setting-repository.js +8 -5
- package/dist/server/storage/repositories/user-affairs-library-setting-repository.js.map +1 -1
- package/dist/server/storage/repositories/user-teable-credential-repository.d.ts +9 -0
- package/dist/server/storage/repositories/user-teable-credential-repository.js +45 -0
- package/dist/server/storage/repositories/user-teable-credential-repository.js.map +1 -0
- package/dist/server/storage/repositories/user-teable-field-mapping-repository.d.ts +10 -0
- package/dist/server/storage/repositories/user-teable-field-mapping-repository.js +69 -0
- package/dist/server/storage/repositories/user-teable-field-mapping-repository.js.map +1 -0
- package/dist/server/storage/repositories/user-teable-global-setting-repository.d.ts +8 -0
- package/dist/server/storage/repositories/user-teable-global-setting-repository.js +52 -0
- package/dist/server/storage/repositories/user-teable-global-setting-repository.js.map +1 -0
- package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.d.ts +9 -0
- package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.js +66 -0
- package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.js.map +1 -0
- package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.d.ts +9 -0
- package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.js +67 -0
- package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.js.map +1 -0
- package/dist/server/storage/repositories/user-teable-sync-log-repository.d.ts +14 -0
- package/dist/server/storage/repositories/user-teable-sync-log-repository.js +97 -0
- package/dist/server/storage/repositories/user-teable-sync-log-repository.js.map +1 -0
- package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.d.ts +8 -0
- package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.js +55 -0
- package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.js.map +1 -0
- package/dist/server/storage/repositories/workspace-repository.d.ts +3 -1
- package/dist/server/storage/repositories/workspace-repository.js +24 -10
- package/dist/server/storage/repositories/workspace-repository.js.map +1 -1
- package/dist/server/storage/sqlite/client.js +692 -1
- package/dist/server/storage/sqlite/client.js.map +1 -1
- package/dist/server/storage/sqlite/schema.sql +200 -10
- package/dist/server/types/domain.d.ts +114 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.js +34 -7
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +3 -7
- package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.d.ts +22 -3
- package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js +29 -2
- package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/package.json +3 -1
- package/package.json +1 -1
- package/dist/public/assets/DesktopWindowPage-D0blSuKd.js +0 -2
- package/dist/public/assets/FileContextPanel-BrKO8Xt6.js +0 -1
- package/dist/public/assets/GitSidebar-BdwiDtOr.js +0 -6
- package/dist/public/assets/MobileCreateSessionSheet-Cx_dBiBb.js +0 -1
- package/dist/public/assets/SettingsPage-BlAZCHsy.js +0 -2
- package/dist/public/assets/TerminalManagerPanel-CjzbiWjl.js +0 -1
- package/dist/public/assets/WorkbenchLayout-CikJBS62.js +0 -1019
- package/dist/public/assets/WorkbenchShellRoute-BbbSOiZw.js +0 -1
- package/dist/public/assets/WorkbenchShellRoute-DT3VMjWD.css +0 -1
- package/dist/public/assets/WorkspaceDebugDetailPage-CVivdPx5.js +0 -1
- package/dist/public/assets/WorkspaceDetailPage-DgOSjscR.js +0 -1
- package/dist/public/assets/WorkspaceHomePage-HPa7M_Vh.js +0 -1
- package/dist/public/assets/index-BxJPQpFM.css +0 -1
- package/dist/public/assets/index-CeXGOT_T.js +0 -50
- package/dist/public/assets/useRegisteredDebugTemplates-Bol3NVfN.js +0 -1
- package/dist/public/assets/workbench-navigation-B7IjRQd8.js +0 -1
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { AppError } from "../../shared/errors/app-error.js";
|
|
4
4
|
import { HOST_TASK_TYPES } from "../tasks/task-types.js";
|
|
5
|
+
import { AFFAIRS_GLOBAL_WORKSPACE_ID } from "./affairs-library-service.js";
|
|
5
6
|
import { CatalogRepository, } from "../affairs-indexer/core/src/repositories/catalog-repository.js";
|
|
6
7
|
import { CatalogWriteRepository, } from "../affairs-indexer/core/src/repositories/catalog-write-repository.js";
|
|
7
8
|
import { createAffairsIndexerRuntimeConfig } from "../affairs-indexer/internal-command-runner.js";
|
|
@@ -14,14 +15,25 @@ export class AffairsTagService {
|
|
|
14
15
|
workspaceService;
|
|
15
16
|
affairsLibraryService;
|
|
16
17
|
taskManager;
|
|
18
|
+
teableMirrorSyncNotifier = null;
|
|
17
19
|
constructor(workspaceService, affairsLibraryService, taskManager) {
|
|
18
20
|
this.workspaceService = workspaceService;
|
|
19
21
|
this.affairsLibraryService = affairsLibraryService;
|
|
20
22
|
this.taskManager = taskManager;
|
|
21
23
|
this.registerBackgroundTasks();
|
|
22
24
|
}
|
|
25
|
+
configureTeableMirrorSyncNotifier(notifier) {
|
|
26
|
+
this.teableMirrorSyncNotifier = notifier;
|
|
27
|
+
}
|
|
23
28
|
listTags(workspaceId, userId, input = {}) {
|
|
24
29
|
const { dbPath } = this.requireBinding(workspaceId, userId);
|
|
30
|
+
return this.listTagsFromCatalog(dbPath, input);
|
|
31
|
+
}
|
|
32
|
+
listGlobalTags(userId, input = {}) {
|
|
33
|
+
const { dbPath } = this.requireGlobalBinding(userId);
|
|
34
|
+
return this.listTagsFromCatalog(dbPath, input);
|
|
35
|
+
}
|
|
36
|
+
listTagsFromCatalog(dbPath, input = {}) {
|
|
25
37
|
const repository = new CatalogRepository(dbPath);
|
|
26
38
|
const definitions = repository.listTagDefinitions(input.includeDisabled === true);
|
|
27
39
|
const enabledRules = repository.listAllEnabledTagRules();
|
|
@@ -155,6 +167,7 @@ export class AffairsTagService {
|
|
|
155
167
|
reason: `tag_definition_ensured:${lastTagId}`,
|
|
156
168
|
},
|
|
157
169
|
});
|
|
170
|
+
this.notifyTeableTagChanged(userId, `tag_definition_ensured:${lastTagId}`);
|
|
158
171
|
return this.getTagDetail(workspaceId, userId, lastTagId);
|
|
159
172
|
}
|
|
160
173
|
saveTagDefinition(workspaceId, userId, input) {
|
|
@@ -271,6 +284,7 @@ export class AffairsTagService {
|
|
|
271
284
|
},
|
|
272
285
|
});
|
|
273
286
|
}
|
|
287
|
+
this.notifyTeableTagChanged(userId, `tag_definition_saved:${result.id}`);
|
|
274
288
|
return detail;
|
|
275
289
|
}
|
|
276
290
|
deleteTagDefinition(workspaceId, userId, tagId) {
|
|
@@ -300,6 +314,7 @@ export class AffairsTagService {
|
|
|
300
314
|
reason: `tag_definition_deleted:${tagId}`,
|
|
301
315
|
},
|
|
302
316
|
});
|
|
317
|
+
this.notifyTeableTagChanged(userId, `tag_definition_deleted:${tagId}`);
|
|
303
318
|
return {
|
|
304
319
|
deletedTagIds,
|
|
305
320
|
deletedPaths,
|
|
@@ -324,11 +339,22 @@ export class AffairsTagService {
|
|
|
324
339
|
const manualBindings = repository.listManualDocumentTagBindingsByDocumentIds([documentId]);
|
|
325
340
|
const folderBindings = repository.listEffectiveFolderTagBindingsForDocumentPaths([context.path]);
|
|
326
341
|
const resolved = repository.listResolvedDocumentTagsByDocumentIds([documentId]);
|
|
342
|
+
const manualTagIds = new Set(manualBindings.map(item => item.tagId));
|
|
343
|
+
const excludedTagIds = new Set([
|
|
344
|
+
...manualBindings.map(item => item.tagId),
|
|
345
|
+
...folderBindings.map(item => item.tagId),
|
|
346
|
+
...resolved.map(item => item.tagId),
|
|
347
|
+
]);
|
|
348
|
+
const excludedTagPaths = new Set([
|
|
349
|
+
...manualBindings.map(item => item.tagPath),
|
|
350
|
+
...folderBindings.map(item => item.tagPath),
|
|
351
|
+
...resolved.map(item => item.path),
|
|
352
|
+
]);
|
|
327
353
|
return {
|
|
328
354
|
documentId,
|
|
329
355
|
path: context.path,
|
|
330
356
|
title: context.title,
|
|
331
|
-
manualTagIds:
|
|
357
|
+
manualTagIds: [...manualTagIds],
|
|
332
358
|
effectiveFolderBindings: folderBindings.map(item => ({
|
|
333
359
|
id: item.id,
|
|
334
360
|
folderPath: item.folderPath,
|
|
@@ -343,6 +369,15 @@ export class AffairsTagService {
|
|
|
343
369
|
confidence: item.confidence,
|
|
344
370
|
priority: resolvePriority(item.sourceType),
|
|
345
371
|
})),
|
|
372
|
+
recommendedTags: this.recommendTagsForTarget(repository, {
|
|
373
|
+
kind: "document",
|
|
374
|
+
path: context.path,
|
|
375
|
+
title: context.title,
|
|
376
|
+
extension: context.extension,
|
|
377
|
+
modifiedAt: context.modifiedAt,
|
|
378
|
+
excludedTagIds,
|
|
379
|
+
excludedTagPaths,
|
|
380
|
+
}),
|
|
346
381
|
};
|
|
347
382
|
}
|
|
348
383
|
saveDocumentTagBindings(workspaceId, userId, documentId, tagIds) {
|
|
@@ -374,6 +409,7 @@ export class AffairsTagService {
|
|
|
374
409
|
scope: { kind: "document", documentId },
|
|
375
410
|
},
|
|
376
411
|
});
|
|
412
|
+
this.notifyTeableTagChanged(userId, `manual_document_binding_saved:${documentId}`);
|
|
377
413
|
return {
|
|
378
414
|
target: {
|
|
379
415
|
type: "document",
|
|
@@ -398,16 +434,23 @@ export class AffairsTagService {
|
|
|
398
434
|
}).exists;
|
|
399
435
|
const repository = new CatalogRepository(dbPath);
|
|
400
436
|
const bindings = repository.listFolderTagBindingsByPaths([normalizedFolderPath]);
|
|
437
|
+
const assignedTagIds = new Set(bindings.map(item => item.tagId));
|
|
401
438
|
return {
|
|
402
439
|
folderPath: normalizedFolderPath,
|
|
403
440
|
exists,
|
|
404
|
-
bindingTagIds:
|
|
441
|
+
bindingTagIds: [...assignedTagIds],
|
|
405
442
|
bindings: bindings.map(item => ({
|
|
406
443
|
id: item.id,
|
|
407
444
|
tagId: item.tagId,
|
|
408
445
|
tagPath: item.tagPath,
|
|
409
446
|
applyMode: item.applyMode,
|
|
410
447
|
})),
|
|
448
|
+
recommendedTags: this.recommendTagsForTarget(repository, {
|
|
449
|
+
kind: "folder",
|
|
450
|
+
path: normalizedFolderPath,
|
|
451
|
+
title: normalizedFolderPath === "." ? path.basename(rootDir) : path.posix.basename(normalizedFolderPath),
|
|
452
|
+
excludedTagIds: assignedTagIds,
|
|
453
|
+
}),
|
|
411
454
|
};
|
|
412
455
|
}
|
|
413
456
|
getFolderTagApplyTaskSnapshot(workspaceId, userId, folderPath) {
|
|
@@ -450,6 +493,9 @@ export class AffairsTagService {
|
|
|
450
493
|
scope: "full",
|
|
451
494
|
};
|
|
452
495
|
}
|
|
496
|
+
notifyTeableTagChanged(userId, reason) {
|
|
497
|
+
this.teableMirrorSyncNotifier?.(userId, reason);
|
|
498
|
+
}
|
|
453
499
|
saveFolderTagBindings(workspaceId, userId, folderPath, tagIds) {
|
|
454
500
|
const { dbPath, rootDir } = this.requireBinding(workspaceId, userId);
|
|
455
501
|
const normalizedFolderPath = normalizeFolderPath(folderPath);
|
|
@@ -467,6 +513,7 @@ export class AffairsTagService {
|
|
|
467
513
|
scope: { kind: "folder", folderPath: normalizedFolderPath },
|
|
468
514
|
},
|
|
469
515
|
});
|
|
516
|
+
this.notifyTeableTagChanged(userId, `folder_binding_saved:${normalizedFolderPath}`);
|
|
470
517
|
return {
|
|
471
518
|
target: {
|
|
472
519
|
type: "folder",
|
|
@@ -481,8 +528,11 @@ export class AffairsTagService {
|
|
|
481
528
|
};
|
|
482
529
|
}
|
|
483
530
|
requireBinding(workspaceId, userId) {
|
|
484
|
-
|
|
485
|
-
|
|
531
|
+
const normalizedWorkspaceId = workspaceId.trim();
|
|
532
|
+
if (normalizedWorkspaceId !== AFFAIRS_GLOBAL_WORKSPACE_ID) {
|
|
533
|
+
this.workspaceService.getWorkspaceOrThrow(normalizedWorkspaceId);
|
|
534
|
+
}
|
|
535
|
+
const binding = this.affairsLibraryService.getBinding(normalizedWorkspaceId || AFFAIRS_GLOBAL_WORKSPACE_ID, userId);
|
|
486
536
|
const rootDir = binding?.rootDir?.trim() ?? "";
|
|
487
537
|
if (!rootDir || binding?.enabled !== true) {
|
|
488
538
|
throw new AppError({
|
|
@@ -501,6 +551,22 @@ export class AffairsTagService {
|
|
|
501
551
|
dbPath: resolveCatalogDbPath(rootDir),
|
|
502
552
|
};
|
|
503
553
|
}
|
|
554
|
+
requireGlobalBinding(userId) {
|
|
555
|
+
const binding = this.affairsLibraryService.getGlobalBinding(userId);
|
|
556
|
+
const rootDir = binding?.rootDir?.trim() ?? "";
|
|
557
|
+
if (!rootDir || binding?.enabled !== true) {
|
|
558
|
+
throw new AppError({
|
|
559
|
+
statusCode: 409,
|
|
560
|
+
errorCode: "AFFAIRS_LIBRARY_BINDING_REQUIRED",
|
|
561
|
+
detail: "事务文档库还没有启用",
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
initCatalog(createAffairsIndexerRuntimeConfig(rootDir));
|
|
565
|
+
return {
|
|
566
|
+
rootDir,
|
|
567
|
+
dbPath: resolveCatalogDbPath(rootDir),
|
|
568
|
+
};
|
|
569
|
+
}
|
|
504
570
|
registerBackgroundTasks() {
|
|
505
571
|
if (!this.taskManager.has(HOST_TASK_TYPES.affairsLibraryTagRecompute)) {
|
|
506
572
|
this.taskManager.register({
|
|
@@ -578,6 +644,89 @@ export class AffairsTagService {
|
|
|
578
644
|
});
|
|
579
645
|
return countByPath;
|
|
580
646
|
}
|
|
647
|
+
recommendTagsForTarget(repository, target) {
|
|
648
|
+
const definitions = repository.listTagDefinitions(false)
|
|
649
|
+
.filter((tag) => isBusinessTagDefinition(tag)
|
|
650
|
+
&& !target.excludedTagIds.has(tag.id)
|
|
651
|
+
&& !target.excludedTagPaths?.has(tag.path));
|
|
652
|
+
if (definitions.length === 0) {
|
|
653
|
+
return [];
|
|
654
|
+
}
|
|
655
|
+
const candidates = new Map();
|
|
656
|
+
const tagById = new Map(definitions.map(tag => [tag.id, tag]));
|
|
657
|
+
const countByPath = this.buildTagDocumentCountMap(repository);
|
|
658
|
+
const targetText = buildRecommendationTargetText(target.path, target.title);
|
|
659
|
+
for (const tag of definitions) {
|
|
660
|
+
const score = scoreTagNameMatch(tag, targetText);
|
|
661
|
+
if (score <= 0) {
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
setTagRecommendation(candidates, tag, {
|
|
665
|
+
score,
|
|
666
|
+
reason: "name_match",
|
|
667
|
+
evidence: "文件夹或文件名称里出现了这个标签的关键词",
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
for (const binding of repository.listAllFolderTagBindings()) {
|
|
671
|
+
const tag = tagById.get(binding.tagId);
|
|
672
|
+
if (!tag) {
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
const relationScore = scoreFolderContext(target.kind, target.path, binding.folderPath);
|
|
676
|
+
if (relationScore <= 0) {
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
setTagRecommendation(candidates, tag, {
|
|
680
|
+
score: relationScore,
|
|
681
|
+
reason: "folder_context",
|
|
682
|
+
evidence: binding.folderPath === "."
|
|
683
|
+
? "根目录已经配置过这个标签"
|
|
684
|
+
: `相关文件夹“${binding.folderPath}”已经配置过这个标签`,
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
const rulesByTagId = new Map();
|
|
688
|
+
for (const rule of repository.listAllEnabledTagRules()) {
|
|
689
|
+
const rules = rulesByTagId.get(rule.tagId) ?? [];
|
|
690
|
+
rules.push(rule);
|
|
691
|
+
rulesByTagId.set(rule.tagId, rules);
|
|
692
|
+
}
|
|
693
|
+
for (const [tagId, rules] of rulesByTagId) {
|
|
694
|
+
const tag = tagById.get(tagId);
|
|
695
|
+
const matchedRule = tag ? resolveMatchedRecommendationRule(target, rules) : null;
|
|
696
|
+
if (!tag || !matchedRule) {
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
setTagRecommendation(candidates, tag, {
|
|
700
|
+
score: 82,
|
|
701
|
+
reason: "smart_rule",
|
|
702
|
+
evidence: resolveRecommendationRuleEvidence(matchedRule),
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
if (target.kind === "document" && target.modifiedAt) {
|
|
706
|
+
const timeScore = scoreRecentModifiedAt(target.modifiedAt);
|
|
707
|
+
if (timeScore > 0) {
|
|
708
|
+
for (const tag of definitions) {
|
|
709
|
+
if (!isTimeLikeBusinessTag(tag)) {
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
setTagRecommendation(candidates, tag, {
|
|
713
|
+
score: timeScore,
|
|
714
|
+
reason: "time_pattern",
|
|
715
|
+
evidence: "最近修改时间和这个标签有关",
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
return [...candidates.values()]
|
|
721
|
+
.map(item => ({
|
|
722
|
+
...item,
|
|
723
|
+
score: Math.min(100, item.score + Math.min(8, Math.log2((countByPath.get(item.path) ?? 0) + 1) * 1.5)),
|
|
724
|
+
}))
|
|
725
|
+
.sort((left, right) => right.score - left.score
|
|
726
|
+
|| left.path.localeCompare(right.path, "zh-Hans-CN"))
|
|
727
|
+
.slice(0, 8)
|
|
728
|
+
.map(item => ({ ...item, score: Number(item.score.toFixed(2)) }));
|
|
729
|
+
}
|
|
581
730
|
}
|
|
582
731
|
function isDescendantTag(definitions, candidateId, ancestorId) {
|
|
583
732
|
let current = definitions.find(item => item.id === candidateId) ?? null;
|
|
@@ -677,4 +826,419 @@ function normalizeTagRulesInput(rules) {
|
|
|
677
826
|
}))
|
|
678
827
|
.sort((left, right) => left.priority - right.priority);
|
|
679
828
|
}
|
|
829
|
+
function isBusinessTagDefinition(tag) {
|
|
830
|
+
if (tag.status === "disabled") {
|
|
831
|
+
return false;
|
|
832
|
+
}
|
|
833
|
+
const rootType = tag.rootType.trim().toLowerCase();
|
|
834
|
+
return rootType !== "类型" && rootType !== "type" && rootType !== "时间" && rootType !== "time";
|
|
835
|
+
}
|
|
836
|
+
function buildRecommendationTargetText(targetPath, title) {
|
|
837
|
+
return buildSearchableRecommendationText([
|
|
838
|
+
targetPath,
|
|
839
|
+
path.posix.basename(targetPath),
|
|
840
|
+
title,
|
|
841
|
+
targetPath.split(/[\/._\-\s]+/g).join(" "),
|
|
842
|
+
]);
|
|
843
|
+
}
|
|
844
|
+
function normalizeRecommendationText(value) {
|
|
845
|
+
return value
|
|
846
|
+
.trim()
|
|
847
|
+
.toLowerCase()
|
|
848
|
+
.replace(/[\\/_\-–—.()[\]{}【】()]+/g, " ")
|
|
849
|
+
.replace(/\s+/g, " ");
|
|
850
|
+
}
|
|
851
|
+
function buildSearchableRecommendationText(parts) {
|
|
852
|
+
const values = new Set();
|
|
853
|
+
for (const part of parts) {
|
|
854
|
+
const normalized = normalizeRecommendationText(part);
|
|
855
|
+
const compact = compactRecommendationText(part);
|
|
856
|
+
const stripped = stripMeaninglessRecommendationWords(compact);
|
|
857
|
+
if (normalized) {
|
|
858
|
+
values.add(normalized);
|
|
859
|
+
}
|
|
860
|
+
if (compact) {
|
|
861
|
+
values.add(compact);
|
|
862
|
+
}
|
|
863
|
+
if (stripped) {
|
|
864
|
+
values.add(stripped);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
return [...values].join(" ");
|
|
868
|
+
}
|
|
869
|
+
function scoreTagNameMatch(tag, targetText) {
|
|
870
|
+
const tokens = splitRecommendationTokens(targetText);
|
|
871
|
+
const tokenSet = new Set(tokens);
|
|
872
|
+
const segments = tag.path.split("/").map(normalizeRecommendationText).filter((segment) => isUsefulRecommendationToken(segment));
|
|
873
|
+
const tagName = normalizeRecommendationText(tag.name);
|
|
874
|
+
const tagPath = normalizeRecommendationText(tag.path);
|
|
875
|
+
const tagNameTokens = splitRecommendationTokens(tagName).filter(isUsefulRecommendationToken);
|
|
876
|
+
const tagMatchTexts = buildTagMatchTexts(tag);
|
|
877
|
+
let score = 0;
|
|
878
|
+
if (tagName && isUsefulRecommendationToken(tagName) && tokenSet.has(tagName)) {
|
|
879
|
+
score = Math.max(score, 90);
|
|
880
|
+
}
|
|
881
|
+
if (tagName && isUsefulRecommendationToken(tagName) && tokens.some(token => token.length > tagName.length && token.includes(tagName))) {
|
|
882
|
+
score = Math.max(score, 86);
|
|
883
|
+
}
|
|
884
|
+
if (tagPath && targetText.includes(tagPath)) {
|
|
885
|
+
score = Math.max(score, 94);
|
|
886
|
+
}
|
|
887
|
+
for (const tagText of tagMatchTexts) {
|
|
888
|
+
const overlapLength = findLongestCommonChineseTextLength(tagText, targetText);
|
|
889
|
+
if (overlapLength >= MIN_RECOMMENDATION_OVERLAP_LENGTH) {
|
|
890
|
+
score = Math.max(score, scoreTextOverlap(overlapLength, tagText.length));
|
|
891
|
+
continue;
|
|
892
|
+
}
|
|
893
|
+
const bestSimilarity = Math.max(0, ...tokens.map(token => similarityRatio(tagText, stripMeaninglessRecommendationWords(token))));
|
|
894
|
+
if (tagText.length >= 4 && bestSimilarity >= 0.88) {
|
|
895
|
+
score = Math.max(score, 76 + Math.round((bestSimilarity - 0.88) * 70));
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
const matchedSegments = segments.filter(segment => tokenSet.has(segment));
|
|
899
|
+
if (matchedSegments.length >= 2) {
|
|
900
|
+
score = Math.max(score, 84 + matchedSegments.length * 3);
|
|
901
|
+
}
|
|
902
|
+
const matchedNameTokens = tagNameTokens.filter(token => tokenSet.has(token));
|
|
903
|
+
if (tagNameTokens.length >= 2 && matchedNameTokens.length === tagNameTokens.length) {
|
|
904
|
+
score = Math.max(score, 88);
|
|
905
|
+
}
|
|
906
|
+
if (score === 0 && tagName.length >= 3) {
|
|
907
|
+
const bestSimilarity = Math.max(0, ...tokens.map(token => similarityRatio(tagName, token)));
|
|
908
|
+
if (bestSimilarity >= 0.86) {
|
|
909
|
+
score = Math.max(score, 78 + Math.round((bestSimilarity - 0.86) * 60));
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
return Math.min(score, 94);
|
|
913
|
+
}
|
|
914
|
+
function buildTagMatchTexts(tag) {
|
|
915
|
+
const rawNames = [
|
|
916
|
+
tag.name,
|
|
917
|
+
path.posix.basename(tag.path),
|
|
918
|
+
];
|
|
919
|
+
const candidates = new Set();
|
|
920
|
+
for (const rawName of rawNames) {
|
|
921
|
+
const compact = compactRecommendationText(rawName);
|
|
922
|
+
const stripped = stripMeaninglessRecommendationWords(compact);
|
|
923
|
+
for (const candidate of [compact, stripped]) {
|
|
924
|
+
if (isUsefulTagMatchText(candidate)) {
|
|
925
|
+
candidates.add(candidate);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
return [...candidates].sort((left, right) => right.length - left.length);
|
|
930
|
+
}
|
|
931
|
+
function compactRecommendationText(value) {
|
|
932
|
+
return normalizeRecommendationText(value).replace(/\s+/g, "");
|
|
933
|
+
}
|
|
934
|
+
function stripMeaninglessRecommendationWords(value) {
|
|
935
|
+
let result = value;
|
|
936
|
+
let changed = true;
|
|
937
|
+
while (changed) {
|
|
938
|
+
changed = false;
|
|
939
|
+
for (const word of MEANINGLESS_RECOMMENDATION_WORDS) {
|
|
940
|
+
if (word && result.includes(word)) {
|
|
941
|
+
result = result.replaceAll(word, "");
|
|
942
|
+
changed = true;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
return result;
|
|
947
|
+
}
|
|
948
|
+
function isUsefulTagMatchText(value) {
|
|
949
|
+
if (value.length < MIN_RECOMMENDATION_OVERLAP_LENGTH) {
|
|
950
|
+
return false;
|
|
951
|
+
}
|
|
952
|
+
if (GENERIC_RECOMMENDATION_TOKENS.has(value)) {
|
|
953
|
+
return false;
|
|
954
|
+
}
|
|
955
|
+
return !MEANINGLESS_RECOMMENDATION_WORDS.includes(value);
|
|
956
|
+
}
|
|
957
|
+
function findLongestCommonChineseTextLength(left, right) {
|
|
958
|
+
const leftText = compactRecommendationText(left);
|
|
959
|
+
const rightText = compactRecommendationText(right);
|
|
960
|
+
const maxLength = Math.min(leftText.length, rightText.length);
|
|
961
|
+
for (let length = maxLength; length >= MIN_RECOMMENDATION_OVERLAP_LENGTH; length -= 1) {
|
|
962
|
+
for (let index = 0; index + length <= leftText.length; index += 1) {
|
|
963
|
+
const fragment = leftText.slice(index, index + length);
|
|
964
|
+
if (isUsefulTagMatchText(fragment) && rightText.includes(fragment)) {
|
|
965
|
+
return length;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return 0;
|
|
970
|
+
}
|
|
971
|
+
function scoreTextOverlap(overlapLength, tagTextLength) {
|
|
972
|
+
const coverage = tagTextLength > 0 ? overlapLength / tagTextLength : 0;
|
|
973
|
+
if (overlapLength >= 6 || coverage >= 0.72) {
|
|
974
|
+
return 92;
|
|
975
|
+
}
|
|
976
|
+
if (overlapLength >= 4 || coverage >= 0.56) {
|
|
977
|
+
return 86;
|
|
978
|
+
}
|
|
979
|
+
return 80;
|
|
980
|
+
}
|
|
981
|
+
function splitRecommendationTokens(value) {
|
|
982
|
+
return value
|
|
983
|
+
.split(/\s+/g)
|
|
984
|
+
.map(token => token.trim())
|
|
985
|
+
.filter(Boolean);
|
|
986
|
+
}
|
|
987
|
+
function isUsefulRecommendationToken(value) {
|
|
988
|
+
const token = value.trim().toLowerCase();
|
|
989
|
+
if (token.length < 2) {
|
|
990
|
+
return false;
|
|
991
|
+
}
|
|
992
|
+
return !GENERIC_RECOMMENDATION_TOKENS.has(token);
|
|
993
|
+
}
|
|
994
|
+
const GENERIC_RECOMMENDATION_TOKENS = new Set([
|
|
995
|
+
"文档",
|
|
996
|
+
"文件",
|
|
997
|
+
"资料",
|
|
998
|
+
"附件",
|
|
999
|
+
"其他",
|
|
1000
|
+
"相关",
|
|
1001
|
+
"临时",
|
|
1002
|
+
"新建",
|
|
1003
|
+
"默认",
|
|
1004
|
+
"document",
|
|
1005
|
+
"documents",
|
|
1006
|
+
"file",
|
|
1007
|
+
"files",
|
|
1008
|
+
"other",
|
|
1009
|
+
"misc",
|
|
1010
|
+
"temp",
|
|
1011
|
+
"有限公司",
|
|
1012
|
+
"有限责任公司",
|
|
1013
|
+
"股份有限公司",
|
|
1014
|
+
"集团有限公司",
|
|
1015
|
+
"公司",
|
|
1016
|
+
"集团",
|
|
1017
|
+
]);
|
|
1018
|
+
const MEANINGLESS_RECOMMENDATION_WORDS = [
|
|
1019
|
+
"集团有限公司",
|
|
1020
|
+
"股份有限公司",
|
|
1021
|
+
"有限责任公司",
|
|
1022
|
+
"有限公司",
|
|
1023
|
+
"集团公司",
|
|
1024
|
+
"总公司",
|
|
1025
|
+
"分公司",
|
|
1026
|
+
"公司",
|
|
1027
|
+
"集团",
|
|
1028
|
+
"co.,ltd",
|
|
1029
|
+
"coltd",
|
|
1030
|
+
"ltd",
|
|
1031
|
+
"inc",
|
|
1032
|
+
"llc",
|
|
1033
|
+
"corp",
|
|
1034
|
+
"corporation",
|
|
1035
|
+
"company",
|
|
1036
|
+
"采购",
|
|
1037
|
+
"服务",
|
|
1038
|
+
"管理",
|
|
1039
|
+
"建设",
|
|
1040
|
+
];
|
|
1041
|
+
const MIN_RECOMMENDATION_OVERLAP_LENGTH = 3;
|
|
1042
|
+
function similarityRatio(left, right) {
|
|
1043
|
+
if (!left || !right) {
|
|
1044
|
+
return 0;
|
|
1045
|
+
}
|
|
1046
|
+
if (left === right) {
|
|
1047
|
+
return 1;
|
|
1048
|
+
}
|
|
1049
|
+
const maxLength = Math.max(left.length, right.length);
|
|
1050
|
+
if (maxLength === 0) {
|
|
1051
|
+
return 1;
|
|
1052
|
+
}
|
|
1053
|
+
const distance = levenshteinDistance(left, right);
|
|
1054
|
+
return (maxLength - distance) / maxLength;
|
|
1055
|
+
}
|
|
1056
|
+
function levenshteinDistance(left, right) {
|
|
1057
|
+
const previous = Array.from({ length: right.length + 1 }, (_, index) => index);
|
|
1058
|
+
const current = Array.from({ length: right.length + 1 }, () => 0);
|
|
1059
|
+
for (let i = 1; i <= left.length; i += 1) {
|
|
1060
|
+
current[0] = i;
|
|
1061
|
+
for (let j = 1; j <= right.length; j += 1) {
|
|
1062
|
+
const substitutionCost = left[i - 1] === right[j - 1] ? 0 : 1;
|
|
1063
|
+
current[j] = Math.min(current[j - 1] + 1, previous[j] + 1, previous[j - 1] + substitutionCost);
|
|
1064
|
+
}
|
|
1065
|
+
for (let j = 0; j < previous.length; j += 1) {
|
|
1066
|
+
previous[j] = current[j];
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
return previous[right.length] ?? 0;
|
|
1070
|
+
}
|
|
1071
|
+
function setTagRecommendation(target, tag, input) {
|
|
1072
|
+
const current = target.get(tag.id);
|
|
1073
|
+
if (current && current.score > input.score) {
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
target.set(tag.id, {
|
|
1077
|
+
tagId: tag.id,
|
|
1078
|
+
path: tag.path,
|
|
1079
|
+
name: tag.name,
|
|
1080
|
+
score: input.score,
|
|
1081
|
+
reason: input.reason,
|
|
1082
|
+
evidence: input.evidence,
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
function scoreFolderContext(targetKind, targetPath, bindingFolderPath) {
|
|
1086
|
+
const targetFolderPath = targetKind === "document"
|
|
1087
|
+
? normalizeFolderPath(targetPath.includes("/") ? path.posix.dirname(targetPath) : ".")
|
|
1088
|
+
: normalizeFolderPath(targetPath);
|
|
1089
|
+
const bindingPath = normalizeFolderPath(bindingFolderPath);
|
|
1090
|
+
if (bindingPath === ".") {
|
|
1091
|
+
return 0;
|
|
1092
|
+
}
|
|
1093
|
+
if (bindingPath === targetFolderPath) {
|
|
1094
|
+
return 86;
|
|
1095
|
+
}
|
|
1096
|
+
if (targetFolderPath.startsWith(`${bindingPath}/`)) {
|
|
1097
|
+
return 80;
|
|
1098
|
+
}
|
|
1099
|
+
const parentPath = normalizeFolderPath(path.posix.dirname(targetFolderPath));
|
|
1100
|
+
if (bindingPath === parentPath) {
|
|
1101
|
+
return 76;
|
|
1102
|
+
}
|
|
1103
|
+
if (parentPath !== "." && path.posix.dirname(bindingPath) === parentPath && areSiblingFolderNamesRelated(targetFolderPath, bindingPath)) {
|
|
1104
|
+
return 72;
|
|
1105
|
+
}
|
|
1106
|
+
return 0;
|
|
1107
|
+
}
|
|
1108
|
+
function areSiblingFolderNamesRelated(leftPath, rightPath) {
|
|
1109
|
+
const leftName = normalizeRecommendationText(path.posix.basename(leftPath));
|
|
1110
|
+
const rightName = normalizeRecommendationText(path.posix.basename(rightPath));
|
|
1111
|
+
if (!leftName || !rightName) {
|
|
1112
|
+
return false;
|
|
1113
|
+
}
|
|
1114
|
+
const leftTokens = splitRecommendationTokens(leftName).filter(isUsefulRecommendationToken);
|
|
1115
|
+
const rightTokens = splitRecommendationTokens(rightName).filter(isUsefulRecommendationToken);
|
|
1116
|
+
if (leftTokens.some(token => rightTokens.includes(token))) {
|
|
1117
|
+
return true;
|
|
1118
|
+
}
|
|
1119
|
+
return similarityRatio(leftName, rightName) >= 0.82;
|
|
1120
|
+
}
|
|
1121
|
+
function matchesRecommendationRule(target, rule) {
|
|
1122
|
+
switch (rule.ruleType) {
|
|
1123
|
+
case "file_name_contains": {
|
|
1124
|
+
const keyword = String(rule.matcher.keyword ?? "").trim().toLowerCase();
|
|
1125
|
+
return keyword.length > 0 && path.posix.basename(target.path).toLowerCase().includes(keyword);
|
|
1126
|
+
}
|
|
1127
|
+
case "file_content_contains": {
|
|
1128
|
+
const keyword = String(rule.matcher.keyword ?? "").trim().toLowerCase();
|
|
1129
|
+
const text = `${target.title}\n${target.path}`.toLowerCase();
|
|
1130
|
+
return keyword.length > 0 && text.includes(keyword);
|
|
1131
|
+
}
|
|
1132
|
+
case "file_extension_in": {
|
|
1133
|
+
if (target.kind !== "document") {
|
|
1134
|
+
return false;
|
|
1135
|
+
}
|
|
1136
|
+
const rawExtensions = Array.isArray(rule.matcher.extensions)
|
|
1137
|
+
? rule.matcher.extensions ?? []
|
|
1138
|
+
: [];
|
|
1139
|
+
const extensions = rawExtensions
|
|
1140
|
+
.map(item => item.trim().toLowerCase())
|
|
1141
|
+
.filter(Boolean)
|
|
1142
|
+
.map(item => item.startsWith(".") ? item : `.${item}`);
|
|
1143
|
+
return Boolean(target.extension) && extensions.includes(String(target.extension).toLowerCase());
|
|
1144
|
+
}
|
|
1145
|
+
case "modified_time_between": {
|
|
1146
|
+
if (target.kind !== "document" || !target.modifiedAt) {
|
|
1147
|
+
return false;
|
|
1148
|
+
}
|
|
1149
|
+
const matcher = rule.matcher;
|
|
1150
|
+
const modifiedAt = new Date(target.modifiedAt).getTime();
|
|
1151
|
+
if (Number.isNaN(modifiedAt)) {
|
|
1152
|
+
return false;
|
|
1153
|
+
}
|
|
1154
|
+
const startTime = matcher.start ? new Date(matcher.start).getTime() : null;
|
|
1155
|
+
const endTime = matcher.end ? new Date(matcher.end).getTime() : null;
|
|
1156
|
+
if (startTime !== null && (Number.isNaN(startTime) || modifiedAt < startTime)) {
|
|
1157
|
+
return false;
|
|
1158
|
+
}
|
|
1159
|
+
if (endTime !== null && (Number.isNaN(endTime) || modifiedAt > endTime)) {
|
|
1160
|
+
return false;
|
|
1161
|
+
}
|
|
1162
|
+
return startTime !== null || endTime !== null;
|
|
1163
|
+
}
|
|
1164
|
+
case "document_path_in_folder": {
|
|
1165
|
+
const folderPath = normalizeFolderPath(rule.matcher.folderPath ?? "");
|
|
1166
|
+
return matchesPathInFolderScope(target.path, folderPath);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
function resolveMatchedRecommendationRule(target, rules) {
|
|
1171
|
+
const sortedRules = [...rules].sort((left, right) => left.priority - right.priority);
|
|
1172
|
+
const matchedAnd = [];
|
|
1173
|
+
const matchedOr = [];
|
|
1174
|
+
let hasOrRule = false;
|
|
1175
|
+
for (const rule of sortedRules) {
|
|
1176
|
+
const matched = matchesRecommendationRule(target, rule);
|
|
1177
|
+
if (rule.relation === "not") {
|
|
1178
|
+
if (matched) {
|
|
1179
|
+
return null;
|
|
1180
|
+
}
|
|
1181
|
+
continue;
|
|
1182
|
+
}
|
|
1183
|
+
if (rule.relation === "or") {
|
|
1184
|
+
hasOrRule = true;
|
|
1185
|
+
if (matched) {
|
|
1186
|
+
matchedOr.push(rule);
|
|
1187
|
+
}
|
|
1188
|
+
continue;
|
|
1189
|
+
}
|
|
1190
|
+
if (!matched) {
|
|
1191
|
+
return null;
|
|
1192
|
+
}
|
|
1193
|
+
matchedAnd.push(rule);
|
|
1194
|
+
}
|
|
1195
|
+
if (hasOrRule && matchedOr.length === 0) {
|
|
1196
|
+
return null;
|
|
1197
|
+
}
|
|
1198
|
+
return matchedAnd[0] ?? matchedOr[0] ?? null;
|
|
1199
|
+
}
|
|
1200
|
+
function resolveRecommendationRuleEvidence(rule) {
|
|
1201
|
+
switch (rule.ruleType) {
|
|
1202
|
+
case "file_name_contains":
|
|
1203
|
+
return `智能规则:文件名包含“${String(rule.matcher.keyword ?? "").trim()}”`;
|
|
1204
|
+
case "file_content_contains":
|
|
1205
|
+
return `智能规则:标题、路径或内容包含“${String(rule.matcher.keyword ?? "").trim()}”`;
|
|
1206
|
+
case "file_extension_in": {
|
|
1207
|
+
const extensions = Array.isArray(rule.matcher.extensions)
|
|
1208
|
+
? rule.matcher.extensions ?? []
|
|
1209
|
+
: [];
|
|
1210
|
+
return `智能规则:文件类型命中 ${extensions.join("、")}`;
|
|
1211
|
+
}
|
|
1212
|
+
case "modified_time_between":
|
|
1213
|
+
return "智能规则:修改时间命中";
|
|
1214
|
+
case "document_path_in_folder": {
|
|
1215
|
+
const folderPath = normalizeFolderPath(rule.matcher.folderPath ?? "");
|
|
1216
|
+
return folderPath === "." ? "智能规则:位于根目录下" : `智能规则:位于“${folderPath}”下`;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
function matchesPathInFolderScope(targetPath, folderPath) {
|
|
1221
|
+
if (folderPath === ".") {
|
|
1222
|
+
return true;
|
|
1223
|
+
}
|
|
1224
|
+
return targetPath === folderPath || targetPath.startsWith(`${folderPath}/`);
|
|
1225
|
+
}
|
|
1226
|
+
function scoreRecentModifiedAt(modifiedAt) {
|
|
1227
|
+
const time = new Date(modifiedAt).getTime();
|
|
1228
|
+
if (Number.isNaN(time)) {
|
|
1229
|
+
return 0;
|
|
1230
|
+
}
|
|
1231
|
+
const dayDistance = Math.floor((Date.now() - time) / 86400000);
|
|
1232
|
+
if (dayDistance <= 7) {
|
|
1233
|
+
return 54;
|
|
1234
|
+
}
|
|
1235
|
+
if (dayDistance <= 30) {
|
|
1236
|
+
return 44;
|
|
1237
|
+
}
|
|
1238
|
+
return 0;
|
|
1239
|
+
}
|
|
1240
|
+
function isTimeLikeBusinessTag(tag) {
|
|
1241
|
+
const text = `${tag.path}/${tag.name}`.toLowerCase();
|
|
1242
|
+
return /最近|近期|本周|本月|待处理|跟进|urgent|recent|week|month|todo|follow/.test(text);
|
|
1243
|
+
}
|
|
680
1244
|
//# sourceMappingURL=affairs-tag-service.js.map
|