autosnippet 3.0.1 → 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 +655 -260
  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,16 +4,19 @@
4
4
  * 在 macOS 上构建 native-ui 辅助程序(可选)
5
5
  */
6
6
 
7
- import { fileURLToPath } from 'node:url';
8
7
  import { dirname } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+
9
10
  const __filename = fileURLToPath(import.meta.url);
10
11
  const __dirname = dirname(__filename);
11
12
 
12
13
  import { execSync } from 'node:child_process';
13
- import path from 'node:path';
14
14
  import fs from 'node:fs';
15
+ import path from 'node:path';
15
16
 
16
- if (process.platform !== 'darwin') process.exit(0);
17
+ if (process.platform !== 'darwin') {
18
+ process.exit(0);
19
+ }
17
20
 
18
21
  const root = path.resolve(__dirname, '..');
19
22
  const src = path.join(root, 'resources', 'native-ui', 'main.swift');
@@ -24,31 +27,28 @@ const out = path.join(root, 'resources', 'native-ui', 'native-ui');
24
27
  const isPublishing = process.env.npm_lifecycle_event === 'prepublishOnly';
25
28
 
26
29
  try {
27
- // 编译 native-ui(包含所有源文件)
28
- execSync(`swiftc "${src}" "${combinedSrc}" -o "${out}" -framework AppKit`, {
29
- cwd: root,
30
- stdio: 'pipe'
31
- });
32
-
33
- // 验证构建结果
34
- if (fs.existsSync(out)) {
35
- console.log('✅ Native UI 构建成功');
36
- }
37
- } catch (err) {
38
- // 如果在发布流程中构建失败,应该报错
39
- if (isPublishing) {
40
- console.error('❌ Native UI 构建失败(发布流程中)');
41
- console.error('请确保:');
42
- console.error(' 1. 当前系统是 macOS');
43
- console.error(' 2. 已安装 Xcode Command Line Tools: xcode-select --install');
44
- console.error(' 3. Swift 编译器可用: which swiftc');
45
- process.exit(1);
46
- }
47
-
48
- // 在用户安装时,如果已有预编译的二进制文件,静默跳过
49
- if (fs.existsSync(out)) {
50
- console.log('ℹ️ 使用预编译的 Native UI');
51
- } else {
52
- console.log('⚠️ Native UI 未构建(部分功能可能不可用)');
53
- }
30
+ // 编译 native-ui(包含所有源文件)
31
+ execSync(`swiftc "${src}" "${combinedSrc}" -o "${out}" -framework AppKit`, {
32
+ cwd: root,
33
+ stdio: 'pipe',
34
+ });
35
+
36
+ // 验证构建结果
37
+ if (fs.existsSync(out)) {
38
+ }
39
+ } catch (_err) {
40
+ // 如果在发布流程中构建失败,应该报错
41
+ if (isPublishing) {
42
+ console.error('❌ Native UI 构建失败(发布流程中)');
43
+ console.error('请确保:');
44
+ console.error(' 1. 当前系统是 macOS');
45
+ console.error(' 2. 已安装 Xcode Command Line Tools: xcode-select --install');
46
+ console.error(' 3. Swift 编译器可用: which swiftc');
47
+ process.exit(1);
48
+ }
49
+
50
+ // 在用户安装时,如果已有预编译的二进制文件,静默跳过
51
+ if (fs.existsSync(out)) {
52
+ } else {
53
+ }
54
54
  }
@@ -7,70 +7,40 @@
7
7
 
8
8
  import fs from 'node:fs';
9
9
  import path from 'node:path';
10
+
10
11
  const args = process.argv.slice(2);
11
12
  const projectRoot = args[0] || '/Users/gaoxuefeng/Documents/github/BiliDemo';
12
13
 
13
- console.log('🧹 清除旧形式的向量索引(含 AutoSnippet/recipes 前缀)\n');
14
- console.log('═══════════════════════════════════════════════════════════\n');
15
-
16
14
  const indexDir = path.join(projectRoot, 'AutoSnippet/.autosnippet/context/index');
17
15
  const vectorIndexPath = path.join(indexDir, 'vector_index.json');
18
16
 
19
17
  if (!fs.existsSync(vectorIndexPath)) {
20
- console.log('✅ 无需清除:向量索引不存在或已清除\n');
21
18
  process.exit(0);
22
19
  }
23
20
 
24
21
  // 检查索引格式
25
22
  const data = JSON.parse(fs.readFileSync(vectorIndexPath, 'utf8'));
