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.
- package/README.md +230 -324
- package/bin/api-server.js +1 -1
- package/bin/cli.js +204 -244
- package/bin/mcp-server.js +5 -3
- package/config/knowledge-base.config.js +132 -132
- package/dashboard/dist/assets/{icons-CEfgGaZi.js → icons-Cdq22n2i.js} +95 -100
- package/dashboard/dist/assets/index-ClkyPkDX.js +133 -0
- package/dashboard/dist/assets/index-t4QrJwv1.css +1 -0
- package/dashboard/dist/index.html +3 -3
- package/lib/bootstrap.js +8 -8
- package/lib/cli/AiScanService.js +86 -40
- package/lib/cli/KnowledgeSyncService.js +113 -74
- package/lib/cli/SetupService.js +439 -277
- package/lib/cli/UpgradeService.js +63 -100
- package/lib/core/AstAnalyzer.js +276 -597
- package/lib/core/ast/ProjectGraph.js +101 -40
- package/lib/core/ast/ensure-grammars.js +232 -0
- package/lib/core/ast/index.js +115 -0
- package/lib/core/ast/lang-dart.js +661 -0
- package/lib/core/ast/lang-go.js +530 -0
- package/lib/core/ast/lang-java.js +435 -0
- package/lib/core/ast/lang-javascript.js +272 -0
- package/lib/core/ast/lang-kotlin.js +423 -0
- package/lib/core/ast/lang-objc.js +388 -0
- package/lib/core/ast/lang-python.js +371 -0
- package/lib/core/ast/lang-swift.js +337 -0
- package/lib/core/ast/lang-typescript.js +503 -0
- package/lib/core/capability/CapabilityProbe.js +18 -9
- package/lib/core/constitution/Constitution.js +2 -3
- package/lib/core/constitution/ConstitutionValidator.js +65 -24
- package/lib/core/discovery/DartDiscoverer.js +534 -0
- package/lib/core/discovery/DiscovererRegistry.js +83 -0
- package/lib/core/discovery/GenericDiscoverer.js +225 -0
- package/lib/core/discovery/GoDiscoverer.js +541 -0
- package/lib/core/discovery/JvmDiscoverer.js +506 -0
- package/lib/core/discovery/NodeDiscoverer.js +466 -0
- package/lib/core/discovery/ProjectDiscoverer.js +93 -0
- package/lib/core/discovery/PythonDiscoverer.js +338 -0
- package/lib/core/discovery/SpmDiscoverer.js +5 -0
- package/lib/core/discovery/index.js +53 -0
- package/lib/core/enhancement/EnhancementPack.js +71 -0
- package/lib/core/enhancement/EnhancementRegistry.js +47 -0
- package/lib/core/enhancement/android-enhancement.js +102 -0
- package/lib/core/enhancement/django-enhancement.js +70 -0
- package/lib/core/enhancement/fastapi-enhancement.js +63 -0
- package/lib/core/enhancement/go-grpc-enhancement.js +152 -0
- package/lib/core/enhancement/go-web-enhancement.js +201 -0
- package/lib/core/enhancement/index.js +65 -0
- package/lib/core/enhancement/node-server-enhancement.js +88 -0
- package/lib/core/enhancement/react-enhancement.js +86 -0
- package/lib/core/enhancement/spring-enhancement.js +112 -0
- package/lib/core/enhancement/vue-enhancement.js +96 -0
- package/lib/core/gateway/Gateway.js +8 -9
- package/lib/core/gateway/GatewayActionRegistry.js +1 -1
- package/lib/core/permission/PermissionManager.js +12 -8
- package/lib/domain/index.js +13 -9
- package/lib/domain/knowledge/KnowledgeEntry.js +111 -101
- package/lib/domain/knowledge/KnowledgeRepository.js +0 -1
- package/lib/domain/knowledge/Lifecycle.js +22 -22
- package/lib/domain/knowledge/index.js +9 -12
- package/lib/domain/knowledge/values/Constraints.js +31 -21
- package/lib/domain/knowledge/values/Content.js +21 -13
- package/lib/domain/knowledge/values/Quality.js +31 -18
- package/lib/domain/knowledge/values/Reasoning.js +20 -12
- package/lib/domain/knowledge/values/Relations.js +37 -25
- package/lib/domain/knowledge/values/Stats.js +18 -12
- package/lib/domain/knowledge/values/index.js +4 -3
- package/lib/domain/snippet/Snippet.js +35 -10
- package/lib/external/ai/AiFactory.js +48 -16
- package/lib/external/ai/AiProvider.js +184 -90
- package/lib/external/ai/providers/ClaudeProvider.js +25 -12
- package/lib/external/ai/providers/GoogleGeminiProvider.js +59 -30
- package/lib/external/ai/providers/MockProvider.js +9 -3
- package/lib/external/ai/providers/OpenAiProvider.js +51 -29
- package/lib/external/mcp/McpServer.js +66 -36
- package/lib/external/mcp/errorHandler.js +23 -11
- package/lib/external/mcp/handlers/LanguageExtensions.js +138 -53
- package/lib/external/mcp/handlers/TargetClassifier.js +52 -16
- package/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +81 -20
- package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +71 -42
- package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +9 -17
- package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +14 -9
- package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +15 -7
- package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +352 -153
- package/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +52 -12
- package/lib/external/mcp/handlers/bootstrap/skills.js +143 -39
- package/lib/external/mcp/handlers/bootstrap.js +691 -168
- package/lib/external/mcp/handlers/browse.js +66 -22
- package/lib/external/mcp/handlers/candidate.js +118 -35
- package/lib/external/mcp/handlers/consolidated.js +49 -17
- package/lib/external/mcp/handlers/guard.js +104 -39
- package/lib/external/mcp/handlers/knowledge.js +60 -36
- package/lib/external/mcp/handlers/search.js +43 -14
- package/lib/external/mcp/handlers/skill.js +120 -45
- package/lib/external/mcp/handlers/structure.js +240 -86
- package/lib/external/mcp/handlers/system.js +42 -12
- package/lib/external/mcp/handlers/wiki.js +58 -33
- package/lib/external/mcp/tools.js +306 -123
- package/lib/http/HttpServer.js +72 -47
- package/lib/http/middleware/RateLimiter.js +5 -3
- package/lib/http/middleware/errorHandler.js +6 -1
- package/lib/http/middleware/requestLogger.js +14 -3
- package/lib/http/middleware/roleResolver.js +30 -23
- package/lib/http/routes/ai.js +387 -265
- package/lib/http/routes/auth.js +81 -61
- package/lib/http/routes/candidates.js +430 -320
- package/lib/http/routes/commands.js +289 -189
- package/lib/http/routes/extract.js +158 -125
- package/lib/http/routes/guardRules.js +309 -217
- package/lib/http/routes/knowledge.js +213 -154
- package/lib/http/routes/modules.js +578 -0
- package/lib/http/routes/monitoring.js +6 -6
- package/lib/http/routes/recipes.js +104 -93
- package/lib/http/routes/search.js +361 -305
- package/lib/http/routes/skills.js +145 -98
- package/lib/http/routes/snippets.js +42 -30
- package/lib/http/routes/spm.js +3 -405
- package/lib/http/routes/violations.js +113 -93
- package/lib/http/routes/wiki.js +211 -170
- package/lib/http/utils/routeHelpers.js +3 -1
- package/lib/http/utils/sse-sessions.js +16 -6
- package/lib/http/utils/sse.js +15 -5
- package/lib/infrastructure/audit/AuditLogger.js +5 -2
- package/lib/infrastructure/audit/AuditStore.js +10 -7
- package/lib/infrastructure/cache/CacheService.js +3 -1
- package/lib/infrastructure/cache/GraphCache.js +8 -4
- package/lib/infrastructure/cache/UnifiedCacheAdapter.js +1 -1
- package/lib/infrastructure/config/ConfigLoader.js +9 -5
- package/lib/infrastructure/config/Defaults.js +30 -10
- package/lib/infrastructure/config/Paths.js +28 -8
- package/lib/infrastructure/config/TriggerSymbol.js +22 -10
- package/lib/infrastructure/database/DatabaseConnection.js +15 -10
- package/lib/infrastructure/database/migrations/001_initial_schema.js +0 -1
- package/lib/infrastructure/external/ClipboardManager.js +6 -2
- package/lib/infrastructure/external/NativeUi.js +50 -43
- package/lib/infrastructure/external/OpenBrowser.js +14 -17
- package/lib/infrastructure/external/XcodeAutomation.js +14 -258
- package/lib/infrastructure/logging/Logger.js +46 -30
- package/lib/infrastructure/monitoring/ErrorTracker.js +7 -5
- package/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -4
- package/lib/infrastructure/paths/HeaderResolver.js +25 -9
- package/lib/infrastructure/paths/PathFinder.js +34 -12
- package/lib/infrastructure/plugin/PluginManager.js +26 -8
- package/lib/infrastructure/realtime/RealtimeService.js +2 -2
- package/lib/infrastructure/vector/Chunker.js +22 -7
- package/lib/infrastructure/vector/IndexingPipeline.js +46 -22
- package/lib/infrastructure/vector/JsonVectorAdapter.js +90 -53
- package/lib/infrastructure/vector/VectorStore.js +28 -10
- package/lib/injection/ServiceContainer.js +247 -93
- package/lib/platform/ios/index.js +63 -0
- package/lib/platform/ios/routes/spm.js +437 -0
- package/lib/platform/ios/snippet/PlaceholderConverter.js +55 -0
- package/lib/platform/ios/snippet/XcodeCodec.js +112 -0
- package/lib/{service → platform/ios}/spm/DependencyGraph.js +41 -17
- package/lib/{service → platform/ios}/spm/PackageSwiftParser.js +41 -14
- package/lib/{service → platform/ios}/spm/PolicyEngine.js +9 -4
- package/lib/platform/ios/spm/SpmDiscoverer.js +122 -0
- package/lib/{service → platform/ios}/spm/SpmService.js +385 -127
- package/lib/{service/automation → platform/ios/xcode}/SaveEventFilter.js +8 -7
- package/lib/platform/ios/xcode/XcodeAutomation.js +350 -0
- package/lib/{service/automation → platform/ios/xcode}/XcodeIntegration.js +325 -145
- package/lib/repository/base/BaseRepository.js +7 -9
- package/lib/repository/knowledge/KnowledgeRepository.impl.js +98 -75
- package/lib/repository/token/TokenUsageStore.js +4 -2
- package/lib/service/automation/ActionPipeline.js +1 -1
- package/lib/service/automation/AutomationOrchestrator.js +8 -4
- package/lib/service/automation/ContextCollector.js +7 -5
- package/lib/service/automation/DirectiveDetector.js +23 -16
- package/lib/service/automation/FileWatcher.js +112 -56
- package/lib/service/automation/TriggerResolver.js +6 -4
- package/lib/service/automation/handlers/AlinkHandler.js +24 -12
- package/lib/service/automation/handlers/CreateHandler.js +19 -20
- package/lib/service/automation/handlers/DraftHandler.js +14 -8
- package/lib/service/automation/handlers/GuardHandler.js +93 -63
- package/lib/service/automation/handlers/HeaderHandler.js +1 -6
- package/lib/service/automation/handlers/SearchHandler.js +155 -88
- package/lib/service/bootstrap/BootstrapTaskManager.js +77 -35
- package/lib/service/candidate/SimilarityService.js +25 -9
- package/lib/service/chat/AnalystAgent.js +50 -24
- package/lib/service/chat/CandidateGuardrail.js +143 -17
- package/lib/service/chat/ChatAgent.js +655 -260
- package/lib/service/chat/ContextWindow.js +116 -71
- package/lib/service/chat/ConversationStore.js +77 -36
- package/lib/service/chat/EpisodicConsolidator.js +47 -23
- package/lib/service/chat/HandoffProtocol.js +98 -22
- package/lib/service/chat/Memory.js +34 -14
- package/lib/service/chat/ProducerAgent.js +40 -20
- package/lib/service/chat/ProjectSemanticMemory.js +109 -78
- package/lib/service/chat/ReasoningLayer.js +148 -70
- package/lib/service/chat/ReasoningTrace.js +44 -32
- package/lib/service/chat/TaskPipeline.js +39 -19
- package/lib/service/chat/ToolRegistry.js +48 -29
- package/lib/service/chat/WorkingMemory.js +44 -18
- package/lib/service/chat/tools.js +1096 -494
- package/lib/service/context/RecipeExtractor.js +132 -51
- package/lib/service/cursor/CursorDeliveryPipeline.js +82 -37
- package/lib/service/cursor/KnowledgeCompressor.js +25 -22
- package/lib/service/cursor/RulesGenerator.js +13 -7
- package/lib/service/cursor/SkillsSyncer.js +77 -27
- package/lib/service/cursor/TokenBudget.js +2 -2
- package/lib/service/cursor/TopicClassifier.js +54 -20
- package/lib/service/guard/ComplianceReporter.js +55 -43
- package/lib/service/guard/ExclusionManager.js +67 -29
- package/lib/service/guard/GuardCheckEngine.js +381 -86
- package/lib/service/guard/GuardFeedbackLoop.js +22 -10
- package/lib/service/guard/GuardService.js +29 -19
- package/lib/service/guard/RuleLearner.js +55 -23
- package/lib/service/guard/SourceFileCollector.js +27 -20
- package/lib/service/guard/ViolationsStore.js +43 -38
- package/lib/service/knowledge/CodeEntityGraph.js +147 -82
- package/lib/service/knowledge/ConfidenceRouter.js +12 -10
- package/lib/service/knowledge/KnowledgeFileWriter.js +147 -56
- package/lib/service/knowledge/KnowledgeGraphService.js +81 -34
- package/lib/service/knowledge/KnowledgeService.js +222 -112
- package/lib/service/module/ModuleService.js +969 -0
- package/lib/service/quality/FeedbackCollector.js +27 -15
- package/lib/service/quality/QualityScorer.js +78 -24
- package/lib/service/recipe/RecipeCandidateValidator.js +110 -44
- package/lib/service/recipe/RecipeParser.js +78 -45
- package/lib/service/search/CoarseRanker.js +43 -28
- package/lib/service/search/CrossEncoderReranker.js +32 -21
- package/lib/service/search/InvertedIndex.js +21 -7
- package/lib/service/search/MultiSignalRanker.js +90 -28
- package/lib/service/search/RetrievalFunnel.js +45 -24
- package/lib/service/search/SearchEngine.js +255 -103
- package/lib/service/skills/EventAggregator.js +32 -15
- package/lib/service/skills/SignalCollector.js +140 -64
- package/lib/service/skills/SkillAdvisor.js +79 -42
- package/lib/service/skills/SkillHooks.js +16 -14
- package/lib/service/snippet/PlaceholderConverter.js +5 -0
- package/lib/service/snippet/SnippetFactory.js +116 -99
- package/lib/service/snippet/SnippetInstaller.js +234 -62
- package/lib/service/snippet/codecs/SnippetCodec.js +67 -0
- package/lib/service/snippet/codecs/VSCodeCodec.js +102 -0
- package/lib/service/snippet/codecs/XcodeCodec.js +5 -0
- package/lib/service/wiki/WikiGenerator.js +637 -263
- package/lib/shared/DimensionCopyRegistry.js +472 -0
- package/lib/shared/LanguageService.js +399 -0
- package/lib/shared/PathGuard.js +45 -28
- package/lib/shared/RecipeReadinessChecker.js +72 -12
- package/lib/shared/constants.js +41 -41
- package/lib/shared/errors/BaseError.js +2 -2
- package/lib/shared/errors/index.js +4 -4
- package/lib/shared/similarity.js +25 -8
- package/lib/shared/token-utils.js +6 -2
- package/lib/shared/utils/common.js +12 -4
- package/package.json +49 -13
- package/scripts/bench-real-projects.mjs +256 -0
- package/scripts/build-native-ui.js +30 -30
- package/scripts/clear-old-vector-index.js +5 -35
- package/scripts/clear-vector-cache.js +7 -37
- package/scripts/collect-test-project-stats.mjs +160 -0
- package/scripts/diagnose-mcp.js +41 -32
- package/scripts/ensure-parse-package.js +6 -9
- package/scripts/generate-recipe-drafts.js +116 -77
- package/scripts/init-db.js +3 -20
- package/scripts/init-snippets.js +305 -0
- package/scripts/init-vector-db.js +173 -170
- package/scripts/install-cursor-skill.js +148 -104
- package/scripts/install-full.js +8 -21
- package/scripts/install-vscode-copilot.js +146 -145
- package/scripts/migrate-md-to-knowledge.mjs +139 -151
- package/scripts/postinstall-safe.js +5 -17
- package/scripts/recipe-audit.js +106 -82
- package/scripts/release.js +283 -323
- package/scripts/setup-mcp-config.js +60 -52
- package/scripts/verify-context-api.js +20 -20
- package/skills/autosnippet-analysis/SKILL.md +10 -6
- package/skills/autosnippet-candidates/SKILL.md +27 -26
- package/skills/autosnippet-coldstart/SKILL.md +555 -38
- package/skills/autosnippet-concepts/SKILL.md +349 -337
- package/skills/autosnippet-create/SKILL.md +5 -5
- package/skills/autosnippet-reference-dart/SKILL.md +543 -0
- package/skills/autosnippet-reference-go/SKILL.md +539 -0
- package/skills/autosnippet-reference-java/SKILL.md +534 -0
- package/skills/autosnippet-reference-jsts/SKILL.md +41 -9
- package/skills/autosnippet-reference-kotlin/SKILL.md +526 -0
- package/skills/autosnippet-reference-objc/SKILL.md +29 -6
- package/skills/autosnippet-reference-python/SKILL.md +800 -0
- package/skills/autosnippet-reference-swift/SKILL.md +70 -14
- package/skills/autosnippet-structure/SKILL.md +4 -4
- package/templates/cursor-rules/autosnippet-conventions.mdc +2 -2
- package/templates/recipes-setup/README.md +2 -2
- package/templates/recipes-setup/_template.md +1 -1
- package/dashboard/dist/assets/index-Bun3ld_J.css +0 -1
- package/dashboard/dist/assets/index-_Sk_Dmg3.js +0 -143
- package/resources/asd-entry/main.swift +0 -159
- package/scripts/build-asd-entry.js +0 -51
- package/scripts/init-xcode-snippets.js +0 -311
- 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 =
|
|
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)
|
|
58
|
+
if (cbMatch) {
|
|
59
|
+
meta.createdBy = cbMatch[1].trim();
|
|
60
|
+
}
|
|
60
61
|
const caMatch = fm.match(/^createdAt:\s*(.+?)$/m);
|
|
61
|
-
if (caMatch)
|
|
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
|
|
103
|
-
.
|
|
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, {
|
|
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
|
|
113
|
-
.
|
|
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, {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
211
|
-
|
|
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 {
|
|
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 =
|
|
292
|
-
|
|
293
|
-
|
|
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
|
-
`
|
|
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 {
|
|
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
|
-
|
|
396
|
+
const projectSkills = [];
|
|
350
397
|
const projectSkillsDir = _getProjectSkillsDir();
|
|
351
398
|
try {
|
|
352
|
-
const dirs = fs
|
|
353
|
-
.
|
|
354
|
-
.
|
|
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 {
|
|
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 {
|
|
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: {
|
|
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)
|
|
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(
|
|
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': [
|
|
640
|
-
|
|
641
|
-
|
|
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
|
}
|