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
|
@@ -9,12 +9,20 @@ import { envelope } from '../envelope.js';
|
|
|
9
9
|
function _projectItem(r) {
|
|
10
10
|
const json = typeof r.toJSON === 'function' ? r.toJSON() : r;
|
|
11
11
|
return {
|
|
12
|
-
id: json.id,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
id: json.id,
|
|
13
|
+
title: json.title,
|
|
14
|
+
description: json.description,
|
|
15
|
+
trigger: json.trigger || '',
|
|
16
|
+
lifecycle: json.lifecycle,
|
|
17
|
+
kind: json.kind,
|
|
18
|
+
language: json.language,
|
|
19
|
+
category: json.category,
|
|
20
|
+
knowledgeType: json.knowledgeType,
|
|
21
|
+
complexity: json.complexity,
|
|
22
|
+
scope: json.scope,
|
|
23
|
+
tags: json.tags || [],
|
|
24
|
+
quality: json.quality || null,
|
|
25
|
+
stats: json.stats || null,
|
|
18
26
|
status: json.lifecycle,
|
|
19
27
|
statistics: json.stats,
|
|
20
28
|
};
|
|
@@ -23,41 +31,73 @@ function _projectItem(r) {
|
|
|
23
31
|
export async function listByKind(ctx, kind, args) {
|
|
24
32
|
const ks = ctx.container.get('knowledgeService');
|
|
25
33
|
const filters = { kind };
|
|
26
|
-
if (args.language)
|
|
27
|
-
|
|
34
|
+
if (args.language) {
|
|
35
|
+
filters.language = args.language;
|
|
36
|
+
}
|
|
37
|
+
if (args.category) {
|
|
38
|
+
filters.category = args.category;
|
|
39
|
+
}
|
|
28
40
|
const result = await ks.list(filters, { page: 1, pageSize: args.limit || 20 });
|
|
29
41
|
const items = (result?.data || []).map(_projectItem);
|
|
30
|
-
return envelope({
|
|
42
|
+
return envelope({
|
|
43
|
+
success: true,
|
|
44
|
+
data: { kind, count: items.length, total: result?.pagination?.total || items.length, items },
|
|
45
|
+
meta: { tool: `autosnippet_list_${kind}s` },
|
|
46
|
+
});
|
|
31
47
|
}
|
|
32
48
|
|
|
33
49
|
export async function listRecipes(ctx, args) {
|
|
34
50
|
const ks = ctx.container.get('knowledgeService');
|
|
35
51
|
const filters = {};
|
|
36
|
-
if (args.kind)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (args.
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
if (args.kind) {
|
|
53
|
+
filters.kind = args.kind;
|
|
54
|
+
}
|
|
55
|
+
if (args.language) {
|
|
56
|
+
filters.language = args.language;
|
|
57
|
+
}
|
|
58
|
+
if (args.category) {
|
|
59
|
+
filters.category = args.category;
|
|
60
|
+
}
|
|
61
|
+
if (args.knowledgeType) {
|
|
62
|
+
filters.knowledgeType = args.knowledgeType;
|
|
63
|
+
}
|
|
64
|
+
if (args.complexity) {
|
|
65
|
+
filters.complexity = args.complexity;
|
|
66
|
+
}
|
|
67
|
+
if (args.status) {
|
|
68
|
+
filters.lifecycle = args.status;
|
|
69
|
+
}
|
|
42
70
|
const result = await ks.list(filters, { page: 1, pageSize: args.limit || 20 });
|
|
43
71
|
const items = (result?.data || []).map(_projectItem);
|
|
44
|
-
return envelope({
|
|
72
|
+
return envelope({
|
|
73
|
+
success: true,
|
|
74
|
+
data: { count: items.length, total: result?.pagination?.total || items.length, items },
|
|
75
|
+
meta: { tool: 'autosnippet_list_recipes' },
|
|
76
|
+
});
|
|
45
77
|
}
|
|
46
78
|
|
|
47
79
|
export async function getRecipe(ctx, args) {
|
|
48
|
-
if (!args.id)
|
|
80
|
+
if (!args.id) {
|
|
81
|
+
throw new Error('id is required');
|
|
82
|
+
}
|
|
49
83
|
const ks = ctx.container.get('knowledgeService');
|
|
50
84
|
const entry = await ks.get(args.id);
|
|
51
|
-
if (!entry)
|
|
85
|
+
if (!entry) {
|
|
86
|
+
throw new Error(`Knowledge entry not found: ${args.id}`);
|
|
87
|
+
}
|
|
52
88
|
const json = typeof entry.toJSON === 'function' ? entry.toJSON() : entry;
|
|
53
89
|
return envelope({ success: true, data: json, meta: { tool: 'autosnippet_get_recipe' } });
|
|
54
90
|
}
|
|
55
91
|
|
|
56
92
|
export async function recipeInsights(ctx, args) {
|
|
57
|
-
if (!args.id)
|
|
93
|
+
if (!args.id) {
|
|
94
|
+
throw new Error('id is required');
|
|
95
|
+
}
|
|
58
96
|
const ks = ctx.container.get('knowledgeService');
|
|
59
97
|
const entry = await ks.get(args.id);
|
|
60
|
-
if (!entry)
|
|
98
|
+
if (!entry) {
|
|
99
|
+
throw new Error(`Knowledge entry not found: ${args.id}`);
|
|
100
|
+
}
|
|
61
101
|
const json = typeof entry.toJSON === 'function' ? entry.toJSON() : entry;
|
|
62
102
|
|
|
63
103
|
// 聚合关系摘要
|
|
@@ -123,7 +163,9 @@ export async function recipeInsights(ctx, args) {
|
|
|
123
163
|
}
|
|
124
164
|
|
|
125
165
|
export async function confirmUsage(ctx, args) {
|
|
126
|
-
if (!args.recipeId)
|
|
166
|
+
if (!args.recipeId) {
|
|
167
|
+
throw new Error('recipeId is required');
|
|
168
|
+
}
|
|
127
169
|
const ks = ctx.container.get('knowledgeService');
|
|
128
170
|
const usageType = args.usageType || 'adoption';
|
|
129
171
|
const feedback = args.feedback || null;
|
|
@@ -143,7 +185,9 @@ export async function confirmUsage(ctx, args) {
|
|
|
143
185
|
comment: feedback,
|
|
144
186
|
});
|
|
145
187
|
}
|
|
146
|
-
} catch {
|
|
188
|
+
} catch {
|
|
189
|
+
/* feedbackCollector 降级不影响主流程 */
|
|
190
|
+
}
|
|
147
191
|
}
|
|
148
192
|
|
|
149
193
|
return envelope({
|
|
@@ -17,42 +17,85 @@ export async function validateCandidate(ctx, args) {
|
|
|
17
17
|
const suggestions = [];
|
|
18
18
|
|
|
19
19
|
// Layer 1: 核心必填
|
|
20
|
-
if (!c.title?.trim())
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
if (!c.title?.trim()) {
|
|
21
|
+
errors.push('缺少 title');
|
|
22
|
+
}
|
|
23
|
+
if (!c.code?.trim() && args.strict) {
|
|
24
|
+
errors.push('strict 模式下需要 code');
|
|
25
|
+
}
|
|
26
|
+
if (!c.language) {
|
|
27
|
+
warnings.push('缺少 language');
|
|
28
|
+
}
|
|
23
29
|
|
|
24
30
|
// Layer 2: 分类
|
|
25
|
-
if (!c.category)
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
if (!c.category) {
|
|
32
|
+
warnings.push('缺少 category');
|
|
33
|
+
}
|
|
34
|
+
if (!c.knowledgeType) {
|
|
35
|
+
warnings.push('缺少 knowledgeType(code-pattern/architecture/best-practice/...)');
|
|
36
|
+
}
|
|
37
|
+
if (!c.complexity) {
|
|
38
|
+
suggestions.push({ field: 'complexity', value: 'intermediate' });
|
|
39
|
+
}
|
|
28
40
|
|
|
29
41
|
// Layer 3: 描述文档
|
|
30
|
-
if (!c.trigger?.trim())
|
|
42
|
+
if (!c.trigger?.trim()) {
|
|
43
|
+
warnings.push('缺少 trigger(建议 @ 开头)');
|
|
44
|
+
}
|
|
31
45
|
if (c.trigger && !c.trigger.startsWith('@')) {
|
|
32
46
|
suggestions.push({ field: 'trigger', value: `@${c.trigger.replace(/^@+/, '')}` });
|
|
33
47
|
}
|
|
34
|
-
if (!c.summary?.trim() && !c.description?.trim())
|
|
35
|
-
|
|
48
|
+
if (!c.summary?.trim() && !c.description?.trim()) {
|
|
49
|
+
warnings.push('缺少 summary 或 description');
|
|
50
|
+
}
|
|
51
|
+
if (!c.usageGuide?.trim()) {
|
|
52
|
+
warnings.push('缺少 usageGuide');
|
|
53
|
+
}
|
|
36
54
|
|
|
37
55
|
// Layer 4: 结构化内容
|
|
38
|
-
if (!c.rationale)
|
|
39
|
-
|
|
40
|
-
|
|
56
|
+
if (!c.rationale) {
|
|
57
|
+
warnings.push('缺少 rationale(设计原理)');
|
|
58
|
+
}
|
|
59
|
+
if (!Array.isArray(c.headers) || c.headers.length === 0) {
|
|
60
|
+
warnings.push('缺少 headers(import 声明)');
|
|
61
|
+
}
|
|
62
|
+
if (!c.steps && !c.codeChanges) {
|
|
63
|
+
suggestions.push({ field: 'steps', value: '[{title, description, code}]' });
|
|
64
|
+
}
|
|
41
65
|
|
|
42
66
|
// Layer 5: 约束与关系
|
|
43
|
-
if (!c.constraints)
|
|
67
|
+
if (!c.constraints) {
|
|
68
|
+
suggestions.push({
|
|
69
|
+
field: 'constraints',
|
|
70
|
+
value: '{boundaries[], preconditions[], sideEffects[], guards[]}',
|
|
71
|
+
});
|
|
72
|
+
}
|
|
44
73
|
|
|
45
74
|
// Reasoning 推理依据
|
|
46
75
|
if (!c.reasoning) {
|
|
47
76
|
errors.push('缺少 reasoning(推理依据 — whyStandard + sources + confidence)');
|
|
48
77
|
} else {
|
|
49
|
-
if (!c.reasoning.whyStandard?.trim())
|
|
50
|
-
|
|
51
|
-
|
|
78
|
+
if (!c.reasoning.whyStandard?.trim()) {
|
|
79
|
+
errors.push('reasoning.whyStandard 不能为空');
|
|
80
|
+
}
|
|
81
|
+
if (!Array.isArray(c.reasoning.sources) || c.reasoning.sources.length === 0) {
|
|
82
|
+
errors.push('reasoning.sources 至少包含一项来源');
|
|
83
|
+
}
|
|
84
|
+
if (
|
|
85
|
+
typeof c.reasoning.confidence !== 'number' ||
|
|
86
|
+
c.reasoning.confidence < 0 ||
|
|
87
|
+
c.reasoning.confidence > 1
|
|
88
|
+
) {
|
|
89
|
+
warnings.push('reasoning.confidence 应为 0-1 的数字');
|
|
90
|
+
}
|
|
52
91
|
}
|
|
53
92
|
|
|
54
93
|
const ok = errors.length === 0;
|
|
55
|
-
return envelope({
|
|
94
|
+
return envelope({
|
|
95
|
+
success: ok,
|
|
96
|
+
data: { ok, errors, warnings, suggestions },
|
|
97
|
+
meta: { tool: 'autosnippet_validate_candidate' },
|
|
98
|
+
});
|
|
56
99
|
}
|
|
57
100
|
|
|
58
101
|
export async function checkDuplicate(ctx, args) {
|
|
@@ -63,7 +106,11 @@ export async function checkDuplicate(ctx, args) {
|
|
|
63
106
|
threshold: args.threshold ?? 0.7,
|
|
64
107
|
topK: args.topK ?? 5,
|
|
65
108
|
});
|
|
66
|
-
return envelope({
|
|
109
|
+
return envelope({
|
|
110
|
+
success: true,
|
|
111
|
+
data: { similar },
|
|
112
|
+
meta: { tool: 'autosnippet_check_duplicate' },
|
|
113
|
+
});
|
|
67
114
|
}
|
|
68
115
|
|
|
69
116
|
// ─── 语义字段缺失诊断(无 AI 依赖) ──────────────────────────
|
|
@@ -78,14 +125,33 @@ export async function enrichCandidates(ctx, args) {
|
|
|
78
125
|
}
|
|
79
126
|
|
|
80
127
|
const knowledgeService = ctx.container.get('knowledgeService');
|
|
81
|
-
if (!knowledgeService)
|
|
128
|
+
if (!knowledgeService) {
|
|
129
|
+
throw new Error('KnowledgeService not available');
|
|
130
|
+
}
|
|
82
131
|
|
|
83
|
-
const SEMANTIC_KEYS = [
|
|
132
|
+
const SEMANTIC_KEYS = [
|
|
133
|
+
'content.rationale',
|
|
134
|
+
'knowledgeType',
|
|
135
|
+
'complexity',
|
|
136
|
+
'scope',
|
|
137
|
+
'content.steps',
|
|
138
|
+
'constraints',
|
|
139
|
+
];
|
|
84
140
|
const RECIPE_READY_KEYS = [
|
|
85
|
-
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
141
|
+
{
|
|
142
|
+
key: 'category',
|
|
143
|
+
check: (v) =>
|
|
144
|
+
v &&
|
|
145
|
+
['View', 'Service', 'Tool', 'Model', 'Network', 'Storage', 'UI', 'Utility'].includes(v),
|
|
146
|
+
hint: 'category 必须为 8 标准值之一',
|
|
147
|
+
},
|
|
148
|
+
{ key: 'trigger', check: (v) => v?.startsWith('@'), hint: 'trigger 必须以 @ 开头' },
|
|
149
|
+
{ key: 'description', check: (v) => !!v, hint: '知识条目描述' },
|
|
150
|
+
{
|
|
151
|
+
key: 'headers',
|
|
152
|
+
check: (v) => Array.isArray(v) && v.length > 0,
|
|
153
|
+
hint: '完整 import 语句数组',
|
|
154
|
+
},
|
|
89
155
|
];
|
|
90
156
|
|
|
91
157
|
const results = [];
|
|
@@ -105,11 +171,17 @@ export async function enrichCandidates(ctx, args) {
|
|
|
105
171
|
for (const keyPath of SEMANTIC_KEYS) {
|
|
106
172
|
const parts = keyPath.split('.');
|
|
107
173
|
let val = json;
|
|
108
|
-
for (const p of parts) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
174
|
+
for (const p of parts) {
|
|
175
|
+
val = val?.[p];
|
|
176
|
+
}
|
|
177
|
+
if (
|
|
178
|
+
val === undefined ||
|
|
179
|
+
val === null ||
|
|
180
|
+
val === '' ||
|
|
181
|
+
(typeof val === 'string' && val.trim() === '') ||
|
|
182
|
+
(Array.isArray(val) && val.length === 0) ||
|
|
183
|
+
(typeof val === 'object' && !Array.isArray(val) && Object.keys(val).length === 0)
|
|
184
|
+
) {
|
|
113
185
|
missing.push(keyPath);
|
|
114
186
|
}
|
|
115
187
|
}
|
|
@@ -134,10 +206,20 @@ export async function enrichCandidates(ctx, args) {
|
|
|
134
206
|
recipeReadyMissing,
|
|
135
207
|
complete: missing.length === 0 && recipeReadyMissing.length === 0,
|
|
136
208
|
});
|
|
137
|
-
if (missing.length > 0)
|
|
138
|
-
|
|
209
|
+
if (missing.length > 0) {
|
|
210
|
+
needsEnrichment++;
|
|
211
|
+
}
|
|
212
|
+
if (recipeReadyMissing.length > 0) {
|
|
213
|
+
needsRecipeFields++;
|
|
214
|
+
}
|
|
139
215
|
} catch (err) {
|
|
140
|
-
results.push({
|
|
216
|
+
results.push({
|
|
217
|
+
id,
|
|
218
|
+
found: false,
|
|
219
|
+
error: err.message,
|
|
220
|
+
missingFields: [],
|
|
221
|
+
recipeReadyMissing: [],
|
|
222
|
+
});
|
|
141
223
|
}
|
|
142
224
|
}
|
|
143
225
|
|
|
@@ -149,9 +231,10 @@ export async function enrichCandidates(ctx, args) {
|
|
|
149
231
|
needsRecipeFields,
|
|
150
232
|
fullyComplete: ids.length - Math.max(needsEnrichment, needsRecipeFields),
|
|
151
233
|
entries: results,
|
|
152
|
-
hint:
|
|
153
|
-
|
|
154
|
-
|
|
234
|
+
hint:
|
|
235
|
+
needsEnrichment > 0 || needsRecipeFields > 0
|
|
236
|
+
? '请 Agent 根据 missingFields(语义)和 recipeReadyMissing(必填)自行补全后重新提交'
|
|
237
|
+
: '所有条目字段完整',
|
|
155
238
|
},
|
|
156
239
|
meta: { tool: 'autosnippet_enrich_candidates' },
|
|
157
240
|
});
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* 不包含业务逻辑,仅做参数解构 → 路由 → 转发。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import * as
|
|
10
|
+
import * as bootstrapHandlers from './bootstrap.js';
|
|
11
11
|
import * as browseHandlers from './browse.js';
|
|
12
|
-
import * as
|
|
12
|
+
import * as candidateHandlers from './candidate.js';
|
|
13
13
|
import * as guardHandlers from './guard.js';
|
|
14
|
+
import * as searchHandlers from './search.js';
|
|
14
15
|
import * as skillHandlers from './skill.js';
|
|
15
|
-
import * as
|
|
16
|
-
import * as candidateHandlers from './candidate.js';
|
|
16
|
+
import * as structureHandlers from './structure.js';
|
|
17
17
|
|
|
18
18
|
// ─── autosnippet_search (整合 4 → 1) ────────────────────────
|
|
19
19
|
|
|
@@ -33,8 +33,6 @@ export async function consolidatedSearch(ctx, args) {
|
|
|
33
33
|
return searchHandlers.semanticSearch(ctx, args);
|
|
34
34
|
case 'context':
|
|
35
35
|
return searchHandlers.contextSearch(ctx, args);
|
|
36
|
-
case 'auto':
|
|
37
|
-
case 'bm25':
|
|
38
36
|
default:
|
|
39
37
|
return searchHandlers.search(ctx, { ...args, mode });
|
|
40
38
|
}
|
|
@@ -71,7 +69,9 @@ export async function consolidatedKnowledge(ctx, args) {
|
|
|
71
69
|
}
|
|
72
70
|
return browseHandlers.confirmUsage(ctx, args);
|
|
73
71
|
default:
|
|
74
|
-
throw new Error(
|
|
72
|
+
throw new Error(
|
|
73
|
+
`Unknown knowledge operation: ${op}. Expected: list, get, insights, confirm_usage`
|
|
74
|
+
);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -108,7 +108,9 @@ export async function consolidatedStructure(ctx, args) {
|
|
|
108
108
|
*/
|
|
109
109
|
export async function consolidatedGraph(ctx, args) {
|
|
110
110
|
const op = args.operation;
|
|
111
|
-
if (!op)
|
|
111
|
+
if (!op) {
|
|
112
|
+
throw new Error('Missing required parameter: operation. Expected: query, impact, path, stats');
|
|
113
|
+
}
|
|
112
114
|
switch (op) {
|
|
113
115
|
case 'query':
|
|
114
116
|
return structureHandlers.graphQuery(ctx, args);
|
|
@@ -137,7 +139,9 @@ export async function consolidatedGuard(ctx, args) {
|
|
|
137
139
|
if (args.code) {
|
|
138
140
|
return guardHandlers.guardCheck(ctx, args);
|
|
139
141
|
}
|
|
140
|
-
throw new Error(
|
|
142
|
+
throw new Error(
|
|
143
|
+
'autosnippet_guard requires either "code" (single check) or "files" (batch audit) parameter'
|
|
144
|
+
);
|
|
141
145
|
}
|
|
142
146
|
|
|
143
147
|
// ─── autosnippet_skill (整合 6 → 1) ─────────────────────────
|
|
@@ -153,7 +157,11 @@ export async function consolidatedGuard(ctx, args) {
|
|
|
153
157
|
*/
|
|
154
158
|
export async function consolidatedSkill(ctx, args) {
|
|
155
159
|
const op = args.operation;
|
|
156
|
-
if (!op)
|
|
160
|
+
if (!op) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
'Missing required parameter: operation. Expected: list, load, create, update, delete, suggest'
|
|
163
|
+
);
|
|
164
|
+
}
|
|
157
165
|
|
|
158
166
|
// loadSkill expects { skillName }, map from { name }
|
|
159
167
|
if (args.name && !args.skillName) {
|
|
@@ -174,7 +182,9 @@ export async function consolidatedSkill(ctx, args) {
|
|
|
174
182
|
case 'suggest':
|
|
175
183
|
return skillHandlers.suggestSkills(ctx);
|
|
176
184
|
default:
|
|
177
|
-
throw new Error(
|
|
185
|
+
throw new Error(
|
|
186
|
+
`Unknown skill operation: ${op}. Expected: list, load, create, update, delete, suggest`
|
|
187
|
+
);
|
|
178
188
|
}
|
|
179
189
|
}
|
|
180
190
|
|
|
@@ -188,7 +198,9 @@ export async function consolidatedSkill(ctx, args) {
|
|
|
188
198
|
*/
|
|
189
199
|
export async function consolidatedBootstrap(ctx, args) {
|
|
190
200
|
const op = args.operation;
|
|
191
|
-
if (!op)
|
|
201
|
+
if (!op) {
|
|
202
|
+
throw new Error('Missing required parameter: operation. Expected: knowledge, refine, scan');
|
|
203
|
+
}
|
|
192
204
|
switch (op) {
|
|
193
205
|
case 'knowledge':
|
|
194
206
|
return bootstrapHandlers.bootstrapKnowledge(ctx, args);
|
|
@@ -248,7 +260,21 @@ export async function enhancedSubmitKnowledge(ctx, args) {
|
|
|
248
260
|
data: {
|
|
249
261
|
missingFields: readiness.missing,
|
|
250
262
|
suggestions: readiness.suggestions,
|
|
251
|
-
requiredFields: [
|
|
263
|
+
requiredFields: [
|
|
264
|
+
'title',
|
|
265
|
+
'language',
|
|
266
|
+
'content (pattern/markdown)',
|
|
267
|
+
'content.rationale',
|
|
268
|
+
'kind (rule/pattern/fact)',
|
|
269
|
+
'doClause',
|
|
270
|
+
'category (View/Service/Tool/Model/Network/Storage/UI/Utility)',
|
|
271
|
+
'trigger (@前缀)',
|
|
272
|
+
'description',
|
|
273
|
+
'headers (import 语句数组)',
|
|
274
|
+
'usageGuide (### 章节格式)',
|
|
275
|
+
'knowledgeType',
|
|
276
|
+
'reasoning (whyStandard + sources + confidence)',
|
|
277
|
+
],
|
|
252
278
|
},
|
|
253
279
|
meta: { tool: 'autosnippet_submit_knowledge' },
|
|
254
280
|
});
|
|
@@ -258,7 +284,9 @@ export async function enhancedSubmitKnowledge(ctx, args) {
|
|
|
258
284
|
const result = await submitKnowledge(ctx, args);
|
|
259
285
|
|
|
260
286
|
// 如果提交本身失败,直接返回
|
|
261
|
-
if (result && !result.success)
|
|
287
|
+
if (result && !result.success) {
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
262
290
|
|
|
263
291
|
// ── 附加去重检测结果(非阻塞) ──
|
|
264
292
|
let duplicateCheck = null;
|
|
@@ -269,10 +297,14 @@ export async function enhancedSubmitKnowledge(ctx, args) {
|
|
|
269
297
|
summary: args.description || '',
|
|
270
298
|
code: args.content?.pattern || '',
|
|
271
299
|
};
|
|
272
|
-
const dedupResult = await candidateHandlers.checkDuplicate(ctx, {
|
|
300
|
+
const dedupResult = await candidateHandlers.checkDuplicate(ctx, {
|
|
301
|
+
candidate: dedupCandidate,
|
|
302
|
+
threshold: 0.7,
|
|
303
|
+
topK: 3,
|
|
304
|
+
});
|
|
273
305
|
if (dedupResult?.data) {
|
|
274
306
|
duplicateCheck = {
|
|
275
|
-
hasSimilar: dedupResult.data.hasDuplicate ??
|
|
307
|
+
hasSimilar: dedupResult.data.hasDuplicate ?? dedupResult.data.matches?.length > 0,
|
|
276
308
|
closest: dedupResult.data.matches?.[0] || null,
|
|
277
309
|
};
|
|
278
310
|
}
|
|
@@ -282,7 +314,7 @@ export async function enhancedSubmitKnowledge(ctx, args) {
|
|
|
282
314
|
}
|
|
283
315
|
|
|
284
316
|
// 将去重结果附到响应中
|
|
285
|
-
if (result
|
|
317
|
+
if (result?.data) {
|
|
286
318
|
result.data.duplicateCheck = duplicateCheck;
|
|
287
319
|
}
|
|
288
320
|
|