autosnippet 3.3.4 → 3.3.6

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 (221) hide show
  1. package/README.md +174 -83
  2. package/config/constitution.yaml +2 -0
  3. package/dashboard/dist/assets/icons-D1aVZYFW.js +1 -0
  4. package/dashboard/dist/assets/index-CxHOu8Hd.css +1 -0
  5. package/dashboard/dist/assets/index-DDdAOpYT.js +128 -0
  6. package/dashboard/dist/index.html +3 -3
  7. package/dist/bin/api-server.js +1 -0
  8. package/dist/bin/cli.d.ts +1 -0
  9. package/dist/bin/cli.js +136 -9
  10. package/dist/lib/agent/AgentFactory.d.ts +0 -17
  11. package/dist/lib/agent/AgentFactory.js +1 -25
  12. package/dist/lib/agent/capabilities.d.ts +11 -0
  13. package/dist/lib/agent/capabilities.js +29 -5
  14. package/dist/lib/agent/context/ExplorationTracker.js +10 -1
  15. package/dist/lib/agent/context/exploration/ExplorationStrategies.d.ts +2 -0
  16. package/dist/lib/agent/context/exploration/ExplorationStrategies.js +2 -2
  17. package/dist/lib/agent/domain/insight-analyst.d.ts +47 -3
  18. package/dist/lib/agent/domain/insight-analyst.js +111 -11
  19. package/dist/lib/agent/domain/insight-evolver.d.ts +69 -0
  20. package/dist/lib/agent/domain/insight-evolver.js +230 -0
  21. package/dist/lib/agent/domain/insight-gate.d.ts +42 -0
  22. package/dist/lib/agent/domain/insight-gate.js +41 -0
  23. package/dist/lib/agent/domain/insight-producer.d.ts +27 -2
  24. package/dist/lib/agent/domain/insight-producer.js +60 -5
  25. package/dist/lib/agent/domain/scan-prompts.js +10 -7
  26. package/dist/lib/agent/memory/ActiveContext.d.ts +2 -28
  27. package/dist/lib/agent/memory/MemoryCoordinator.d.ts +2 -2
  28. package/dist/lib/agent/memory/SessionStore.d.ts +6 -12
  29. package/dist/lib/agent/memory/SessionStore.js +9 -15
  30. package/dist/lib/agent/memory/memory-flush-contract.d.ts +49 -0
  31. package/dist/lib/agent/memory/memory-flush-contract.js +16 -0
  32. package/dist/lib/agent/memory/session-store-schema.d.ts +20 -0
  33. package/dist/lib/agent/memory/session-store-schema.js +41 -0
  34. package/dist/lib/agent/presets.d.ts +89 -1
  35. package/dist/lib/agent/presets.js +53 -5
  36. package/dist/lib/agent/tools/_shared.d.ts +7 -15
  37. package/dist/lib/agent/tools/_shared.js +20 -21
  38. package/dist/lib/agent/tools/composite.d.ts +25 -22
  39. package/dist/lib/agent/tools/composite.js +108 -109
  40. package/dist/lib/agent/tools/evolution-tools.d.ts +145 -0
  41. package/dist/lib/agent/tools/evolution-tools.js +161 -0
  42. package/dist/lib/agent/tools/index.d.ts +163 -92
  43. package/dist/lib/agent/tools/index.js +9 -1
  44. package/dist/lib/agent/tools/lifecycle.d.ts +7 -1
  45. package/dist/lib/agent/tools/lifecycle.js +59 -75
  46. package/dist/lib/cli/AiScanService.js +1 -1
  47. package/dist/lib/cli/KnowledgeSyncService.d.ts +5 -1
  48. package/dist/lib/cli/KnowledgeSyncService.js +6 -3
  49. package/dist/lib/core/AstAnalyzer.d.ts +1 -0
  50. package/dist/lib/{service/bootstrap/DimensionCopyRegistry.d.ts → domain/dimension/DimensionCopy.d.ts} +2 -2
  51. package/dist/lib/{service/bootstrap/DimensionCopyRegistry.js → domain/dimension/DimensionCopy.js} +22 -72
  52. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +54 -0
  53. package/dist/lib/domain/dimension/DimensionRegistry.js +620 -0
  54. package/dist/lib/domain/dimension/DimensionSop.d.ts +55 -0
  55. package/dist/lib/domain/dimension/DimensionSop.js +1604 -0
  56. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +61 -0
  57. package/dist/lib/domain/dimension/UnifiedDimension.js +53 -0
  58. package/dist/lib/domain/dimension/index.d.ts +10 -0
  59. package/dist/lib/domain/dimension/index.js +9 -0
  60. package/dist/lib/domain/knowledge/FieldSpec.d.ts +1 -1
  61. package/dist/lib/domain/knowledge/FieldSpec.js +29 -16
  62. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +33 -111
  63. package/dist/lib/domain/knowledge/KnowledgeEntry.js +27 -6
  64. package/dist/lib/domain/knowledge/KnowledgeRepository.d.ts +1 -0
  65. package/dist/lib/domain/knowledge/KnowledgeRepository.js +3 -0
  66. package/dist/lib/domain/knowledge/Lifecycle.js +1 -1
  67. package/dist/lib/domain/knowledge/StyleGuide.d.ts +1 -1
  68. package/dist/lib/domain/knowledge/StyleGuide.js +1 -1
  69. package/dist/lib/domain/knowledge/UnifiedValidator.js +15 -0
  70. package/dist/lib/domain/knowledge/values/Stats.d.ts +1 -1
  71. package/dist/lib/domain/knowledge/values/Stats.js +2 -2
  72. package/dist/lib/external/mcp/McpServer.js +4 -0
  73. package/dist/lib/external/mcp/handlers/TargetClassifier.d.ts +1 -1
  74. package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.d.ts +8 -16
  75. package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.js +10 -10
  76. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.d.ts +7 -0
  77. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +20 -0
  78. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +52 -132
  79. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +204 -17
  80. package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.d.ts +11 -75
  81. package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.js +40 -191
  82. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.d.ts +13 -78
  83. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.js +30 -52
  84. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.d.ts +0 -1
  85. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.d.ts +99 -12
  86. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +172 -161
  87. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +7 -17
  88. package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.d.ts +46 -0
  89. package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.js +58 -0
  90. package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.d.ts +25 -0
  91. package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.js +47 -0
  92. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +50 -12
  93. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +30 -10
  94. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-text.js +1 -1
  95. package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.d.ts +24 -0
  96. package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.js +14 -0
  97. package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.d.ts +14 -0
  98. package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.js +48 -0
  99. package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.d.ts +21 -0
  100. package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.js +45 -0
  101. package/dist/lib/external/mcp/handlers/bootstrap/shared/skill-generator.d.ts +1 -1
  102. package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.d.ts +27 -0
  103. package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.js +44 -0
  104. package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +14 -10
  105. package/dist/lib/external/mcp/handlers/bootstrap-external.js +39 -51
  106. package/dist/lib/external/mcp/handlers/bootstrap-internal.d.ts +2 -0
  107. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +115 -82
  108. package/dist/lib/external/mcp/handlers/consolidated.d.ts +4 -4
  109. package/dist/lib/external/mcp/handlers/consolidated.js +115 -162
  110. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +69 -1
  111. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +54 -0
  112. package/dist/lib/external/mcp/handlers/evolve-external.js +226 -0
  113. package/dist/lib/external/mcp/handlers/knowledge.js +26 -2
  114. package/dist/lib/external/mcp/handlers/rescan-external.d.ts +76 -0
  115. package/dist/lib/external/mcp/handlers/rescan-external.js +335 -0
  116. package/dist/lib/external/mcp/handlers/rescan-internal.d.ts +120 -0
  117. package/dist/lib/external/mcp/handlers/rescan-internal.js +359 -0
  118. package/dist/lib/external/mcp/handlers/search.d.ts +6 -5
  119. package/dist/lib/external/mcp/handlers/search.js +6 -5
  120. package/dist/lib/external/mcp/handlers/types.d.ts +2 -1
  121. package/dist/lib/external/mcp/handlers/wiki-external.js +2 -2
  122. package/dist/lib/external/mcp/tools.d.ts +8 -18
  123. package/dist/lib/external/mcp/tools.js +60 -3
  124. package/dist/lib/http/routes/knowledge.js +122 -1
  125. package/dist/lib/http/routes/modules.js +25 -3
  126. package/dist/lib/http/routes/panorama.js +16 -4
  127. package/dist/lib/infrastructure/cache/CacheCoordinator.d.ts +41 -0
  128. package/dist/lib/infrastructure/cache/CacheCoordinator.js +105 -0
  129. package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.d.ts +7 -0
  130. package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.js +28 -0
  131. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +1 -1
  132. package/dist/lib/injection/ServiceContainer.js +55 -0
  133. package/dist/lib/injection/ServiceMap.d.ts +8 -1
  134. package/dist/lib/injection/modules/InfraModule.js +4 -1
  135. package/dist/lib/injection/modules/KnowledgeModule.js +38 -1
  136. package/dist/lib/repository/evolution/ProposalRepository.d.ts +99 -0
  137. package/dist/lib/repository/evolution/ProposalRepository.js +255 -0
  138. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +4 -0
  139. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +16 -1
  140. package/dist/lib/service/bootstrap/BootstrapEventEmitter.d.ts +3 -2
  141. package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +1 -1
  142. package/dist/lib/service/bootstrap/DeliveryVerifier.d.ts +51 -0
  143. package/dist/lib/service/bootstrap/DeliveryVerifier.js +163 -0
  144. package/dist/lib/service/bootstrap/UiStartupTasks.d.ts +22 -4
  145. package/dist/lib/service/bootstrap/UiStartupTasks.js +73 -5
  146. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +54 -0
  147. package/dist/lib/service/bootstrap/bootstrap-event-types.js +10 -0
  148. package/dist/lib/service/cleanup/CleanupService.d.ts +85 -0
  149. package/dist/lib/service/cleanup/CleanupService.js +324 -0
  150. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +39 -43
  151. package/dist/lib/service/delivery/FileProtection.d.ts +20 -0
  152. package/dist/lib/service/delivery/FileProtection.js +54 -0
  153. package/dist/lib/service/delivery/SkillsSyncer.js +16 -21
  154. package/dist/lib/service/evolution/ContentPatcher.d.ts +44 -0
  155. package/dist/lib/service/evolution/ContentPatcher.js +310 -0
  156. package/dist/lib/service/evolution/DecayDetector.d.ts +4 -3
  157. package/dist/lib/service/evolution/DecayDetector.js +97 -22
  158. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -2
  159. package/dist/lib/service/evolution/KnowledgeMetabolism.js +29 -2
  160. package/dist/lib/service/evolution/ProposalExecutor.d.ts +66 -0
  161. package/dist/lib/service/evolution/ProposalExecutor.js +424 -0
  162. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +64 -0
  163. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +458 -0
  164. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +89 -0
  165. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +492 -0
  166. package/dist/lib/service/evolution/StagingManager.js +5 -3
  167. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +44 -0
  168. package/dist/lib/service/evolution/createSupersedeProposal.js +81 -0
  169. package/dist/lib/service/guard/ComplianceReporter.d.ts +4 -0
  170. package/dist/lib/service/guard/ComplianceReporter.js +51 -0
  171. package/dist/lib/service/guard/GuardCheckEngine.js +5 -4
  172. package/dist/lib/service/guard/GuardCrossFileChecks.js +2 -0
  173. package/dist/lib/service/guard/ReverseGuard.d.ts +1 -1
  174. package/dist/lib/service/guard/ReverseGuard.js +32 -2
  175. package/dist/lib/service/knowledge/ConfidenceRouter.js +1 -1
  176. package/dist/lib/service/knowledge/KnowledgeService.d.ts +11 -1
  177. package/dist/lib/service/knowledge/KnowledgeService.js +44 -4
  178. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +225 -0
  179. package/dist/lib/service/knowledge/RecipeProductionGateway.js +384 -0
  180. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +2 -0
  181. package/dist/lib/service/knowledge/SourceRefReconciler.js +48 -0
  182. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +3 -2
  183. package/dist/lib/service/panorama/DimensionAnalyzer.js +15 -140
  184. package/dist/lib/service/search/BM25Scorer.d.ts +2 -2
  185. package/dist/lib/service/search/SearchEngine.d.ts +11 -10
  186. package/dist/lib/service/search/SearchEngine.js +38 -36
  187. package/dist/lib/service/search/SearchTypes.d.ts +14 -8
  188. package/dist/lib/service/search/SearchTypes.js +1 -1
  189. package/dist/lib/service/search/tokenizer.d.ts +1 -1
  190. package/dist/lib/service/search/tokenizer.js +2 -2
  191. package/dist/lib/shared/schemas/common.d.ts +4 -4
  192. package/dist/lib/shared/schemas/http-requests.d.ts +12 -1
  193. package/dist/lib/shared/schemas/http-requests.js +8 -0
  194. package/dist/lib/shared/schemas/mcp-tools.d.ts +33 -2
  195. package/dist/lib/shared/schemas/mcp-tools.js +42 -0
  196. package/dist/lib/types/evolution.d.ts +135 -0
  197. package/dist/lib/types/evolution.js +6 -0
  198. package/dist/lib/types/graph-shared.d.ts +25 -0
  199. package/dist/lib/types/graph-shared.js +7 -0
  200. package/dist/lib/types/knowledge-wire.d.ts +131 -0
  201. package/dist/lib/types/knowledge-wire.js +7 -0
  202. package/dist/lib/types/project-snapshot-builder.d.ts +19 -0
  203. package/dist/lib/types/project-snapshot-builder.js +189 -0
  204. package/dist/lib/types/project-snapshot.d.ts +399 -0
  205. package/dist/lib/types/project-snapshot.js +17 -0
  206. package/dist/lib/types/search-wire.d.ts +46 -0
  207. package/dist/lib/types/search-wire.js +7 -0
  208. package/dist/lib/types/snapshot-views.d.ts +58 -0
  209. package/dist/lib/types/snapshot-views.js +103 -0
  210. package/package.json +1 -1
  211. package/skills/autosnippet-recipes/SKILL.md +1 -1
  212. package/templates/instructions/agent-static.md +2 -0
  213. package/templates/instructions/conventions.md +3 -1
  214. package/templates/recipes-setup/README.md +2 -2
  215. package/dashboard/dist/assets/icons-BJ2mUBi8.js +0 -1
  216. package/dashboard/dist/assets/index-B659K9t5.js +0 -128
  217. package/dashboard/dist/assets/index-NCm40PMD.css +0 -1
  218. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.d.ts +0 -169
  219. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.js +0 -727
  220. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.d.ts +0 -370
  221. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +0 -821
