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
@@ -42,9 +42,7 @@ function _getProjectSkillsDir() {
42
42
  */
43
43
  function _parseSkillMeta(skillName, baseDir = SKILLS_DIR) {
44
44
  try {
45
- const content = fs.readFileSync(
46
- path.join(baseDir, skillName, 'SKILL.md'), 'utf8',
47
- );
45
+ const content = fs.readFileSync(path.join(baseDir, skillName, 'SKILL.md'), 'utf8');
48
46
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
49
47
  const meta = { description: skillName, createdBy: null, createdAt: null };
50
48
  if (fmMatch) {
@@ -53,12 +51,17 @@ function _parseSkillMeta(skillName, baseDir = SKILLS_DIR) {
53
51
  if (descMatch) {
54
52
  const desc = descMatch[1].trim();
55
53
  const firstSentence = desc.split(/\.\s/)[0];
56
- meta.description = firstSentence.length < desc.length ? `${firstSentence}.` : desc.substring(0, 120);
54
+ meta.description =
55
+ firstSentence.length < desc.length ? `${firstSentence}.` : desc.substring(0, 120);
57
56
  }
58
57
  const cbMatch = fm.match(/^createdBy:\s*(.+?)$/m);
59
- if (cbMatch) meta.createdBy = cbMatch[1].trim();
58
+ if (cbMatch) {
59
+ meta.createdBy = cbMatch[1].trim();
60
+ }
60
61
  const caMatch = fm.match(/^createdAt:\s*(.+?)$/m);
61
- if (caMatch) meta.createdAt = caMatch[1].trim();
62
+ if (caMatch) {
63
+ meta.createdAt = caMatch[1].trim();
64
+ }
62
65
  }
63
66
  return meta;
64
67
  } catch {
@@ -83,6 +86,10 @@ const SKILL_USE_CASES = {
83
86
  'autosnippet-reference-swift': 'Swift 语言最佳实践参考',
84
87
  'autosnippet-reference-objc': 'Objective-C 语言最佳实践参考',
85
88
  'autosnippet-reference-jsts': 'JavaScript/TypeScript 语言最佳实践参考',
89
+ 'autosnippet-reference-python': 'Python 语言最佳实践参考',
90
+ 'autosnippet-reference-java': 'Java 语言最佳实践参考',
91
+ 'autosnippet-reference-kotlin': 'Kotlin 语言最佳实践参考',
92
+ 'autosnippet-reference-go': 'Go 语言最佳实践参考',
86
93
  };
87
94
 
88
95
  // ═══════════════════════════════════════════════════════════
@@ -99,23 +106,43 @@ export function listSkills() {
99
106
  const skillMap = new Map();
100
107
 
101
108
  // 内置 Skills
102
- const builtinDirs = fs.readdirSync(SKILLS_DIR, { withFileTypes: true })
103
- .filter(d => d.isDirectory()).map(d => d.name);
109
+ const builtinDirs = fs
110
+ .readdirSync(SKILLS_DIR, { withFileTypes: true })
111
+ .filter((d) => d.isDirectory())
112
+ .map((d) => d.name);
104
113
  for (const name of builtinDirs) {
105
114
  const meta = _parseSkillMeta(name, SKILLS_DIR);
106
- skillMap.set(name, { name, source: 'builtin', summary: meta.description, createdBy: null, createdAt: null, useCase: SKILL_USE_CASES[name] || null });
115
+ skillMap.set(name, {
116
+ name,
117
+ source: 'builtin',
118
+ summary: meta.description,
119
+ createdBy: null,
120
+ createdAt: null,
121
+ useCase: SKILL_USE_CASES[name] || null,
122
+ });
107
123
  }
108
124
 
109
125
  // 项目级 Skills(覆盖同名内置)
110
126
  try {
111
127
  const projectSkillsDir = _getProjectSkillsDir();
112
- const projectDirs = fs.readdirSync(projectSkillsDir, { withFileTypes: true })
113
- .filter(d => d.isDirectory()).map(d => d.name);
128
+ const projectDirs = fs
129
+ .readdirSync(projectSkillsDir, { withFileTypes: true })
130
+ .filter((d) => d.isDirectory())
131
+ .map((d) => d.name);
114
132
  for (const name of projectDirs) {
115
133
  const meta = _parseSkillMeta(name, projectSkillsDir);
116
- skillMap.set(name, { name, source: 'project', summary: meta.description, createdBy: meta.createdBy, createdAt: meta.createdAt, useCase: SKILL_USE_CASES[name] || null });
134
+ skillMap.set(name, {
135
+ name,
136
+ source: 'project',
137
+ summary: meta.description,
138
+ createdBy: meta.createdBy,
139
+ createdAt: meta.createdAt,
140
+ useCase: SKILL_USE_CASES[name] || null,
141
+ });
117
142
  }
118
- } catch { /* no project skills */ }
143
+ } catch {
144
+ /* no project skills */
145
+ }
119
146
 
120
147
  const skills = [...skillMap.values()].sort((a, b) => a.name.localeCompare(b.name));
121
148
 
@@ -126,7 +153,9 @@ export function listSkills() {
126
153
  const snapshot = global._signalCollector.getSnapshot();
127
154
  suggestionCount = snapshot?.lastResult?.newSuggestions || 0;
128
155
  }
129
- } catch { /* silent */ }
156
+ } catch {
157
+ /* silent */
158
+ }
130
159
 
131
160
  return JSON.stringify({
132
161
  success: true,
@@ -180,7 +209,7 @@ export function loadSkill(_ctx, args) {
180
209
  if (section) {
181
210
  const sectionRe = new RegExp(
182
211
  `^##\\s+.*${section.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}.*$\\n([\\s\\S]*?)(?=^##\\s|$)`,
183
- 'mi',
212
+ 'mi'
184
213
  );
185
214
  const match = content.match(sectionRe);
186
215
  if (match) {
@@ -207,8 +236,16 @@ export function loadSkill(_ctx, args) {
207
236
  } catch {
208
237
  // 列出所有可用 Skills
209
238
  const available = new Set();
210
- try { fs.readdirSync(SKILLS_DIR, { withFileTypes: true }).filter(d => d.isDirectory()).forEach(d => available.add(d.name)); } catch {}
211
- try { fs.readdirSync(_getProjectSkillsDir(), { withFileTypes: true }).filter(d => d.isDirectory()).forEach(d => available.add(d.name)); } catch {}
239
+ try {
240
+ fs.readdirSync(SKILLS_DIR, { withFileTypes: true })
241
+ .filter((d) => d.isDirectory())
242
+ .forEach((d) => available.add(d.name));
243
+ } catch {}
244
+ try {
245
+ fs.readdirSync(_getProjectSkillsDir(), { withFileTypes: true })
246
+ .filter((d) => d.isDirectory())
247
+ .forEach((d) => available.add(d.name));
248
+ } catch {}
212
249
 
213
250
  return JSON.stringify({
214
251
  success: false,
@@ -234,7 +271,14 @@ export function loadSkill(_ctx, args) {
234
271
  * @returns {string} JSON envelope
235
272
  */
236
273
  export function createSkill(_ctx, args) {
237
- const { name, description, content, overwrite = false, createdBy = 'external-ai', title } = args || {};
274
+ const {
275
+ name,
276
+ description,
277
+ content,
278
+ overwrite = false,
279
+ createdBy = 'external-ai',
280
+ title,
281
+ } = args || {};
238
282
 
239
283
  // ── 参数校验 ──
240
284
  if (!name || !description || !content) {
@@ -288,22 +332,23 @@ export function createSkill(_ctx, args) {
288
332
  fs.mkdirSync(skillDir, { recursive: true });
289
333
 
290
334
  // 自动推断 title: 优先使用传入参数,否则从 content 的第一个 # heading 提取
291
- const resolvedTitle = title || (() => {
292
- const m = (content || '').match(/^#\s+(.+)/m);
293
- return m ? m[1].trim() : '';
294
- })();
335
+ const resolvedTitle =
336
+ title ||
337
+ (() => {
338
+ const m = (content || '').match(/^#\s+(.+)/m);
339
+ return m ? m[1].trim() : '';
340
+ })();
295
341
 
296
- const fmLines = [
297
- '---',
298
- `name: ${name}`,
299
- ];
300
- if (resolvedTitle) fmLines.push(`title: "${resolvedTitle.replace(/"/g, '\\"')}"`);
342
+ const fmLines = ['---', `name: ${name}`];
343
+ if (resolvedTitle) {
344
+ fmLines.push(`title: "${resolvedTitle.replace(/"/g, '\\"')}"`);
345
+ }
301
346
  fmLines.push(
302
347
  `description: ${description}`,
303
348
  `createdBy: ${createdBy}`,
304
349
  `createdAt: ${new Date().toISOString()}`,
305
350
  '---',
306
- '',
351
+ ''
307
352
  );
308
353
  const frontmatter = fmLines.join('\n');
309
354
 
@@ -323,7 +368,9 @@ export function createSkill(_ctx, args) {
323
368
  if (global._signalCollector) {
324
369
  global._signalCollector.removePendingSuggestion(name);
325
370
  }
326
- } catch { /* silent */ }
371
+ } catch {
372
+ /* silent */
373
+ }
327
374
 
328
375
  return JSON.stringify({
329
376
  success: true,
@@ -346,17 +393,20 @@ export function createSkill(_ctx, args) {
346
393
  function _regenerateEditorIndex() {
347
394
  try {
348
395
  // 扫描项目级 Skills
349
- let projectSkills = [];
396
+ const projectSkills = [];
350
397
  const projectSkillsDir = _getProjectSkillsDir();
351
398
  try {
352
- const dirs = fs.readdirSync(projectSkillsDir, { withFileTypes: true })
353
- .filter(d => d.isDirectory())
354
- .map(d => d.name);
399
+ const dirs = fs
400
+ .readdirSync(projectSkillsDir, { withFileTypes: true })
401
+ .filter((d) => d.isDirectory())
402
+ .map((d) => d.name);
355
403
  for (const name of dirs) {
356
404
  const meta = _parseSkillMeta(name, projectSkillsDir);
357
405
  projectSkills.push({ name, summary: meta.description });
358
406
  }
359
- } catch { /* no project skills dir */ }
407
+ } catch {
408
+ /* no project skills dir */
409
+ }
360
410
 
361
411
  const projectRoot = _getProjectRoot();
362
412
  const rulesDir = path.join(projectRoot, '.cursor', 'rules');
@@ -364,14 +414,16 @@ function _regenerateEditorIndex() {
364
414
  if (projectSkills.length === 0) {
365
415
  // 没有项目级 Skills 时,删除索引文件(如果存在)
366
416
  const indexPath = path.join(rulesDir, 'autosnippet-skills.mdc');
367
- try { fs.unlinkSync(indexPath); } catch { /* not exists */ }
417
+ try {
418
+ fs.unlinkSync(indexPath);
419
+ } catch {
420
+ /* not exists */
421
+ }
368
422
  return { success: true, skillCount: 0 };
369
423
  }
370
424
 
371
425
  // 生成 .mdc 内容
372
- const skillLines = projectSkills
373
- .map(s => `- **${s.name}**: ${s.summary}`)
374
- .join('\n');
426
+ const skillLines = projectSkills.map((s) => `- **${s.name}**: ${s.summary}`).join('\n');
375
427
 
376
428
  const mdcContent = [
377
429
  '---',
@@ -505,7 +557,10 @@ export function updateSkill(_ctx, args) {
505
557
  if (!description && !content) {
506
558
  return JSON.stringify({
507
559
  success: false,
508
- error: { code: 'NOTHING_TO_UPDATE', message: 'At least one of description or content must be provided.' },
560
+ error: {
561
+ code: 'NOTHING_TO_UPDATE',
562
+ message: 'At least one of description or content must be provided.',
563
+ },
509
564
  });
510
565
  }
511
566
 
@@ -563,14 +618,16 @@ export function updateSkill(_ctx, args) {
563
618
 
564
619
  // 重建 frontmatter
565
620
  const fmLines = ['---', `name: ${name}`];
566
- if (title) fmLines.push(`title: ${title}`);
621
+ if (title) {
622
+ fmLines.push(`title: ${title}`);
623
+ }
567
624
  fmLines.push(
568
625
  `description: ${newDesc}`,
569
626
  `createdBy: ${createdBy}`,
570
627
  `createdAt: ${createdAt}`,
571
628
  `updatedAt: ${new Date().toISOString()}`,
572
629
  '---',
573
- '',
630
+ ''
574
631
  );
575
632
 
576
633
  pathGuard.assertProjectWriteSafe(path.join(projectSkillsDir, name));
@@ -590,7 +647,9 @@ export function updateSkill(_ctx, args) {
590
647
  data: {
591
648
  skillName: name,
592
649
  updated: true,
593
- fieldsUpdated: [description ? 'description' : null, content ? 'content' : null].filter(Boolean),
650
+ fieldsUpdated: [description ? 'description' : null, content ? 'content' : null].filter(
651
+ Boolean
652
+ ),
594
653
  editorIndex: indexResult,
595
654
  hint: `Skill "${name}" updated. Use autosnippet_skill({ operation: "load", name: "${name}" }) to verify content.`,
596
655
  },
@@ -636,9 +695,21 @@ export async function suggestSkills(ctx) {
636
695
  */
637
696
  function _getRelatedSkills(skillName) {
638
697
  const relations = {
639
- 'autosnippet-coldstart': ['autosnippet-analysis', 'autosnippet-candidates', 'autosnippet-structure'],
640
- 'autosnippet-analysis': ['autosnippet-candidates', 'autosnippet-coldstart', 'autosnippet-structure'],
641
- 'autosnippet-candidates': ['autosnippet-analysis', 'autosnippet-create', 'autosnippet-lifecycle'],
698
+ 'autosnippet-coldstart': [
699
+ 'autosnippet-analysis',
700
+ 'autosnippet-candidates',
701
+ 'autosnippet-structure',
702
+ ],
703
+ 'autosnippet-analysis': [
704
+ 'autosnippet-candidates',
705
+ 'autosnippet-coldstart',
706
+ 'autosnippet-structure',
707
+ ],
708
+ 'autosnippet-candidates': [
709
+ 'autosnippet-analysis',
710
+ 'autosnippet-create',
711
+ 'autosnippet-lifecycle',
712
+ ],
642
713
  'autosnippet-create': ['autosnippet-candidates', 'autosnippet-lifecycle'],
643
714
  'autosnippet-guard': ['autosnippet-recipes', 'autosnippet-analysis'],
644
715
  'autosnippet-recipes': ['autosnippet-guard', 'autosnippet-structure', 'autosnippet-concepts'],
@@ -649,6 +720,10 @@ function _getRelatedSkills(skillName) {
649
720
  'autosnippet-reference-swift': ['autosnippet-coldstart', 'autosnippet-analysis'],
650
721
  'autosnippet-reference-objc': ['autosnippet-coldstart', 'autosnippet-analysis'],
651
722
  'autosnippet-reference-jsts': ['autosnippet-coldstart', 'autosnippet-analysis'],
723
+ 'autosnippet-reference-python': ['autosnippet-coldstart', 'autosnippet-analysis'],
724
+ 'autosnippet-reference-java': ['autosnippet-coldstart', 'autosnippet-analysis'],
725
+ 'autosnippet-reference-kotlin': ['autosnippet-coldstart', 'autosnippet-analysis'],
726
+ 'autosnippet-reference-go': ['autosnippet-coldstart', 'autosnippet-analysis'],
652
727
  };
653
728
  return relations[skillName] || [];
654
729
  }