autosnippet 3.0.0 → 3.0.2

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.
Files changed (290) hide show
  1. package/README.md +230 -324
  2. package/bin/api-server.js +1 -1
  3. package/bin/cli.js +204 -244
  4. package/bin/mcp-server.js +5 -3
  5. package/config/knowledge-base.config.js +132 -132
  6. package/dashboard/dist/assets/{icons-CEfgGaZi.js → icons-Cdq22n2i.js} +95 -100
  7. package/dashboard/dist/assets/index-ClkyPkDX.js +133 -0
  8. package/dashboard/dist/assets/index-t4QrJwv1.css +1 -0
  9. package/dashboard/dist/index.html +3 -3
  10. package/lib/bootstrap.js +8 -8
  11. package/lib/cli/AiScanService.js +86 -40
  12. package/lib/cli/KnowledgeSyncService.js +113 -74
  13. package/lib/cli/SetupService.js +439 -277
  14. package/lib/cli/UpgradeService.js +63 -100
  15. package/lib/core/AstAnalyzer.js +276 -597
  16. package/lib/core/ast/ProjectGraph.js +101 -40
  17. package/lib/core/ast/ensure-grammars.js +232 -0
  18. package/lib/core/ast/index.js +115 -0
  19. package/lib/core/ast/lang-dart.js +661 -0
  20. package/lib/core/ast/lang-go.js +530 -0
  21. package/lib/core/ast/lang-java.js +435 -0
  22. package/lib/core/ast/lang-javascript.js +272 -0
  23. package/lib/core/ast/lang-kotlin.js +423 -0
  24. package/lib/core/ast/lang-objc.js +388 -0
  25. package/lib/core/ast/lang-python.js +371 -0
  26. package/lib/core/ast/lang-swift.js +337 -0
  27. package/lib/core/ast/lang-typescript.js +503 -0
  28. package/lib/core/capability/CapabilityProbe.js +18 -9
  29. package/lib/core/constitution/Constitution.js +2 -3
  30. package/lib/core/constitution/ConstitutionValidator.js +65 -24
  31. package/lib/core/discovery/DartDiscoverer.js +534 -0
  32. package/lib/core/discovery/DiscovererRegistry.js +83 -0
  33. package/lib/core/discovery/GenericDiscoverer.js +225 -0
  34. package/lib/core/discovery/GoDiscoverer.js +541 -0
  35. package/lib/core/discovery/JvmDiscoverer.js +506 -0
  36. package/lib/core/discovery/NodeDiscoverer.js +466 -0
  37. package/lib/core/discovery/ProjectDiscoverer.js +93 -0
  38. package/lib/core/discovery/PythonDiscoverer.js +338 -0
  39. package/lib/core/discovery/SpmDiscoverer.js +5 -0
  40. package/lib/core/discovery/index.js +53 -0
  41. package/lib/core/enhancement/EnhancementPack.js +71 -0
  42. package/lib/core/enhancement/EnhancementRegistry.js +47 -0
  43. package/lib/core/enhancement/android-enhancement.js +102 -0
  44. package/lib/core/enhancement/django-enhancement.js +70 -0
  45. package/lib/core/enhancement/fastapi-enhancement.js +63 -0
  46. package/lib/core/enhancement/go-grpc-enhancement.js +152 -0
  47. package/lib/core/enhancement/go-web-enhancement.js +201 -0
  48. package/lib/core/enhancement/index.js +65 -0
  49. package/lib/core/enhancement/node-server-enhancement.js +88 -0
  50. package/lib/core/enhancement/react-enhancement.js +86 -0
  51. package/lib/core/enhancement/spring-enhancement.js +112 -0
  52. package/lib/core/enhancement/vue-enhancement.js +96 -0
  53. package/lib/core/gateway/Gateway.js +8 -9
  54. package/lib/core/gateway/GatewayActionRegistry.js +1 -1
  55. package/lib/core/permission/PermissionManager.js +12 -8
  56. package/lib/domain/index.js +13 -9
  57. package/lib/domain/knowledge/KnowledgeEntry.js +111 -101
  58. package/lib/domain/knowledge/KnowledgeRepository.js +0 -1
  59. package/lib/domain/knowledge/Lifecycle.js +22 -22
  60. package/lib/domain/knowledge/index.js +9 -12
  61. package/lib/domain/knowledge/values/Constraints.js +31 -21
  62. package/lib/domain/knowledge/values/Content.js +21 -13
  63. package/lib/domain/knowledge/values/Quality.js +31 -18
  64. package/lib/domain/knowledge/values/Reasoning.js +20 -12
  65. package/lib/domain/knowledge/values/Relations.js +37 -25
  66. package/lib/domain/knowledge/values/Stats.js +18 -12
  67. package/lib/domain/knowledge/values/index.js +4 -3
  68. package/lib/domain/snippet/Snippet.js +35 -10
  69. package/lib/external/ai/AiFactory.js +48 -16
  70. package/lib/external/ai/AiProvider.js +184 -90
  71. package/lib/external/ai/providers/ClaudeProvider.js +25 -12
  72. package/lib/external/ai/providers/GoogleGeminiProvider.js +59 -30
  73. package/lib/external/ai/providers/MockProvider.js +9 -3
  74. package/lib/external/ai/providers/OpenAiProvider.js +51 -29
  75. package/lib/external/mcp/McpServer.js +66 -36
  76. package/lib/external/mcp/errorHandler.js +23 -11
  77. package/lib/external/mcp/handlers/LanguageExtensions.js +138 -53
  78. package/lib/external/mcp/handlers/TargetClassifier.js +52 -16
  79. package/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +81 -20
  80. package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +71 -42
  81. package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +9 -17
  82. package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +14 -9
  83. package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +15 -7
  84. package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +352 -153
  85. package/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +52 -12
  86. package/lib/external/mcp/handlers/bootstrap/skills.js +143 -39
  87. package/lib/external/mcp/handlers/bootstrap.js +691 -168
  88. package/lib/external/mcp/handlers/browse.js +66 -22
  89. package/lib/external/mcp/handlers/candidate.js +118 -35
  90. package/lib/external/mcp/handlers/consolidated.js +49 -17
  91. package/lib/external/mcp/handlers/guard.js +104 -39
  92. package/lib/external/mcp/handlers/knowledge.js +60 -36
  93. package/lib/external/mcp/handlers/search.js +43 -14
  94. package/lib/external/mcp/handlers/skill.js +120 -45
  95. package/lib/external/mcp/handlers/structure.js +240 -86
  96. package/lib/external/mcp/handlers/system.js +42 -12
  97. package/lib/external/mcp/handlers/wiki.js +58 -33
  98. package/lib/external/mcp/tools.js +306 -123
  99. package/lib/http/HttpServer.js +72 -47
  100. package/lib/http/middleware/RateLimiter.js +5 -3
  101. package/lib/http/middleware/errorHandler.js +6 -1
  102. package/lib/http/middleware/requestLogger.js +14 -3
  103. package/lib/http/middleware/roleResolver.js +30 -23
  104. package/lib/http/routes/ai.js +387 -265
  105. package/lib/http/routes/auth.js +81 -61
  106. package/lib/http/routes/candidates.js +430 -320
  107. package/lib/http/routes/commands.js +289 -189
  108. package/lib/http/routes/extract.js +158 -125
  109. package/lib/http/routes/guardRules.js +309 -217
  110. package/lib/http/routes/knowledge.js +213 -154
  111. package/lib/http/routes/modules.js +578 -0
  112. package/lib/http/routes/monitoring.js +6 -6
  113. package/lib/http/routes/recipes.js +104 -93
  114. package/lib/http/routes/search.js +361 -305
  115. package/lib/http/routes/skills.js +145 -98
  116. package/lib/http/routes/snippets.js +42 -30
  117. package/lib/http/routes/spm.js +3 -405
  118. package/lib/http/routes/violations.js +113 -93
  119. package/lib/http/routes/wiki.js +211 -170
  120. package/lib/http/utils/routeHelpers.js +3 -1
  121. package/lib/http/utils/sse-sessions.js +16 -6
  122. package/lib/http/utils/sse.js +15 -5
  123. package/lib/infrastructure/audit/AuditLogger.js +5 -2
  124. package/lib/infrastructure/audit/AuditStore.js +10 -7
  125. package/lib/infrastructure/cache/CacheService.js +3 -1
  126. package/lib/infrastructure/cache/GraphCache.js +8 -4
  127. package/lib/infrastructure/cache/UnifiedCacheAdapter.js +1 -1
  128. package/lib/infrastructure/config/ConfigLoader.js +9 -5
  129. package/lib/infrastructure/config/Defaults.js +30 -10
  130. package/lib/infrastructure/config/Paths.js +28 -8
  131. package/lib/infrastructure/config/TriggerSymbol.js +22 -10
  132. package/lib/infrastructure/database/DatabaseConnection.js +15 -10
  133. package/lib/infrastructure/database/migrations/001_initial_schema.js +0 -1
  134. package/lib/infrastructure/external/ClipboardManager.js +6 -2
  135. package/lib/infrastructure/external/NativeUi.js +50 -43
  136. package/lib/infrastructure/external/OpenBrowser.js +14 -17
  137. package/lib/infrastructure/external/XcodeAutomation.js +14 -258
  138. package/lib/infrastructure/logging/Logger.js +46 -30
  139. package/lib/infrastructure/monitoring/ErrorTracker.js +7 -5
  140. package/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -4
  141. package/lib/infrastructure/paths/HeaderResolver.js +25 -9
  142. package/lib/infrastructure/paths/PathFinder.js +34 -12
  143. package/lib/infrastructure/plugin/PluginManager.js +26 -8
  144. package/lib/infrastructure/realtime/RealtimeService.js +2 -2
  145. package/lib/infrastructure/vector/Chunker.js +22 -7
  146. package/lib/infrastructure/vector/IndexingPipeline.js +46 -22
  147. package/lib/infrastructure/vector/JsonVectorAdapter.js +90 -53
  148. package/lib/infrastructure/vector/VectorStore.js +28 -10
  149. package/lib/injection/ServiceContainer.js +247 -93
  150. package/lib/platform/ios/index.js +63 -0
  151. package/lib/platform/ios/routes/spm.js +437 -0
  152. package/lib/platform/ios/snippet/PlaceholderConverter.js +55 -0
  153. package/lib/platform/ios/snippet/XcodeCodec.js +112 -0
  154. package/lib/{service → platform/ios}/spm/DependencyGraph.js +41 -17
  155. package/lib/{service → platform/ios}/spm/PackageSwiftParser.js +41 -14
  156. package/lib/{service → platform/ios}/spm/PolicyEngine.js +9 -4
  157. package/lib/platform/ios/spm/SpmDiscoverer.js +122 -0
  158. package/lib/{service → platform/ios}/spm/SpmService.js +385 -127
  159. package/lib/{service/automation → platform/ios/xcode}/SaveEventFilter.js +8 -7
  160. package/lib/platform/ios/xcode/XcodeAutomation.js +350 -0
  161. package/lib/{service/automation → platform/ios/xcode}/XcodeIntegration.js +325 -145
  162. package/lib/repository/base/BaseRepository.js +7 -9
  163. package/lib/repository/knowledge/KnowledgeRepository.impl.js +98 -75
  164. package/lib/repository/token/TokenUsageStore.js +4 -2
  165. package/lib/service/automation/ActionPipeline.js +1 -1
  166. package/lib/service/automation/AutomationOrchestrator.js +8 -4
  167. package/lib/service/automation/ContextCollector.js +7 -5
  168. package/lib/service/automation/DirectiveDetector.js +23 -16
  169. package/lib/service/automation/FileWatcher.js +112 -56
  170. package/lib/service/automation/TriggerResolver.js +6 -4
  171. package/lib/service/automation/handlers/AlinkHandler.js +24 -12
  172. package/lib/service/automation/handlers/CreateHandler.js +19 -20
  173. package/lib/service/automation/handlers/DraftHandler.js +14 -8
  174. package/lib/service/automation/handlers/GuardHandler.js +93 -63
  175. package/lib/service/automation/handlers/HeaderHandler.js +1 -6
  176. package/lib/service/automation/handlers/SearchHandler.js +155 -88
  177. package/lib/service/bootstrap/BootstrapTaskManager.js +77 -35
  178. package/lib/service/candidate/SimilarityService.js +25 -9
  179. package/lib/service/chat/AnalystAgent.js +50 -24
  180. package/lib/service/chat/CandidateGuardrail.js +143 -17
  181. package/lib/service/chat/ChatAgent.js +759 -243
  182. package/lib/service/chat/ContextWindow.js +116 -71
  183. package/lib/service/chat/ConversationStore.js +77 -36
  184. package/lib/service/chat/EpisodicConsolidator.js +47 -23
  185. package/lib/service/chat/HandoffProtocol.js +98 -22
  186. package/lib/service/chat/Memory.js +34 -14
  187. package/lib/service/chat/ProducerAgent.js +40 -20
  188. package/lib/service/chat/ProjectSemanticMemory.js +109 -78
  189. package/lib/service/chat/ReasoningLayer.js +148 -70
  190. package/lib/service/chat/ReasoningTrace.js +44 -32
  191. package/lib/service/chat/TaskPipeline.js +39 -19
  192. package/lib/service/chat/ToolRegistry.js +48 -29
  193. package/lib/service/chat/WorkingMemory.js +44 -18
  194. package/lib/service/chat/tools.js +1096 -494
  195. package/lib/service/context/RecipeExtractor.js +132 -51
  196. package/lib/service/cursor/CursorDeliveryPipeline.js +82 -37
  197. package/lib/service/cursor/KnowledgeCompressor.js +25 -22
  198. package/lib/service/cursor/RulesGenerator.js +13 -7
  199. package/lib/service/cursor/SkillsSyncer.js +77 -27
  200. package/lib/service/cursor/TokenBudget.js +2 -2
  201. package/lib/service/cursor/TopicClassifier.js +54 -20
  202. package/lib/service/guard/ComplianceReporter.js +55 -43
  203. package/lib/service/guard/ExclusionManager.js +67 -29
  204. package/lib/service/guard/GuardCheckEngine.js +381 -86
  205. package/lib/service/guard/GuardFeedbackLoop.js +22 -10
  206. package/lib/service/guard/GuardService.js +29 -19
  207. package/lib/service/guard/RuleLearner.js +55 -23
  208. package/lib/service/guard/SourceFileCollector.js +27 -20
  209. package/lib/service/guard/ViolationsStore.js +43 -38
  210. package/lib/service/knowledge/CodeEntityGraph.js +147 -82
  211. package/lib/service/knowledge/ConfidenceRouter.js +12 -10
  212. package/lib/service/knowledge/KnowledgeFileWriter.js +147 -56
  213. package/lib/service/knowledge/KnowledgeGraphService.js +81 -34
  214. package/lib/service/knowledge/KnowledgeService.js +222 -112
  215. package/lib/service/module/ModuleService.js +969 -0
  216. package/lib/service/quality/FeedbackCollector.js +27 -15
  217. package/lib/service/quality/QualityScorer.js +78 -24
  218. package/lib/service/recipe/RecipeCandidateValidator.js +110 -44
  219. package/lib/service/recipe/RecipeParser.js +78 -45
  220. package/lib/service/search/CoarseRanker.js +43 -28
  221. package/lib/service/search/CrossEncoderReranker.js +32 -21
  222. package/lib/service/search/InvertedIndex.js +21 -7
  223. package/lib/service/search/MultiSignalRanker.js +90 -28
  224. package/lib/service/search/RetrievalFunnel.js +45 -24
  225. package/lib/service/search/SearchEngine.js +255 -103
  226. package/lib/service/skills/EventAggregator.js +32 -15
  227. package/lib/service/skills/SignalCollector.js +140 -64
  228. package/lib/service/skills/SkillAdvisor.js +79 -42
  229. package/lib/service/skills/SkillHooks.js +16 -14
  230. package/lib/service/snippet/PlaceholderConverter.js +5 -0
  231. package/lib/service/snippet/SnippetFactory.js +116 -99
  232. package/lib/service/snippet/SnippetInstaller.js +234 -62
  233. package/lib/service/snippet/codecs/SnippetCodec.js +67 -0
  234. package/lib/service/snippet/codecs/VSCodeCodec.js +102 -0
  235. package/lib/service/snippet/codecs/XcodeCodec.js +5 -0
  236. package/lib/service/wiki/WikiGenerator.js +637 -263
  237. package/lib/shared/DimensionCopyRegistry.js +472 -0
  238. package/lib/shared/LanguageService.js +399 -0
  239. package/lib/shared/PathGuard.js +45 -28
  240. package/lib/shared/RecipeReadinessChecker.js +72 -12
  241. package/lib/shared/constants.js +41 -41
  242. package/lib/shared/errors/BaseError.js +2 -2
  243. package/lib/shared/errors/index.js +4 -4
  244. package/lib/shared/similarity.js +25 -8
  245. package/lib/shared/token-utils.js +6 -2
  246. package/lib/shared/utils/common.js +12 -4
  247. package/package.json +49 -13
  248. package/scripts/bench-real-projects.mjs +256 -0
  249. package/scripts/build-native-ui.js +30 -30
  250. package/scripts/clear-old-vector-index.js +5 -35
  251. package/scripts/clear-vector-cache.js +7 -37
  252. package/scripts/collect-test-project-stats.mjs +160 -0
  253. package/scripts/diagnose-mcp.js +41 -32
  254. package/scripts/ensure-parse-package.js +6 -9
  255. package/scripts/generate-recipe-drafts.js +116 -77
  256. package/scripts/init-db.js +3 -20
  257. package/scripts/init-snippets.js +305 -0
  258. package/scripts/init-vector-db.js +173 -170
  259. package/scripts/install-cursor-skill.js +148 -104
  260. package/scripts/install-full.js +8 -21
  261. package/scripts/install-vscode-copilot.js +146 -145
  262. package/scripts/migrate-md-to-knowledge.mjs +139 -151
  263. package/scripts/postinstall-safe.js +5 -17
  264. package/scripts/recipe-audit.js +106 -82
  265. package/scripts/release.js +283 -323
  266. package/scripts/setup-mcp-config.js +60 -52
  267. package/scripts/verify-context-api.js +20 -20
  268. package/skills/autosnippet-analysis/SKILL.md +10 -6
  269. package/skills/autosnippet-candidates/SKILL.md +27 -26
  270. package/skills/autosnippet-coldstart/SKILL.md +555 -38
  271. package/skills/autosnippet-concepts/SKILL.md +349 -337
  272. package/skills/autosnippet-create/SKILL.md +5 -5
  273. package/skills/autosnippet-reference-dart/SKILL.md +543 -0
  274. package/skills/autosnippet-reference-go/SKILL.md +539 -0
  275. package/skills/autosnippet-reference-java/SKILL.md +534 -0
  276. package/skills/autosnippet-reference-jsts/SKILL.md +41 -9
  277. package/skills/autosnippet-reference-kotlin/SKILL.md +526 -0
  278. package/skills/autosnippet-reference-objc/SKILL.md +29 -6
  279. package/skills/autosnippet-reference-python/SKILL.md +800 -0
  280. package/skills/autosnippet-reference-swift/SKILL.md +70 -14
  281. package/skills/autosnippet-structure/SKILL.md +4 -4
  282. package/templates/cursor-rules/autosnippet-conventions.mdc +2 -2
  283. package/templates/recipes-setup/README.md +2 -2
  284. package/templates/recipes-setup/_template.md +1 -1
  285. package/dashboard/dist/assets/index-Bun3ld_J.css +0 -1
  286. package/dashboard/dist/assets/index-_Sk_Dmg3.js +0 -143
  287. package/resources/asd-entry/main.swift +0 -159
  288. package/scripts/build-asd-entry.js +0 -51
  289. package/scripts/init-xcode-snippets.js +0 -311
  290. package/template.json +0 -39
