autosnippet 3.2.17 → 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 (184) 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 +88 -49
  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/HttpServer.js +15 -2
  80. package/dist/lib/http/utils/routeHelpers.d.ts +1 -1
  81. package/dist/lib/http/utils/routeHelpers.js +1 -1
  82. package/dist/lib/http/utils/sse-sessions.d.ts +1 -1
  83. package/dist/lib/http/utils/sse-sessions.js +1 -1
  84. package/dist/lib/infrastructure/cache/CacheService.js +1 -1
  85. package/dist/lib/infrastructure/vector/AsyncPersistence.js +8 -8
  86. package/dist/lib/infrastructure/vector/BatchEmbedder.d.ts +1 -1
  87. package/dist/lib/infrastructure/vector/BatchEmbedder.js +2 -2
  88. package/dist/lib/infrastructure/vector/HnswIndex.d.ts +4 -4
  89. package/dist/lib/infrastructure/vector/HnswIndex.js +5 -5
  90. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +8 -8
  91. package/dist/lib/infrastructure/vector/ScalarQuantizer.d.ts +1 -1
  92. package/dist/lib/infrastructure/vector/ScalarQuantizer.js +4 -4
  93. package/dist/lib/infrastructure/vector/VectorStore.d.ts +1 -1
  94. package/dist/lib/infrastructure/vector/VectorStore.js +1 -1
  95. package/dist/lib/injection/ServiceContainer.d.ts +1 -1
  96. package/dist/lib/injection/ServiceContainer.js +1 -1
  97. package/dist/lib/platform/NativeUi.d.ts +1 -1
  98. package/dist/lib/platform/NativeUi.js +1 -1
  99. package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +1 -1
  100. package/dist/lib/platform/ios/spm/DependencyGraph.js +1 -1
  101. package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +1 -1
  102. package/dist/lib/platform/ios/spm/PolicyEngine.js +1 -1
  103. package/dist/lib/platform/ios/spm/SpmDiscoverer.js +1 -1
  104. package/dist/lib/platform/ios/spm/SpmHelper.js +3 -3
  105. package/dist/lib/platform/ios/xcode/SaveEventFilter.js +2 -2
  106. package/dist/lib/platform/ios/xcode/XcodeIntegration.js +1 -1
  107. package/dist/lib/repository/base/BaseRepository.js +1 -1
  108. package/dist/lib/repository/task/TaskRepository.impl.d.ts +2 -2
  109. package/dist/lib/repository/task/TaskRepository.impl.js +1 -1
  110. package/dist/lib/repository/token/TokenUsageStore.js +1 -1
  111. package/dist/lib/service/automation/ActionPipeline.d.ts +1 -1
  112. package/dist/lib/service/automation/ActionPipeline.js +1 -1
  113. package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +2 -2
  114. package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +1 -1
  115. package/dist/lib/service/bootstrap/BootstrapTaskManager.js +2 -2
  116. package/dist/lib/service/bootstrap/DimensionCopyRegistry.d.ts +2 -2
  117. package/dist/lib/service/bootstrap/DimensionCopyRegistry.js +2 -2
  118. package/dist/lib/service/delivery/AgentInstructionsGenerator.d.ts +6 -15
  119. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +53 -189
  120. package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +6 -16
  121. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +14 -19
  122. package/dist/lib/service/delivery/KnowledgeCompressor.d.ts +1 -1
  123. package/dist/lib/service/delivery/KnowledgeCompressor.js +1 -1
  124. package/dist/lib/service/delivery/RulesGenerator.d.ts +10 -3
  125. package/dist/lib/service/delivery/RulesGenerator.js +43 -3
  126. package/dist/lib/service/delivery/SkillsSyncer.d.ts +21 -7
  127. package/dist/lib/service/delivery/SkillsSyncer.js +46 -10
  128. package/dist/lib/service/delivery/TopicClassifier.d.ts +3 -6
  129. package/dist/lib/service/delivery/TopicClassifier.js +0 -3
  130. package/dist/lib/service/guard/ExclusionManager.d.ts +1 -1
  131. package/dist/lib/service/guard/ExclusionManager.js +1 -1
  132. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -3
  133. package/dist/lib/service/guard/GuardCheckEngine.js +5 -5
  134. package/dist/lib/service/guard/GuardCrossFileChecks.d.ts +1 -1
  135. package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -3
  136. package/dist/lib/service/guard/GuardFeedbackLoop.js +3 -3
  137. package/dist/lib/service/guard/GuardPatternUtils.js +1 -1
  138. package/dist/lib/service/guard/GuardService.d.ts +1 -15
  139. package/dist/lib/service/guard/GuardService.js +0 -1
  140. package/dist/lib/service/guard/RuleLearner.d.ts +1 -1
  141. package/dist/lib/service/guard/RuleLearner.js +1 -1
  142. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +3 -3
  143. package/dist/lib/service/knowledge/CodeEntityGraph.js +3 -3
  144. package/dist/lib/service/knowledge/KnowledgeService.d.ts +0 -1
  145. package/dist/lib/service/knowledge/KnowledgeService.js +0 -1
  146. package/dist/lib/service/module/ModuleService.d.ts +1 -1
  147. package/dist/lib/service/module/ModuleService.js +2 -2
  148. package/dist/lib/service/search/HybridRetriever.d.ts +2 -2
  149. package/dist/lib/service/search/HybridRetriever.js +2 -2
  150. package/dist/lib/service/search/SearchEngine.d.ts +1 -3
  151. package/dist/lib/service/search/SearchEngine.js +1 -3
  152. package/dist/lib/service/search/contextBoost.d.ts +1 -1
  153. package/dist/lib/service/skills/EventAggregator.js +2 -2
  154. package/dist/lib/service/skills/SignalCollector.js +1 -1
  155. package/dist/lib/service/snippet/codecs/VSCodeCodec.js +1 -1
  156. package/dist/lib/service/task/TaskGraphService.d.ts +0 -3
  157. package/dist/lib/service/task/TaskGraphService.js +0 -3
  158. package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +8 -27
  159. package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -8
  160. package/dist/lib/service/task/TaskReadyEngine.d.ts +1 -2
  161. package/dist/lib/service/task/TaskReadyEngine.js +0 -1
  162. package/dist/lib/service/wiki/WikiRenderers.js +0 -1
  163. package/dist/lib/service/wiki/WikiUtils.js +2 -7
  164. package/dist/lib/shared/PathGuard.js +6 -6
  165. package/dist/lib/shared/schemas/mcp-tools.js +84 -43
  166. package/dist/scripts/install-vscode-copilot.js +14 -4
  167. package/package.json +1 -1
  168. package/skills/autosnippet-create/SKILL.md +131 -131
  169. package/skills/autosnippet-devdocs/SKILL.md +1 -2
  170. package/skills/autosnippet-guard/SKILL.md +20 -89
  171. package/skills/autosnippet-recipes/SKILL.md +35 -117
  172. package/skills/autosnippet-structure/SKILL.md +23 -55
  173. package/templates/cursor-rules/autosnippet-skills.mdc +17 -33
  174. package/templates/instructions/agent-static.md +24 -0
  175. package/templates/instructions/conventions.md +42 -0
  176. package/skills/autosnippet-analysis/SKILL.md +0 -169
  177. package/skills/autosnippet-candidates/SKILL.md +0 -367
  178. package/skills/autosnippet-coldstart/SKILL.md +0 -988
  179. package/skills/autosnippet-concepts/SKILL.md +0 -630
  180. package/skills/autosnippet-intent/SKILL.md +0 -55
  181. package/skills/autosnippet-lifecycle/SKILL.md +0 -100
  182. package/templates/copilot-instructions.md +0 -66
  183. package/templates/cursor-rules/autosnippet-conventions.mdc +0 -172
  184. package/templates/cursor-rules/autosnippet-workflow.mdc +0 -76
