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
@@ -11,10 +11,10 @@
11
11
  /** QualityScorer 维度权重 */
12
12
  export const QUALITY_WEIGHTS = Object.freeze({
13
13
  completeness: 0.35,
14
- format: 0.25,
15
- codeQuality: 0.25,
16
- metadata: 0.15,
17
- engagement: 0.00,
14
+ format: 0.25,
15
+ codeQuality: 0.25,
16
+ metadata: 0.15,
17
+ engagement: 0.0,
18
18
  });
19
19
 
20
20
  /** QualityScorer 等级分界线 */
@@ -39,38 +39,38 @@ export const RULE_LEARNER = Object.freeze({
39
39
  PROBLEMATIC_FALSE_POSITIVE_RATE: 0.3,
40
40
  PROBLEMATIC_MIN_TRIGGERS: 5,
41
41
  /** 规则建议置信度 */
42
- CONFIDENCE_TUNE: 0.7,
43
- CONFIDENCE_DISABLE: 0.8,
44
- CONFIDENCE_SPECIALIZE: 0.6,
45
- CONFIDENCE_REVIEW: 0.4,
42
+ CONFIDENCE_TUNE: 0.7,
43
+ CONFIDENCE_DISABLE: 0.8,
44
+ CONFIDENCE_SPECIALIZE: 0.6,
45
+ CONFIDENCE_REVIEW: 0.4,
46
46
  /** 触发数阈值 */
47
- HIGH_TRIGGER_COUNT: 50,
48
- HIGH_PRECISION: 0.8,
47
+ HIGH_TRIGGER_COUNT: 50,
48
+ HIGH_PRECISION: 0.8,
49
49
  /** 闲置天数阈值 */
50
- UNUSED_DAYS_THRESHOLD: 30,
50
+ UNUSED_DAYS_THRESHOLD: 30,
51
51
  /** 精度下限 */
52
- LOW_PRECISION: 0.5,
52
+ LOW_PRECISION: 0.5,
53
53
  });
54
54
 
55
55
  // ─── 合规报告 ────────────────────────────────────────────
56
56
 
57
57
  /** ComplianceReporter 默认 Quality Gate */
58
58
  export const QUALITY_GATE = Object.freeze({
59
- MAX_ERRORS: 0,
59
+ MAX_ERRORS: 0,
60
60
  MAX_WARNINGS: 20,
61
- MIN_SCORE: 70,
61
+ MIN_SCORE: 70,
62
62
  });
63
63
 
64
64
  /** ComplianceReporter 扣分权重 */
65
65
  export const COMPLIANCE_SCORING = Object.freeze({
66
- ERROR_PENALTY: 5,
67
- WARNING_PENALTY: 1,
68
- INFO_PENALTY: 0.2,
66
+ ERROR_PENALTY: 5,
67
+ WARNING_PENALTY: 1,
68
+ INFO_PENALTY: 0.2,
69
69
  PROBLEMATIC_RULE_PENALTY: 3,
70
- HIGH_F1_BONUS: 5,
71
- HIGH_F1_THRESHOLD: 0.8,
72
- LOW_PRECISION_THRESHOLD: 0.5,
73
- MAX_FILES_DEFAULT: 500,
70
+ HIGH_F1_BONUS: 5,
71
+ HIGH_F1_THRESHOLD: 0.8,
72
+ LOW_PRECISION_THRESHOLD: 0.5,
73
+ MAX_FILES_DEFAULT: 500,
74
74
  });
75
75
 
76
76
  // ─── 知识置信度 ──────────────────────────────────────────