@@ -4,39 +4,40 @@
4
4
  * 集成监控、缓存和错误追踪
5
5
  */
6
6
 
7
- import { join } from 'path';
8
- import express from 'express';
7
+ import { join } from 'node:path';
9
8
  import cors from 'cors';
9
+ import express from 'express';
10
10
  import helmet from 'helmet';
11
+ import { CapabilityProbe } from '../core/capability/CapabilityProbe.js';
12
+ import { registerGatewayActions } from '../core/gateway/GatewayActionRegistry.js';
13
+ import { initCacheAdapter } from '../infrastructure/cache/UnifiedCacheAdapter.js';
11
14
  import Logger from '../infrastructure/logging/Logger.js';
15
+ import { initErrorTracker } from '../infrastructure/monitoring/ErrorTracker.js';
16
+ import { initPerformanceMonitor } from '../infrastructure/monitoring/PerformanceMonitor.js';
17
+ import { initRealtimeService } from '../infrastructure/realtime/RealtimeService.js';
18
+ import { getServiceContainer } from '../injection/ServiceContainer.js';
19
+ import apiSpec from './api-spec.js';
12
20
  import { errorHandler } from './middleware/errorHandler.js';
13
- import { requestLogger } from './middleware/requestLogger.js';
14
21
  import { gatewayMiddleware } from './middleware/gatewayMiddleware.js';
