autosnippet 2.9.0 → 2.11.0

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 (115) hide show
  1. package/README.md +12 -12
  2. package/bin/cli.js +53 -40
  3. package/config/constitution.yaml +9 -2
  4. package/dashboard/dist/assets/{icons-CH-H9x0E.js → icons-D4IWpDIk.js} +105 -100
  5. package/dashboard/dist/assets/index-CWBNcF9z.css +1 -0
  6. package/dashboard/dist/assets/index-DHtzhbuG.js +120 -0
  7. package/dashboard/dist/index.html +3 -3
  8. package/lib/cli/AiScanService.js +35 -36
  9. package/lib/cli/KnowledgeSyncService.js +345 -0
  10. package/lib/cli/SetupService.js +8 -26
  11. package/lib/cli/UpgradeService.js +28 -0
  12. package/lib/core/gateway/GatewayActionRegistry.js +48 -58
  13. package/lib/domain/index.js +16 -11
  14. package/lib/domain/knowledge/KnowledgeEntry.js +289 -0
  15. package/lib/domain/knowledge/KnowledgeRepository.js +123 -0
  16. package/lib/domain/knowledge/Lifecycle.js +99 -0
  17. package/lib/domain/knowledge/index.js +27 -0
  18. package/lib/domain/knowledge/values/Constraints.js +128 -0
  19. package/lib/domain/knowledge/values/Content.js +69 -0
  20. package/lib/domain/knowledge/values/Quality.js +81 -0
  21. package/lib/domain/knowledge/values/Reasoning.js +70 -0
  22. package/lib/domain/knowledge/values/Relations.js +142 -0
  23. package/lib/domain/knowledge/values/Stats.js +72 -0
  24. package/lib/domain/knowledge/values/index.js +9 -0
  25. package/lib/external/ai/AiProvider.js +85 -11
  26. package/lib/external/mcp/McpServer.js +7 -5
  27. package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +18 -2
  28. package/lib/external/mcp/handlers/bootstrap.js +116 -11
  29. package/lib/external/mcp/handlers/browse.js +76 -73
  30. package/lib/external/mcp/handlers/candidate.js +26 -275
  31. package/lib/external/mcp/handlers/guard.js +2 -0
  32. package/lib/external/mcp/handlers/knowledge.js +267 -0
  33. package/lib/external/mcp/handlers/structure.js +25 -23
  34. package/lib/external/mcp/handlers/system.js +10 -12
  35. package/lib/external/mcp/tools.js +134 -140
  36. package/lib/http/HttpServer.js +14 -8
  37. package/lib/http/routes/ai.js +4 -3
  38. package/lib/http/routes/extract.js +48 -4
  39. package/lib/http/routes/knowledge.js +246 -0
  40. package/lib/http/routes/search.js +12 -17
  41. package/lib/infrastructure/database/migrations/016_unified_knowledge_entries.js +395 -0
  42. package/lib/infrastructure/database/migrations/017_camelcase_knowledge_entries.js +107 -0
  43. package/lib/infrastructure/external/XcodeAutomation.js +187 -103
  44. package/lib/injection/ServiceContainer.js +69 -60
  45. package/lib/repository/knowledge/KnowledgeRepository.impl.js +338 -0
  46. package/lib/service/automation/DirectiveDetector.js +2 -3
  47. package/lib/service/automation/FileWatcher.js +59 -28
  48. package/lib/service/automation/XcodeIntegration.js +931 -156
  49. package/lib/service/automation/handlers/AlinkHandler.js +5 -4
  50. package/lib/service/automation/handlers/CreateHandler.js +53 -19
  51. package/lib/service/automation/handlers/DraftHandler.js +1 -1
  52. package/lib/service/automation/handlers/GuardHandler.js +183 -20
  53. package/lib/service/automation/handlers/SearchHandler.js +25 -22
  54. package/lib/service/candidate/SimilarityService.js +2 -2
  55. package/lib/service/chat/AnalystAgent.js +9 -0
  56. package/lib/service/chat/CandidateGuardrail.js +22 -11
  57. package/lib/service/chat/ChatAgent.js +132 -54
  58. package/lib/service/chat/ContextWindow.js +5 -5
  59. package/lib/service/chat/HandoffProtocol.js +1 -0
  60. package/lib/service/chat/ProducerAgent.js +40 -13
  61. package/lib/service/chat/ReasoningLayer.js +854 -0
  62. package/lib/service/chat/ReasoningTrace.js +329 -0
  63. package/lib/service/chat/tools.js +308 -205
  64. package/lib/service/cursor/CursorDeliveryPipeline.js +279 -0
  65. package/lib/service/cursor/KnowledgeCompressor.js +87 -0
  66. package/lib/service/cursor/RulesGenerator.js +168 -0
  67. package/lib/service/cursor/SkillsSyncer.js +268 -0
  68. package/lib/service/cursor/TokenBudget.js +58 -0
  69. package/lib/service/cursor/TopicClassifier.js +141 -0
  70. package/lib/service/guard/GuardCheckEngine.js +99 -10
  71. package/lib/service/guard/GuardService.js +57 -46
  72. package/lib/service/knowledge/ConfidenceRouter.js +159 -0
  73. package/lib/service/knowledge/KnowledgeFileWriter.js +595 -0
  74. package/lib/service/knowledge/KnowledgeService.js +802 -0
  75. package/lib/service/recipe/RecipeParser.js +3 -12
  76. package/lib/service/search/SearchEngine.js +67 -22
  77. package/lib/service/skills/SignalCollector.js +14 -9
  78. package/lib/service/skills/SkillAdvisor.js +13 -11
  79. package/lib/service/snippet/SnippetFactory.js +5 -5
  80. package/lib/service/spm/SpmService.js +15 -48
  81. package/lib/shared/RecipeReadinessChecker.js +6 -11
  82. package/package.json +1 -1
  83. package/scripts/install-cursor-skill.js +0 -6
  84. package/scripts/migrate-md-to-knowledge.mjs +364 -0
  85. package/skills/autosnippet-analysis/SKILL.md +15 -7
  86. package/skills/autosnippet-candidates/SKILL.md +8 -8
  87. package/skills/autosnippet-coldstart/SKILL.md +8 -4
  88. package/skills/autosnippet-concepts/SKILL.md +7 -6
  89. package/skills/autosnippet-create/SKILL.md +13 -13
  90. package/skills/autosnippet-intent/SKILL.md +3 -2
  91. package/skills/autosnippet-lifecycle/SKILL.md +5 -5
  92. package/skills/autosnippet-recipes/SKILL.md +18 -6
  93. package/templates/constitution.yaml +1 -1
  94. package/templates/copilot-instructions.md +6 -6
  95. package/templates/recipes-setup/README.md +3 -3
  96. package/dashboard/dist/assets/index-CqJRvYRL.js +0 -197
  97. package/dashboard/dist/assets/index-DICm9PNa.css +0 -1
  98. package/lib/cli/CandidateSyncService.js +0 -261
  99. package/lib/cli/SyncService.js +0 -356
  100. package/lib/domain/candidate/Candidate.js +0 -196
  101. package/lib/domain/candidate/CandidateRepository.js +0 -107
  102. package/lib/domain/candidate/Reasoning.js +0 -52
  103. package/lib/domain/recipe/Recipe.js +0 -421
  104. package/lib/domain/recipe/RecipeRepository.js +0 -54
  105. package/lib/domain/types/CandidateStatus.js +0 -52
  106. package/lib/http/routes/candidates.js +0 -559
  107. package/lib/http/routes/recipes.js +0 -397
  108. package/lib/repository/candidate/CandidateRepository.impl.js +0 -230
  109. package/lib/repository/recipe/RecipeRepository.impl.js +0 -498
  110. package/lib/service/candidate/CandidateAggregator.js +0 -52
  111. package/lib/service/candidate/CandidateFileWriter.js +0 -383
  112. package/lib/service/candidate/CandidateService.js +0 -1001
  113. package/lib/service/recipe/RecipeFileWriter.js +0 -514
  114. package/lib/service/recipe/RecipeService.js +0 -786
  115. package/lib/service/recipe/RecipeStatsTracker.js +0 -148