26
- const hasOldFormat = data.items?.some(item =>
23
+ const hasOldFormat = data.items?.some((item) =>
27
24
  item.metadata?.sourcePath?.startsWith('AutoSnippet/recipes/')
28
25
  );
29
26
 
30
27
  if (!hasOldFormat) {
31
- console.log('✅ 索引已是新格式(无 AutoSnippet/recipes 前缀)\n');
32
28
  process.exit(0);
33
29
  }
34
-
35
- console.log('📊 检测到旧形式的索引:\n');
36
- const oldItems = data.items.filter(item =>
30
+ const oldItems = data.items.filter((item) =>
37
31
  item.metadata?.sourcePath?.startsWith('AutoSnippet/recipes/')
38
32
  );
39
- console.log(` • 含前缀的项目:${oldItems.length}`);
40
- console.log(` • 总项目数:${data.items.length}\n`);
41
-
42
- console.log('示例:');
43
- oldItems.slice(0, 3).forEach(item => {
44
- console.log(` "${item.metadata.sourcePath}"`);
45
- });
46
- console.log('\n');
33
+ oldItems.slice(0, 3).forEach((_item) => {});
47
34
 
48
35
  // 删除旧索引
49
36
  try {
50
37
  fs.unlinkSync(vectorIndexPath);
51
- console.log('✅ 已删除旧索引\n');
52
-
38
+
53
39
  // 删除 manifest.json
54
40
  const manifestPath = path.join(indexDir, '../manifest.json');
55
41
  if (fs.existsSync(manifestPath)) {
56
42
  fs.unlinkSync(manifestPath);
57
- console.log('✅ 已删除 manifest.json\n');
58
43
  }
59
-
60
- console.log('📝 下一步:\n');
61
- console.log('1. 使用源头修复版本重新生成索引:');
62
- console.log(` cd ${"'" + projectRoot + "'"}`);
63
- console.log(' asd embed\n');
64
- console.log('2. 或在开发模式下(本地测试):');
65
- console.log(' npm run dev:link');
66
- console.log(' cd ' + projectRoot);
67
- console.log(' ASD_SKIP_ENTRY_CHECK=1 asd embed\n');
68
-
69
- console.log('3. 新生成的索引将采用无前缀形式:');
70
- console.log(' "Check-Network-Permission.md" // 不再是 AutoSnippet/recipes/Check-Network-Permission.md\n');
71
-
72
- console.log('4. 搜索 API 会自动兼容两种形式(新旧数据均支持)\n');
73
-
74
44
  } catch (e) {
75
45
  console.error('❌ 删除失败:', e.message);
76
46
  process.exit(1);
@@ -6,19 +6,14 @@
6
6
  */
7
7
 
8
8
  import { fileURLToPath } from 'node:url';
9
+
9
10
  const __filename = fileURLToPath(import.meta.url);
10
11
 
11
12
  import fs from 'node:fs';
12
13
  import path from 'node:path';
13
- console.log('🧹 清理向量数据库缓存');
14
- console.log(' 原因: 向量维度不匹配 (Vectors must have the same length)');
15
- console.log(' 操作: 删除旧的向量索引,让系统重新生成 768 维向量');
16
- console.log('');
17
14
 
18
15
  // 获取项目路径(从参数或当前目录)
19
16
  const projectRoot = process.argv[2] || process.cwd();
20
- console.log(`📂 项目路径: ${projectRoot}`);
21
- console.log('');
22
17
 
23
18
  // 向量索引文件位置
24
19
  const vectorIndexPaths = [
@@ -30,7 +25,7 @@ const vectorIndexPaths = [
30
25
  ];
31
26
 
32
27
  let deletedCount = 0;
33
- let totalVectors = 0;
28
+ let _totalVectors = 0;
34
29
 
35
30
  for (const filePath of vectorIndexPaths) {
36
31
  if (fs.existsSync(filePath)) {
@@ -38,42 +33,17 @@ for (const filePath of vectorIndexPaths) {
38
33
  // 读取并显示信息
39
34
  const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
40
35
  const vectorCount = data.items ? data.items.length : 0;
41
- const firstVectorDim = data.items?.[0]?.vector?.length || 0;
42
-
43
- console.log(`📄 找到向量索引: ${filePath}`);
44
- console.log(` 向量数量: ${vectorCount}`);
45
- console.log(` 向量维度: ${firstVectorDim}${firstVectorDim !== 768 ? ' ⚠️ (不匹配,应为 768)' : ' ✅'}`);
46
-
47
- totalVectors += vectorCount;
48
-
36
+ const _firstVectorDim = data.items?.[0]?.vector?.length || 0;
37
+
38
+ _totalVectors += vectorCount;
39
+
49
40
  // 删除文件
50
41
  fs.unlinkSync(filePath);
51
- console.log(` ✅ 已删除`);
52
42
  deletedCount++;
53
- } catch (err) {
54
- console.log(` ❌ 处理失败: ${err.message}`);
55
- }
56
- console.log('');
43
+ } catch (_err) {}
57
44
  }
58
45
  }
59
46
 
60
47
  if (deletedCount > 0) {
61
- console.log(`✅ 成功清理 ${deletedCount} 个向量索引文件 (共 ${totalVectors} 个向量)`);
62
- console.log('');
63
- console.log('📝 下一步:');
64
- console.log(' 1. 重新运行搜索 (例如在 Xcode 中输入 // as:search color)');
65
- console.log(' 2. 系统会自动重建向量索引,使用统一的 768 维度');
66
- console.log(' 3. 首次搜索可能较慢(需要重新生成 embedding)');
67
48
  } else {
68
- console.log('ℹ️ 未找到向量索引文件(可能已经是干净状态)');
69
- console.log('');
70
- console.log('📝 如果问题仍然存在,请尝试:');
71
- console.log(` 1. 手动检查项目中的 .autosnippet 目录`);
72
- console.log(` 2. 运行: node ${__filename} <your-project-path>`);
73
49
  }
74
-
75
- console.log('');
76
- console.log('🔧 Google Gemini Embedding 配置:');
77
- console.log(' 模型: gemini-embedding-001');
78
- console.log(' 维度: 768 (统一)');
79
- console.log(' API: v1beta');
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @file collect-test-project-stats.mjs
5
+ * @description 遍历 20 个真实测试项目,执行 Discovery → langStats 收集,
6
+ * 输出 JSON 快照供单元测试使用。
7
+ *
8
+ * 用法: node scripts/collect-test-project-stats.mjs
9
+ * 输出: test/fixtures/real-project-stats.json
10
+ */
11
+
12
+ import fs from 'node:fs';
13
+ import path from 'node:path';
14
+ import { fileURLToPath } from 'node:url';
15
+
16
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
+ const ROOT = path.resolve(__dirname, '..');
18
+
19
+ // ── 测试项目列表 ──────────────────────────────────────────────────
20
+ const GITHUB_DIR = path.resolve(ROOT, '..');
21
+ const PROJECTS = [
22
+ 'Alamofire',
23
+ 'iCarousel',
24
+ 'Euclid',
25
+ 'Expression',
26
+ 'VectorMath',
27
+ 'layout',
28
+ 'RetroRampage',
29
+ 'Consumer',
30
+ 'SwiftFormat',
31
+ 'flask',
32
+ 'fastapi',
33
+ 'django-website',
34
+ 'spring-petclinic',
35
+ 'Pokedex',
36
+ 'gin',
37
+ 'axum',
38
+ 'nest',
39
+ 'todomvc',
40
+ 'vue-element-admin',
41
+ 'discourse',
42
+ ];
43
+
44
+ // ── 加载 AutoSnippet 模块 ─────────────────────────────────────────
45
+ const { getDiscovererRegistry, resetDiscovererRegistry } = await import(
46
+ '../lib/core/discovery/index.js'
47
+ );
48
+ const { LanguageService } = await import('../lib/shared/LanguageService.js');
49
+
50
+ // ── 主逻辑 ───────────────────────────────────────────────────────
51
+ async function collectStats() {
52
+ const results = {};
53
+
54
+ for (const name of PROJECTS) {
55
+ const projectRoot = path.join(GITHUB_DIR, name);
56
+ if (!fs.existsSync(projectRoot)) {
57
+ console.warn(`⚠ 跳过 ${name} — 目录不存在: ${projectRoot}`);
58
+ continue;
59
+ }
60
+ const t0 = Date.now();
61
+ process.stdout.write(`▶ 分析 ${name} ...\n`);
62
+
63
+ try {
64
+ // 每次重置 registry 以避免缓存干扰
65
+ resetDiscovererRegistry();
66
+ const registry = getDiscovererRegistry();
67
+
68
+ // Phase 1: Discovery
69
+ const discoverer = await registry.detect(projectRoot);
70
+ await discoverer.load(projectRoot);
71
+ const targets = await discoverer.listTargets();
72
+
73
+ // 收集文件
74
+ const seenPaths = new Set();
75
+ const files = [];
76
+ for (const t of targets) {
77
+ try {
78
+ const fileList = await discoverer.getTargetFiles(t);
79
+ for (const f of fileList) {
80
+ const fp = typeof f === 'string' ? f : f.path;
81
+ if (seenPaths.has(fp)) {
82
+ continue;
83
+ }
84
+ seenPaths.add(fp);
85
+ files.push({
86
+ name: typeof f === 'string' ? path.basename(f) : f.name || path.basename(fp),
87
+ path: fp,
88
+ });
89
+ if (files.length >= 2000) {
90
+ break;
91
+ }
92
+ }
93
+ } catch {
94
+ /* skip target */
95
+ }
96
+ if (files.length >= 2000) {
97
+ break;
98
+ }
99
+ }
100
+
101
+ // langStats
102
+ const langStats = {};
103
+ for (const f of files) {
104
+ const ext = path.extname(f.name).replace('.', '') || 'unknown';
105
+ langStats[ext] = (langStats[ext] || 0) + 1;
106
+ }
107
+
108
+ // LanguageService
109
+ const profile = LanguageService.detectProfile(langStats);
110
+ const primaryLang = LanguageService.detectPrimary(langStats);
111
+
112
+ // 依赖图
113
+ let depGraph = null;
114
+ try {
115
+ depGraph = await discoverer.getDependencyGraph();
116
+ } catch {
117
+ /* not available */
118
+ }
119
+
120
+ const elapsed = Date.now() - t0;
121
+
122
+ results[name] = {
123
+ projectRoot,
124
+ discoverer: discoverer.id,
125
+ discovererName: discoverer.displayName,
126
+ targets: targets.length,
127
+ files: files.length,
128
+ langStats,
129
+ primaryLang,
130
+ profile: {
131
+ primary: profile.primary,
132
+ secondary: profile.secondary,
133
+ isMultiLang: profile.isMultiLang,
134
+ },
135
+ depEdges: depGraph?.edges?.length || 0,
136
+ elapsedMs: elapsed,
137
+ };
138
+
139
+ process.stdout.write(
140
+ ` ✓ ${discoverer.id} | ${files.length} files | primary=${primaryLang} | ${elapsed}ms\n`
141
+ );
142
+ } catch (err) {
143
+ console.error(` ✗ ${name} 失败: ${err.message}`);
144
+ results[name] = { error: err.message };
145
+ }
146
+ }
147
+
148
+ // 写入 fixtures
149
+ const outPath = path.join(ROOT, 'test', 'fixtures', 'real-project-stats.json');
150
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
151
+ fs.writeFileSync(outPath, JSON.stringify(results, null, 2));
152
+ process.stdout.write(`\n✅ 写入 ${outPath} (${Object.keys(results).length} 个项目)\n`);
153
+
154
+ return results;
155
+ }
156
+
157
+ collectStats().catch((err) => {
158
+ console.error('Fatal:', err);
159
+ process.exit(1);
160
+ });
@@ -19,17 +19,28 @@ function getBaseUrl() {
19
19
  function request(method, urlStr) {
20
20
  const url = new URL(urlStr);
21
21
  const client = url.protocol === 'https:' ? https : http;
22
- const opts = { hostname: url.hostname, port: url.port || (url.protocol === 'https:' ? 443 : 80), path: url.pathname, method };
22
+ const opts = {
23
+ hostname: url.hostname,
24
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
25
+ path: url.pathname,
26
+ method,
27
+ };
23
28
  return new Promise((resolve, reject) => {
24
- const req = client.request(opts, (res) => {
25
- let data = '';
26
- res.on('data', (ch) => { data += ch; });
27
- res.on('end', () => {
28
- try { resolve(JSON.parse(data)); } catch { resolve({ statusCode: res.statusCode, raw: data }); }
29
+ const req = client.request(opts, (res) => {
30
+ let data = '';
31
+ res.on('data', (ch) => {
32
+ data += ch;
33
+ });
34
+ res.on('end', () => {
35
+ try {
36
+ resolve(JSON.parse(data));
37
+ } catch {
38
+ resolve({ statusCode: res.statusCode, raw: data });
39
+ }
40
+ });
29
41
  });
30
- });
31
- req.on('error', reject);
32
- req.end();
42
+ req.on('error', reject);
43
+ req.end();
33
44
  });
34
45
  }
35
46
 
@@ -37,38 +48,36 @@ function request(method, urlStr) {
37
48
  const base = getBaseUrl();
38
49
  const healthUrl = new URL('/api/health', base).toString();
39
50
  const env = {
40
- ASD_UI_URL: process.env.ASD_UI_URL || null,
41
- ASD_MCP_TOKEN: process.env.ASD_MCP_TOKEN ? 'set' : 'unset'
51
+ ASD_UI_URL: process.env.ASD_UI_URL || null,
52
+ ASD_MCP_TOKEN: process.env.ASD_MCP_TOKEN ? 'set' : 'unset',
42
53
  };
43
54
 
44
55
  let health = null;
45
56
  let ok = false;
46
57
  let msg = '';
47
58
  try {
48
- health = await request('GET', healthUrl);
49
- ok = Boolean(health && (health.status === 'healthy' || health.healthy === true));
50
- msg = ok ? 'UI 健康检查通过' : 'UI 健康检查返回非健康状态';
59
+ health = await request('GET', healthUrl);
60
+ ok = Boolean(health && (health.status === 'healthy' || health.healthy === true));
61
+ msg = ok ? 'UI 健康检查通过' : 'UI 健康检查返回非健康状态';
51
62
  } catch (e) {
52
- msg = `无法连接到 UI: ${e.message}`;
63
+ msg = `无法连接到 UI: ${e.message}`;
53
64
  }
54
65
 
55
- const report = {
56
- success: ok,
57
- message: msg,
58
- data: { health },
59
- meta: {
60
- checker: 'diagnose-mcp',
61
- baseUrl: base,
62
- healthUrl,
63
- env
64
- },
65
- next: [
66
- '在 MCP 客户端调用 autosnippet_health / autosnippet_capabilities 进行能力自检',
67
- '如需鉴权,请在 MCP 服务器环境设置 ASD_MCP_TOKEN',
68
- '提交候选时传入 clientId 以启用限流(避免短时间批量提交)'
69
- ]
66
+ const _report = {
67
+ success: ok,
68
+ message: msg,
69
+ data: { health },
70
+ meta: {
71
+ checker: 'diagnose-mcp',
72
+ baseUrl: base,
73
+ healthUrl,
74
+ env,
75
+ },
76
+ next: [
77
+ '在 MCP 客户端调用 autosnippet_health / autosnippet_capabilities 进行能力自检',
78
+ '如需鉴权,请在 MCP 服务器环境设置 ASD_MCP_TOKEN',
79
+ '提交候选时传入 clientId 以启用限流(避免短时间批量提交)',
80
+ ],
70
81
  };
71
-
72
- console.log(JSON.stringify(report, null, 2));
73
82
  process.exit(ok ? 0 : 1);
74
83
  })();
@@ -5,14 +5,15 @@
5
5
  * 仅当 ASD_BUILD_SWIFT_PARSER=1 时构建;否则打印说明并跳过。成功则运行时优先使用 ParsePackage;未构建时回退 dump-package / AST-lite。
6
6
  */
7
7
 
8
- import { fileURLToPath } from 'node:url';
9
8
  import { dirname } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+
10
11
  const __filename = fileURLToPath(import.meta.url);
11
12
  const __dirname = dirname(__filename);
12
13
 
13
14
  import { spawnSync } from 'node:child_process';
14
- import path from 'node:path';
15
15
  import fs from 'node:fs';
16
+ import path from 'node:path';
16
17
 
17
18
  const rootDir = path.resolve(__dirname, '..');
18
19
  const parsePackageDir = path.join(rootDir, 'tools', 'parse-package');
@@ -21,12 +22,11 @@ const binaryPath = path.join(parsePackageDir, '.build', 'release', 'ParsePackage
21
22
 
22
23
  function runSwiftBuild() {
23
24
  const result = spawnSync('swift', ['build', '-c', 'release'], {
24
- cwd: parsePackageDir,
25
- stdio: 'inherit',
26
- shell: false,
25
+ cwd: parsePackageDir,
26
+ stdio: 'inherit',
27
+ shell: false,
27
28
  });
28
29
  if (result.status === 0 && fs.existsSync(binaryPath)) {
29
- console.log('Swift 解析器安装完成。');
30
30
  }
31
31
  process.exit(0);
32
32
  }
@@ -40,10 +40,7 @@ if (fs.existsSync(binaryPath)) {
40
40
 
41
41
  // 仅当显式设置环境变量时构建,并说明在安装什么
42
42
  if (process.env.ASD_BUILD_SWIFT_PARSER === '1' || process.env.ASD_BUILD_SWIFT_PARSER === 'true') {
43
- console.log('正在安装 Swift 解析器(ParsePackage)…');
44
43
  runSwiftBuild();
45
44
  process.exit(0);
46
45
  }
47
-
48
- console.log('跳过 Swift 解析器(ParsePackage);需要时执行 asd install:full --parser 或安装时设置 ASD_BUILD_SWIFT_PARSER=1。');
49
46
  process.exit(0);