@@ -1,727 +0,0 @@
1
- /**
2
- * noAiFallback.js — AI 不可用时的规则化降级知识提取
3
- *
4
- * 当 AgentRuntime / AI Provider 不可用时,从 Phase 1-4 的结构化数据中
5
- * 提取基础知识候选和 Project Skill,覆盖以下维度:
6
- *
7
- * ✅ project-profile — 从 langStats + depGraph + targets 构建项目技术画像
8
- * ✅ architecture — 从 depGraph + targets 推断层级/模块关系
9
- * ✅ code-standard — 从 AST 统计推断命名约定和代码风格
10
- * ✅ best-practice — 从 Guard 违规推断反模式
11
- * ✅ agent-guidelines — 从 Guard 高频违规 + 语言特性生成 Agent 注意事项
12
- *
13
- * 产出质量标注为 `source: 'rule-based-fallback'`,区别于 AI 分析产出。
14
- */
15
- import Logger from '#infra/logging/Logger.js';
16
- const logger = Logger.getInstance();
17
- /**
18
- * 主入口 — 当 AI 不可用时调用
19
- *
20
- * @param fillContext 与 fillDimensionsV3 相同的上下文
21
- * @returns >}
22
- */
23
- export async function runNoAiFallback(fillContext) {
24
- const {
25
- // ctx and projectRoot are part of fillContext API but unused in fallback path
26
- dimensions, depGraphData, guardAudit, langStats, primaryLang, astProjectSummary, taskManager, sessionId, } = fillContext;
27
- const t0 = Date.now();
28
- logger.info('[Bootstrap-fallback] Starting rule-based fallback (no AI)');
29
- const candidates = [];
30
- const skills = [];
31
- const report = {
32
- dimensionsProcessed: 0,
33
- candidatesCreated: 0,
34
- skillsCreated: 0,
35
- errors: [],
36
- };
37
- // ── 收集原始数据 ──
38
- const allFiles = fillContext.allFiles || [];
39
- const targetFileMap = fillContext.targetFileMap || {};
40
- const allTargets = Object.keys(targetFileMap);
41
- // ── 1. Project Profile ──
42
- try {
43
- const profile = _buildProjectProfile({
44
- langStats,
45
- primaryLang,
46
- depGraphData,
47
- allTargets,
48
- allFiles,
49
- astProjectSummary,
50
- });
51
- if (profile) {
52
- candidates.push(profile);
53
- skills.push(_wrapAsSkill('project-profile', '项目技术画像', profile.content.markdown));
54
- report.candidatesCreated++;
55
- report.skillsCreated++;
56
- }
57
- _markDimDone(taskManager, sessionId, 'project-profile', 'fallback');
58
- }
59
- catch (e) {
60
- report.errors.push({
61
- dim: 'project-profile',
62
- error: e instanceof Error ? e.message : String(e),
63
- });
64
- _markDimDone(taskManager, sessionId, 'project-profile', 'error');
65
- }
66
- // ── 2. Architecture ──
67
- try {
68
- const arch = _buildArchitecture({
69
- depGraphData,
70
- allTargets,
71
- targetFileMap,
72
- primaryLang,
73
- astProjectSummary,
74
- });
75
- if (arch) {
76
- candidates.push(arch);
77
- skills.push(_wrapAsSkill('architecture', '模块架构', arch.content.markdown));
78
- report.candidatesCreated++;
79
- report.skillsCreated++;
80
- }
81
- _markDimDone(taskManager, sessionId, 'architecture', 'fallback');
82
- }
83
- catch (e) {
84
- report.errors.push({ dim: 'architecture', error: e instanceof Error ? e.message : String(e) });
85
- _markDimDone(taskManager, sessionId, 'architecture', 'error');
86
- }
87
- // ── 3. Code Standard ──
88
- try {
89
- const standard = _buildCodeStandard({ astProjectSummary, primaryLang, allFiles });
90
- if (standard) {
91
- candidates.push(standard);
92
- skills.push(_wrapAsSkill('code-standard', '代码规范', standard.content.markdown));
93
- report.candidatesCreated++;
94
- report.skillsCreated++;
95
- }
96
- _markDimDone(taskManager, sessionId, 'code-standard', 'fallback');
97
- }
98
- catch (e) {
99
- report.errors.push({ dim: 'code-standard', error: e instanceof Error ? e.message : String(e) });
100
- _markDimDone(taskManager, sessionId, 'code-standard', 'error');
101
- }
102
- // ── 4. Best Practice (from Guard violations) ──
103
- try {
104
- const bp = _buildBestPractice({ guardAudit, primaryLang });
105
- if (bp) {
106
- candidates.push(bp);
107
- skills.push(_wrapAsSkill('best-practice', '最佳实践', bp.content.markdown));
108
- report.candidatesCreated++;
109
- report.skillsCreated++;
110
- }
111
- _markDimDone(taskManager, sessionId, 'best-practice', 'fallback');
112
- }
113
- catch (e) {
114
- report.errors.push({ dim: 'best-practice', error: e instanceof Error ? e.message : String(e) });
115
- _markDimDone(taskManager, sessionId, 'best-practice', 'error');
116
- }
117
- // ── 5. Agent Guidelines ──
118
- try {
119
- const guidelines = _buildAgentGuidelines({ guardAudit, primaryLang, astProjectSummary });
120
- if (guidelines) {
121
- candidates.push(guidelines);
122
- skills.push(_wrapAsSkill('agent-guidelines', '项目开发强制规范', guidelines.content.markdown));
123
- report.candidatesCreated++;
124
- report.skillsCreated++;
125
- }
126
- _markDimDone(taskManager, sessionId, 'agent-guidelines', 'fallback');
127
- }
128
- catch (e) {
129
- report.errors.push({
130
- dim: 'agent-guidelines',
131
- error: e instanceof Error ? e.message : String(e),
132
- });
133
- _markDimDone(taskManager, sessionId, 'agent-guidelines', 'error');
134
- }
135
- // ── 标记剩余未处理维度 ──
136
- const processedDims = new Set([
137
- 'project-profile',
138
- 'architecture',
139
- 'code-standard',
140
- 'best-practice',
141
- 'agent-guidelines',
142
- ]);
143
- for (const dim of dimensions) {
144
- if (!processedDims.has(dim.id)) {
145
- _markDimDone(taskManager, sessionId, dim.id, 'skipped-no-ai');
146
- }
147
- }
148
- report.dimensionsProcessed = processedDims.size;
149
- const elapsed = Date.now() - t0;
150
- logger.info(`[Bootstrap-fallback] Complete: ${report.candidatesCreated} candidates, ${report.skillsCreated} skills in ${elapsed}ms`);
151
- return { candidates, skills, report };
152
- }
153
- // ═══════════════════════════════════════════════════════════
154
- // 维度构建器
155
- // ═══════════════════════════════════════════════════════════
156
- function _buildProjectProfile({ langStats, primaryLang, depGraphData, allTargets, allFiles, astProjectSummary, }) {
157
- const lines = ['## 项目技术画像', ''];
158
- // 语言统计
159
- const sortedLangs = Object.entries(langStats || {})
160
- .sort(([, a], [, b]) => b - a)
161
- .slice(0, 8);
162
- if (sortedLangs.length > 0) {
163
- lines.push('### 语言分布', '');
164
- lines.push('| 语言 | 文件数 | 占比 |');
165
- lines.push('|------|--------|------|');
166
- const total = sortedLangs.reduce((s, [, c]) => s + c, 0);
167
- for (const [lang, count] of sortedLangs) {
168
- lines.push(`| ${lang} | ${count} | ${((count / total) * 100).toFixed(1)}% |`);
169
- }
170
- lines.push('');
171
- }
172
- // 模块结构
173
- if (allTargets.length > 0) {
174
- lines.push(`### 模块结构`, '');
175
- lines.push(`项目包含 **${allTargets.length}** 个模块/Target:`, '');
176
- for (const t of allTargets.slice(0, 15)) {
177
- const tName = t;
178
- const fileCount = Array.isArray(allFiles)
179
- ? allFiles.filter((f) => f.targetName === tName).length
180
- : 0;
181
- lines.push(`- \`${tName}\` (${fileCount} files)`);
182
- }
183
- if (allTargets.length > 15) {
184
- lines.push(`- ...及 ${allTargets.length - 15} 个其他模块`);
185
- }
186
- lines.push('');
187
- }
188
- // 依赖关系
189
- if (depGraphData && depGraphData.edges.length > 0) {
190
- lines.push('### 依赖关系', '');
191
- lines.push(`共 ${depGraphData.edges.length} 条模块间依赖关系。`, '');
192
- }
193
- // AST 统计
194
- if (astProjectSummary) {
195
- lines.push('### 代码结构统计', '');
196
- const m = astProjectSummary.projectMetrics || {};
197
- lines.push(`- 类/结构体: ${astProjectSummary.classes?.length || 0}`);
198
- lines.push(`- 协议/接口: ${astProjectSummary.protocols?.length || 0}`);
199
- lines.push(`- 方法总数: ${m.totalMethods || 0}`);
200
- if (m.maxNestingDepth) {
201
- lines.push(`- 最大嵌套深度: ${m.maxNestingDepth}`);
202
- }
203
- if (m.complexMethods && m.complexMethods.length > 0) {
204
- lines.push(`- 高复杂度方法: ${m.complexMethods.length}`);
205
- }
206
- if (m.longMethods && m.longMethods.length > 0) {
207
- lines.push(`- 过长方法 (>50 行): ${m.longMethods.length}`);
208
- }
209
- lines.push('');
210
- }
211
- // 生成 coreCode (P3): 技术栈摘要
212
- const codeParts = [];
213
- if (sortedLangs.length > 0) {
214
- codeParts.push('// 语言分布');
215
- for (const [lang, count] of sortedLangs.slice(0, 5)) {
216
- codeParts.push(`// ${lang}: ${count} files`);
217
- }
218
- }
219
- if (astProjectSummary) {
220
- codeParts.push(`// 类: ${astProjectSummary.classes?.length || 0}, 协议: ${astProjectSummary.protocols?.length || 0}, 方法: ${astProjectSummary.projectMetrics?.totalMethods || 0}`);
221
- }
222
- if (allTargets.length > 0) {
223
- codeParts.push(`// Target: ${allTargets
224
- .slice(0, 8)
225
- .map((t) => t)
226
- .join(', ')}`);
227
- }
228
- const markdown = lines.join('\n');
229
- if (markdown.length < 50) {
230
- return null;
231
- }
232
- return _makeCandidate({
233
- title: `项目技术画像 — ${primaryLang}`,
234
- knowledgeType: 'architecture',
235
- category: 'Architecture',
236
- language: primaryLang,
237
- markdown,
238
- rationale: '基于 Bootstrap 扫描的文件统计、AST 分析和依赖图谱自动生成',
239
- coreCode: codeParts.join('\n'),
240
- trigger: '项目技术画像',
241
- doClause: '了解项目技术栈和模块结构后再开始编码',
242
- dontClause: '',
243
- whenClause: '初次接触项目或需要了解全局架构时',
244
- sources: ['bootstrap-scan'],
245
- });
246
- }
247
- function _buildArchitecture({ depGraphData, allTargets, targetFileMap, primaryLang, astProjectSummary, }) {
248
- if (!(depGraphData && depGraphData.edges.length) && allTargets.length < 2) {
249
- return null;
250
- }
251
- const lines = ['## 模块架构', ''];
252
- // 依赖图
253
- if (depGraphData && depGraphData.edges.length > 0) {
254
- lines.push('### 模块依赖关系', '');
255
- lines.push('```');
256
- const seen = new Set();
257
- for (const e of depGraphData.edges.slice(0, 30)) {
258
- const from = typeof e.from === 'string' ? e.from : e.source;
259
- const to = typeof e.to === 'string' ? e.to : e.target;
260
- if (from && to) {
261
- const key = `${from} → ${to}`;
262
- if (!seen.has(key)) {
263
- lines.push(key);
264
- seen.add(key);
265
- }
266
- }
267
- }
268
- lines.push('```');
269
- lines.push('');
270
- // 入度/出度分析
271
- const inDeg = {};
272
- const outDeg = {};
273
- for (const e of depGraphData.edges) {
274
- const from = typeof e.from === 'string' ? e.from : e.source;
275
- const to = typeof e.to === 'string' ? e.to : e.target;
276
- if (from) {
277
- outDeg[from] = (outDeg[from] || 0) + 1;
278
- }
279
- if (to) {
280
- inDeg[to] = (inDeg[to] || 0) + 1;
281
- }
282
- }
283
- // 核心模块(被依赖最多)
284
- const coreModules = Object.entries(inDeg)
285
- .sort(([, a], [, b]) => b - a)
286
- .slice(0, 5);
287
- if (coreModules.length > 0) {
288
- lines.push('### 核心模块(被依赖最多)', '');
289
- for (const [mod, deg] of coreModules) {
290
- lines.push(`- \`${mod}\` — 被 ${deg} 个模块依赖`);
291
- }
292
- lines.push('');
293
- }
294
- // 叶子模块(不被任何模块依赖)
295
- const leafModules = allTargets.filter((t) => !inDeg[t] && outDeg[t]);
296
- if (leafModules.length > 0) {
297
- lines.push('### 叶子模块(仅依赖他人)', '');
298
- for (const mod of leafModules.slice(0, 8)) {
299
- lines.push(`- \`${mod}\``);
300
- }
301
- lines.push('');
302
- }
303
- }
304
- // P5: ObjC Category 信息
305
- const categories = astProjectSummary?.categories || [];
306
- if (categories.length > 0) {
307
- lines.push('### ObjC Category 扩展', '');
308
- // 按基类分组
309
- const byBase = {};
310
- for (const cat of categories) {
311
- const base = cat.className || cat.baseClass || cat.name?.split('(')[0] || 'Unknown';
312
- if (!byBase[base]) {
313
- byBase[base] = [];
314
- }
315
- byBase[base].push(cat);
316
- }
317
- const sortedBases = Object.entries(byBase).sort(([, a], [, b]) => b.length - a.length);
318
- lines.push(`共 **${categories.length}** 个 Category,分布在 **${sortedBases.length}** 个基类上:`, '');
319
- for (const [base, cats] of sortedBases.slice(0, 10)) {
320
- const catNames = cats
321
- .map((c) => c.categoryName || c.name || '')
322
- .filter(Boolean)
323
- .slice(0, 5)
324
- .join(', ');
325
- const loc = cats[0]?.file ? ` (来源: ${_basename(cats[0].file)})` : '';
326
- lines.push(`- \`${base}\` — ${cats.length} 个 Category${catNames ? `: ${catNames}` : ''}${loc}`);
327
- }
328
- if (sortedBases.length > 10) {
329
- lines.push(`- ...及 ${sortedBases.length - 10} 个其他基类`);
330
- }
331
- lines.push('');
332
- }
333
- // 生成代码块 (P3)
334
- const codeLines = [];
335
- if (depGraphData && depGraphData.edges.length > 0) {
336
- codeLines.push(`// 模块依赖关系 (共 ${depGraphData.edges.length} 条)`);
337
- const seen = new Set();
338
- for (const e of depGraphData.edges.slice(0, 15)) {
339
- const from = typeof e.from === 'string' ? e.from : e.source;
340
- const to = typeof e.to === 'string' ? e.to : e.target;
341
- if (from && to) {
342
- const key = `${from} -> ${to}`;
343
- if (!seen.has(key)) {
344
- codeLines.push(key);
345
- seen.add(key);
346
- }
347
- }
348
- }
349
- }
350
- const markdown = lines.join('\n');
351
- if (markdown.length < 80) {
352
- return null;
353
- }
354
- return _makeCandidate({
355
- title: '模块架构与依赖关系',
356
- knowledgeType: 'architecture',
357
- category: 'Architecture',
358
- language: primaryLang,
359
- markdown,
360
- rationale: '基于项目依赖图谱和模块扫描自动生成',
361
- coreCode: codeLines.length > 1 ? codeLines.join('\n') : '',
362
- trigger: '模块架构',
363
- doClause: '遵循现有模块边界,新功能放入对应模块',
364
- dontClause: '',
365
- whenClause: '新建文件或模块时',
366
- sources: ['bootstrap-scan'],
367
- });
368
- }
369
- function _buildCodeStandard({ astProjectSummary, primaryLang, allFiles, }) {
370
- if (!astProjectSummary) {
371
- return null;
372
- }
373
- const lines = ['## 代码规范发现', ''];
374
- const classes = astProjectSummary.classes || [];
375
- const methods = [];
376
- // 从 file 级聚合方法
377
- if (astProjectSummary.files) {
378
- for (const f of astProjectSummary.files) {
379
- if (f.methods) {
380
- methods.push(...f.methods);
381
- }
382
- }
383
- }
384
- // 命名模式分析
385
- let usedSuffixes = [];
386
- if (classes.length > 0) {
387
- lines.push('### 类命名模式', '');
388
- // 检测常见后缀
389
- const suffixCounts = {};
390
- const COMMON_SUFFIXES = [
391
- 'Service',
392
- 'Manager',
393
- 'Controller',
394
- 'Handler',
395
- 'Provider',
396
- 'Repository',
397
- 'Factory',
398
- 'Helper',
399
- 'Utils',
400
- 'ViewModel',
401
- 'View',
402
- 'Model',
403
- 'Store',
404
- 'Client',
405
- 'Adapter',
406
- 'Impl',
407
- ];
408
- for (const cls of classes) {
409
- for (const sfx of COMMON_SUFFIXES) {
410
- if (cls.name?.endsWith(sfx)) {
411
- suffixCounts[sfx] = (suffixCounts[sfx] || 0) + 1;
412
- }
413
- }
414
- }
415
- usedSuffixes = Object.entries(suffixCounts)
416
- .filter(([, c]) => c > 0)
417
- .sort(([, a], [, b]) => b - a);
418
- if (usedSuffixes.length > 0) {
419
- lines.push('| 后缀约定 | 类数量 | 推断角色 |');
420
- lines.push('|----------|--------|----------|');
421
- const roleMap = {
422
- Service: '业务服务',
423
- Manager: '管理器',
424
- Controller: '控制器/路由',
425
- Handler: '事件/请求处理',
426
- Provider: '数据/功能提供者',
427
- Repository: '数据访问',
428
- Factory: '工厂',
429
- Helper: '辅助工具',
430
- Utils: '工具类',
431
- ViewModel: '视图模型',
432
- View: '视图/UI',
433
- Model: '数据模型',
434
- Store: '状态存储',
435
- Client: 'API 客户端',
436
- Adapter: '适配器',
437
- Impl: '接口实现',
438
- };
439
- for (const [sfx, count] of usedSuffixes) {
440
- lines.push(`| *${sfx} | ${count} | ${roleMap[sfx] || sfx} |`);
441
- }
442
- lines.push('');
443
- }
444
- lines.push(`共发现 **${classes.length}** 个类/结构体。`, '');
445
- }
446
- // 代码质量指标
447
- const metrics = astProjectSummary.projectMetrics;
448
- if (metrics) {
449
- lines.push('### 代码质量指标', '');
450
- if (metrics.avgMethodsPerClass) {
451
- lines.push(`- 平均方法数/类: ${metrics.avgMethodsPerClass.toFixed(1)}`);
452
- }
453
- if (metrics.complexMethods && metrics.complexMethods.length > 0) {
454
- lines.push(`- 高圈复杂度方法: ${metrics.complexMethods.length} 个`);
455
- for (const m of metrics.complexMethods.slice(0, 5)) {
456
- const loc = m.file ? ` (来源: ${_basename(m.file)}${m.line ? `:${m.line}` : ''})` : '';
457
- lines.push(` - \`${m.className ? `${m.className}.` : ''}${m.name}\` — complexity ${m.complexity}${loc}`);
458
- }
459
- }
460
- if (metrics.longMethods && metrics.longMethods.length > 0) {
461
- lines.push(`- 过长方法: ${metrics.longMethods.length} 个`);
462
- for (const m of metrics.longMethods.slice(0, 5)) {
463
- const bodyLen = m.lines || m.bodyLines || '?';
464
- const loc = m.file ? ` (来源: ${_basename(m.file)}${m.line ? `:${m.line}` : ''})` : '';
465
- lines.push(` - \`${m.className ? `${m.className}.` : ''}${m.name}\` — ${bodyLen} 行${loc}`);
466
- }
467
- }
468
- lines.push('');
469
- }
470
- // 收集源文件引用 (P4)
471
- const sourceFiles = new Set();
472
- if (metrics) {
473
- for (const m of (metrics.longMethods || []).concat(metrics.complexMethods || [])) {
474
- if (m.file) {
475
- sourceFiles.add(m.file);
476
- }
477
- }
478
- }
479
- // 生成 coreCode (P3): 命名规范摘要
480
- const codeLines = [];
481
- if (usedSuffixes?.length > 0) {
482
- codeLines.push('// 命名约定示例');
483
- for (const [sfx, count] of usedSuffixes.slice(0, 6)) {
484
- codeLines.push(`// *${sfx} → ${count} 个类使用此后缀`);
485
- }
486
- }
487
- if (metrics && metrics.longMethods && metrics.longMethods.length > 0) {
488
- codeLines.push('');
489
- codeLines.push('// 过长方法示例 (应重构)');
490
- for (const m of metrics.longMethods.slice(0, 3)) {
491
- const bodyLen = m.lines || m.bodyLines || '?';
492
- codeLines.push(`// ${m.className ? `${m.className}.` : ''}${m.name} — ${bodyLen} 行`);
493
- }
494
- }
495
- const markdown = lines.join('\n');
496
- if (markdown.length < 80) {
497
- return null;
498
- }
499
- return _makeCandidate({
500
- title: '代码规范与命名约定',
501
- knowledgeType: 'code-standard',
502
- category: 'Architecture',
503
- language: primaryLang,
504
- markdown,
505
- rationale: '基于 AST 分析的类名、方法统计和代码复杂度指标自动生成',
506
- coreCode: codeLines.join('\n'),
507
- trigger: '代码规范',
508
- doClause: '遵循项目现有命名约定,新类名使用已有后缀模式',
509
- dontClause: '不要写超过 50 行的方法,不要超过 4 层嵌套',
510
- whenClause: '新建类或方法时',
511
- sources: sourceFiles.size > 0 ? [...sourceFiles].slice(0, 10) : ['bootstrap-scan'],
512
- });
513
- }
514
- function _buildBestPractice({ guardAudit, primaryLang, }) {
515
- if (!guardAudit?.files?.length) {
516
- return null;
517
- }
518
- // 聚合所有违规
519
- const ruleStats = {};
520
- for (const f of guardAudit.files) {
521
- for (const v of f.violations || []) {
522
- if (!ruleStats[v.ruleId]) {
523
- ruleStats[v.ruleId] = {
524
- count: 0,
525
- severity: v.severity,
526
- message: v.message,
527
- files: new Set(),
528
- fixSuggestion: v.fixSuggestion || null,
529
- };
530
- }
531
- ruleStats[v.ruleId].count++;
532
- ruleStats[v.ruleId].files.add(f.filePath);
533
- }
534
- }
535
- const sortedRules = Object.entries(ruleStats).sort(([, a], [, b]) => b.count - a.count);
536
- if (sortedRules.length === 0) {
537
- return null;
538
- }
539
- const lines = ['## 最佳实践(基于 Guard 审计)', ''];
540
- lines.push(`Bootstrap 扫描发现 **${guardAudit.summary?.totalViolations || 0}** 个违规,` +
541
- `涉及 **${sortedRules.length}** 条规则:`, '');
542
- lines.push('### 高频违规(应优先修复)', '');
543
- lines.push('| 规则 | 严重性 | 违规数 | 影响文件数 | 说明 |');
544
- lines.push('|------|--------|--------|-----------|------|');
545
- for (const [ruleId, stat] of sortedRules.slice(0, 15)) {
546
- lines.push(`| \`${ruleId}\` | ${stat.severity} | ${stat.count} | ${stat.files.size} | ${stat.message} |`);
547
- }
548
- lines.push('');
549
- // 修复建议
550
- const withFix = sortedRules.filter(([, s]) => s.fixSuggestion);
551
- if (withFix.length > 0) {
552
- lines.push('### 修复建议', '');
553
- for (const [ruleId, stat] of withFix.slice(0, 10)) {
554
- lines.push(`- **${ruleId}**: ${stat.fixSuggestion}`);
555
- }
556
- lines.push('');
557
- }
558
- // 收集违规文件路径 (P4)
559
- const violationFiles = new Set();
560
- for (const f of guardAudit.files) {
561
- if (f.violations?.length > 0 && f.filePath) {
562
- violationFiles.add(f.filePath);
563
- }
564
- }
565
- // 生成 coreCode (P3): Guard 规则摘要
566
- const codeLines = ['// Guard 高频违规规则'];
567
- for (const [ruleId, stat] of sortedRules.slice(0, 5)) {
568
- codeLines.push(`// ${ruleId}: ${stat.message} (${stat.count}次)`);
569
- }
570
- const markdown = lines.join('\n');
571
- return _makeCandidate({
572
- title: '最佳实践与常见问题',
573
- knowledgeType: 'best-practice',
574
- category: 'Service',
575
- language: primaryLang,
576
- markdown,
577
- rationale: '基于 Guard 静态审计发现的违规模式和修复建议自动生成',
578
- coreCode: codeLines.join('\n'),
579
- trigger: 'Guard 审计结果',
580
- doClause: '修复 Guard 标记的违规,特别是 error 级别',
581
- dontClause: '不要忽略 Guard 警告,不要引入已知反模式',
582
- whenClause: '修改现有代码或新建文件时',
583
- sources: violationFiles.size > 0 ? [...violationFiles].slice(0, 10) : ['bootstrap-scan'],
584
- });
585
- }
586
- function _buildAgentGuidelines({ guardAudit, primaryLang, astProjectSummary, }) {
587
- const lines = ['## Agent 开发注意事项', ''];
588
- lines.push('> 以下规则基于项目静态分析自动生成,AI Agent 在本项目中编写代码时应遵守。', '');
589
- // 从 Guard 高频违规推断
590
- if (guardAudit?.files?.length) {
591
- const ruleStats = {};
592
- for (const f of guardAudit.files) {
593
- for (const v of f.violations || []) {
594
- ruleStats[v.ruleId] = ruleStats[v.ruleId] || {
595
- count: 0,
596
- message: v.message,
597
- severity: v.severity,
598
- };
599
- ruleStats[v.ruleId].count++;
600
- }
601
- }
602
- const topErrors = Object.entries(ruleStats)
603
- .filter(([, s]) => s.severity === 'error')
604
- .sort(([, a], [, b]) => b.count - a.count)
605
- .slice(0, 8);
606
- const topWarnings = Object.entries(ruleStats)
607
- .filter(([, s]) => s.severity === 'warning')
608
- .sort(([, a], [, b]) => b.count - a.count)
609
- .slice(0, 8);
610
- if (topErrors.length > 0) {
611
- lines.push('### 必须(must)- 基于 error 级违规', '');
612
- for (const [ruleId, stat] of topErrors) {
613
- lines.push(`- ❌ **${ruleId}**: ${stat.message} (项目中出现 ${stat.count} 次)`);
614
- }
615
- lines.push('');
616
- }
617
- if (topWarnings.length > 0) {
618
- lines.push('### 建议(should)- 基于 warning 级违规', '');
619
- for (const [ruleId, stat] of topWarnings) {
620
- lines.push(`- ⚠️ **${ruleId}**: ${stat.message} (${stat.count} 处)`);
621
- }
622
- lines.push('');
623
- }
624
- }
625
- // 从 AST 复杂度推断
626
- if (astProjectSummary?.projectMetrics) {
627
- const m = astProjectSummary.projectMetrics;
628
- lines.push('### 代码质量约束', '');
629
- if (m.maxNestingDepth != null && m.maxNestingDepth >= 5) {
630
- lines.push(`- 当前项目最大嵌套深度 ${m.maxNestingDepth} — 新代码应避免超过 4 层嵌套`);
631
- }
632
- if (m.complexMethods && m.complexMethods.length > 0) {
633
- const avgComplexity = m.complexMethods.reduce((s, c) => s + (c.complexity ?? 0), 0) /
634
- m.complexMethods.length;
635
- lines.push(`- 已有 ${m.complexMethods.length} 个高复杂度方法 (avg ${avgComplexity.toFixed(1)}) — 新方法圈复杂度应 <10`);
636
- }
637
- if (m.longMethods && m.longMethods.length > 0) {
638
- lines.push(`- 已有 ${m.longMethods.length} 个过长方法 — 新方法建议 <50 行`);
639
- }
640
- lines.push('');
641
- }
642
- const markdown = lines.join('\n');
643
- if (markdown.length < 100) {
644
- return null;
645
- }
646
- // 生成 coreCode (P3)
647
- const codeLines = ['// Agent 强制规则'];
648
- if (astProjectSummary?.projectMetrics &&
649
- (astProjectSummary.projectMetrics.maxNestingDepth ?? 0) >= 5) {
650
- codeLines.push(`// 最大嵌套: ${astProjectSummary.projectMetrics.maxNestingDepth} → 新代码应 <4`);
651
- }
652
- if (astProjectSummary?.projectMetrics?.longMethods &&
653
- astProjectSummary.projectMetrics.longMethods.length > 0) {
654
- codeLines.push(`// 过长方法: ${astProjectSummary.projectMetrics.longMethods.length} 个 → 新方法应 <50行`);
655
- }
656
- return _makeCandidate({
657
- title: 'Agent 开发注意事项',
658
- knowledgeType: 'boundary-constraint',
659
- category: 'Architecture',
660
- language: primaryLang,
661
- markdown,
662
- rationale: '基于 Guard 错误级违规和 AST 复杂度指标自动生成的 Agent 约束',
663
- coreCode: codeLines.join('\n'),
664
- trigger: 'Agent 开发规范',
665
- doClause: '新代码嵌套不超过 4 层,方法不超过 50 行,圈复杂度 <10',
666
- dontClause: '不要引入 Guard 已标记的反模式',
667
- whenClause: '在本项目中编写任何代码时',
668
- sources: ['bootstrap-scan'],
669
- });
670
- }
671
- // ═══════════════════════════════════════════════════════════
672
- // 工具函数
673
- // ═══════════════════════════════════════════════════════════
674
- /** 从绝对/相对路径取文件名 */
675
- function _basename(fp) {
676
- if (!fp) {
677
- return '';
678
- }
679
- const idx = fp.lastIndexOf('/');
680
- return idx >= 0 ? fp.slice(idx + 1) : fp;
681
- }
682
- function _makeCandidate({ title, knowledgeType, category, language, markdown, rationale, coreCode, trigger, doClause, dontClause, whenClause, sources, }) {
683
- return {
684
- title,
685
- content: { pattern: coreCode || '', markdown, rationale },
686
- language: language || '',
687
- category,
688
- knowledgeType,
689
- source: 'bootstrap-fallback',
690
- difficulty: 'beginner',
691
- scope: 'project-specific',
692
- trigger: trigger || title,
693
- doClause: doClause || '',
694
- dontClause: dontClause || '',
695
- whenClause: whenClause || '',
696
- coreCode: coreCode || '',
697
- reasoning: {
698
- whyStandard: rationale,
699
- sources: sources || ['bootstrap-scan'],
700
- confidence: 0.6,
701
- },
702
- };
703
- }
704
- function _wrapAsSkill(dimId, label, markdown) {
705
- return {
706
- dimId,
707
- name: `project-${dimId}`,
708
- description: `Auto-generated from bootstrap scan (no-AI fallback): ${label}`,
709
- content: [
710
- `# ${label}`,
711
- '',
712
- '> Auto-generated by Bootstrap fallback (rule-based, no AI). Quality: basic.',
713
- '',
714
- markdown,
715
- ].join('\n'),
716
- };
717
- }
718
- function _markDimDone(taskManager, sessionId, dimId, type) {
719
- try {
720
- if (taskManager && sessionId) {
721
- taskManager.markTaskCompleted(dimId, { type, reason: type });
722
- }
723
- }
724
- catch {
725
- /* non-critical */
726
- }
727
- }