22
+ import { requestLogger } from './middleware/requestLogger.js';
15
23
  import { roleResolverMiddleware } from './middleware/roleResolver.js';
16
- import { CapabilityProbe } from '../core/capability/CapabilityProbe.js';
24
+ import aiRouter from './routes/ai.js';
25
+ import authRouter from './routes/auth.js';
26
+ import candidatesRouter from './routes/candidates.js';
27
+ import commandsRouter from './routes/commands.js';
28
+ import extractRouter from './routes/extract.js';
17
29
  import guardRuleRouter from './routes/guardRules.js';
18
- import searchRouter from './routes/search.js';
19
30
  import healthRouter from './routes/health.js';
31
+ import knowledgeRouter from './routes/knowledge.js';
20
32
  import monitoringRouter from './routes/monitoring.js';
33
+ import recipesRouter from './routes/recipes.js';
34
+ import searchRouter from './routes/search.js';
35
+ import skillsRouter from './routes/skills.js';
21
36
  import snippetRouter from './routes/snippets.js';
22
- import aiRouter from './routes/ai.js';
23
- import extractRouter from './routes/extract.js';
24
- import commandsRouter from './routes/commands.js';
25
37
  import spmRouter from './routes/spm.js';
38
+ import modulesRouter from './routes/modules.js';
26
39
  import violationsRouter from './routes/violations.js';