package/README.md CHANGED
@@ -86,7 +86,7 @@ asd status # 自检项目根、AI Provider、索引、Dashboard
86
86
 
87
87
  ```
88
88
  用户:「扫描 NetworkModule 这个 Target,提取最佳实践」
89
- Cursor → autosnippet_get_targetsautosnippet_get_target_files → 逐文件提取 → autosnippet_submit_candidates
89
+ Cursor → get_targetsget_target_files → 逐文件提取 → submit_knowledge_batch
90
90
  → Dashboard Candidates 页面审核 → 保存为 Recipe
91
91
  ```
92
92
 
@@ -171,20 +171,20 @@ asd install:vscode-copilot # 配置 MCP 和 Copilot 指令
171
171
 
172
172
  ## MCP 工具一览
173
173
 
174
- 38 个 MCP 工具按功能分组:
174
+ 38 个 MCP 工具按功能分组(省略了 **autosnippet_** 前缀):
175
175
 
176
176
  | 分类 | 工具 |
177
177
  |------|------|
178
- | **系统** | `autosnippet_health`、`autosnippet_capabilities` |
179
- | **搜索** | `autosnippet_search`(统合入口)、`autosnippet_context_search`(4 层漏斗)、`autosnippet_keyword_search`、`autosnippet_semantic_search` |
180
- | **Recipe 浏览** | `autosnippet_list_recipes`、`autosnippet_get_recipe`、`autosnippet_list_rules`、`autosnippet_list_patterns`、`autosnippet_list_facts`、`autosnippet_recipe_insights`、`autosnippet_confirm_usage` |
181
- | **候选管理** | `autosnippet_validate_candidate`、`autosnippet_check_duplicate`、`autosnippet_submit_candidate`、`autosnippet_submit_candidates`、`autosnippet_submit_draft_recipes`、`autosnippet_enrich_candidates` |
182
- | **知识图谱** | `autosnippet_graph_query`、`autosnippet_graph_impact`、`autosnippet_graph_path`、`autosnippet_graph_stats` |
183
- | **项目结构** | `autosnippet_get_targets`、`autosnippet_get_target_files`、`autosnippet_get_target_metadata` |
184
- | **Guard** | `autosnippet_guard_check`、`autosnippet_guard_audit_files`、`autosnippet_scan_project` |
185
- | **冷启动** | `autosnippet_bootstrap_knowledge`、`autosnippet_bootstrap_refine` |
186
- | **Skills** | `autosnippet_list_skills`、`autosnippet_load_skill`、`autosnippet_create_skill`、`autosnippet_delete_skill`、`autosnippet_update_skill`、`autosnippet_suggest_skills` |
187
- | **治理** | `autosnippet_compliance_report` |
178
+ | **系统** | `health`、`capabilities` |
179
+ | **搜索** | `search`(统合入口)、`context_search`(4 层漏斗)、`keyword_search`、`semantic_search` |
180
+ | **Recipe 浏览** | `list_recipes`、`get_recipe`、`list_rules`、`patterns`、`list_facts`、`recipe_insights`、`confirm_usage` |
181
+ | **候选管理** | `validate_candidate`、`check_duplicate`、`submit_knowledge`、`submit_knowledge_batch`、`submit_knowledge_batch`、`enrich_candidates` |
182
+ | **知识图谱** | `graph_query`、`graph_impact`、`graph_path`、`graph_stats` |
183
+ | **项目结构** | `get_targets`、`get_target_files`、`get_target_metadata` |
184
+ | **Guard** | `guard_check`、`guard_audit_files`、`scan_project` |
185
+ | **冷启动** | `bootstrap_knowledge`、`bootstrap_refine` |
186
+ | **Skills** | `list_skills`、`load_skill`、`create_skill`、`delete_skill`、`update_skill`、`suggest_skills` |
187
+ | **治理** | `compliance_report` |
188
188
 