@@ -67,7 +67,7 @@ export declare class SetupService {
67
67
  /** 子仓库远程仓库 URL(为空则 recipes/ 作为普通目录随主仓库提交) */
68
68
  subRepoUrl: string | undefined;
69
69
  /**
70
- * @param {{ projectRoot: string, force?: boolean, seed?: boolean, subRepoDir?: string, subRepoUrl?: string }} options
70
+ * @param options
71
71
  */
72
72
  constructor(options: {
73
73
  projectRoot: string;
@@ -106,8 +106,8 @@ export declare class SetupService {
106
106
  ok: boolean;
107
107
  error?: string;
108
108
  }[]>;
109
- /** @private 格式化步骤结果的简要信息 */
110
- _formatStepDetail(r: Record<string, unknown> | undefined): string;
109
+ /** 格式化步骤结果的简要信息 */
110
+ private _formatStepDetail;
111
111
  printSummary(): void;
112
112
  stepRuntime(): {
113
113
  created: string;
@@ -118,16 +118,16 @@ export declare class SetupService {
118
118
  subRepoPath: string;
119
119
  hasUrl: boolean;
120
120
  };
121
- /** @private 写入 constitution.yaml(优先从模板复制) */
122
- _writeConstitution(): void;
123
- /** @private 写入 boxspec.json */
124
- _writeBoxspec(): void;
125
- /** @private 复制 _template.md 到 recipes/ */
126
- _copyRecipeTemplate(): void;
127
- /** @private 复制示例 Recipe(冷启动推荐) */
128
- _copySeedRecipes(): void;
129
- /** @private 写入核心目录 README */
130
- _writeCoreReadme(): void;
121
+ /** 写入 constitution.yaml(优先从模板复制) */
122
+ private _writeConstitution;
123
+ /** 写入 boxspec.json */
124
+ private _writeBoxspec;
125
+ /** 复制 _template.md 到 recipes/ */
126
+ private _copyRecipeTemplate;
127
+ /** 复制示例 Recipe(冷启动推荐) */
128
+ private _copySeedRecipes;
129
+ /** 写入核心目录 README */
130
+ private _writeCoreReadme;
131
131
  stepIDE(): {
132
132
  configured: string[];
133
133
  };
@@ -135,27 +135,27 @@ export declare class SetupService {
135
135
  dbPath: string;
136
136
  }>;
137
137
  /**
138
- * @private 从 AutoSnippet/recipes/*.md + candidates/*.md 同步到 DB 缓存
138
+ * 从 AutoSnippet/recipes/*.md + candidates/*.md 同步到 DB 缓存
139
139
  * 委托 KnowledgeSyncService 执行全字段同步(setup 场景跳过违规记录)
140
140
  */
141
- _syncRecipesToDB(db: unknown): Promise<void>;
141
+ private _syncRecipesToDB;
142
142
  stepPlatform(): Promise<any>;
143
143
  /**
144
- * @private 在项目根目录创建 .env 文件(从 .env.example 复制)
144
+ * 在项目根目录创建 .env 文件(从 .env.example 复制)
145
145
  * 如果 .env 已存在则跳过并提示用户手动配置。
146
146
  */
147
- _ensureEnvFile(): void;
148
- /** @private 在指定目录执行 git 命令 */
149
- _git(args: string[], cwd: string): string;
150
- /** @private 检查目录中是否有文件(排除 . 和 ..) */
151
- _hasFiles(dirPath: string): boolean;
152
- /** @private 确保子仓库的 remote origin 与给定 URL 一致 */
153
- _ensureRemote(url: string): void;
147
+ private _ensureEnvFile;
148
+ /** 在指定目录执行 git 命令 */
149
+ private _git;
150
+ /** 检查目录中是否有文件(排除 . 和 ..) */
151
+ private _hasFiles;
152
+ /** 确保子仓库的 remote origin 与给定 URL 一致 */
153
+ private _ensureRemote;
154
154
  /**
155
- * @private 备份已有文件 → clone → 合并回来(不覆盖远端文件)
155
+ * 备份已有文件 → clone → 合并回来(不覆盖远端文件)
156
156
  * 适用于 recipes/ 有模板文件但还不是 git 仓库的场景
157
157
  */
158
- _cloneWithMerge(url: string): void;
158
+ private _cloneWithMerge;
159
159
  /**
160
160
  * 尝试初始化向量索引: 检查 embedding provider 可用性,
161
161
  * 若可用则自动构建初始索引;否则提示用户手动运行 asd embed。
@@ -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: {