27
- import authRouter from './routes/auth.js';
28
- import skillsRouter from './routes/skills.js';
29
- import candidatesRouter from './routes/candidates.js';
30
- import knowledgeRouter from './routes/knowledge.js';
31
- import recipesRouter from './routes/recipes.js';
32
40
  import wikiRouter from './routes/wiki.js';
33
- import apiSpec from './api-spec.js';
34
- import { initCacheAdapter } from '../infrastructure/cache/UnifiedCacheAdapter.js';
35
- import { initPerformanceMonitor } from '../infrastructure/monitoring/PerformanceMonitor.js';
36
- import { initErrorTracker } from '../infrastructure/monitoring/ErrorTracker.js';
37
- import { initRealtimeService } from '../infrastructure/realtime/RealtimeService.js';
38
- import { registerGatewayActions } from '../core/gateway/GatewayActionRegistry.js';
39
- import { getServiceContainer } from '../injection/ServiceContainer.js';
40
41
 
41
42
  export class HttpServer {
42
43
  constructor(config = {}) {
@@ -47,7 +48,7 @@ export class HttpServer {
47
48
  cacheMode: 'memory',
48
49
  ...config,
49
50
  };
50
-
51
+
51
52
  this.logger = Logger.getInstance();
52
53
  this.app = express();
53
54
  this.server = null;
@@ -69,10 +70,10 @@ export class HttpServer {
69
70
 
70
71
  // 中间件
71
72
  this.setupMiddleware();
72
-
73
+
73
74
  // 路由
74
75
  this.setupRoutes();
75
-
76
+
76
77
  // 错误处理
77
78
  this.setupErrorHandling();
78
79
 
@@ -124,37 +125,48 @@ export class HttpServer {
124
125
  }
125
126
 
126
127
  // 安全头(放宽 CSP 以兼容 Vite 构建的 Dashboard SPA:script/style 需要内联和 crossorigin)
127
- this.app.use(helmet({
128
- contentSecurityPolicy: {
129
- directives: {
130
- defaultSrc: ["'self'"],
131
- scriptSrc: ["'self'", "'unsafe-inline'"],
132
- styleSrc: ["'self'", "'unsafe-inline'", "https:"],
133
- imgSrc: ["'self'", "data:", "blob:"],
134
- connectSrc: ["'self'", "ws:", "wss:"],
135
- fontSrc: ["'self'", "https:", "data:"],
136
- objectSrc: ["'none'"],
137
- frameSrc: ["'none'"],
128
+ this.app.use(
129
+ helmet({
130
+ contentSecurityPolicy: {
131
+ directives: {
132
+ defaultSrc: ["'self'"],
133
+ scriptSrc: ["'self'", "'unsafe-inline'"],
134
+ styleSrc: ["'self'", "'unsafe-inline'", 'https:'],
135
+ imgSrc: ["'self'", 'data:', 'blob:'],
136
+ connectSrc: ["'self'", 'ws:', 'wss:'],
137
+ fontSrc: ["'self'", 'https:', 'data:'],
138
+ objectSrc: ["'none'"],
139
+ frameSrc: ["'none'"],
140
+ },
138
141
  },
139
- },
140
- }));
142
+ })
143
+ );
141
144
 
142
145
  // 请求日志
143
146
  this.app.use(requestLogger(this.logger));
144
147
 
145
148
  // 解析 JSON 请求体
146
149
  this.app.use(express.json({ limit: '10mb' }));
147
-
150
+
148
151
  // 解析 URL 编码的请求体
149
152
  this.app.use(express.urlencoded({ limit: '10mb', extended: true }));
150
153
 
151
154
  // 跨域处理 (CORS)
152
- this.app.use(cors({
153
- origin: this.config.corsOrigin || '*',
154
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
155
- allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization', 'X-User-Id'],
156
- credentials: true,
157
- }));
155
+ this.app.use(
156
+ cors({
157
+ origin: this.config.corsOrigin || '*',
158
+ methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
159
+ allowedHeaders: [
160
+ 'Origin',
161
+ 'X-Requested-With',
162
+ 'Content-Type',
163
+ 'Accept',
164
+ 'Authorization',
165
+ 'X-User-Id',
166
+ ],
167
+ credentials: true,
168
+ })
169
+ );
158
170
 
159
171
  // 角色解析中间件(双路径:token / 探针)
160
172
  try {
@@ -174,7 +186,12 @@ export class HttpServer {
174
186
 
175
187
  // 请求超时设置(AI 扫描类路由需要更长时间,SSE 流式路由需要更长时间)
176
188
  this.app.use((req, res, next) => {
177
- const isLongRunning = req.path.includes('/spm/scan') || req.path.includes('/spm/bootstrap') || req.path.includes('/extract/');
189
+ const isLongRunning =
190
+ req.path.includes('/spm/scan') ||
191
+ req.path.includes('/spm/bootstrap') ||
192
+ req.path.includes('/modules/scan') ||
193
+ req.path.includes('/modules/bootstrap') ||
194
+ req.path.includes('/extract/');
178
195
  const isStreaming = req.path.includes('/stream') || req.path.includes('/events/');
179
196
  req.setTimeout(isLongRunning ? 600000 : isStreaming ? 300000 : 60000); // AI 扫描 10分钟, SSE/EventSource 5分钟, 其他 60秒
180
197
  next();
@@ -219,7 +236,10 @@ export class HttpServer {
219
236
  this.app.get(`${apiPrefix}/auth/probe`, (req, res) => {
220
237
  const role = req.resolvedRole || 'visitor';
221
238
  const user = req.resolvedUser || 'anonymous';
222
- const mode = (process.env.VITE_AUTH_ENABLED === 'true' || process.env.ASD_AUTH_ENABLED === 'true') ? 'token' : 'probe';
239
+ const mode =
240
+ process.env.VITE_AUTH_ENABLED === 'true' || process.env.ASD_AUTH_ENABLED === 'true'
241
+ ? 'token'
242
+ : 'probe';
223
243
  const probeCache = this.capabilityProbe ? this.capabilityProbe.getCacheStatus() : null;
224
244
  res.json({
225
245
  success: true,
@@ -256,9 +276,12 @@ export class HttpServer {
256
276
  // Candidates 路由(AI 补齐/润色)
257
277
  this.app.use(`${apiPrefix}/candidates`, candidatesRouter);
258
278
 
259
- // SPM 路由
279
+ // SPM 路由(向后兼容保留)
260
280
  this.app.use(`${apiPrefix}/spm`, spmRouter);
261
281
 
282
+ // Modules 路由(v3.2 统一多语言模块扫描)
283
+ this.app.use(`${apiPrefix}/modules`, modulesRouter);
284
+
262
285
  // 违规记录路由
263
286
  this.app.use(`${apiPrefix}/violations`, violationsRouter);
264
287
 
@@ -417,7 +440,9 @@ export class HttpServer {
417
440
  const layer = layers[i];
418
441
  if (layer.route) {
419
442
  removedLayers.unshift(layers.splice(i, 1)[0]);
420
- if (removedLayers.length >= 2) break;
443
+ if (removedLayers.length >= 2) {
444
+ break;
445
+ }
421
446
  }
422
447
  }
423
448
 
@@ -12,10 +12,12 @@ const PRUNE_INTERVAL = 300_000; // 5 分钟清理一次过期 bucket
12
12
  */
13
13
  function _pruneIfNeeded(windowMs) {
14
14
  const now = Date.now();
15
- if (now - _lastPrune < PRUNE_INTERVAL) return;
15
+ if (now - _lastPrune < PRUNE_INTERVAL) {
16
+ return;
17
+ }
16
18
  _lastPrune = now;
17
19
  for (const [key, bucket] of _buckets) {
18
- bucket.timestamps = bucket.timestamps.filter(t => now - t < windowMs);
20
+ bucket.timestamps = bucket.timestamps.filter((t) => now - t < windowMs);
19
21
  if (bucket.timestamps.length === 0) {
20
22
  _buckets.delete(key);
21
23
  }
@@ -45,7 +47,7 @@ export function checkRecipeSave(projectRoot, clientId, opts = {}) {
45
47
  }
46
48
 
47
49
  // 清除过期记录
48
- bucket.timestamps = bucket.timestamps.filter(t => now - t < windowMs);
50
+ bucket.timestamps = bucket.timestamps.filter((t) => now - t < windowMs);
49
51
 
50
52
  if (bucket.timestamps.length >= maxRequests) {
51
53
  const oldest = bucket.timestamps[0];
@@ -2,7 +2,12 @@
2
2
  * 错误处理中间件
3
3
  */
4
4
 
5
- import { ValidationError, ConflictError, NotFoundError, PermissionDenied } from '../../shared/errors/index.js';
5
+ import {
6
+ ConflictError,
7
+ NotFoundError,
8
+ PermissionDenied,
9
+ ValidationError,
10
+ } from '../../shared/errors/index.js';
6
11
 
7
12
  export function errorHandler(logger) {
8
13
  return (error, req, res, next) => {
@@ -15,7 +15,13 @@
15
15
  */
16
16
 
17
17
  // 轮询/心跳路径 — 完全静默
18
- const SILENT_PATHS = ['/api/v1/health', '/api/health', '/api/realtime/events', '/api/sse', '/socket.io'];
18
+ const SILENT_PATHS = [
19
+ '/api/v1/health',
20
+ '/api/health',
21
+ '/api/realtime/events',
22
+ '/api/sse',
23
+ '/socket.io',
24
+ ];
19
25
 
20
26
  /**
21
27
  * 从 originalUrl 中提取 pathname(去除 query string)
@@ -35,7 +41,9 @@ export function requestLogger(logger) {
35
41
  const duration = Date.now() - startTime;
36
42
 
37
43
  // 完全静默的路径
38
- if (SILENT_PATHS.some(p => originalPath.startsWith(p))) return;
44
+ if (SILENT_PATHS.some((p) => originalPath.startsWith(p))) {
45
+ return;
46
+ }
39
47
 
40
48
  const logData = {
41
49
  method: req.method,
@@ -45,7 +53,10 @@ export function requestLogger(logger) {
45
53
  };
46
54
 
47
55
  // 非 GET / 非 2xx / 慢请求 → info; GET + 2xx/304 → debug(304 是缓存命中,与 200 同级)
48
- const isNoisy = req.method === 'GET' && (res.statusCode >= 200 && res.statusCode < 300 || res.statusCode === 304) && duration < 2000;
56
+ const isNoisy =
57
+ req.method === 'GET' &&
58
+ ((res.statusCode >= 200 && res.statusCode < 300) || res.statusCode === 304) &&
59
+ duration < 2000;
49
60
  const isSlow = duration >= 1000;
50
61
  if (isSlow) {
51
62
  logger.warn(`🐌慢请求: ${req.method} ${originalPath} - ${duration}ms`, logData);
@@ -13,7 +13,8 @@ import Logger from '../../infrastructure/logging/Logger.js';
13
13
 
14
14
  const logger = Logger.getInstance();
15
15
 
16
- const AUTH_ENABLED = process.env.VITE_AUTH_ENABLED === 'true' || process.env.ASD_AUTH_ENABLED === 'true';
16
+ const AUTH_ENABLED =
17
+ process.env.VITE_AUTH_ENABLED === 'true' || process.env.ASD_AUTH_ENABLED === 'true';
17
18
 
18
19
  /**
19
20
  * 验证 token 并提取 payload
@@ -47,7 +48,11 @@ export function roleResolverMiddleware(options = {}) {
47
48
 
48
49
  return (req, _res, next) => {
49
50
  // 已有 x-user-id header(MCP / 内部调用)→ 直接信任
50
- if (req.headers['x-user-id'] && req.headers['x-user-id'] !== 'anonymous' && req.headers['x-user-id'] !== 'dashboard') {
51
+ if (
52
+ req.headers['x-user-id'] &&
53
+ req.headers['x-user-id'] !== 'anonymous' &&
54
+ req.headers['x-user-id'] !== 'dashboard'
55
+ ) {
51
56
  req.resolvedRole = req.headers['x-user-id'];
52
57
  next();
53
58
  return;
@@ -58,31 +63,33 @@ export function roleResolverMiddleware(options = {}) {
58
63
  const authHeader = req.headers.authorization || '';
59
64
  const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : '';
60
65
 
61
- verifyTokenPromise.then(verifyToken => {
62
- const payload = verifyToken(token);
66
+ verifyTokenPromise
67
+ .then((verifyToken) => {
68
+ const payload = verifyToken(token);
63
69
 
64
- if (payload && payload.role) {
65
- req.resolvedRole = payload.role;
66
- req.resolvedUser = payload.sub;
67
- logger.debug('roleResolver: token-based', { role: payload.role, user: payload.sub });
68
- } else {
69
- // Token 无效/缺失 → visitor(只读)
70
+ if (payload?.role) {
71
+ req.resolvedRole = payload.role;
72
+ req.resolvedUser = payload.sub;
73
+ logger.debug('roleResolver: token-based', { role: payload.role, user: payload.sub });
74
+ } else {
75
+ // Token 无效/缺失 → visitor(只读)
76
+ req.resolvedRole = 'visitor';
77
+ req.resolvedUser = 'anonymous';
78
+ }
79
+
80
+ logger.debug('roleResolver: resolved', {
81
+ mode: 'token',
82
+ role: req.resolvedRole,
83
+ user: req.resolvedUser,
84
+ });
85
+
86
+ next();
87
+ })
88
+ .catch(() => {
70
89
  req.resolvedRole = 'visitor';
71
90
  req.resolvedUser = 'anonymous';
72
- }
73
-
74
- logger.debug('roleResolver: resolved', {
75
- mode: 'token',
76
- role: req.resolvedRole,
77
- user: req.resolvedUser,
91
+ next();
78
92
  });
79
-
80
- next();
81
- }).catch(() => {
82
- req.resolvedRole = 'visitor';
83
- req.resolvedUser = 'anonymous';
84
- next();
85
- });
86
93
  } else {
87
94
  // ── Path B: Probe-based ────────────────────
88
95
  if (capabilityProbe) {