189
189
  ## 配置
190
190
 
package/bin/cli.js CHANGED
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Usage:
7
7
  * asd setup - 初始化项目
8
- * asd ais [Target] - AI 扫描 Target → Candidates
8
+ * asd ais [Target] - AI 扫描 Target → 直接发布 Recipes
9
9
  * asd search <query> - 搜索知识库
10
10
  * asd guard <file> - Guard 检查
11
11
  * asd watch - 文件监控
@@ -78,10 +78,10 @@ program
78
78
  // ─────────────────────────────────────────────────────
79
79
  program
80
80
  .command('ais [target]')
81
- .description('AI 扫描 Target 源码 → 提取 Candidates(需配置 AI Provider)')
81
+ .description('AI 扫描 Target 源码 → 提取并发布 Recipes(需配置 AI Provider)')
82
82
  .option('-d, --dir <path>', '项目目录', '.')
83
83
  .option('-m, --max-files <n>', '最大扫描文件数', '200')
84
- .option('--dry-run', '仅预览,不创建 Candidate')
84
+ .option('--dry-run', '仅预览,不发布 Recipe')
85
85
  .option('--json', '以 JSON 格式输出')
86
86
  .action(async (target, opts) => {
87
87
  const projectRoot = resolve(opts.dir);
@@ -99,7 +99,7 @@ program
99
99
  const scanner = new AiScanService({ container, projectRoot });
100
100
 
101
101
  const ora = (await import('ora')).default;
102
- const spinner = ora('正在扫描源文件并提取候选...').start();
102
+ const spinner = ora('正在扫描源文件并提取 Recipe...').start();
103
103
 
104
104
  const report = await scanner.scan(target || null, {
105
105
  maxFiles: parseInt(opts.maxFiles, 10),
@@ -114,7 +114,7 @@ program
114
114
  console.log(`\n✅ AI 扫描完成`);
115
115
  console.log(` 扫描文件: ${report.files}`);
116
116
  console.log(` 跳过: ${report.skipped}`);
117
- console.log(` 提取候选: ${report.candidates}`);
117
+ console.log(` 发布 Recipe: ${report.published}`);
118
118
  if (report.errors.length > 0) {
119
119
  console.log(`\n⚠️ ${report.errors.length} 个错误:`);
120
120
  for (const err of report.errors.slice(0, 10)) {
@@ -122,8 +122,8 @@ program
122
122
  }
123
123
  if (report.errors.length > 10) console.log(` ... 及其他 ${report.errors.length - 10} 个`);
124
124
  }
125
- if (!opts.dryRun && report.candidates > 0) {
126
- console.log(`\n📋 候选已创建,请运行 asd ui 打开 Dashboard 审核`);
125
+ if (!opts.dryRun && report.published > 0) {
126
+ console.log(`\n📋 Recipe 已发布,可通过 asd search Cursor Rules 使用`);
127
127
  }
128
128
  }
129
129
 
@@ -490,6 +490,47 @@ program
490
490
  });
491
491
  });
