autosnippet 3.2.18 → 3.2.20

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 (183) hide show
  1. package/README.md +73 -104
  2. package/dashboard/dist/assets/{index-CKMy5LY6.js → index-DdvZE4Yd.js} +1 -1
  3. package/dashboard/dist/index.html +1 -1
  4. package/dist/bin/cli.js +45 -10
  5. package/dist/lib/agent/AgentEventBus.js +3 -3
  6. package/dist/lib/agent/AgentFactory.d.ts +3 -3
  7. package/dist/lib/agent/AgentFactory.js +4 -4
  8. package/dist/lib/agent/AgentMessage.d.ts +8 -8
  9. package/dist/lib/agent/AgentMessage.js +8 -8
  10. package/dist/lib/agent/AgentRuntime.js +2 -2
  11. package/dist/lib/agent/AgentState.js +4 -4
  12. package/dist/lib/agent/ConversationStore.d.ts +1 -1
  13. package/dist/lib/agent/ConversationStore.js +1 -1
  14. package/dist/lib/agent/PipelineStrategy.js +1 -1
  15. package/dist/lib/agent/context/ContextWindow.d.ts +2 -2
  16. package/dist/lib/agent/context/ContextWindow.js +7 -7
  17. package/dist/lib/agent/context/ExplorationTracker.js +9 -9
  18. package/dist/lib/agent/context/exploration/PlanTracker.js +2 -2
  19. package/dist/lib/agent/context/exploration/SignalDetector.d.ts +1 -1
  20. package/dist/lib/agent/context/exploration/SignalDetector.js +1 -1
  21. package/dist/lib/agent/core/LoopContext.d.ts +21 -21
  22. package/dist/lib/agent/core/LoopContext.js +21 -21
  23. package/dist/lib/agent/core/SystemPromptBuilder.js +4 -4
  24. package/dist/lib/agent/domain/EvidenceCollector.js +5 -5
  25. package/dist/lib/agent/memory/ActiveContext.js +1 -1
  26. package/dist/lib/agent/memory/MemoryRetriever.js +1 -1
  27. package/dist/lib/agent/memory/MemoryStore.js +2 -2
  28. package/dist/lib/agent/memory/SessionStore.js +3 -3
  29. package/dist/lib/agent/policies.d.ts +1 -1
  30. package/dist/lib/agent/policies.js +1 -1
  31. package/dist/lib/agent/strategies.d.ts +1 -1
  32. package/dist/lib/agent/strategies.js +4 -4
  33. package/dist/lib/agent/tools/_shared.d.ts +1 -1
  34. package/dist/lib/agent/tools/_shared.js +1 -1
  35. package/dist/lib/agent/tools/infrastructure.js +2 -2
  36. package/dist/lib/cli/SetupService.d.ts +25 -25
  37. package/dist/lib/cli/SetupService.js +28 -15
  38. package/dist/lib/cli/deploy/FileDeployer.d.ts +9 -2
  39. package/dist/lib/cli/deploy/FileDeployer.js +139 -46
  40. package/dist/lib/cli/deploy/FileManifest.d.ts +23 -39
  41. package/dist/lib/cli/deploy/FileManifest.js +22 -27
  42. package/dist/lib/core/AstAnalyzer.d.ts +2 -2
  43. package/dist/lib/core/AstAnalyzer.js +2 -2
  44. package/dist/lib/core/analysis/CallEdgeResolver.d.ts +7 -7
  45. package/dist/lib/core/analysis/CallEdgeResolver.js +9 -9
  46. package/dist/lib/core/analysis/CallGraphAnalyzer.d.ts +4 -4
  47. package/dist/lib/core/analysis/CallGraphAnalyzer.js +2 -2
  48. package/dist/lib/core/analysis/ImportPathResolver.d.ts +0 -2
  49. package/dist/lib/core/analysis/ImportPathResolver.js +2 -4
  50. package/dist/lib/core/ast/ProjectGraph.js +7 -7
  51. package/dist/lib/core/capability/CapabilityProbe.js +6 -14
  52. package/dist/lib/domain/knowledge/UnifiedValidator.js +2 -2
  53. package/dist/lib/domain/knowledge/values/Constraints.js +4 -4
  54. package/dist/lib/domain/knowledge/values/Content.js +6 -6
  55. package/dist/lib/domain/knowledge/values/Quality.js +5 -5
  56. package/dist/lib/domain/knowledge/values/Reasoning.js +5 -5
  57. package/dist/lib/domain/knowledge/values/Relations.js +1 -1
  58. package/dist/lib/domain/knowledge/values/Stats.js +6 -6
  59. package/dist/lib/domain/task/TaskIdGenerator.d.ts +4 -4
  60. package/dist/lib/domain/task/TaskIdGenerator.js +2 -2
  61. package/dist/lib/external/lark/LarkTransport.js +4 -4
  62. package/dist/lib/external/mcp/McpServer.d.ts +3 -7
  63. package/dist/lib/external/mcp/McpServer.js +9 -13
  64. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +5 -5
  65. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +4 -3
  66. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +3 -3
  67. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +3 -3
  68. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.d.ts +1 -1
  69. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +1 -1
  70. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +3 -3
  71. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +27 -14
  72. package/dist/lib/external/mcp/handlers/bootstrap-external.js +6 -0
  73. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +55 -1
  74. package/dist/lib/external/mcp/handlers/skill.js +9 -31
  75. package/dist/lib/external/mcp/handlers/system.js +2 -2
  76. package/dist/lib/external/mcp/handlers/task.js +16 -1
  77. package/dist/lib/external/mcp/tools.d.ts +12 -10
  78. package/dist/lib/external/mcp/tools.js +97 -69
  79. package/dist/lib/http/utils/routeHelpers.d.ts +1 -1
  80. package/dist/lib/http/utils/routeHelpers.js +1 -1
  81. package/dist/lib/http/utils/sse-sessions.d.ts +1 -1
  82. package/dist/lib/http/utils/sse-sessions.js +1 -1
  83. package/dist/lib/infrastructure/cache/CacheService.js +1 -1
  84. package/dist/lib/infrastructure/vector/AsyncPersistence.js +8 -8
  85. package/dist/lib/infrastructure/vector/BatchEmbedder.d.ts +1 -1
  86. package/dist/lib/infrastructure/vector/BatchEmbedder.js +2 -2
  87. package/dist/lib/infrastructure/vector/HnswIndex.d.ts +4 -4
  88. package/dist/lib/infrastructure/vector/HnswIndex.js +5 -5
  89. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +8 -8
  90. package/dist/lib/infrastructure/vector/ScalarQuantizer.d.ts +1 -1
  91. package/dist/lib/infrastructure/vector/ScalarQuantizer.js +4 -4
  92. package/dist/lib/infrastructure/vector/VectorStore.d.ts +1 -1
  93. package/dist/lib/infrastructure/vector/VectorStore.js +1 -1
  94. package/dist/lib/injection/ServiceContainer.d.ts +1 -1
  95. package/dist/lib/injection/ServiceContainer.js +1 -1
  96. package/dist/lib/platform/NativeUi.d.ts +1 -1
  97. package/dist/lib/platform/NativeUi.js +1 -1
  98. package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +1 -1
  99. package/dist/lib/platform/ios/spm/DependencyGraph.js +1 -1
  100. package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +1 -1
  101. package/dist/lib/platform/ios/spm/PolicyEngine.js +1 -1
  102. package/dist/lib/platform/ios/spm/SpmDiscoverer.js +1 -1
  103. package/dist/lib/platform/ios/spm/SpmHelper.js +3 -3
  104. package/dist/lib/platform/ios/xcode/SaveEventFilter.js +2 -2
  105. package/dist/lib/platform/ios/xcode/XcodeIntegration.js +1 -1
  106. package/dist/lib/repository/base/BaseRepository.js +1 -1
  107. package/dist/lib/repository/task/TaskRepository.impl.d.ts +2 -2
  108. package/dist/lib/repository/task/TaskRepository.impl.js +1 -1
  109. package/dist/lib/repository/token/TokenUsageStore.js +1 -1
  110. package/dist/lib/service/automation/ActionPipeline.d.ts +1 -1
  111. package/dist/lib/service/automation/ActionPipeline.js +1 -1
  112. package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +2 -2
  113. package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +1 -1
  114. package/dist/lib/service/bootstrap/BootstrapTaskManager.js +2 -2
  115. package/dist/lib/service/bootstrap/DimensionCopyRegistry.d.ts +2 -2
  116. package/dist/lib/service/bootstrap/DimensionCopyRegistry.js +2 -2
  117. package/dist/lib/service/delivery/AgentInstructionsGenerator.d.ts +6 -15
  118. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +53 -189
  119. package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +6 -16
  120. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +14 -19
  121. package/dist/lib/service/delivery/KnowledgeCompressor.d.ts +1 -1
  122. package/dist/lib/service/delivery/KnowledgeCompressor.js +1 -1
  123. package/dist/lib/service/delivery/RulesGenerator.d.ts +10 -3
  124. package/dist/lib/service/delivery/RulesGenerator.js +43 -3
  125. package/dist/lib/service/delivery/SkillsSyncer.d.ts +21 -7
  126. package/dist/lib/service/delivery/SkillsSyncer.js +46 -10
  127. package/dist/lib/service/delivery/TopicClassifier.d.ts +3 -6
  128. package/dist/lib/service/delivery/TopicClassifier.js +0 -3
  129. package/dist/lib/service/guard/ExclusionManager.d.ts +1 -1
  130. package/dist/lib/service/guard/ExclusionManager.js +1 -1
  131. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -3
  132. package/dist/lib/service/guard/GuardCheckEngine.js +5 -5
  133. package/dist/lib/service/guard/GuardCrossFileChecks.d.ts +1 -1
  134. package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -3
  135. package/dist/lib/service/guard/GuardFeedbackLoop.js +3 -3
  136. package/dist/lib/service/guard/GuardPatternUtils.js +1 -1
  137. package/dist/lib/service/guard/GuardService.d.ts +1 -15
  138. package/dist/lib/service/guard/GuardService.js +0 -1
  139. package/dist/lib/service/guard/RuleLearner.d.ts +1 -1
  140. package/dist/lib/service/guard/RuleLearner.js +1 -1
  141. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +3 -3
  142. package/dist/lib/service/knowledge/CodeEntityGraph.js +3 -3
  143. package/dist/lib/service/knowledge/KnowledgeService.d.ts +0 -1
  144. package/dist/lib/service/knowledge/KnowledgeService.js +0 -1
  145. package/dist/lib/service/module/ModuleService.d.ts +1 -1
  146. package/dist/lib/service/module/ModuleService.js +2 -2
  147. package/dist/lib/service/search/HybridRetriever.d.ts +2 -2
  148. package/dist/lib/service/search/HybridRetriever.js +2 -2
  149. package/dist/lib/service/search/SearchEngine.d.ts +1 -3
  150. package/dist/lib/service/search/SearchEngine.js +1 -3
  151. package/dist/lib/service/search/contextBoost.d.ts +1 -1
  152. package/dist/lib/service/skills/EventAggregator.js +2 -2
  153. package/dist/lib/service/skills/SignalCollector.js +1 -1
  154. package/dist/lib/service/snippet/codecs/VSCodeCodec.js +1 -1
  155. package/dist/lib/service/task/TaskGraphService.d.ts +0 -3
  156. package/dist/lib/service/task/TaskGraphService.js +0 -3
  157. package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +8 -27
  158. package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -8
  159. package/dist/lib/service/task/TaskReadyEngine.d.ts +1 -2
  160. package/dist/lib/service/task/TaskReadyEngine.js +0 -1
  161. package/dist/lib/service/wiki/WikiRenderers.js +0 -1
  162. package/dist/lib/service/wiki/WikiUtils.js +2 -7
  163. package/dist/lib/shared/PathGuard.js +6 -6
  164. package/dist/lib/shared/schemas/mcp-tools.js +84 -43
  165. package/dist/scripts/install-vscode-copilot.js +14 -4
  166. package/package.json +1 -1
  167. package/skills/autosnippet-create/SKILL.md +131 -131
  168. package/skills/autosnippet-devdocs/SKILL.md +1 -2
  169. package/skills/autosnippet-guard/SKILL.md +20 -89
  170. package/skills/autosnippet-recipes/SKILL.md +35 -117
  171. package/skills/autosnippet-structure/SKILL.md +23 -55
  172. package/templates/cursor-rules/autosnippet-skills.mdc +17 -33
  173. package/templates/instructions/agent-static.md +24 -0
  174. package/templates/instructions/conventions.md +42 -0
  175. package/skills/autosnippet-analysis/SKILL.md +0 -169
  176. package/skills/autosnippet-candidates/SKILL.md +0 -367
  177. package/skills/autosnippet-coldstart/SKILL.md +0 -988
  178. package/skills/autosnippet-concepts/SKILL.md +0 -630
  179. package/skills/autosnippet-intent/SKILL.md +0 -55
  180. package/skills/autosnippet-lifecycle/SKILL.md +0 -100
  181. package/templates/copilot-instructions.md +0 -66
  182. package/templates/cursor-rules/autosnippet-conventions.mdc +0 -172
  183. package/templates/cursor-rules/autosnippet-workflow.mdc +0 -76