@@ -78,34 +78,34 @@ export const COMPLIANCE_SCORING = Object.freeze({
78
78
  /** 知识条目默认置信度和阈值 */
79
79
  export const KNOWLEDGE_CONFIDENCE = Object.freeze({
80
80
  /** 默认 confidence(Reasoning VO) */
81
- DEFAULT: 0.7,
81
+ DEFAULT: 0.7,
82
82
  /** pending 条目纳入交付的最低 confidence */
83
- PENDING_MIN: 0.7,
83
+ PENDING_MIN: 0.7,
84
84
  /** rankScore 中 confidence 缺省值 */
85
- RANK_DEFAULT: 0.5,
85
+ RANK_DEFAULT: 0.5,
86
86
  /** Bootstrap refine 时的 AI 默认 confidence */
87
- BOOTSTRAP_DEFAULT: 0.6,
87
+ BOOTSTRAP_DEFAULT: 0.6,
88
88
  /** 自动提交时的 bootstrap confidence */
89
- BOOTSTRAP_SUBMIT: 0.8,
89
+ BOOTSTRAP_SUBMIT: 0.8,
90
90
  });
91
91
 
92
92
  // ─── 搜索管线 ────────────────────────────────────────────
93
93
 
94
94
  /** SearchEngine 配置 */
95
95
  export const SEARCH = Object.freeze({
96
- DEFAULT_LIMIT: 10,
97
- MAX_RESULTS: 100,
96
+ DEFAULT_LIMIT: 10,
97
+ MAX_RESULTS: 100,
98
98
  });
99
99
 
100
100
  // ─── 文件监听器 ──────────────────────────────────────────
101
101
 
102
102
  /** FileWatcher 配置 */
103
103
  export const FILE_WATCHER = Object.freeze({
104
- DEBOUNCE_DELAY_MS: 300,
105
- STABILITY_THRESHOLD_MS: 500,
106
- POLL_INTERVAL_MS: 100,
107
- BINARY_INTERVAL_MS: 300,
108
- MAX_FILE_SIZE_BYTES: 1024 * 1024,
104
+ DEBOUNCE_DELAY_MS: 300,
105
+ STABILITY_THRESHOLD_MS: 500,
106
+ POLL_INTERVAL_MS: 100,
107
+ BINARY_INTERVAL_MS: 300,
108
+ MAX_FILE_SIZE_BYTES: 1024 * 1024,
109
109
  });
110
110
 
111
111
  // ─── AI Provider ─────────────────────────────────────────
@@ -119,10 +119,10 @@ export const AI_CIRCUIT_BREAKER = Object.freeze({
119
119
 
120
120
  /** ToolResultCache 配置 */
121
121
  export const CACHE = Object.freeze({
122
- MAX_FILE_ENTRIES: 200,
122
+ MAX_FILE_ENTRIES: 200,
123
123
  MAX_SEARCH_ENTRIES: 500,
124
124
  /** 缓存条目默认 TTL(毫秒),0 = 不过期 */
125
- DEFAULT_TTL_MS: 30 * 60 * 1000, // 30 分钟
125
+ DEFAULT_TTL_MS: 30 * 60 * 1000, // 30 分钟
126
126
  });
127
127
 
128
128
  // ─── 性能监控 ────────────────────────────────────────────
@@ -130,18 +130,18 @@ export const CACHE = Object.freeze({
130
130
  /** PerformanceMonitor 配置 */
131
131
  export const MONITORING = Object.freeze({
132
132
  SLOW_REQUEST_THRESHOLD_MS: 1000,
133
- ERROR_ALERT_THRESHOLD: 10,
133
+ ERROR_ALERT_THRESHOLD: 10,
134
134
  });
135
135
 
136
136
  // ─── Cursor 交付 ─────────────────────────────────────────
137
137
 
138
138
  /** CursorDeliveryPipeline 排序权重 */
139
139
  export const DELIVERY_RANK = Object.freeze({
140
- CONFIDENCE_WEIGHT: 50,
141
- AUTHORITY_WEIGHT: 30,
142
- USE_COUNT_MAX: 10,
143
- USE_COUNT_WEIGHT: 2,
144
- ACTIVE_BONUS: 10,
140
+ CONFIDENCE_WEIGHT: 50,
141
+ AUTHORITY_WEIGHT: 30,
142
+ USE_COUNT_MAX: 10,
143
+ USE_COUNT_WEIGHT: 2,
144
+ ACTIVE_BONUS: 10,
145
145
  });
146
146
 
147
147
  export default {
@@ -58,14 +58,14 @@ export class NotFoundError extends BaseError {
58
58
  // 如果没有提供 message,那么第一个参数就是 resource
59
59
  let finalMessage = message;
60
60
  let finalResource = resource;
61
-
61
+
62
62
  if (!resource) {
63
63
  finalMessage = `Resource not found: ${message}`;
64
64
  finalResource = message;
65
65
  } else if (resourceId) {
66
66
  finalMessage = `${message} (${resource}:${resourceId})`;
67
67
  }
68
-
68
+
69
69
  super(finalMessage, 'NOT_FOUND', 404);
70
70
  this.resource = finalResource;
71
71
  this.resourceId = resourceId;
@@ -5,10 +5,10 @@
5
5
 
6
6
  export {
7
7
  BaseError,
8
- PermissionDenied,
9
- ConstitutionViolation,
10
- ValidationError,
11
- NotFoundError,
12
8
  ConflictError,
9
+ ConstitutionViolation,
13
10
  InternalError,
11
+ NotFoundError,
12
+ PermissionDenied,
13
+ ValidationError,
14
14
  } from './BaseError.js';
@@ -21,12 +21,19 @@
21
21
  * @returns {Set<string>} token 集合
22
22
  */
23
23
  export function tokenizeForSimilarity(text, n = 2) {
24
- if (!text) return new Set();
25
- const lower = text.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\u3400-\u4dbf]+/g, ' ').trim();
24
+ if (!text) {
25
+ return new Set();
26
+ }
27
+ const lower = text
28
+ .toLowerCase()
29
+ .replace(/[^a-z0-9\u4e00-\u9fff\u3400-\u4dbf]+/g, ' ')
30
+ .trim();
26
31
  const tokens = new Set();
27
32
  const words = lower.split(/\s+/);
28
33
  for (const w of words) {
29
- if (w.length >= n) tokens.add(w);
34
+ if (w.length >= n) {
35
+ tokens.add(w);
36
+ }
30
37
  for (let i = 0; i <= w.length - n; i++) {
31
38
  tokens.add(w.slice(i, i + n));
32
39
  }
@@ -42,13 +49,19 @@ export function tokenizeForSimilarity(text, n = 2) {
42
49
  * @returns {number} 0.0 - 1.0
43
50
  */
44
51
  export function jaccardSimilarity(a, b) {
45
- if ((!a || a.size === 0) && (!b || b.size === 0)) return 0;
46
- if (!a || a.size === 0 || !b || b.size === 0) return 0;
52
+ if ((!a || a.size === 0) && (!b || b.size === 0)) {
53
+ return 0;
54
+ }
55
+ if (!a || a.size === 0 || !b || b.size === 0) {
56
+ return 0;
57
+ }
47
58
  let intersection = 0;
48
59
  const smaller = a.size <= b.size ? a : b;
49
60
  const larger = a.size <= b.size ? b : a;
50
61
  for (const t of smaller) {
51
- if (larger.has(t)) intersection++;
62
+ if (larger.has(t)) {
63
+ intersection++;
64
+ }
52
65
  }
53
66
  const union = a.size + b.size - intersection;
54
67
  return union > 0 ? intersection / union : 0;
@@ -62,8 +75,12 @@ export function jaccardSimilarity(a, b) {
62
75
  * @returns {number} 0.0 - 1.0(输入均为正值时)
63
76
  */
64
77
  export function cosineSimilarity(a, b) {
65
- if (!a || !b || a.length !== b.length || a.length === 0) return 0;
66
- let dotProduct = 0, normA = 0, normB = 0;
78
+ if (!a || !b || a.length !== b.length || a.length === 0) {
79
+ return 0;
80
+ }
81
+ let dotProduct = 0,
82
+ normA = 0,
83
+ normB = 0;
67
84
  for (let i = 0; i < a.length; i++) {
68
85
  dotProduct += a[i] * b[i];
69
86
  normA += a[i] * a[i];
@@ -19,7 +19,9 @@
19
19
  * @returns {number} 估算 token 数(向上取整)
20
20
  */
21
21
  export function estimateTokens(text) {
22
- if (!text) return 0;
22
+ if (!text) {
23
+ return 0;
24
+ }
23
25
  let tokens = 0;
24
26
  for (const ch of text) {
25
27
  // CJK Unified Ideographs + 扩展区 + 常见符号区
@@ -41,6 +43,8 @@ export function estimateTokens(text) {
41
43
  * @returns {number}
42
44
  */
43
45
  export function estimateTokensFast(text) {
44
- if (!text) return 0;
46
+ if (!text) {
47
+ return 0;
48
+ }
45
49
  return Math.ceil(text.length / 3.5);
46
50
  }
@@ -15,8 +15,12 @@
15
15
  * @returns {*}
16
16
  */
17
17
  export function safeJsonParse(value, fallback = null) {
18
- if (value == null || value === 'null' || value === '') return fallback;
19
- if (typeof value === 'object') return value;
18
+ if (value == null || value === 'null' || value === '') {
19
+ return fallback;
20
+ }
21
+ if (typeof value === 'object') {
22
+ return value;
23
+ }
20
24
  try {
21
25
  return JSON.parse(value);
22
26
  } catch {
@@ -33,7 +37,9 @@ export function safeJsonParse(value, fallback = null) {
33
37
  * @returns {string}
34
38
  */
35
39
  export function safeJsonStringify(value, fallback = '{}') {
36
- if (value == null) return fallback;
40
+ if (value == null) {
41
+ return fallback;
42
+ }
37
43
  if (typeof value?.toJSON === 'function') {
38
44
  return JSON.stringify(value.toJSON());
39
45
  }
@@ -61,7 +67,9 @@ export function unixNow() {
61
67
  * @returns {string}
62
68
  */
63
69
  export function strOr(value, fallback = '') {
64
- if (typeof value === 'string' && value.trim()) return value;
70
+ if (typeof value === 'string' && value.trim()) {
71
+ return value;
72
+ }
65
73
  return fallback;
66
74
  }
67
75
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autosnippet",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "AutoSnippet - 连接开发者、AI 与项目知识库的工具",
5
5
  "type": "module",
6
6
  "main": "lib/bootstrap.js",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "scripts": {
11
11
  "postinstall": "node scripts/postinstall-safe.js",
12
- "prepublishOnly": "node scripts/build-native-ui.js && node scripts/build-asd-entry.js",
12
+ "prepublishOnly": "node scripts/build-native-ui.js",
13
13
  "build:native-ui": "swiftc resources/native-ui/main.swift resources/native-ui/combined-window.swift -o resources/native-ui/native-ui -framework AppKit",
14
14
  "install:cursor-skill": "node scripts/install-cursor-skill.js",
15
15
  "install:cursor-skill:mcp": "node scripts/install-cursor-skill.js --mcp",
@@ -32,9 +32,9 @@
32
32
  "release:major": "node scripts/release.js major",
33
33
  "cli": "node bin/cli.js",
34
34
  "mcp": "node bin/mcp-server.js",
35
- "init:snippets": "node scripts/init-xcode-snippets.js init",
36
- "list:snippets": "node scripts/init-xcode-snippets.js list",
37
- "remove:snippets": "node scripts/init-xcode-snippets.js remove",
35
+ "init:snippets": "node scripts/init-snippets.js init",
36
+ "list:snippets": "node scripts/init-snippets.js list",
37
+ "remove:snippets": "node scripts/init-snippets.js remove",
38
38
  "diagnose:mcp": "node scripts/diagnose-mcp.js"
39
39
  },
40
40
  "author": "gaoxuefeng",
@@ -70,9 +70,7 @@
70
70
  "open": "^8.0.4",
71
71
  "ora": "^8.0.1",
72
72
  "socket.io": "^4.8.1",
73
- "tree-sitter": "^0.22.4",
74
- "tree-sitter-objc": "^3.0.2",
75
- "tree-sitter-swift": "^0.7.1",
73
+ "tree-sitter": "^0.25.0",
76
74
  "undici": "^6.23.0",
77
75
  "uuid": "^9.0.1",
78
76
  "winston": "^3.11.0",
@@ -94,7 +92,6 @@
94
92
  "resources/native-ui/combined-window.swift",
95
93
  "resources/native-ui/native-ui",
96
94
  "resources/native-ui/README.md",
97
- "resources/asd-entry/main.swift",
98
95
  "resources/openChrome.applescript"
99
96
  ],
100
97
  "directories": {
@@ -103,12 +100,51 @@
103
100
  "test": "test"
104
101
  },
105
102
  "devDependencies": {
103
+ "@biomejs/biome": "2.0.0",
106
104
  "@types/node": "^20.10.6",
107
- "eslint": "^8.56.0",
108
- "jest": "^29.7.0",
109
- "mocha": "^11.3.0",
110
- "nodemon": "^3.0.2",
105
+ "jest": "^30.2.0",
106
+ "mocha": "^11.7.5",
107
+ "nodemon": "^3.1.13",
111
108
  "prettier": "^3.1.1",
112
109
  "supertest": "^6.3.3"
110
+ },
111
+ "optionalDependencies": {
112
+ "tree-sitter-go": "^0.25.0",
113
+ "tree-sitter-java": "^0.23.5",
114
+ "tree-sitter-javascript": "^0.25.0",
115
+ "tree-sitter-kotlin": "^0.3.8",
116
+ "tree-sitter-objc": "^3.0.2",
117
+ "tree-sitter-python": "^0.25.0",
118
+ "tree-sitter-swift": "^0.7.1",
119
+ "tree-sitter-typescript": "^0.23.2"
120
+ },
121
+ "overrides": {
122
+ "tree-sitter-kotlin": {
123
+ "tree-sitter": "$tree-sitter"
124
+ },
125
+ "tree-sitter-java": {
126
+ "tree-sitter": "$tree-sitter"
127
+ },
128
+ "tree-sitter-python": {
129
+ "tree-sitter": "$tree-sitter"
130
+ },
131
+ "tree-sitter-javascript": {
132
+ "tree-sitter": "$tree-sitter"
133
+ },
134
+ "tree-sitter-typescript": {
135
+ "tree-sitter": "$tree-sitter"
136
+ },
137
+ "tree-sitter-swift": {
138
+ "tree-sitter": "$tree-sitter"
139
+ },
140
+ "tree-sitter-objc": {
141
+ "tree-sitter": "$tree-sitter"
142
+ },
143
+ "tree-sitter-c": {
144
+ "tree-sitter": "$tree-sitter"
145
+ },
146
+ "minimatch": "^10.2.2",
147
+ "diff": "^8.0.3",
148
+ "glob": "^11.0.0"
113
149
  }
114
150
  }
@@ -0,0 +1,256 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @file bench-real-projects.mjs
5
+ * @description 性能基准测试 — 对 20 个真实项目执行 Discovery → AST → Enhancement 全链路
6
+ * 输出每个阶段的耗时表。
7
+ *
8
+ * 用法: node scripts/bench-real-projects.mjs
9
+ */
10
+
11
+ import fs from 'node:fs';
12
+ import path from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+
15
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
+ const ROOT = path.resolve(__dirname, '..');
17
+ const GITHUB_DIR = path.resolve(ROOT, '..');
18
+
19
+ const PROJECTS = [
20
+ 'Alamofire',
21
+ 'iCarousel',
22
+ 'Euclid',
23
+ 'Expression',
24
+ 'VectorMath',
25
+ 'layout',
26
+ 'RetroRampage',
27
+ 'Consumer',
28
+ 'SwiftFormat',
29
+ 'flask',
30
+ 'fastapi',
31
+ 'django-website',
32
+ 'spring-petclinic',
33
+ 'Pokedex',
34
+ 'gin',
35
+ 'axum',
36
+ 'nest',
37
+ 'todomvc',
38
+ 'vue-element-admin',
39
+ 'discourse',
40
+ ];
41
+
42
+ // ── 加载模块 ──────────────────────────────────────────────────────
43
+ const { getDiscovererRegistry, resetDiscovererRegistry } = await import(
44
+ '../lib/core/discovery/index.js'
45
+ );
46
+ const { LanguageService } = await import('../lib/shared/LanguageService.js');
47
+ const { DimensionCopy } = await import('../lib/shared/DimensionCopyRegistry.js');
48
+
49
+ // AST
50
+ await import('../lib/core/ast/index.js');
51
+ const { analyzeProject, isAvailable: astIsAvailable } = await import('../lib/core/AstAnalyzer.js');
52
+
53
+ // Enhancement
54
+ const { initEnhancementRegistry } = await import('../lib/core/enhancement/index.js');
55
+
56
+ // ── 主逻辑 ────────────────────────────────────────────────────────
57
+ async function benchmark() {
58
+ const enhRegistry = await initEnhancementRegistry();
59
+
60
+ const results = [];
61
+
62
+ for (const name of PROJECTS) {
63
+ const projectRoot = path.join(GITHUB_DIR, name);
64
+ if (!fs.existsSync(projectRoot)) {
65
+ console.warn(`⚠ 跳过 ${name}`);
66
+ continue;
67
+ }
68
+
69
+ const row = { project: name, files: 0 };
70
+
71
+ // Phase 1: Discovery
72
+ const t1 = Date.now();
73
+ resetDiscovererRegistry();
74
+ const registry = getDiscovererRegistry();
75
+ const discoverer = await registry.detect(projectRoot);
76
+ row.detectMs = Date.now() - t1;
77
+
78
+ const t2 = Date.now();
79
+ await discoverer.load(projectRoot);
80
+ const targets = await discoverer.listTargets();
81
+ row.loadMs = Date.now() - t2;
82
+
83
+ // File collection
84
+ const t3 = Date.now();
85
+ const seenPaths = new Set();
86
+ const allFiles = [];
87
+ const langStats = {};
88
+ const MAX_FILES = 500;
89
+
90
+ for (const t of targets) {
91
+ try {
92
+ const fileList = await discoverer.getTargetFiles(t);
93
+ for (const f of fileList) {
94
+ const fp = typeof f === 'string' ? f : f.path;
95
+ if (seenPaths.has(fp)) {
96
+ continue;
97
+ }
98
+ seenPaths.add(fp);
99
+ const fname = typeof f === 'string' ? path.basename(f) : f.name || path.basename(fp);
100
+ try {
101
+ const content = fs.readFileSync(fp, 'utf8');
102
+ allFiles.push({ name: fname, relativePath: path.relative(projectRoot, fp), content });
103
+ } catch {
104
+ /* skip */
105
+ }
106
+
107
+ const ext = path.extname(fname).replace('.', '') || 'unknown';
108
+ langStats[ext] = (langStats[ext] || 0) + 1;
109
+
110
+ if (allFiles.length >= MAX_FILES) {
111
+ break;
112
+ }
113
+ }
114
+ } catch {
115
+ /* skip */
116
+ }
117
+ if (allFiles.length >= MAX_FILES) {
118
+ break;
119
+ }
120
+ }
121
+ row.fileCollectMs = Date.now() - t3;
122
+ row.files = allFiles.length;
123
+ row.discoverer = discoverer.id;
124
+
125
+ // Phase 2: Language detection
126
+ const t4 = Date.now();
127
+ const primaryLang = LanguageService.detectPrimary(langStats);
128
+ const profile = LanguageService.detectProfile(langStats);
129
+ row.langDetectMs = Date.now() - t4;
130
+ row.primaryLang = primaryLang;
131
+
132
+ // Phase 3: AST
133
+ const t5 = Date.now();
134
+ let astSummary = null;
135
+ if (astIsAvailable() && primaryLang) {
136
+ try {
137
+ astSummary = analyzeProject(allFiles, primaryLang);
138
+ } catch {
139
+ /* graceful */
140
+ }
141
+ }
142
+ row.astMs = Date.now() - t5;
143
+ row.astClasses = astSummary?.classes?.length || 0;
144
+ row.astMethods = astSummary?.methods?.length || 0;
145
+
146
+ // Phase 4: Enhancement
147
+ const t6 = Date.now();
148
+ const frameworks = targets
149
+ .map((t) => (typeof t === 'object' ? t.framework : null))
150
+ .filter(Boolean);
151
+ const packs = enhRegistry.resolve(primaryLang, frameworks);
152
+ row.enhancementMs = Date.now() - t6;
153
+ row.enhPacks = packs.map((p) => p.id).join(',') || '—';
154
+
155
+ // Phase 5: DimensionCopy
156
+ const t7 = Date.now();
157
+ const dims = [
158
+ { id: 'code-standard', label: '代码规范', guide: 'default' },
159
+ { id: 'architecture', label: '架构模式', guide: 'default' },
160
+ ];
161
+ try {
162
+ DimensionCopy.applyMulti(dims, profile.primary, profile.secondary);
163
+ } catch {
164
+ /* graceful */
165
+ }
166
+ row.dimCopyMs = Date.now() - t7;
167
+
168
+ row.totalMs =
169
+ row.detectMs +
170
+ row.loadMs +
171
+ row.fileCollectMs +
172
+ row.langDetectMs +
173
+ row.astMs +
174
+ row.enhancementMs +
175
+ row.dimCopyMs;
176
+
177
+ results.push(row);
178
+ process.stdout.write(
179
+ `✓ ${name.padEnd(20)} ${row.files.toString().padStart(5)} files | ` +
180
+ `detect=${row.detectMs}ms load=${row.loadMs}ms collect=${row.fileCollectMs}ms ` +
181
+ `ast=${row.astMs}ms total=${row.totalMs}ms\n`
182
+ );
183
+ }
184
+
185
+ // ── 汇总表 ──────────────────────────────────────────────────────
186
+ process.stdout.write('\n' + '═'.repeat(120) + '\n');
187
+ process.stdout.write(
188
+ 'Project'.padEnd(22) +
189
+ 'Files'.padStart(6) +
190
+ 'Disc'.padStart(10) +
191
+ 'Detect'.padStart(8) +
192
+ 'Load'.padStart(8) +
193
+ 'Collect'.padStart(9) +
194
+ 'Lang'.padStart(10) +
195
+ 'AST'.padStart(8) +
196
+ 'Cls'.padStart(5) +
197
+ 'Enh'.padStart(8) +
198
+ 'DimC'.padStart(6) +
199
+ 'Total'.padStart(8) +
200
+ ' Packs\n'
201
+ );
202
+ process.stdout.write('─'.repeat(120) + '\n');
203
+
204
+ for (const r of results) {
205
+ process.stdout.write(
206
+ r.project.padEnd(22) +
207
+ r.files.toString().padStart(6) +
208
+ r.discoverer.padStart(10) +
209
+ `${r.detectMs}ms`.padStart(8) +
210
+ `${r.loadMs}ms`.padStart(8) +
211
+ `${r.fileCollectMs}ms`.padStart(9) +
212
+ (r.primaryLang || '?').padStart(10) +
213
+ `${r.astMs}ms`.padStart(8) +
214
+ r.astClasses.toString().padStart(5) +
215
+ `${r.enhancementMs}ms`.padStart(8) +
216
+ `${r.dimCopyMs}ms`.padStart(6) +
217
+ `${r.totalMs}ms`.padStart(8) +
218
+ ` ${r.enhPacks}\n`
219
+ );
220
+ }
221
+ process.stdout.write('═'.repeat(120) + '\n');
222
+
223
+ // 性能阈值检查
224
+ let warnings = 0;
225
+ for (const r of results) {
226
+ if (r.detectMs > 500) {
227
+ console.warn(`⚠ ${r.project}: detect ${r.detectMs}ms > 500ms 阈值`);
228
+ warnings++;
229
+ }
230
+ if (r.totalMs > 120000) {
231
+ console.warn(`⚠ ${r.project}: total ${r.totalMs}ms > 120s 阈值`);
232
+ warnings++;
233
+ }
234
+ if (r.astMs > 30000) {
235
+ console.warn(`⚠ ${r.project}: AST ${r.astMs}ms > 30s 阈值`);
236
+ warnings++;
237
+ }
238
+ }
239
+
240
+ if (warnings === 0) {
241
+ process.stdout.write('\n✅ 所有性能指标在阈值内\n');
242
+ } else {
243
+ console.warn(`\n⚠ ${warnings} 项超过阈值`);
244
+ }
245
+
246
+ // 写入 JSON
247
+ const outPath = path.join(ROOT, 'test', 'fixtures', 'real-project-bench.json');
248
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
249
+ fs.writeFileSync(outPath, JSON.stringify(results, null, 2));
250
+ process.stdout.write(`\n📄 结果写入 ${outPath}\n`);
251
+ }
252
+
253
+ benchmark().catch((err) => {
254
+ console.error('Fatal:', err);
255
+ process.exit(1);
256
+ });