492
492
 
493
+ // ─────────────────────────────────────────────────────
494
+ // cursor-rules 命令
495
+ // ─────────────────────────────────────────────────────
496
+ program
497
+ .command('cursor-rules')
498
+ .description('生成 Cursor 4 通道交付物料(Rules + Skills → .cursor/)')
499
+ .option('-d, --dir <path>', '项目目录', '.')
500
+ .option('--verbose', '详细输出')
501
+ .action(async (opts) => {
502
+ const projectRoot = resolve(opts.dir);
503
+
504
+ console.log(`\n🚀 AutoSnippet — Cursor Delivery Pipeline`);
505
+ console.log(` 项目: ${basename(projectRoot)}`);
506
+ console.log(` 路径: ${projectRoot}\n`);
507
+
508
+ const { bootstrap, container } = await initContainer({ projectRoot });
509
+ try {
510
+ const pipeline = container.get('cursorDeliveryPipeline');
511
+ const result = await pipeline.deliver();
512
+
513
+ console.log(`✅ Cursor 交付物料生成完成\n`);
514
+ console.log(` Channel A (Always-On Rules): ${result.channelA.rulesCount} 条规则 (${result.channelA.tokensUsed} tokens)`);
515
+ console.log(` Channel B (Smart Rules): ${result.channelB.topicCount} 个主题, ${result.channelB.patternsCount} 个模式 (${result.channelB.totalTokens} tokens)`);
516
+ console.log(` Channel C (Agent Skills): ${result.channelC.synced} 个 Skills 已同步`);
517
+ if (result.channelC.errors > 0) {
518
+ console.log(` ⚠️ ${result.channelC.errors} 个错误`);
519
+ }
520
+ console.log(`\n 总耗时: ${result.stats.duration}ms`);
521
+
522
+ if (opts.verbose && result.channelB.topics) {
523
+ console.log(`\n Channel B 主题明细:`);
524
+ for (const [topic, info] of Object.entries(result.channelB.topics)) {
525
+ console.log(` - ${topic}: ${info.patternsCount} patterns (${info.tokensUsed} tokens)`);
526
+ }
527
+ }
528
+ console.log('');
529
+ } finally {
530
+ await bootstrap.shutdown?.();
531
+ }
532
+ });
533
+
493
534
  // ─────────────────────────────────────────────────────
