autosnippet 3.2.18 → 3.2.21

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 (189) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +73 -104
  3. package/config/default.json +1 -1
  4. package/dashboard/dist/assets/{index-CKMy5LY6.js → index-DdvZE4Yd.js} +1 -1
  5. package/dashboard/dist/index.html +1 -1
  6. package/dist/bin/cli.js +45 -10
  7. package/dist/lib/agent/AgentEventBus.js +3 -3
  8. package/dist/lib/agent/AgentFactory.d.ts +3 -3
  9. package/dist/lib/agent/AgentFactory.js +4 -4
  10. package/dist/lib/agent/AgentMessage.d.ts +8 -8
  11. package/dist/lib/agent/AgentMessage.js +8 -8
  12. package/dist/lib/agent/AgentRuntime.js +2 -2
  13. package/dist/lib/agent/AgentState.js +4 -4
  14. package/dist/lib/agent/ConversationStore.d.ts +1 -1
  15. package/dist/lib/agent/ConversationStore.js +1 -1
  16. package/dist/lib/agent/PipelineStrategy.js +1 -1
  17. package/dist/lib/agent/context/ContextWindow.d.ts +2 -2
  18. package/dist/lib/agent/context/ContextWindow.js +7 -7
  19. package/dist/lib/agent/context/ExplorationTracker.js +9 -9
  20. package/dist/lib/agent/context/exploration/PlanTracker.js +2 -2
  21. package/dist/lib/agent/context/exploration/SignalDetector.d.ts +1 -1
  22. package/dist/lib/agent/context/exploration/SignalDetector.js +1 -1
  23. package/dist/lib/agent/core/LoopContext.d.ts +21 -21
  24. package/dist/lib/agent/core/LoopContext.js +21 -21
  25. package/dist/lib/agent/core/SystemPromptBuilder.js +4 -4
  26. package/dist/lib/agent/domain/EvidenceCollector.js +5 -5
  27. package/dist/lib/agent/memory/ActiveContext.js +1 -1
  28. package/dist/lib/agent/memory/MemoryRetriever.js +1 -1
  29. package/dist/lib/agent/memory/MemoryStore.js +2 -2
  30. package/dist/lib/agent/memory/SessionStore.js +3 -3
  31. package/dist/lib/agent/policies.d.ts +1 -1
  32. package/dist/lib/agent/policies.js +1 -1
  33. package/dist/lib/agent/strategies.d.ts +1 -1
  34. package/dist/lib/agent/strategies.js +4 -4
  35. package/dist/lib/agent/tools/_shared.d.ts +1 -1
  36. package/dist/lib/agent/tools/_shared.js +1 -1
  37. package/dist/lib/agent/tools/infrastructure.js +2 -2
  38. package/dist/lib/cli/SetupService.d.ts +25 -25
  39. package/dist/lib/cli/SetupService.js +28 -15
  40. package/dist/lib/cli/deploy/FileDeployer.d.ts +9 -2
  41. package/dist/lib/cli/deploy/FileDeployer.js +139 -46
  42. package/dist/lib/cli/deploy/FileManifest.d.ts +23 -39
  43. package/dist/lib/cli/deploy/FileManifest.js +22 -33
  44. package/dist/lib/core/AstAnalyzer.d.ts +2 -2
  45. package/dist/lib/core/AstAnalyzer.js +2 -2
  46. package/dist/lib/core/analysis/CallEdgeResolver.d.ts +7 -7
  47. package/dist/lib/core/analysis/CallEdgeResolver.js +9 -9
  48. package/dist/lib/core/analysis/CallGraphAnalyzer.d.ts +4 -4
  49. package/dist/lib/core/analysis/CallGraphAnalyzer.js +2 -2
  50. package/dist/lib/core/analysis/ImportPathResolver.d.ts +0 -2
  51. package/dist/lib/core/analysis/ImportPathResolver.js +2 -4
  52. package/dist/lib/core/ast/ProjectGraph.js +7 -7
  53. package/dist/lib/core/capability/CapabilityProbe.js +6 -14
  54. package/dist/lib/domain/knowledge/UnifiedValidator.js +2 -2
  55. package/dist/lib/domain/knowledge/values/Constraints.js +4 -4
  56. package/dist/lib/domain/knowledge/values/Content.js +6 -6
  57. package/dist/lib/domain/knowledge/values/Quality.js +5 -5
  58. package/dist/lib/domain/knowledge/values/Reasoning.js +5 -5
  59. package/dist/lib/domain/knowledge/values/Relations.js +1 -1
  60. package/dist/lib/domain/knowledge/values/Stats.js +6 -6
  61. package/dist/lib/domain/task/TaskIdGenerator.d.ts +4 -4
  62. package/dist/lib/domain/task/TaskIdGenerator.js +2 -2
  63. package/dist/lib/external/lark/LarkTransport.js +4 -4
  64. package/dist/lib/external/mcp/McpServer.d.ts +3 -7
  65. package/dist/lib/external/mcp/McpServer.js +9 -13
  66. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +5 -5
  67. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +4 -3
  68. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +3 -3
  69. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +3 -3
  70. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.d.ts +1 -1
  71. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +1 -1
  72. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +3 -3
  73. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +27 -14
  74. package/dist/lib/external/mcp/handlers/bootstrap-external.js +6 -0
  75. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +55 -1
  76. package/dist/lib/external/mcp/handlers/skill.js +9 -31
  77. package/dist/lib/external/mcp/handlers/system.js +6 -4
  78. package/dist/lib/external/mcp/handlers/task.js +16 -1
  79. package/dist/lib/external/mcp/tools.d.ts +12 -10
  80. package/dist/lib/external/mcp/tools.js +97 -69
  81. package/dist/lib/http/utils/routeHelpers.d.ts +1 -1
  82. package/dist/lib/http/utils/routeHelpers.js +1 -1
  83. package/dist/lib/http/utils/sse-sessions.d.ts +1 -1
  84. package/dist/lib/http/utils/sse-sessions.js +1 -1
  85. package/dist/lib/infrastructure/cache/CacheService.js +1 -1
  86. package/dist/lib/infrastructure/logging/Logger.js +1 -1
  87. package/dist/lib/infrastructure/monitoring/ErrorTracker.js +1 -1
  88. package/dist/lib/infrastructure/vector/AsyncPersistence.js +8 -8
  89. package/dist/lib/infrastructure/vector/BatchEmbedder.d.ts +1 -1
  90. package/dist/lib/infrastructure/vector/BatchEmbedder.js +2 -2
  91. package/dist/lib/infrastructure/vector/HnswIndex.d.ts +4 -4
  92. package/dist/lib/infrastructure/vector/HnswIndex.js +5 -5
  93. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +8 -8
  94. package/dist/lib/infrastructure/vector/ScalarQuantizer.d.ts +1 -1
  95. package/dist/lib/infrastructure/vector/ScalarQuantizer.js +4 -4
  96. package/dist/lib/infrastructure/vector/VectorStore.d.ts +1 -1
  97. package/dist/lib/infrastructure/vector/VectorStore.js +1 -1
  98. package/dist/lib/injection/ServiceContainer.d.ts +1 -1
  99. package/dist/lib/injection/ServiceContainer.js +1 -1
  100. package/dist/lib/injection/modules/KnowledgeModule.js +4 -5
  101. package/dist/lib/platform/NativeUi.d.ts +1 -1
  102. package/dist/lib/platform/NativeUi.js +1 -1
  103. package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +1 -1
  104. package/dist/lib/platform/ios/spm/DependencyGraph.js +1 -1
  105. package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +1 -1
  106. package/dist/lib/platform/ios/spm/PolicyEngine.js +1 -1
  107. package/dist/lib/platform/ios/spm/SpmDiscoverer.js +1 -1
  108. package/dist/lib/platform/ios/spm/SpmHelper.js +3 -3
  109. package/dist/lib/platform/ios/xcode/SaveEventFilter.js +2 -2
  110. package/dist/lib/platform/ios/xcode/XcodeIntegration.js +1 -1
  111. package/dist/lib/repository/base/BaseRepository.js +1 -1
  112. package/dist/lib/repository/task/TaskRepository.impl.d.ts +2 -2
  113. package/dist/lib/repository/task/TaskRepository.impl.js +1 -1
  114. package/dist/lib/repository/token/TokenUsageStore.js +1 -1
  115. package/dist/lib/service/automation/ActionPipeline.d.ts +1 -1
  116. package/dist/lib/service/automation/ActionPipeline.js +1 -1
  117. package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +2 -2
  118. package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +1 -1
  119. package/dist/lib/service/bootstrap/BootstrapTaskManager.js +2 -2
  120. package/dist/lib/service/bootstrap/DimensionCopyRegistry.d.ts +2 -2
  121. package/dist/lib/service/bootstrap/DimensionCopyRegistry.js +2 -2
  122. package/dist/lib/service/delivery/AgentInstructionsGenerator.d.ts +6 -15
  123. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +53 -189
  124. package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +6 -16
  125. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +14 -19
  126. package/dist/lib/service/delivery/KnowledgeCompressor.d.ts +1 -1
  127. package/dist/lib/service/delivery/KnowledgeCompressor.js +1 -1
  128. package/dist/lib/service/delivery/RulesGenerator.d.ts +10 -3
  129. package/dist/lib/service/delivery/RulesGenerator.js +43 -3
  130. package/dist/lib/service/delivery/SkillsSyncer.d.ts +21 -7
  131. package/dist/lib/service/delivery/SkillsSyncer.js +46 -10
  132. package/dist/lib/service/delivery/TopicClassifier.d.ts +3 -6
  133. package/dist/lib/service/delivery/TopicClassifier.js +0 -3
  134. package/dist/lib/service/guard/ExclusionManager.d.ts +1 -1
  135. package/dist/lib/service/guard/ExclusionManager.js +1 -1
  136. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -3
  137. package/dist/lib/service/guard/GuardCheckEngine.js +5 -5
  138. package/dist/lib/service/guard/GuardCrossFileChecks.d.ts +1 -1
  139. package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -3
  140. package/dist/lib/service/guard/GuardFeedbackLoop.js +3 -3
  141. package/dist/lib/service/guard/GuardPatternUtils.js +1 -1
  142. package/dist/lib/service/guard/GuardService.d.ts +1 -15
  143. package/dist/lib/service/guard/GuardService.js +0 -1
  144. package/dist/lib/service/guard/RuleLearner.d.ts +1 -1
  145. package/dist/lib/service/guard/RuleLearner.js +1 -1
  146. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +3 -3
  147. package/dist/lib/service/knowledge/CodeEntityGraph.js +3 -3
  148. package/dist/lib/service/knowledge/KnowledgeService.d.ts +0 -1
  149. package/dist/lib/service/knowledge/KnowledgeService.js +0 -1
  150. package/dist/lib/service/module/ModuleService.d.ts +1 -1
  151. package/dist/lib/service/module/ModuleService.js +2 -2
  152. package/dist/lib/service/search/HybridRetriever.d.ts +2 -2
  153. package/dist/lib/service/search/HybridRetriever.js +2 -2
  154. package/dist/lib/service/search/SearchEngine.d.ts +1 -3
  155. package/dist/lib/service/search/SearchEngine.js +1 -3
  156. package/dist/lib/service/search/contextBoost.d.ts +1 -1
  157. package/dist/lib/service/skills/EventAggregator.js +2 -2
  158. package/dist/lib/service/skills/SignalCollector.js +1 -1
  159. package/dist/lib/service/snippet/codecs/VSCodeCodec.js +1 -1
  160. package/dist/lib/service/task/TaskGraphService.d.ts +0 -3
  161. package/dist/lib/service/task/TaskGraphService.js +0 -3
  162. package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +8 -27
  163. package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -8
  164. package/dist/lib/service/task/TaskReadyEngine.d.ts +1 -2
  165. package/dist/lib/service/task/TaskReadyEngine.js +0 -1
  166. package/dist/lib/service/wiki/WikiRenderers.js +0 -1
  167. package/dist/lib/service/wiki/WikiUtils.js +2 -7
  168. package/dist/lib/shared/PathGuard.js +6 -6
  169. package/dist/lib/shared/schemas/config.js +1 -1
  170. package/dist/lib/shared/schemas/mcp-tools.js +84 -43
  171. package/dist/scripts/install-vscode-copilot.js +14 -4
  172. package/package.json +1 -1
  173. package/skills/autosnippet-create/SKILL.md +131 -131
  174. package/skills/autosnippet-devdocs/SKILL.md +1 -2
  175. package/skills/autosnippet-guard/SKILL.md +20 -89
  176. package/skills/autosnippet-recipes/SKILL.md +35 -117
  177. package/skills/autosnippet-structure/SKILL.md +23 -55
  178. package/templates/cursor-rules/autosnippet-skills.mdc +17 -33
  179. package/templates/instructions/agent-static.md +24 -0
  180. package/templates/instructions/conventions.md +42 -0
  181. package/skills/autosnippet-analysis/SKILL.md +0 -169
  182. package/skills/autosnippet-candidates/SKILL.md +0 -367
  183. package/skills/autosnippet-coldstart/SKILL.md +0 -988
  184. package/skills/autosnippet-concepts/SKILL.md +0 -630
  185. package/skills/autosnippet-intent/SKILL.md +0 -55
  186. package/skills/autosnippet-lifecycle/SKILL.md +0 -100
  187. package/templates/copilot-instructions.md +0 -66
  188. package/templates/cursor-rules/autosnippet-conventions.mdc +0 -172
  189. package/templates/cursor-rules/autosnippet-workflow.mdc +0 -76