@@ -62,17 +62,17 @@ const PROJECT_WRITE_SCOPE_PREFIXES = [
62
62
  const PROJECT_ROOT_WRITABLE_FILES = ['.gitignore', '.env'];
63
63
  class PathGuard {
64
64
  targetPath;
65
- /** @type {string|null} 项目根目录(绝对路径) */
65
+ /** 项目根目录(绝对路径) */
66
66
  #projectRoot = null;
67
- /** @type {string|null} AutoSnippet 包自身根目录 */
67
+ /** AutoSnippet 包自身根目录 */
68
68
  #packageRoot = null;
69
- /** @type {Set<string>} 额外允许的绝对路径前缀 */
69
+ /** 额外允许的绝对路径前缀 */
70
70
  #allowList = new Set();
71
- /** @type {string|null} 知识库目录名(如 'AutoSnippet') */
71
+ /** 知识库目录名(如 'AutoSnippet') */
72
72
  #knowledgeBaseDir = null;
73
- /** @type {boolean} 是否已配置 */
73
+ /** 是否已配置 */
74
74
  #configured = false;
75
- /** @type {boolean} projectRoot 是否是 AutoSnippet 自身的开发仓库 */
75
+ /** projectRoot 是否是 AutoSnippet 自身的开发仓库 */
76
76
  #isDevRepo = false;
77
77
  /**
78
78
  * 配置 PathGuard(每个进程执行一次)
@@ -18,11 +18,14 @@ export const HealthInput = z.object({});
18
18
  // 2. autosnippet_search
19
19
  // ══════════════════════════════════════════════════════
20
20
  export const SearchInput = z.object({
21
- query: z.string().min(1, 'query is required'),
22
- mode: z.enum(['auto', 'keyword', 'bm25', 'semantic', 'context']).default('auto'),
23
- kind: KindEnum.default('all'),
21
+ query: z.string().min(1, 'query is required').describe('搜索关键词或自然语言描述'),
22
+ mode: z
23
+ .enum(['auto', 'keyword', 'bm25', 'semantic', 'context'])
24
+ .default('auto')
25
+ .describe('auto=自动选策略 | keyword=精确匹配 | bm25=全文检索 | semantic=向量语义 | context=综合+上下文'),
26
+ kind: KindEnum.default('all').describe('过滤知识类型: all/rule/pattern/fact'),
24
27
  limit: z.number().int().min(1).max(100).default(10),
25
- language: z.string().optional(),
28
+ language: z.string().optional().describe('按编程语言过滤,如 swift/typescript'),
26
29
  sessionId: z.string().optional(),
27
30
  sessionHistory: z.array(z.record(z.string(), z.unknown())).optional(),
28
31
  });
@@ -31,8 +34,11 @@ export const SearchInput = z.object({
31
34
  // ══════════════════════════════════════════════════════
32
35
  export const KnowledgeInput = z
33
36
  .object({
34
- operation: z.enum(['list', 'get', 'insights', 'confirm_usage']).default('list'),
35
- id: z.string().optional(),
37
+ operation: z
38
+ .enum(['list', 'get', 'insights', 'confirm_usage'])
39
+ .default('list')
40
+ .describe('list=列表 | get=单条详情(id) | insights=质量分析(id) | confirm_usage=记录采纳(id)'),
41
+ id: z.string().optional().describe('get/insights/confirm_usage 时必填'),
36
42
  kind: KindEnum.optional(),
37
43
  language: z.string().optional(),
38
44
  category: z.string().optional(),
@@ -53,8 +59,11 @@ export const KnowledgeInput = z
53
59
  // 4. autosnippet_structure
54
60
  // ══════════════════════════════════════════════════════
55
61
  export const StructureInput = z.object({
56
- operation: z.enum(['targets', 'files', 'metadata']).default('targets'),
57
- targetName: z.string().optional(),
62
+ operation: z
63
+ .enum(['targets', 'files', 'metadata'])
64
+ .default('targets')
65
+ .describe('targets=构建目标列表 | files=Target文件列表 | metadata=项目元数据'),
66
+ targetName: z.string().optional().describe('files 操作时指定目标名'),
58
67
  includeSummary: z.boolean().default(true),
59
68
  includeContent: z.boolean().default(false),
60
69
  contentMaxLines: z.number().int().min(1).default(100),
@@ -64,8 +73,10 @@ export const StructureInput = z.object({
64
73
  // 5. autosnippet_graph
65
74
  // ══════════════════════════════════════════════════════
66
75
  export const GraphInput = z.object({
67
- operation: z.enum(['query', 'impact', 'path', 'stats']),
68
- nodeId: z.string().optional(),
76
+ operation: z
77
+ .enum(['query', 'impact', 'path', 'stats'])
78
+ .describe('query=节点关系 | impact=影响分析 | path=路径查找 | stats=全局统计'),
79
+ nodeId: z.string().optional().describe('query/impact 时指定节点 ID'),
69
80
  nodeType: z.string().default('recipe'),
70
81
  fromId: z.string().optional(),
71
82
  toId: z.string().optional(),
@@ -77,8 +88,11 @@ export const GraphInput = z.object({
77
88
  // 6. autosnippet_call_context
78
89
  // ══════════════════════════════════════════════════════
79
90
  export const CallContextInput = z.object({
80
- methodName: z.string().min(1, 'methodName is required'),
81
- direction: z.enum(['callers', 'callees', 'both', 'impact']).default('both'),
91
+ methodName: z.string().min(1, 'methodName is required').describe('函数/方法名称,支持部分匹配'),
92
+ direction: z
93
+ .enum(['callers', 'callees', 'both', 'impact'])
94
+ .default('both')
95
+ .describe('callers=上游调用者 | callees=下游依赖 | both=双向 | impact=影响半径'),
82
96
  maxDepth: z.number().int().min(1).max(5).default(2),
83
97
  });
84
98
  // ══════════════════════════════════════════════════════
@@ -95,21 +109,33 @@ export const GuardInput = z.object({
95
109
  // ══════════════════════════════════════════════════════
96
110
  export const SubmitKnowledgeInput = z.object({
97
111
  // ── 必填字段 ──
98
- title: TitleField,
99
- language: LanguageField,
100
- content: ContentSchema,
101
- kind: StrictKindEnum,
102
- doClause: z.string().min(1, 'doClause is required'),
103
- dontClause: z.string().min(1, 'dontClause is required'),
104
- whenClause: z.string().min(1, 'whenClause is required'),
105
- coreCode: z.string().min(1, 'coreCode is required'),
106
- category: z.string().min(1, 'category is required'),
107
- trigger: z.string().min(1, 'trigger is required'),
108
- description: z.string().min(1, 'description is required'),
109
- headers: z.array(z.string()),
110
- usageGuide: z.string().min(1, 'usageGuide is required'),
111
- knowledgeType: z.string().min(1, 'knowledgeType is required'),
112
- reasoning: ReasoningSchema,
112
+ title: TitleField.describe('知识标题,简洁明确'),
113
+ language: LanguageField.describe('编程语言,如 typescript/swift/python'),
114
+ content: ContentSchema.describe('内容对象: { pattern?: "代码片段", markdown?: "正文", rationale: "设计原理" }。pattern/markdown 至少提供一个,rationale 必填'),
115
+ kind: StrictKindEnum.describe('rule=规范约束 | pattern=代码模式 | fact=项目事实'),
116
+ doClause: z
117
+ .string()
118
+ .min(1, 'doClause is required')
119
+ .describe(' 应该怎么做(Channel A+B 硬依赖)'),
120
+ dontClause: z.string().min(1, 'dontClause is required').describe('❌ 不应该怎么做'),
121
+ whenClause: z.string().min(1, 'whenClause is required').describe('何时适用(Channel B 硬依赖)'),
122
+ coreCode: z.string().min(1, 'coreCode is required').describe('核心代码片段(Channel B 模板块)'),
123
+ category: z
124
+ .string()
125
+ .min(1, 'category is required')
126
+ .describe('View/Service/Tool/Model/Network/Storage/UI/Utility'),
127
+ trigger: z.string().min(1, 'trigger is required').describe('触发关键词,如 @NetworkMonitor'),
128
+ description: z.string().min(1, 'description is required').describe('一句话描述用途'),
129
+ headers: z.array(z.string()).describe('完整 import 语句列表'),
130
+ usageGuide: z
131
+ .string()
132
+ .min(1, 'usageGuide is required')
133
+ .describe('使用指南(Markdown,用 ### 分节:何时用/关键点/何时不用)'),
134
+ knowledgeType: z
135
+ .string()
136
+ .min(1, 'knowledgeType is required')
137
+ .describe('code-pattern/architecture/best-practice/code-standard 等'),
138
+ reasoning: ReasoningSchema.describe('推理对象: { whyStandard: "原因", sources: ["来源"], confidence: 0.0-1.0 }'),
113
139
  // ── 可选字段 ──
114
140
  topicHint: z.string().optional(),
115
141
  complexity: ComplexityEnum.optional(),
@@ -130,12 +156,18 @@ export const SubmitKnowledgeInput = z.object({
130
156
  // 8. autosnippet_submit_knowledge_batch
131
157
  // ══════════════════════════════════════════════════════
132
158
  export const SubmitKnowledgeBatchInput = z.object({
133
- target_name: z.string().min(1, 'target_name is required'),
134
- items: z.array(z.record(z.string(), z.unknown())).min(1, 'items array must not be empty'),
159
+ target_name: z
160
+ .string()
161
+ .min(1, 'target_name is required')
162
+ .describe('批量来源标识,如 network-module-scan'),
163
+ items: z
164
+ .array(z.record(z.string(), z.unknown()))
165
+ .min(1, 'items array must not be empty')
166
+ .describe('知识条目数组,每条字段同 submit_knowledge。content/reasoning 必须是对象'),
135
167
  source: z.string().default('cursor-scan'),
136
- deduplicate: z.boolean().default(true),
168
+ deduplicate: z.boolean().default(true).describe('基于 title 自动去重,默认开启'),
137
169
  client_id: z.string().optional(),
138
- dimensionId: z.string().optional(),
170
+ dimensionId: z.string().optional().describe('冷启动时关联维度 ID'),
139
171
  });
140
172
  // ══════════════════════════════════════════════════════
141
173
  // 9. autosnippet_save_document
@@ -152,12 +184,14 @@ export const SaveDocumentInput = z.object({
152
184
  // 10. autosnippet_skill
153
185
  // ══════════════════════════════════════════════════════
154
186
  export const SkillInput = z.object({
155
- operation: z.enum(['list', 'load', 'create', 'update', 'delete', 'suggest']),
156
- name: z.string().optional(),
157
- skillName: z.string().optional(),
158
- section: z.string().optional(),
159
- description: z.string().optional(),
160
- content: z.string().optional(),
187
+ operation: z
188
+ .enum(['list', 'load', 'create', 'update', 'delete', 'suggest'])
189
+ .describe('list=列表 | load=加载内容(name) | create=创建 | update=更新 | delete=删除 | suggest=推荐'),
190
+ name: z.string().optional().describe('Skill 名称(kebab-case,如 autosnippet-create)'),
191
+ skillName: z.string().optional().describe('name 的别名,与 name 等价'),
192
+ section: z.string().optional().describe('load 时过滤指定章节'),
193
+ description: z.string().optional().describe('create/update 时的简短描述'),
194
+ content: z.string().optional().describe('create/update 时的 Markdown 内容'),
161
195
  overwrite: z.boolean().default(false),
162
196
  createdBy: z.enum(['manual', 'user-ai', 'system-ai', 'external-ai']).default('external-ai'),
163
197
  });
@@ -172,7 +206,10 @@ export const DimensionCompleteInput = z.object({
172
206
  sessionId: z.string().optional(),
173
207
  dimensionId: z.string().min(1, 'dimensionId is required'),
174
208
  submittedRecipeIds: z.array(z.string()).optional(),
175
- analysisText: z.string().min(1, 'analysisText is required'),
209
+ analysisText: z
210
+ .string()
211
+ .min(1, 'analysisText is required')
212
+ .describe('维度分析报告(Markdown)。写得越详细,生成的 Skill 质量越高;若过短,系统会自动从候选知识中合成。'),
176
213
  referencedFiles: z.array(z.string()).optional(),
177
214
  keyFindings: z.array(z.string()).optional(),
178
215
  candidateCount: z.number().int().min(0).optional(),
@@ -199,7 +236,8 @@ export const CapabilitiesInput = z.object({});
199
236
  // 13. autosnippet_task
200
237
  // ══════════════════════════════════════════════════════
201
238
  export const TaskInput = z.object({
202
- operation: z.enum([
239
+ operation: z
240
+ .enum([
203
241
  'prime',
204
242
  'ready',
205
243
  'create',
@@ -219,7 +257,8 @@ export const TaskInput = z.object({
219
257
  'revise_decision',
220
258
  'unpin_decision',
221
259
  'list_decisions',
222
- ]),
260
+ ])
261
+ .describe('会话: prime(首选) | ready。任务: create/claim/close/fail/defer/progress/show/list/stats/blocked。分解: decompose/dep_add/dep_tree。决策: record_decision/revise_decision/unpin_decision/list_decisions'),
223
262
  title: z.string().optional(),
224
263
  description: z.string().optional(),
225
264
  design: z.string().optional(),
@@ -276,7 +315,8 @@ export const EnrichCandidatesInput = z.object({
276
315
  // 15. autosnippet_knowledge_lifecycle
277
316
  export const KnowledgeLifecycleInput = z.object({
278
317
  id: IdField,
279
- action: z.enum([
318
+ action: z
319
+ .enum([
280
320
  'submit',
281
321
  'approve',
282
322
  'reject',
@@ -285,8 +325,9 @@ export const KnowledgeLifecycleInput = z.object({
285
325
  'reactivate',
286
326
  'to_draft',
287
327
  'fast_track',
288
- ]),
289
- reason: z.string().optional(),
328
+ ])
329
+ .describe('approve/fast_track=发布 | reject=拒绝 | deprecate=废弃 | reactivate=恢复 | to_draft=回草稿'),
330
+ reason: z.string().optional().describe('reject/deprecate 时的理由'),
290
331
  });
291
332
  // 16. autosnippet_validate_candidate
292
333
  export const ValidateCandidateInput = z.object({
@@ -151,16 +151,26 @@ function createCopilotInstructions() {
151
151
  log(`✓ 项目指令已存在,跳过创建`, 'yellow');
152
152
  return true;
153
153
  }
154
- // 从模板文件读取内容
155
- const templatePath = path.join(TEMPLATES_DIR, 'copilot-instructions.md');
154
+ // 从 conventions 模板生成(读模板 + 包装 HTML markers)
155
+ const templatePath = path.join(TEMPLATES_DIR, 'instructions/conventions.md');
156
156
  if (!fs.existsSync(templatePath)) {
157
157
  error(`✗ 模板文件不存在: ${templatePath}`);
158
158
  return false;
159
159
  }
160
- const instructions = fs.readFileSync(templatePath, 'utf8');
160
+ const body = fs.readFileSync(templatePath, 'utf8').trimEnd();
161
+ const content = [
162
+ '<!-- autosnippet:begin -->',
163
+ '',
164
+ '# AutoSnippet Conventions',
165
+ '',
166
+ body,
167
+ '',
168
+ '<!-- autosnippet:end -->',
169
+ '',
170
+ ].join('\n');
161
171
  try {
162
172
  fs.mkdirSync(path.dirname(instructionsPath), { recursive: true });
163
- fs.writeFileSync(instructionsPath, instructions, 'utf8');
173
+ fs.writeFileSync(instructionsPath, content, 'utf8');
164
174
  log(`✅ 项目指令生成完成: ${instructionsPath}`, 'green');
165
175
  return true;
166
176
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autosnippet",
3
- "version": "3.2.18",
3
+ "version": "3.2.20",
4
4
  "description": "Extract code patterns into a knowledge base for AI coding assistants",
5
5
  "type": "module",
6
6
  "main": "dist/lib/bootstrap.js",
@@ -1,180 +1,180 @@
1
1
  ---
2
2
  name: autosnippet-create
3
- description: Guides the agent to submit module usage code (designed/written with Cursor) to the AutoSnippet web (Dashboard) so it is added to the knowledge base (Recipes). Use when the user or Cursor has finished writing usage code and wants to "提交到 web" or "加入知识库".
3
+ description: Submit knowledge to AutoSnippet. Covers single/batch MCP submission, V3 field requirements, quality validation, and lifecycle. Use when user says "提交知识/加入知识库/create recipe" or agent needs to persist code patterns, rules, or facts.
4
4
  ---
5
5
 
6
- # AutoSnippet Create — Submit to Web, Add to AutoSnippet
7
-
8
- > Self-check & Fallback: MCP 工具返回统一 JSON Envelope{ success, errorCode?, message?, data?, meta })。重操作前调用 `autosnippet_health`;失败时不在同一轮重试,转用静态上下文或缩小范围后再试。
9
-
10
- This skill tells the agent how to **submit module usage code** (that Cursor has designed or the user has written) to the **AutoSnippet web (Dashboard)** so it is **added to the knowledge base (Recipes)**. For concepts (knowledge base, Recipe), use **autosnippet-concepts**. For looking up existing Recipes, use **autosnippet-recipes**.
11
-
12
- ## Instructions for the agent (read this first)
13
-
14
- 1. **Goal**: When you (Cursor) have **finished writing or refining** module usage code, or the user says "把这段提交到 web / 加入知识库", guide them to **submit that code to the Dashboard** so it becomes a **Recipe** in `AutoSnippet/recipes/`.
15
- 2. **Draft workflow**: Prefer **creating a draft folder** (e.g. `.autosnippet-drafts`), **one .md file per Recipe**, multiple draft files—**do not use one big file**. Call MCP **`autosnippet_submit_knowledge_batch`** with filePaths (the .md files in the draft folder) to submit to Candidates. **After submit, delete the draft folder** (use `deleteAfterSubmit: true` or run `rm -rf .autosnippet-drafts`). Single-item flow can use `_draft_recipe.md` and watch will auto-add to Candidates.
16
- 3. **When user asks for "candidates"**: Use MCP **`autosnippet_submit_knowledge_batch`** for structured items (title/summary/trigger/code/usageGuide); use **`autosnippet_submit_knowledge_batch`** for Markdown draft files (prefer draft folder + multiple files; delete draft folder after submit).
17
- 4. **One Recipe = one scenario**: If you are drafting content, **split** into multiple Recipes by scenario. Never combine multiple usage patterns into one Recipe file or one candidate.
18
- 5. **Recipe candidates can be intro-only**: Intro-only docs (no code block) can be submitted as candidates; after approval they become Recipes and **do not generate a Snippet**—used only for search and Guard context.
19
- 6. **MUST follow V3 Recipe format**: Include all required fields: `title`, `trigger`, `category` (one of 8 standard values), `language`, `kind` (rule/pattern/fact), `doClause`, `dontClause`, `whenClause`, `coreCode`, `description`, `content` (object with markdown, pattern, rationale), `headers` (complete import statements), `usageGuide` (Markdown ### 章节), `knowledgeType`, `reasoning` (whyStandard + sources + confidence).
20
- - **MCP 不再使用项目内 AI**: 外部 Agent 必须自行填写所有字段。提交后检查返回值中的 `recipeReadyHints`,缺失字段需补全后重新提交。
21
- - **禁止使用旧字段**: 不要使用 `code`、`summary_cn`、`summary_en`,改用 V3 `content` 对象 + `description`。
22
- - **Placeholders**: Use IDE-appropriate placeholders in snippets — Xcode format `<#URL#>`, `<#Token#>` (auto-converted to VSCode `${N:...}` on install). Explain each placeholder in the Usage Guide.
23
- - **Usage Guide structure (强制格式要求)**:
24
- * **MUST use structured format with clear section headings** (### heading name):**NEVER put all content in one continuous line**
25
- * **MUST use newlines (`\n`) to separate sections and bullet points** — at least 2-3 newlines between major sections
26
- * **MUST use bullet lists (`-` or `*`)** for multi-item sections; avoid long paragraphs
27
- * Recommended sections (按需包含):
28
- - **什么时候用** (必填):3~5 条适用场景,用 `-` 列表,每行一条
29
- - **何时不用** (推荐):排除场景、易误用情况,用 `-` 列表
30
- - **使用步骤** (推荐):1~3 步操作手册,用 `1.` `2.` `3.` 列表
31
- - **关键点** (推荐):易错点、约束条件、版本限制,用 `-` 列表
32
- - **依赖与前置条件** (推荐):模块、权限、最低版本,用 `-` 列表
33
- - **错误处理** (推荐):常见失败场景、重试/降级策略
34
- - **性能与资源** (可选):缓存、线程安全、内存
35
- - **安全与合规** (可选):敏感信息、日志脱敏
36
- - **常见误用** (可选):反例(❌)与规避方式(✅)
37
- - **最佳实践** (可选):推荐做法、设计模式
38
- - **替代方案** (可选):其他 Recipe 或方案对比
39
- - **相关 Recipe** (推荐):关联 trigger 或补充模式
40
- * **BAD Example** (❌ 禁止这样写,AI生成会导致格式混乱):`何时用:在需要…时;与…配合;或…时。关键点:…内部…;…支持…;…需…。`
41
- * **GOOD Example** (✅ 应该这样写,清晰的多行结构):
42
- ```
43
- ### 何时用
44
- - App 启动时需持续监测网络状态
45
- - 在应用生命周期管理类中统一启停
46
-
47
- ### 关键点
48
- - 单例 sharedMonitor,线程安全
49
- - startMonitoring 开始,stopMonitoring 停止
50
- - 后台自动停止,前台自动恢复
51
- ```
52
- - See [templates/recipes-setup/README.md](../../templates/recipes-setup/README.md) for detailed format guide & examples.
53
- 7. **Auto-fill headers from project context**: Before submitting, **check `references/project-recipes-context.md`** (轻量索引) to find similar Recipes by title/trigger/category, then call MCP **`autosnippet_knowledge(operation=get, id)`** to get full content including headers. Copy the exact import format for `headers` field. If needed, call MCP **`autosnippet_search(mode=context)`** with the module name to find similar Recipes and extract their header patterns. This ensures consistency and correctness.
54
- 8. **Primary flow (MCP preferred)**: Code is ready → Agent writes to `_draft_recipe.md` or calls `autosnippet_submit_knowledge_batch` / `autosnippet_submit_knowledge_batch` → candidates appear in Dashboard Candidates → user reviews and approves → Recipe is added to the knowledge base.
55
- 9. **Alternative (Dashboard browser)**: Code is ready → user opens Dashboard (`asd ui` running) → **New Recipe** → **Use Copied Code** (paste the code) → AI fills title/summary/trigger/headers → **user reviews and approves** → saved to knowledge base.
56
- 10. **Alternative (in editor)**: User adds **`// as:create`** in the source file, copies the code, saves → **watch** (from `asd watch` or `asd ui`) auto-adds to Candidates → user opens Dashboard **Candidates** to review and save.
57
- 9. **Draft & clipboard auto-add**: When you write to **`_draft_recipe.md`** (project root) or user uses **`// as:create`** with clipboard content, **watch** automatically reads the draft/clipboard, adds it to **Candidates** (target `_draft` or `_watch`), and shows a **friendly prompt** (e.g. "已创建候选「xxx」,请在 Candidates 页审核" in notification and console). User only needs to open Dashboard **Candidates** to review and save — no manual copy-paste required.
58
- 10. **Multiple recipes**: Prefer **one .md file per Recipe** in a draft folder (e.g. `.autosnippet-drafts/`), call **`autosnippet_submit_knowledge_batch`** with the list of file paths, then **delete the draft folder** after submit. Do not use one big file for many Recipes.
59
- 11. **Project root** = directory with `AutoSnippet/AutoSnippet.boxspec.json`. All commands run from the project root.
6
+ # AutoSnippet Create — 知识提交
7
+
8
+ > 前置:MCP 工具返回统一 JSON Envelope `{ success, errorCode?, message?, data?, meta }`。操作前调用 `autosnippet_health` 确认服务可用。
9
+
10
+ Skill 指导 Agent 将代码模式、规则、事实提交到 AutoSnippet 知识库。提交后的条目进入 **Candidates**(pending 状态),用户在 Dashboard 审核后发布。
11
+
12
+ 关联 Skill:**autosnippet-recipes**(检索已有知识)。
60
13
 
61
14
  ---
62
15
 
63
- ## Submit to web (提交到 web) — main flow
16
+ ## 提交路径
64
17
 
65
- **Scenario**: Cursor has just written or refined **module usage code** (e.g. how to use a network API, how to load WebView). The user wants to add it to the **knowledge base** via the **web (Dashboard)**.
18
+ | 路径 | 工具 | 适用场景 |
19
+ |------|------|----------|
20
+ | **单条提交** | `autosnippet_submit_knowledge` | Agent 精心构造一条完整知识 |
21
+ | **批量提交** | `autosnippet_submit_knowledge_batch` | 冷启动维度分析、批量扫描 |
22
+ | **Dashboard** | 浏览器 `http://localhost:3000` | 用户手动粘贴/扫描文件 |
66
23
 
67
- ### Step 1: Content is ready
24
+ **Agent 首选 MCP 提交**,无需浏览器。
68
25
 
69
- - **Code scenario**: Usage code is in current file or clipboard. If not copied, prompt user to copy the code block you provide.
70
- ...rated a full Recipe (frontmatter, Snippet, Usage Guide), **prefer writing to draft file** `_draft_recipe.md` at project root. On save, **watch automatically reads the draft**, adds it to **Candidates** (target `_draft`), and shows a **friendly prompt** ("已创建候选「xxx」,请在 Candidates 页审核"). User opens Dashboard **Candidates** to review and save — no manual copy needed. Or output in copyable format in chat and guide user to copy → Dashboard → Use Copied Code → paste → review → save. **Do not write to `AutoSnippet/recipes/` or `AutoSnippet/snippets/`.**
71
- - **Candidate output rule**: When the user asks for candidates, **do not create files under `AutoSnippet/`**. Use **`autosnippet_submit_knowledge_batch`** for structured items; use **`autosnippet_submit_knowledge_batch`** for draft .md files (prefer draft folder + multiple files; delete draft folder after submit).
26
+ ---
72
27
 
73
- ### Step 2: Open the web (Dashboard) in browser
28
+ ## 单条提交 autosnippet_submit_knowledge
74
29
 
75
- - **Preferred**: Run in terminal: `open "http://localhost:3000/?action=create&source=clipboard"` (macOS). This opens the browser to the New Recipe page.
76
- - **Manual fallback**: User opens **`http://localhost:3000`** in browser (Dashboard 需已运行;若未运行,先执行 `asd ui`).
30
+ 一次提交一条完整的 V3 知识条目。即使部分字段校验未通过也会入库,返回中附带 `recipeReadyHints` 提示缺失字段。
77
31
 
78
- ### Step 3: Submit via Dashboard
32
+ ### V3 必填字段(16 个)
79
33
 
80
- 1. **Browser**: Run terminal command `open "http://localhost:3000/?action=create&source=clipboard"` (macOS) to open the browser.
81
- 2. **Draft file (preferred for Agent)**: Write full Recipe MD to `_draft_recipe.md` at project root → watch auto-adds to Candidates. Or call MCP **`autosnippet_submit_knowledge_batch`** with draft file paths.
82
- 3. **Manual fallback**: User opens **`http://localhost:3000`** in browser → **New Recipe** → **Use Copied Code** → paste.
83
- 3. Pasted code: **Full Recipe MD** (with `---` frontmatter, `## Snippet / Code Reference`, `## AI Context / Usage Guide`) is parsed directly, **no AI rewrite**. Plain code still goes through AI analysis and fill.
84
- 4. **User reviews and approves** 人工审核 title/summary/category/trigger 及内容,确认无误后再保存。
85
- 5. User **saves** Recipe is written to **`AutoSnippet/recipes/`** — i.e. **added to the knowledge base**.
34
+ | 字段 | 类型 | 说明 |
35
+ |------|------|------|
36
+ | `title` | string | 知识标题,简洁明确 |
37
+ | `description` | string | 一句话描述用途 |
38
+ | `trigger` | string | 触发关键词,如 `@NetworkMonitor` |
39
+ | `language` | string | 编程语言,如 `typescript`、`swift` |
40
+ | `kind` | enum | `rule`(规范)/ `pattern`(模式)/ `fact`(事实) |
41
+ | `category` | string | `View`/`Service`/`Tool`/`Model`/`Network`/`Storage`/`UI`/`Utility` |
42
+ | `knowledgeType` | string | 知识类型标识 |
43
+ | `doClause` | string | ✅ 应该做什么(Channel A+B 硬依赖) |
44
+ | `dontClause` | string | ❌ 不应该做什么 |
45
+ | `whenClause` | string | 何时适用(Channel B 硬依赖) |
46
+ | `coreCode` | string | 核心代码片段 |
47
+ | `headers` | string[] | 完整 import 语句列表 |
48
+ | `usageGuide` | string | 使用指南(Markdown,见下方格式要求) |
49
+ | `content` | object | `{ markdown: string, rationale: string }` 至少提供 markdown |
50
+ | `reasoning` | object | `{ whyStandard: string, sources: string[], confidence: number }` |
86
51
 
87
- ### Step 4: Optional — refresh Cursor's project context
52
+ ### 可选字段
88
53
 
89
- - After saving, the user can run **`asd install:cursor-skill`** in the project root to regenerate `references/project-recipes-context.md`(轻量索引)so Cursor's recipes skill has the latest index. This is optional and can be done later.
54
+ `topicHint`、`complexity`(beginner/intermediate/advanced)、`scope`(universal/project-specific/target-specific)、`tags`(string[])、`constraints`、`relations`、`skipDuplicateCheck`(默认 false)
90
55
 
91
- ---
56
+ ### usageGuide 格式要求
92
57
 
93
- ## Alternative: Copy then jump to Web (Xcode and Cursor)
58
+ **必须**使用 Markdown 分节,禁止写成一行长文本。
94
59
 
95
- **Option A — MCP Submit (Cursor 首选)**: After user confirms code, Agent calls **`autosnippet_submit_knowledge_batch`** (for .md drafts) or **`autosnippet_submit_knowledge_batch`** (for structured items) to submit directly to Candidates. User reviews in Dashboard.
60
+ ```markdown
61
+ ### 何时用
62
+ - 场景 A
63
+ - 场景 B
96
64
 
97
- **Option B — Browser (Dashboard)**: Run `open "http://localhost:3000/?action=create&source=clipboard"` to open Dashboard New Recipe page; page reads clipboard and fills.
65
+ ### 何时不用
66
+ - 排除场景
98
67
 
99
- **Option B — // as:create (Xcode / in-editor)**: User adds **`// as:create`**, copies code, saves file. Requires **`asd watch`** or **`asd ui`** running. If clipboard has content, watch **automatically adds to Candidates** and shows a **friendly prompt** ("已创建候选「xxx」,请在 Candidates 页审核"); user opens Dashboard **Candidates** to review and save. If no clipboard, watch opens Dashboard with path for manual paste.
68
+ ### 使用步骤
69
+ 1. 第一步
70
+ 2. 第二步
100
71
 
101
- ---
72
+ ### 关键点
73
+ - 注意事项 A
74
+ - 注意事项 B
75
+ ```
102
76
 
103
- ## Other ways to add to knowledge base (via web)
77
+ 可选章节:依赖与前置条件、错误处理、性能与资源、安全与合规、常见误用、替代方案、相关知识。
104
78
 
105
- | Way | When to use |
106
- |-----|-------------|
107
- | **New Recipe → Scan File** | Code is already in a project file; user enters relative path (e.g. `Sources/MyMod/Foo.m`) → Scan File → AI extracts → save in Dashboard. |
108
- | **Module Explorer** | Mine usage from a module Target: select Target → scan → review in Dashboard → save as Recipe (or Snippet + Recipe). |
109
- | **Candidates** | Batch: run **`asd ais <Target>`** or **`asd ais --all`** → open Dashboard **Candidates** → approve items → saved to knowledge base. |
79
+ ---
110
80
 
111
- All of these **submit through the web (Dashboard)** and result in content in **`AutoSnippet/recipes/`** (and optionally Snippet). The main flow above (Use Copied Code) is for **code that Cursor has just written**.
81
+ ## 批量提交 autosnippet_submit_knowledge_batch
112
82
 
113
- **Friendly prompt (友好提示)**: When draft file or `// as:create` with clipboard is used, the system adds content to **Candidates** and shows: ① Console message "已创建候选「xxx」,请在 Candidates 页审核"; ② On macOS, a notification "已创建候选「xxx」,请在 Candidates 页审核". Tell the user: "内容已加入候选池,请打开 Dashboard 的 **Candidates** 页审核并保存即可。"
83
+ 一次提交多条知识。每条单独校验,不通过的拒绝但不阻塞其他。
114
84
 
115
- **When generating content**: If Agent has drafted Recipe or Snippet content, prefer writing to `_draft_recipe.md` so watch can auto-add to Candidates with friendly prompt. Or pass the full content to user for Dashboard submission.
85
+ ### 参数
116
86
 
117
- **When full copy is difficult**: Long content in chat is hard to copy fully. Agent should **write to draft file** at project root: `_draft_recipe.md` (or `_draft_snippet.md`), outside AutoSnippet/. **Watch automatically reads the draft on save** and adds it to **Candidates** (target `_draft`), then shows a **friendly prompt** ("已创建候选「xxx」,请在 Candidates 页审核"). User opens Dashboard **Candidates** → review and save — no manual copy or Scan File needed. Optional: add `_draft_*.md` to `.gitignore`. Delete draft after save if desired.
87
+ | 字段 | 必填 | 类型 | 说明 |
88
+ |------|------|------|------|
89
+ | `target_name` | ✅ | string | 批量来源标识(如 `network-module-scan`) |
90
+ | `items` | ✅ | object[] | 知识条目数组,每条结构同单条提交的字段 |
91
+ | `source` | | string | 来源标记,默认 `cursor-scan` |
92
+ | `deduplicate` | | boolean | 基于 title 去重,默认 `true` |
118
93
 
119
- **Multiple recipes in one draft**: To submit **several Recipes at once**, write them in one `_draft_recipe.md`. Each Recipe is a **complete block** starting with `---` (frontmatter). **Separate blocks with a blank line, then the next block starts with `---`**. Example structure:
120
- ```
121
- ---
122
- title: Recipe A
123
- trigger: @foo
124
- ...
125
- ---
94
+ ### 返回值
126
95
 
127
- ## Snippet / Code Reference
128
- ```objc
129
- code A
96
+ ```json
97
+ {
98
+ "count": 3,
99
+ "total": 5,
100
+ "ids": ["id1", "id2", "id3"],
101
+ "errors": ["item[2]: missing doClause"],
102
+ "rejectedItems": [2, 4],
103
+ "rejectedSummary": { "commonMissingFields": ["doClause", "reasoning"] }
104
+ }
130
105
  ```
131
106
 
132
- ## AI Context / Usage Guide
133
- usage A
107
+ **批量提交校验更严格**:单条提交校验不通过仍入库(附 hints),**批量提交校验不通过直接拒绝**。
134
108
 
135
109
  ---
136
- title: Recipe B
137
- ...
138
- ---
139
110
 
140
- ## Snippet / Code Reference
141
- ...
111
+ ## 提交工作流
112
+
113
+ ### 标准流程(Agent 通过 MCP)
114
+
115
+ ```
116
+ 1. 分析代码 → 构造 V3 字段
117
+ 2. autosnippet_submit_knowledge / _batch → 入库为 pending
118
+ 3. 检查返回值:
119
+ - 成功 → 告知用户"已提交,请在 Dashboard Candidates 审核"
120
+ - 有 rejectedItems → 根据 rejectedSummary.commonMissingFields 补全后重试
121
+ 4. [可选] autosnippet_enrich_candidates → 诊断候选字段完整性
142
122
  ```
143
- Watch parses all such blocks and adds each as a separate candidate; prompt may say "已创建 N 条候选".
123
+
124
+ ### 一条知识一个场景
125
+
126
+ 拆分原则:不同使用场景、不同 API 入口、不同配置方式→各自一条知识。禁止将多个模式合并为一条。
144
127
 
145
128
  ---
146
129
 
147
- ## Quick reference
130
+ ## 提交后管理
148
131
 
149
- | User / Cursor situation | Action |
150
- |-------------------------|--------|
151
- | "把这段提交到 web / 加入知识库" (code just written) | 1) 提示用户复制代码;2) 写入 `_draft_recipe.md` 或调用 **`autosnippet_submit_knowledge_batch`**;3) 若需 Dashboard,运行 `open "http://localhost:3000/?action=create&source=clipboard"`;4) 用户粘贴并保存。 |
152
- | Agent 起草了 Recipe/Snippet 内容 | **Prefer**: Write to `_draft_recipe.md` (project root) → save → **watch 自动读取并加入候选池**,并给出友好提示 → 用户打开 Dashboard **Candidates** 审核并保存。无需手动复制。 |
153
- | Code in current file, want to submit from editor | **MCP**:`autosnippet_submit_knowledge_batch`(写草稿 .md 后提交)。或 Add **`// as:create`**, copy, save;确保 **`asd watch`** / **`asd ui`** 运行;有剪贴板时自动加入候选并友好提示。 |
154
- | Code already in a file (path known) | 打开 **`http://localhost:3000`** → New Recipe → enter path → **Scan File** → review → save. |
155
- | Agent 起草内容无法完整复制 | Write to `_draft_recipe.md` → save → **watch 自动读取草稿、加入候选并友好提示** → 用户打开 **Candidates** 审核保存。 |
156
- | Batch from Target | **`asd ais <Target>`** → 打开 **`http://localhost:3000`** → **Candidates** → approve. |
132
+ | 需求 | 工具 |
133
+ |------|------|
134
+ | 查看候选状态 | `autosnippet_knowledge(operation=list)` |
135
+ | 诊断缺失字段 | `autosnippet_enrich_candidates` |
136
+ | 审核/发布 | `autosnippet_knowledge_lifecycle(operation=approve/publish/fast_track)` |
137
+ | 搜索已有知识避免重复 | `autosnippet_search(mode=context, query=...)` |
157
138
 
158
139
  ---
159
140
 
160
- ## MCP Tools (when Dashboard is running)
141
+ ## kind 路由与管线影响
161
142
 
162
- | Tool | Use |
163
- |------|-----|
164
- | `autosnippet_search(mode=context)` | On-demand semantic search of knowledge base; pass `query`, `limit?` |
165
- | `autosnippet_submit_knowledge_batch` | Submit draft .md as candidates: prefer draft folder + multiple files (not one big file); supports intro-only docs (no code—no Snippet). Pass `filePaths`, optional `targetName`, `deleteAfterSubmit`. **Delete the draft folder after submit** (e.g. `deleteAfterSubmit: true` or `rm -rf .autosnippet-drafts`). |
166
- | `autosnippet_submit_knowledge_batch` | Submit structured items (title, summary, trigger, language, code, usageGuide) for batch scan, etc. |
167
- | `autosnippet_submit_knowledge` | Submit single structured candidate with full V3 fields. **严格前置校验**——缺少必要字段(title, language, content, kind, doClause, dontClause, whenClause, coreCode, category, trigger, description, headers, usageGuide, knowledgeType, reasoning, content.rationale)的提交将被直接拒绝,不入库。必须一次性提供所有字段。 |
168
- | `autosnippet_save_document` | Save a development document (design doc, debug report, ADR) — only needs title + markdown. See **autosnippet-devdocs** skill. |
143
+ | kind | 用途 | 管线产出 |
144
+ |------|------|----------|
145
+ | `rule` | 编码规范、约束 | Channel A(.mdc 规则文件) |
146
+ | `pattern` | 代码模式、用法 | Channel B(.mdc 模式文件 + Snippet |
147
+ | `fact` | 项目事实、架构决策 | 搜索/Guard 上下文,不直接产出文件 |
169
148
 
170
- **Fallback when Dashboard not open**: Agent can always use `autosnippet_submit_knowledge_batch` or `autosnippet_submit_knowledge_batch` directly via MCP — no browser needed.
149
+ `doClause` Channel A+B 的**硬依赖**——缺少此字段则完全无法生成 .mdc 文件。
171
150
 
172
151
  ---
173
152
 
174
- ## Relation to other skills
175
-
176
- - **autosnippet-concepts**: What the knowledge base and Recipe are; where they live.
177
- - **autosnippet-recipes**: Read or search existing Recipe content; get project context.
178
- - **autosnippet-structure**: Dependency structure (unrelated to submit flow).
179
-
153
+ ## 示例:提交一条知识
154
+
155
+ ```json
156
+ {
157
+ "title": "Network Monitor 网络状态监听",
158
+ "description": "使用 NWPathMonitor 监听网络连通性变化",
159
+ "trigger": "@NetworkMonitor",
160
+ "language": "swift",
161
+ "kind": "pattern",
162
+ "category": "Network",
163
+ "knowledgeType": "api-usage",
164
+ "doClause": "使用 NWPathMonitor 监听网络状态变化,在主队列回调更新 UI",
165
+ "dontClause": "不要用 Reachability 旧库,不要在后台线程直接更新 UI",
166
+ "whenClause": "需要实时感知网络连通性变化时",
167
+ "coreCode": "let monitor = NWPathMonitor()\nmonitor.pathUpdateHandler = { path in\n DispatchQueue.main.async {\n self.isConnected = path.status == .satisfied\n }\n}\nmonitor.start(queue: DispatchQueue.global())",
168
+ "headers": ["import Network"],
169
+ "usageGuide": "### 何时用\n- App 需要实时网络状态\n- 启动时初始化一次\n\n### 关键点\n- 单例模式访问 sharedMonitor\n- start() 开始监听,cancel() 停止\n- 回调在 global queue,更新 UI 需切主线程",
170
+ "content": {
171
+ "markdown": "NWPathMonitor 是 iOS 12+ 推荐的网络状态监听方案,替代废弃的 Reachability。",
172
+ "rationale": "Apple 官方推荐,线程安全,支持蜂窝/WiFi/有线判断。"
173
+ },
174
+ "reasoning": {
175
+ "whyStandard": "Apple Developer Documentation 推荐方案,替代 SCNetworkReachability",
176
+ "sources": ["Apple Developer Documentation - NWPathMonitor"],
177
+ "confidence": 0.95
178
+ }
179
+ }
180
180
  ```
@@ -80,11 +80,10 @@ Documents are stored as `knowledgeType: 'dev-document'` in the knowledge DB. The
80
80
  - For ADRs, use the structure: Context → Decision → Consequences
81
81
  - For debug reports: Symptom → Investigation → Root Cause → Fix
82
82
 
83
- ## Relation to other skills
83
+ ## Related Skills
84
84
 
85
85
  | Skill | When to use |
86
86
  |-------|-------------|
87
87
  | `autosnippet-create` | Saving **code patterns/recipes** (needs trigger, doClause, etc.) |
88
88
  | `autosnippet-devdocs` (this) | Saving **prose documents** (only needs title + markdown) |
89
89
  | `autosnippet-recipes` | Looking up existing knowledge |
90
- | `autosnippet-concepts` | Understanding AutoSnippet concepts |