494
535
  // sync 命令
495
536
  // ─────────────────────────────────────────────────────
@@ -501,12 +542,10 @@ program
501
542
  .option('--force', '忽略 hash 强制覆盖')
502
543
  .action(async (opts) => {
503
544
  const projectRoot = resolve(opts.dir);
504
- const { SyncService } = await import('../lib/cli/SyncService.js');
505
- const { CandidateSyncService } = await import('../lib/cli/CandidateSyncService.js');
506
- const syncService = new SyncService(projectRoot);
507
- const candidateSyncService = new CandidateSyncService(projectRoot);
545
+ const { KnowledgeSyncService } = await import('../lib/cli/KnowledgeSyncService.js');
546
+ const syncService = new KnowledgeSyncService(projectRoot);
508
547
 
509
- console.log(`\n🔄 AutoSnippet V2 — 同步 recipes + candidates`);
548
+ console.log(`\n🔄 AutoSnippet V3 — 同步 knowledge entries`);
510
549
  console.log(` 项目: ${basename(projectRoot)}`);
511
550
  console.log(` 路径: ${projectRoot}`);
512
551
  if (opts.dryRun) console.log(' 模式: dry-run(仅报告)');
@@ -533,7 +572,7 @@ program
533
572
  });
534
573
 
535
574
  // 输出报告
536
- console.log(`✅ Recipes 同步完成`);
575
+ console.log(`✅ Knowledge 同步完成`);
537
576
  console.log(` 扫描: ${report.synced + report.skipped} 文件`);
538
577
  console.log(` 新增: ${report.created}`);
539
578
  console.log(` 更新: ${report.updated}`);
@@ -547,38 +586,12 @@ program
547
586
  }
548
587
 
549
588
  if (report.orphaned.length > 0) {
550
- console.log(`\n🗑️ ${report.orphaned.length} 个孤儿 Recipe 已标记 deprecated:`);
589
+ console.log(`\n🗑️ ${report.orphaned.length} 个孤儿条目已标记 deprecated:`);
551
590
  for (const id of report.orphaned) {
552
591
  console.log(` - ${id}`);
553
592
  }
554
593
  }
555
594
 
556
- // ── Candidates 同步 ──
557
- const cReport = candidateSyncService.sync(db, {
558
- dryRun: opts.dryRun,
559
- force: opts.force,
560
- });
561
-
562
- console.log(`\n✅ Candidates 同步完成`);
563
- console.log(` 扫描: ${cReport.synced + cReport.skipped} 文件`);
564
- console.log(` 新增: ${cReport.created}`);
565
- console.log(` 更新: ${cReport.updated}`);
566
- console.log(` 跳过: ${cReport.skipped}`);
567
-
568
- if (cReport.violations.length > 0) {
569
- console.log(`\n⚠️ 检测到 ${cReport.violations.length} 个 Candidate 手动编辑:`);
570
- for (const v of cReport.violations) {
571
- console.log(` - ${v}`);
572
- }
573
- }
574
-
575
- if (cReport.orphaned.length > 0) {
576
- console.log(`\n📋 ${cReport.orphaned.length} 个 Candidate 仅存于 DB(无 .md 文件):`);
577
- for (const id of cReport.orphaned) {
578
- console.log(` - ${id}`);
579
- }
580
- }
581
-
582
595
  console.log('');
583
596
  } finally {
584
597
  await bootstrap.shutdown?.();
@@ -32,12 +32,19 @@ roles:
32
32
  - "read:recipes"
33
33
  - "read:guard_rules"
34
34
  - "create:candidates"
35
- - "submit:candidates"
35
+ - "candidate:update"
36
+ - "knowledge:create"
37
+ - "knowledge:update"
38
+ - "submit:knowledge"
36
39
  - "read:audit_logs:self"
37
40
  - "knowledge:bootstrap"
38
41
  - "create:skills"
42
+ - "update:skills"
43
+ - "delete:skills"
39
44
  constraints:
40
- - "cannot modify Recipe directly"
45
+ - "can submit knowledge entries (all go to pending)"
46
+ - "cannot publish/deprecate knowledge — only developer can do that"
47
+ - "can reactivate deprecated entries back to pending"
41
48
  - "cannot modify Guard rules"
42
49
  - "cannot delete any data"
43
50
  - id: "chat_agent"