@@ -72,7 +72,7 @@ export class SetupService {
72
72
  /** 子仓库远程仓库 URL(为空则 recipes/ 作为普通目录随主仓库提交) */
73
73
  subRepoUrl;
74
74
  /**
75
- * @param {{ projectRoot: string, force?: boolean, seed?: boolean, subRepoDir?: string, subRepoUrl?: string }} options
75
+ * @param options
76
76
  */
77
77
  constructor(options) {
78
78
  this.projectRoot = resolve(options.projectRoot);
@@ -130,7 +130,7 @@ export class SetupService {
130
130
  this._results = results;
131
131
  return results;
132
132
  }
133
- /** @private 格式化步骤结果的简要信息 */
133
+ /** 格式化步骤结果的简要信息 */
134
134
  _formatStepDetail(r) {
135
135
  if (!r) {
136
136
  return '';
@@ -149,8 +149,21 @@ export class SetupService {
149
149
  }
150
150
  printSummary() {
151
151
  const results = this._results || [];
152
- const _ok = results.filter((r) => r.ok).length;
153
- const _fail = results.filter((r) => !r.ok).length;
152
+ const ok = results.filter((r) => r.ok).length;
153
+ const fail = results.filter((r) => !r.ok).length;
154
+ console.log('');
155
+ if (fail === 0) {
156
+ console.log(` ✅ Setup 完成(${ok} 步骤全部成功)`);
157
+ }
158
+ else {
159
+ console.log(` ⚠️ Setup 完成(${ok} 成功,${fail} 失败)`);
160
+ }
161
+ console.log('');
162
+ console.log(' 下一步:');
163
+ console.log(' 1. 运行 asd ui 启动后台服务');
164
+ console.log(' 2. 打开 IDE Agent Mode,告诉它「帮我冷启动」');
165
+ console.log(' 3. 所有分析和知识提取都通过 IDE 完成,无需额外配置');
166
+ console.log('');
154
167
  }
155
168
  /* ═══ Step 1: 运行时目录与配置 ═══════════════════════ */
156
169
  stepRuntime() {
@@ -252,7 +265,7 @@ export class SetupService {
252
265
  hasUrl: Boolean(this.subRepoUrl),
253
266
  };
254
267
  }
255
- /** @private 写入 constitution.yaml(优先从模板复制) */
268
+ /** 写入 constitution.yaml(优先从模板复制) */
256
269
  _writeConstitution() {
257
270
  const dest = join(this.coreDir, 'constitution.yaml');
258
271
  if (existsSync(dest) && !this.force) {
@@ -307,7 +320,7 @@ export class SetupService {
307
320
  ].join('\n'));
308
321
  }
309
322
  }
310
- /** @private 写入 boxspec.json */
323
+ /** 写入 boxspec.json */
311
324
  _writeBoxspec() {
312
325
  const dest = join(this.coreDir, 'boxspec.json');
313
326
  if (existsSync(dest) && !this.force) {
@@ -323,7 +336,7 @@ export class SetupService {
323
336
  module: { rootDir: DEFAULT_KNOWLEDGE_BASE_DIR },
324
337
  }, null, 2));
325
338
  }
326
- /** @private 复制 _template.md 到 recipes/ */
339
+ /** 复制 _template.md 到 recipes/ */
327
340
  _copyRecipeTemplate() {
328
341
  const src = join(REPO_ROOT, 'templates', 'recipes-setup', '_template.md');
329
342
  if (!existsSync(src)) {
@@ -335,7 +348,7 @@ export class SetupService {
335
348
  }
336
349
  copyFileSync(src, dest);
337
350
  }
338
- /** @private 复制示例 Recipe(冷启动推荐) */
351
+ /** 复制示例 Recipe(冷启动推荐) */
339
352
  _copySeedRecipes() {
340
353
  const seedDir = join(REPO_ROOT, 'templates', 'recipes-setup');
341
354
  if (!existsSync(seedDir)) {
@@ -361,7 +374,7 @@ export class SetupService {
361
374
  if (count > 0) {
362
375
  }
363
376
  }
364
- /** @private 写入核心目录 README */
377
+ /** 写入核心目录 README */
365
378
  _writeCoreReadme() {
366
379
  const dest = join(this.coreDir, 'README.md');
367
380
  if (existsSync(dest) && !this.force) {
@@ -485,7 +498,7 @@ export class SetupService {
485
498
  return { dbPath: this.dbPath };
486
499
  }
487
500
  /**
488
- * @private 从 AutoSnippet/recipes/*.md + candidates/*.md 同步到 DB 缓存
501
+ * 从 AutoSnippet/recipes/*.md + candidates/*.md 同步到 DB 缓存
489
502
  * 委托 KnowledgeSyncService 执行全字段同步(setup 场景跳过违规记录)
490
503
  */
491
504
  async _syncRecipesToDB(db) {
@@ -532,7 +545,7 @@ export class SetupService {
532
545
  }
533
546
  /* ═══ Helpers ════════════════════════════════════════ */
534
547
  /**
535
- * @private 在项目根目录创建 .env 文件(从 .env.example 复制)
548
+ * 在项目根目录创建 .env 文件(从 .env.example 复制)
536
549
  * 如果 .env 已存在则跳过并提示用户手动配置。
537
550
  */
538
551
  _ensureEnvFile() {
@@ -557,7 +570,7 @@ export class SetupService {
557
570
  ].join('\n'));
558
571
  }
559
572
  }
560
- /** @private 在指定目录执行 git 命令 */
573
+ /** 在指定目录执行 git 命令 */
561
574
  _git(args, cwd) {
562
575
  try {
563
576
  return execSync(`git ${args.join(' ')}`, {
@@ -573,7 +586,7 @@ export class SetupService {
573
586
  throw e;
574
587
  }
575
588
  }
576
- /** @private 检查目录中是否有文件(排除 . 和 ..) */
589
+ /** 检查目录中是否有文件(排除 . 和 ..) */
577
590
  _hasFiles(dirPath) {
578
591
  try {
579
592
  const entries = readdirSync(dirPath);
@@ -583,7 +596,7 @@ export class SetupService {
583
596
  return false;
584
597
  }
585
598
  }
586
- /** @private 确保子仓库的 remote origin 与给定 URL 一致 */
599
+ /** 确保子仓库的 remote origin 与给定 URL 一致 */
587
600
  _ensureRemote(url) {
588
601
  try {
589
602
  const currentUrl = this._git(['remote', 'get-url', 'origin'], this.subRepoPath);
@@ -597,7 +610,7 @@ export class SetupService {
597
610
  }
598
611
  }
599
612
  /**
600
- * @private 备份已有文件 → clone → 合并回来(不覆盖远端文件)
613
+ * 备份已有文件 → clone → 合并回来(不覆盖远端文件)
601
614
  * 适用于 recipes/ 有模板文件但还不是 git 仓库的场景
602
615
  */
603
616
  _cloneWithMerge(url) {
@@ -42,7 +42,7 @@ export declare class FileDeployer {
42
42
  });
43
43
  /**
44
44
  * 部署所有适用的文件
45
- * @param {{ filter?: string[] }} options 可选过滤部署的 category
45
+ * @param options 可选过滤部署的 category
46
46
  * @returns > }}
47
47
  */
48
48
  deployAll(mode: 'setup' | 'upgrade', { filter }?: {
@@ -79,7 +79,14 @@ export declare class FileDeployer {
79
79
  _strategyCreateOnly(entry: ManifestEntry): boolean;
80
80
  /** merge-json — 读取现有 JSON,合并 autosnippet 键 */
81
81
  _strategyMergeJson(entry: ManifestEntry): boolean;
82
- /** merge-gitignore — 增量追加规则 + 迁移旧格式 */
82
+ /**
83
+ * merge-gitignore — section-based 管理
84
+ *
85
+ * 设计:用 BEGIN/END 标记包裹 AutoSnippet 规则块,整块替换。
86
+ * - 首次:追加 section 到文件末尾
87
+ * - 升级:替换已有 section(规则变更自动生效)
88
+ * - 迁移:清理旧版逐行追加的散落规则
89
+ */
83
90
  _strategyMergeGitignore(_entry: ManifestEntry): boolean;
84
91
  /** backup-overwrite — 备份旧文件后覆盖 */
85
92
  _strategyBackupOverwrite(entry: ManifestEntry): boolean;
@@ -22,7 +22,7 @@ import { injectAutoApprove } from '../../external/mcp/autoApproveInjector.js';
22
22
  import { checkWriteSafety, safeCopyFile } from '../../service/delivery/FileProtection.js';
23
23
  import { DEFAULT_KNOWLEDGE_BASE_DIR } from '../../shared/ProjectMarkers.js';
24
24
  import { PACKAGE_ROOT, TEMPLATES_DIR } from '../../shared/package-root.js';
25
- import { buildMcpServerEntry, GITIGNORE_MIGRATIONS, GITIGNORE_RULES, MANIFEST, } from './FileManifest.js';
25
+ import { buildMcpServerEntry, GITIGNORE_MIGRATIONS, GITIGNORE_RULES, GITIGNORE_SECTION_BEGIN, GITIGNORE_SECTION_END, MANIFEST, } from './FileManifest.js';
26
26
  /** AutoSnippet 源码仓库根目录 */
27
27
  const REPO_ROOT = PACKAGE_ROOT;
28
28
  export class FileDeployer {
@@ -38,7 +38,7 @@ export class FileDeployer {
38
38
  /* ═══ 公共入口 ═══════════════════════════════════════ */
39
39
  /**
40
40
  * 部署所有适用的文件
41
- * @param {{ filter?: string[] }} options 可选过滤部署的 category
41
+ * @param options 可选过滤部署的 category
42
42
  * @returns > }}
43
43
  */
44
44
  deployAll(mode, { filter } = {}) {
@@ -227,38 +227,90 @@ export class FileDeployer {
227
227
  writeFileSync(dest, JSON.stringify(config, null, 2));
228
228
  return true;
229
229
  }
230
- /** merge-gitignore — 增量追加规则 + 迁移旧格式 */
230
+ /**
231
+ * merge-gitignore — section-based 管理
232
+ *
233
+ * 设计:用 BEGIN/END 标记包裹 AutoSnippet 规则块,整块替换。
234
+ * - 首次:追加 section 到文件末尾
235
+ * - 升级:替换已有 section(规则变更自动生效)
236
+ * - 迁移:清理旧版逐行追加的散落规则
237
+ */
231
238
  _strategyMergeGitignore(_entry) {
232
239
  const giPath = join(this.projectRoot, '.gitignore');
233
240
  let content = existsSync(giPath) ? readFileSync(giPath, 'utf8') : '';
234
241
  let changed = false;
235
- // 1. 迁移旧格式
242
+ // 1. 迁移旧格式(regex-based cleanup)
236
243
  for (const migration of GITIGNORE_MIGRATIONS) {
237
244
  if (migration.find.test(content)) {
238
245
  content = content.replace(migration.find, migration.replace);
239
246
  changed = true;
240
247
  }
241
248
  }
242
- // 2. 追加缺失规则
243
- for (const rule of GITIGNORE_RULES) {
244
- const pattern = rule.pattern;
245
- // 对 negation 规则 (!xxx) 检查原模式
246
- const _checkStr = rule.negation ? pattern : pattern.replace(/[[\]*?]/g, '\\$&');
247
- if (!content.includes(pattern)) {
248
- const prefix = rule.comment ? `\n# ${rule.comment}\n` : '';
249
- content += `${prefix}${pattern}\n`;
249
+ // 2. 迁移:清理旧版散落的 AutoSnippet 规则(无 section marker 时代的残留)
250
+ const oldPatterns = GITIGNORE_RULES.map((r) => r.pattern);
251
+ const oldComments = GITIGNORE_RULES.filter((r) => r.comment).map((r) => `# ${r.comment}`);
252
+ // 也清除旧版注入的通用规则
253
+ const legacyTokens = [
254
+ '.DS_Store',
255
+ 'nohup.out',
256
+ '*.sw[a-p]',
257
+ '# macOS 元数据',
258
+ '# AutoSnippet 运行时缓存(不入库)',
259
+ '# AutoSnippet 环境变量(含 API Key,不入库)',
260
+ '# AutoSnippet 运行日志',
261
+ ];
262
+ const allOldTokens = new Set([...oldPatterns, ...oldComments, ...legacyTokens]);
263
+ // 只有在 section markers 不存在时才清理散落规则(避免误删 section 内容后重复清理)
264
+ if (!content.includes(GITIGNORE_SECTION_BEGIN)) {
265
+ const lines = content.split('\n');
266
+ const cleaned = lines.filter((line) => !allOldTokens.has(line.trim()));
267
+ const cleanedContent = cleaned
268
+ .join('\n')
269
+ .replace(/\n{3,}/g, '\n\n')
270
+ .trimEnd();
271
+ if (cleanedContent !== content.trimEnd()) {
272
+ content = cleanedContent.endsWith('\n') ? cleanedContent : `${cleanedContent}\n`;
250
273
  changed = true;
251
274
  }
252
275
  }
253
- // 3. 确保 AutoSnippet/ 不被忽略
276
+ // 3. 构建 AutoSnippet section block
277
+ const sectionLines = [GITIGNORE_SECTION_BEGIN];
278
+ for (const rule of GITIGNORE_RULES) {
279
+ if (rule.comment) {
280
+ sectionLines.push(`# ${rule.comment}`);
281
+ }
282
+ sectionLines.push(rule.pattern);
283
+ }
284
+ // 确保 AutoSnippet/ 知识库不被忽略
254
285
  const kbDir = DEFAULT_KNOWLEDGE_BASE_DIR;
255
- const lines = content.split('\n');
256
- const hasIgnoreAS = lines.some((l) => {
286
+ const contentLines = content.split('\n');
287
+ const hasIgnoreAS = contentLines.some((l) => {
257
288
  const t = l.trim();
258
289
  return (t === `${kbDir}/` || t === kbDir) && !t.startsWith('#') && !t.startsWith('!');
259
290
  });
260
- if (hasIgnoreAS && !lines.some((l) => l.trim() === `!${kbDir}/`)) {
261
- content += `\n# ${kbDir} 知识库必须入库(取消上方忽略)\n!${kbDir}/\n`;
291
+ if (hasIgnoreAS) {
292
+ sectionLines.push(`# 知识库必须入库`);
293
+ sectionLines.push(`!${kbDir}/`);
294
+ }
295
+ sectionLines.push(GITIGNORE_SECTION_END);
296
+ const sectionBlock = sectionLines.join('\n');
297
+ // 4. 插入或替换 section
298
+ const beginIdx = content.indexOf(GITIGNORE_SECTION_BEGIN);
299
+ const endIdx = content.indexOf(GITIGNORE_SECTION_END);
300
+ if (beginIdx !== -1 && endIdx !== -1) {
301
+ // 替换已有 section
302
+ const before = content.substring(0, beginIdx);
303
+ const after = content.substring(endIdx + GITIGNORE_SECTION_END.length);
304
+ const newContent = `${before}${sectionBlock}${after}`;
305
+ if (newContent !== content) {
306
+ content = newContent;
307
+ changed = true;
308
+ }
309
+ }
310
+ else {
311
+ // 首次追加
312
+ const separator = content.endsWith('\n') || content.length === 0 ? '\n' : '\n\n';
313
+ content += `${separator}${sectionBlock}\n`;
262
314
  changed = true;
263
315
  }
264
316
  if (changed) {
@@ -335,7 +387,71 @@ export class FileDeployer {
335
387
  }
336
388
  /* ═══ 自定义生成器 ═══════════════════════════════════ */
337
389
  _generators = {
338
- /** AGENTS.md 静态骨架 */
390
+ /** .cursor/rules/autosnippet-conventions.mdc — 读 conventions.md + YAML frontmatter */
391
+ generateConventionsMdc() {
392
+ const tpl = join(TEMPLATES_DIR, 'instructions/conventions.md');
393
+ if (!existsSync(tpl)) {
394
+ return false;
395
+ }
396
+ const body = readFileSync(tpl, 'utf8').trimEnd();
397
+ const content = [
398
+ '---',
399
+ 'description: AutoSnippet conventions — behavioral rules for task tracking, knowledge guardrails, and MCP usage',
400
+ 'alwaysApply: true',
401
+ '---',
402
+ '',
403
+ '# AutoSnippet Conventions',
404
+ '',
405
+ body,
406
+ '',
407
+ ].join('\n');
408
+ const dest = join(this.projectRoot, '.cursor/rules/autosnippet-conventions.mdc');
409
+ mkdirSync(dirname(dest), { recursive: true });
410
+ writeFileSync(dest, content);
411
+ return true;
412
+ },
413
+ /** .github/copilot-instructions.md — 读 conventions.md + HTML markers */
414
+ generateCopilotInstructions() {
415
+ const tpl = join(TEMPLATES_DIR, 'instructions/conventions.md');
416
+ if (!existsSync(tpl)) {
417
+ return false;
418
+ }
419
+ const body = readFileSync(tpl, 'utf8').trimEnd();
420
+ const content = [
421
+ '<!-- autosnippet:begin -->',
422
+ '',
423
+ '# AutoSnippet Conventions',
424
+ '',
425
+ body,
426
+ '',
427
+ '<!-- autosnippet:end -->',
428
+ '',
429
+ ].join('\n');
430
+ const dest = join(this.projectRoot, '.github/copilot-instructions.md');
431
+ const destDir = dirname(dest);
432
+ mkdirSync(destDir, { recursive: true });
433
+ // 如果文件已存在且包含 begin/end markers,仅替换标记间内容
434
+ if (existsSync(dest)) {
435
+ const existing = readFileSync(dest, 'utf8');
436
+ const BEGIN = '<!-- autosnippet:begin -->';
437
+ const END = '<!-- autosnippet:end -->';
438
+ if (existing.includes(BEGIN) && existing.includes(END)) {
439
+ const snippet = content.trimEnd();
440
+ const updated = existing.replace(new RegExp(`${BEGIN}[\\s\\S]*?${END}`), snippet);
441
+ writeFileSync(dest, updated);
442
+ return true;
443
+ }
444
+ // 用户文件无 markers 且无 AutoSnippet 签名 → 追加
445
+ const { canWrite } = checkWriteSafety(dest);
446
+ if (!canWrite) {
447
+ writeFileSync(dest, `${existing}\n\n${content}`);
448
+ return true;
449
+ }
450
+ }
451
+ writeFileSync(dest, content);
452
+ return true;
453
+ },
454
+ /** AGENTS.md 静态骨架 — 读 agent-static.md 模板 */
339
455
  generateAgentsMd() {
340
456
  const claudePath = join(this.projectRoot, 'CLAUDE.md');
341
457
  if (existsSync(claudePath)) {
@@ -349,34 +465,11 @@ export class FileDeployer {
349
465
  if (!canWrite) {
350
466
  return false;
351
467
  }
352
- const content = [
353
- `# ${this.projectName} — Agent Instructions`,
354
- '',
355
- '> Auto-generated by AutoSnippet.',
356
- '',
357
- '## AutoSnippet Integration',
358
- '',
359
- 'This project uses **AutoSnippet** for knowledge management and decision tracking.',
360
- '',
361
- '### MCP Tools',
362
- '',
363
- '- `autosnippet_search` — Search knowledge',
364
- '- `autosnippet_knowledge` — Browse/get recipes',
365
- '- `autosnippet_submit_knowledge` — Submit candidate',
366
- '- `autosnippet_guard` — Code compliance check',
367
- '- `autosnippet_health` — Service health & KB stats',
368
- '- `autosnippet_task` — Unified task & decision management (prime/create/claim/close/record_decision/revise_decision/unpin_decision/list_decisions)',
369
- '',
370
- '### VS Code Agent Mode',
371
- '',
372
- 'Type `#asd` before your message in Agent Mode to activate project memory.',
373
- '',
374
- '### Constraints',
375
- '',
376
- '1. Do NOT modify knowledge base files directly.',
377
- '2. Create or update knowledge only through MCP tools.',
378
- '',
379
- ].join('\n');
468
+ const tpl = join(TEMPLATES_DIR, 'instructions/agent-static.md');
469
+ if (!existsSync(tpl)) {
470
+ return false;
471
+ }
472
+ const content = readFileSync(tpl, 'utf8').replace(/\{\{projectName\}\}/g, this.projectName);
380
473
  writeFileSync(agentsPath, content);
381
474
  return true;
382
475
  },
@@ -32,25 +32,23 @@ export declare const MANIFEST: ({
32
32
  on: string;
33
33
  category: string;
34
34
  jsonKey: string;
35
+ generate?: undefined;
35
36
  src?: undefined;
36
37
  chmod?: undefined;
37
38
  cleanup?: undefined;
38
- fallback?: undefined;
39
- generate?: undefined;
40
39
  resolveDest?: undefined;
41
40
  requireDir?: undefined;
42
41
  } | {
43
42
  id: string;
44
- src: string;
45
- dest: string;
46
43
  strategy: string;
44
+ generate: string;
45
+ dest: string;
47
46
  on: string;
48
47
  category: string;
49
48
  jsonKey?: undefined;
49
+ src?: undefined;
50
50
  chmod?: undefined;
51
51
  cleanup?: undefined;
52
- fallback?: undefined;
53
- generate?: undefined;
54
52
  resolveDest?: undefined;
55
53
  requireDir?: undefined;
56
54
  } | {
@@ -60,11 +58,10 @@ export declare const MANIFEST: ({
60
58
  strategy: string;
61
59
  on: string;
62
60
  category: string;
63
- chmod: boolean;
64
61
  jsonKey?: undefined;
65
- cleanup?: undefined;
66
- fallback?: undefined;
67
62
  generate?: undefined;
63
+ chmod?: undefined;
64
+ cleanup?: undefined;
68
65
  resolveDest?: undefined;
69
66
  requireDir?: undefined;
70
67
  } | {
@@ -75,10 +72,9 @@ export declare const MANIFEST: ({
75
72
  on: string;
76
73
  category: string;
77
74
  chmod: boolean;
78
- cleanup: string[];
79
75
  jsonKey?: undefined;
80
- fallback?: undefined;
81
76
  generate?: undefined;
77
+ cleanup?: undefined;
82
78
  resolveDest?: undefined;
83
79
  requireDir?: undefined;
84
80
  } | {
@@ -88,27 +84,12 @@ export declare const MANIFEST: ({
88
84
  strategy: string;
89
85
  on: string;
90
86
  category: string;
91
- fallback: string;
87
+ chmod: boolean;
88
+ cleanup: string[];
92
89
  jsonKey?: undefined;
93
- chmod?: undefined;
94
- cleanup?: undefined;
95
90
  generate?: undefined;
96
91
  resolveDest?: undefined;
97
92
  requireDir?: undefined;
98
- } | {
99
- id: string;
100
- strategy: string;
101
- generate: string;
102
- dest: string;
103
- on: string;
104
- category: string;
105
- jsonKey?: undefined;
106
- src?: undefined;
107
- chmod?: undefined;
108
- cleanup?: undefined;
109
- fallback?: undefined;
110
- resolveDest?: undefined;
111
- requireDir?: undefined;
112
93
  } | {
113
94
  id: string;
114
95
  src: string;
@@ -119,9 +100,8 @@ export declare const MANIFEST: ({
119
100
  chmod: boolean;
120
101
  resolveDest: string;
121
102
  jsonKey?: undefined;
122
- cleanup?: undefined;
123
- fallback?: undefined;
124
103
  generate?: undefined;
104
+ cleanup?: undefined;
125
105
  requireDir?: undefined;
126
106
  } | {
127
107
  id: string;
@@ -132,10 +112,9 @@ export declare const MANIFEST: ({
132
112
  category: string;
133
113
  requireDir: string;
134
114
  jsonKey?: undefined;
115
+ generate?: undefined;
135
116
  chmod?: undefined;
136
117
  cleanup?: undefined;
137
- fallback?: undefined;
138
- generate?: undefined;
139
118
  resolveDest?: undefined;
140
119
  } | {
141
120
  id: string;
@@ -144,11 +123,10 @@ export declare const MANIFEST: ({
144
123
  on: string;
145
124
  category: string;
146
125
  jsonKey?: undefined;
126
+ generate?: undefined;
147
127
  src?: undefined;
148
128
  chmod?: undefined;
149
129
  cleanup?: undefined;
150
- fallback?: undefined;
151
- generate?: undefined;
152
130
  resolveDest?: undefined;
153
131
  requireDir?: undefined;
154
132
  } | {
@@ -162,7 +140,6 @@ export declare const MANIFEST: ({
162
140
  src?: undefined;
163
141
  chmod?: undefined;
164
142
  cleanup?: undefined;
165
- fallback?: undefined;
166
143
  resolveDest?: undefined;
167
144
  requireDir?: undefined;
168
145
  })[];
@@ -170,6 +147,17 @@ export declare const MANIFEST: ({
170
147
  * .gitignore 规则清单 — Setup 和 Upgrade 共用
171
148
  * 每条规则:{ pattern, comment, negation? }
172
149
  */
150
+ /**
151
+ * Section markers for the AutoSnippet block inside .gitignore.
152
+ * merge-gitignore uses these to insert/replace the entire block atomically.
153
+ */
154
+ export declare const GITIGNORE_SECTION_BEGIN = "# >>> AutoSnippet (managed block \u2014 do not edit) >>>";
155
+ export declare const GITIGNORE_SECTION_END = "# <<< AutoSnippet <<<";
156
+ /**
157
+ * AutoSnippet-specific .gitignore rules.
158
+ * Only patterns that are AutoSnippet runtime/build artifacts belong here.
159
+ * Generic OS/editor patterns (.DS_Store, *.swp, nohup.out) are NOT our business.
160
+ */
173
161
  export declare const GITIGNORE_RULES: ({
174
162
  pattern: string;
175
163
  comment: string;
@@ -178,10 +166,6 @@ export declare const GITIGNORE_RULES: ({
178
166
  pattern: string;
179
167
  negation: boolean;
180
168
  comment?: undefined;
181
- } | {
182
- pattern: string;
183
- comment?: undefined;
184
- negation?: undefined;
185
169
  })[];
186
170
  /** .gitignore 迁移规则 — 升级时清理旧格式 */
187
171
  export declare const GITIGNORE_MIGRATIONS: {
@@ -47,9 +47,9 @@ export const MANIFEST = [
47
47
  // ═══ Cursor Rules(AutoSnippet 完全拥有) ═══════════
48
48
  {
49
49
  id: 'cursor-conventions',
50
- src: 'cursor-rules/autosnippet-conventions.mdc',
50
+ strategy: 'generate',
51
+ generate: 'generateConventionsMdc',
51
52
  dest: '.cursor/rules/autosnippet-conventions.mdc',
52
- strategy: 'overwrite',
53
53
  on: 'both',
54
54
  category: 'cursor-rules',
55
55
  },
@@ -61,14 +61,6 @@ export const MANIFEST = [
61
61
  on: 'both',
62
62
  category: 'cursor-rules',
63
63
  },
64
- {
65
- id: 'cursor-workflow',
66
- src: 'cursor-rules/autosnippet-workflow.mdc',
67
- dest: '.cursor/rules/autosnippet-workflow.mdc',
68
- strategy: 'overwrite',
69
- on: 'both',
70
- category: 'cursor-rules',
71
- },
72
64
  // ═══ Cursor Hooks ═════════════════════════════════════
73
65
  {
74
66
  id: 'cursor-hooks-json',
@@ -107,15 +99,14 @@ export const MANIFEST = [
107
99
  chmod: true,
108
100
  cleanup: ['.claude/hooks.yaml'], // 清理旧格式文件
109
101
  },
110
- // ═══ Agent Instructions(签名保护)════════════════════
102
+ // ═══ Agent Instructions(全部从模板生成)═══════════════
111
103
  {
112
104
  id: 'copilot-instructions',
113
- src: 'copilot-instructions.md',
105
+ strategy: 'generate',
106
+ generate: 'generateCopilotInstructions',
114
107
  dest: '.github/copilot-instructions.md',
115
- strategy: 'signature-safe',
116
108
  on: 'both',
117
109
  category: 'copilot-instructions',
118
- fallback: 'inject-marker', // 签名保护失败时,用标记注入
119
110
  },
120
111
  {
121
112
  id: 'agents-md',
@@ -210,29 +201,27 @@ export const MANIFEST = [
210
201
  * .gitignore 规则清单 — Setup 和 Upgrade 共用
211
202
  * 每条规则:{ pattern, comment, negation? }
212
203
  */
204
+ /**
205
+ * Section markers for the AutoSnippet block inside .gitignore.
206
+ * merge-gitignore uses these to insert/replace the entire block atomically.
207
+ */
208
+ export const GITIGNORE_SECTION_BEGIN = '# >>> AutoSnippet (managed block — do not edit) >>>';
209
+ export const GITIGNORE_SECTION_END = '# <<< AutoSnippet <<<';
210
+ /**
211
+ * AutoSnippet-specific .gitignore rules.
212
+ * Only patterns that are AutoSnippet runtime/build artifacts belong here.
213
+ * Generic OS/editor patterns (.DS_Store, *.swp, nohup.out) are NOT our business.
214
+ */
213
215
  export const GITIGNORE_RULES = [
214
- // 核心运行时
215
- { pattern: '.autosnippet/*', comment: 'AutoSnippet 运行时缓存(不入库)' },
216
+ // Runtime cache
217
+ { pattern: '.autosnippet/*', comment: '运行时缓存(不入库)' },
216
218
  { pattern: '!.autosnippet/config.json', negation: true },
217
- // 环境变量
218
- { pattern: '.env', comment: 'AutoSnippet 环境变量(含 API Key,不入库)' },
219
- // 日志
220
- { pattern: 'logs/', comment: 'AutoSnippet 运行日志' },
221
- // AI 草稿
222
- { pattern: '.autosnippet-drafts/', comment: 'AutoSnippet AI 草稿(临时)' },
223
- { pattern: '_draft_*.md', comment: 'AutoSnippet AI 草稿文件(项目根目录临时文件)' },
224
- // 系统 / 编辑器临时文件
225
- { pattern: '.DS_Store', comment: 'macOS 元数据' },
226
- { pattern: 'nohup.out' },
227
- { pattern: '*.sw[a-p]' },
219
+ // Environment (contains API keys created by `asd setup`)
220
+ { pattern: '.env', comment: '环境变量(含 API Key' },
221
+ // Logs(已收纳到 .autosnippet/ 下,由 .autosnippet/* 统一覆盖)
228
222
  ];
229
223
  /** .gitignore 迁移规则 — 升级时清理旧格式 */
230
- export const GITIGNORE_MIGRATIONS = [
231
- // v2.4.0: ".autosnippet/" → ".autosnippet/*"
232
- { find: /^\.autosnippet\/$/m, replace: '.autosnippet/*' },
233
- // Skills 已迁移到 AutoSnippet/skills/,清理旧 negation
234
- { find: /^!?\.autosnippet\/skills\/.*\n?/gm, replace: '' },
235
- ];
224
+ export const GITIGNORE_MIGRATIONS = [];
236
225
  /** MCP Server 配置生成器 */
237
226
  export function buildMcpServerEntry(projectRoot, ide) {
238
227
  const base = {
@@ -197,7 +197,7 @@ export declare function registerLanguage(langId: string, plugin: LangPlugin): vo
197
197
  declare function analyzeFile(source: string, lang: string, options?: AnalyzeFileOptions): AstFileSummary | null;
198
198
  /**
199
199
  * 批量分析多文件,返回项目级汇总
200
- * @param {{ name: string, relativePath: string, content: string }[]} files
200
+ * @param files
201
201
  * @param | null }} [options]
202
202
  */
203
203
  declare function analyzeProject(files: FileInput[], lang: string, options: AnalyzeProjectOptions): ProjectAnalysisResult;
@@ -234,7 +234,7 @@ declare function findCallExpressions(source: string, lang: string, targetCallee:
234
234
  * @param source 源代码
235
235
  * @param lang 'objectivec' | 'swift'
236
236
  * @param pattern 要查找的文本模式(普通字符串匹配)
237
- * @param {{ forbiddenContext?: string, requiredContext?: string }} contextFilter
237
+ * @param contextFilter
238
238
  * forbiddenContext: 如果在此上下文中出现则报告 (如 'dealloc')
239
239
  * requiredContext: 如果不在此上下文中出现则报告
240
240
  * @returns >}