autosnippet 2.9.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +12 -12
  2. package/bin/cli.js +53 -40
  3. package/config/constitution.yaml +9 -2
  4. package/dashboard/dist/assets/{icons-CH-H9x0E.js → icons-D4IWpDIk.js} +105 -100
  5. package/dashboard/dist/assets/index-CWBNcF9z.css +1 -0
  6. package/dashboard/dist/assets/index-DHtzhbuG.js +120 -0
  7. package/dashboard/dist/index.html +3 -3
  8. package/lib/cli/AiScanService.js +35 -36
  9. package/lib/cli/KnowledgeSyncService.js +345 -0
  10. package/lib/cli/SetupService.js +8 -26
  11. package/lib/cli/UpgradeService.js +28 -0
  12. package/lib/core/gateway/GatewayActionRegistry.js +48 -58
  13. package/lib/domain/index.js +16 -11
  14. package/lib/domain/knowledge/KnowledgeEntry.js +289 -0
  15. package/lib/domain/knowledge/KnowledgeRepository.js +123 -0
  16. package/lib/domain/knowledge/Lifecycle.js +99 -0
  17. package/lib/domain/knowledge/index.js +27 -0
  18. package/lib/domain/knowledge/values/Constraints.js +128 -0
  19. package/lib/domain/knowledge/values/Content.js +69 -0
  20. package/lib/domain/knowledge/values/Quality.js +81 -0
  21. package/lib/domain/knowledge/values/Reasoning.js +70 -0
  22. package/lib/domain/knowledge/values/Relations.js +142 -0
  23. package/lib/domain/knowledge/values/Stats.js +72 -0
  24. package/lib/domain/knowledge/values/index.js +9 -0
  25. package/lib/external/ai/AiProvider.js +85 -11
  26. package/lib/external/mcp/McpServer.js +7 -5
  27. package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +18 -2
  28. package/lib/external/mcp/handlers/bootstrap.js +116 -11
  29. package/lib/external/mcp/handlers/browse.js +76 -73
  30. package/lib/external/mcp/handlers/candidate.js +26 -275
  31. package/lib/external/mcp/handlers/guard.js +2 -0
  32. package/lib/external/mcp/handlers/knowledge.js +267 -0
  33. package/lib/external/mcp/handlers/structure.js +25 -23
  34. package/lib/external/mcp/handlers/system.js +10 -12
  35. package/lib/external/mcp/tools.js +134 -140
  36. package/lib/http/HttpServer.js +14 -8
  37. package/lib/http/routes/ai.js +4 -3
  38. package/lib/http/routes/extract.js +48 -4
  39. package/lib/http/routes/knowledge.js +246 -0
  40. package/lib/http/routes/search.js +12 -17
  41. package/lib/infrastructure/database/migrations/016_unified_knowledge_entries.js +395 -0
  42. package/lib/infrastructure/database/migrations/017_camelcase_knowledge_entries.js +107 -0
  43. package/lib/infrastructure/external/XcodeAutomation.js +187 -103
  44. package/lib/injection/ServiceContainer.js +69 -60
  45. package/lib/repository/knowledge/KnowledgeRepository.impl.js +338 -0
  46. package/lib/service/automation/DirectiveDetector.js +2 -3
  47. package/lib/service/automation/FileWatcher.js +59 -28
  48. package/lib/service/automation/XcodeIntegration.js +931 -156
  49. package/lib/service/automation/handlers/AlinkHandler.js +5 -4
  50. package/lib/service/automation/handlers/CreateHandler.js +53 -19
  51. package/lib/service/automation/handlers/DraftHandler.js +1 -1
  52. package/lib/service/automation/handlers/GuardHandler.js +183 -20
  53. package/lib/service/automation/handlers/SearchHandler.js +25 -22
  54. package/lib/service/candidate/SimilarityService.js +2 -2
  55. package/lib/service/chat/AnalystAgent.js +9 -0
  56. package/lib/service/chat/CandidateGuardrail.js +22 -11
  57. package/lib/service/chat/ChatAgent.js +132 -54
  58. package/lib/service/chat/ContextWindow.js +5 -5
  59. package/lib/service/chat/HandoffProtocol.js +1 -0
  60. package/lib/service/chat/ProducerAgent.js +40 -13
  61. package/lib/service/chat/ReasoningLayer.js +854 -0
  62. package/lib/service/chat/ReasoningTrace.js +329 -0
  63. package/lib/service/chat/tools.js +308 -205
  64. package/lib/service/cursor/CursorDeliveryPipeline.js +279 -0
  65. package/lib/service/cursor/KnowledgeCompressor.js +87 -0
  66. package/lib/service/cursor/RulesGenerator.js +168 -0
  67. package/lib/service/cursor/SkillsSyncer.js +268 -0
  68. package/lib/service/cursor/TokenBudget.js +58 -0
  69. package/lib/service/cursor/TopicClassifier.js +141 -0
  70. package/lib/service/guard/GuardCheckEngine.js +99 -10
  71. package/lib/service/guard/GuardService.js +57 -46
  72. package/lib/service/knowledge/ConfidenceRouter.js +159 -0
  73. package/lib/service/knowledge/KnowledgeFileWriter.js +595 -0
  74. package/lib/service/knowledge/KnowledgeService.js +802 -0
  75. package/lib/service/recipe/RecipeParser.js +3 -12
  76. package/lib/service/search/SearchEngine.js +67 -22
  77. package/lib/service/skills/SignalCollector.js +14 -9
  78. package/lib/service/skills/SkillAdvisor.js +13 -11
  79. package/lib/service/snippet/SnippetFactory.js +5 -5
  80. package/lib/service/spm/SpmService.js +15 -48
  81. package/lib/shared/RecipeReadinessChecker.js +6 -11
  82. package/package.json +1 -1
  83. package/scripts/install-cursor-skill.js +0 -6
  84. package/scripts/migrate-md-to-knowledge.mjs +364 -0
  85. package/skills/autosnippet-analysis/SKILL.md +15 -7
  86. package/skills/autosnippet-candidates/SKILL.md +8 -8
  87. package/skills/autosnippet-coldstart/SKILL.md +8 -4
  88. package/skills/autosnippet-concepts/SKILL.md +7 -6
  89. package/skills/autosnippet-create/SKILL.md +13 -13
  90. package/skills/autosnippet-intent/SKILL.md +3 -2
  91. package/skills/autosnippet-lifecycle/SKILL.md +5 -5
  92. package/skills/autosnippet-recipes/SKILL.md +18 -6
  93. package/templates/constitution.yaml +1 -1
  94. package/templates/copilot-instructions.md +6 -6
  95. package/templates/recipes-setup/README.md +3 -3
  96. package/dashboard/dist/assets/index-CqJRvYRL.js +0 -197
  97. package/dashboard/dist/assets/index-DICm9PNa.css +0 -1
  98. package/lib/cli/CandidateSyncService.js +0 -261
  99. package/lib/cli/SyncService.js +0 -356
  100. package/lib/domain/candidate/Candidate.js +0 -196
  101. package/lib/domain/candidate/CandidateRepository.js +0 -107
  102. package/lib/domain/candidate/Reasoning.js +0 -52
  103. package/lib/domain/recipe/Recipe.js +0 -421
  104. package/lib/domain/recipe/RecipeRepository.js +0 -54
  105. package/lib/domain/types/CandidateStatus.js +0 -52
  106. package/lib/http/routes/candidates.js +0 -559
  107. package/lib/http/routes/recipes.js +0 -397
  108. package/lib/repository/candidate/CandidateRepository.impl.js +0 -230
  109. package/lib/repository/recipe/RecipeRepository.impl.js +0 -498
  110. package/lib/service/candidate/CandidateAggregator.js +0 -52
  111. package/lib/service/candidate/CandidateFileWriter.js +0 -383
  112. package/lib/service/candidate/CandidateService.js +0 -1001
  113. package/lib/service/recipe/RecipeFileWriter.js +0 -514
  114. package/lib/service/recipe/RecipeService.js +0 -786
  115. package/lib/service/recipe/RecipeStatsTracker.js +0 -148
@@ -1,421 +0,0 @@
1
- import { v4 as uuidv4 } from 'uuid';
2
- import Logger from '../../infrastructure/logging/Logger.js';
3
-
4
- /* ═══════════════════════════════════════════════════════════
5
- * Recipe — 统一知识实体
6
- *
7
- * 通过 kind 字段实现三层知识分类(Backstage Kind 模式):
8
- * kind = 'rule' → 规约性知识 (Guard 引擎消费)
9
- * kind = 'pattern' → 模式性知识 (搜索/代码生成消费)
10
- * kind = 'fact' → 结构性知识 (图遍历/RAG 消费)
11
- *
12
- * 子仓库文件 (Source of Truth):
13
- * AutoSnippet/recipes/<id>.md → Markdown + YAML front-matter
14
- *
15
- * DB 缓存:
16
- * .autosnippet/autosnippet.db recipes 表 → 索引 + 查询加速
17
- * ═══════════════════════════════════════════════════════════ */
18
-
19
- // ─── 枚举 ────────────────────────────────────────────────
20
-
21
- /**
22
- * Kind — 一级分类(Backstage 风格)
23
- * 决定知识的消费者和生命周期
24
- */
25
- export const Kind = {
26
- /** 规约: 代码规范/最佳实践/边界约束 → Guard 引擎 */
27
- RULE: 'rule',
28
- /** 模式: 可复用代码/架构方案/解决办法 → 搜索/AI代码生成 */
29
- PATTERN: 'pattern',
30
- /** 事实: 结构性知识(继承/调用/依赖) → 图遍历/影响分析 */
31
- FACT: 'fact',
32
- };
33
-
34
- /** knowledgeType → kind 映射 */
35
- const KIND_MAP = {
36
- 'code-standard': Kind.RULE,
37
- 'code-style': Kind.RULE,
38
- 'best-practice': Kind.RULE,
39
- 'boundary-constraint': Kind.RULE,
40
- 'code-pattern': Kind.PATTERN,
41
- 'architecture': Kind.PATTERN,
42
- 'solution': Kind.PATTERN,
43
- 'anti-pattern': Kind.PATTERN,
44
- 'code-relation': Kind.FACT,
45
- 'inheritance': Kind.FACT,
46
- 'call-chain': Kind.FACT,
47
- 'data-flow': Kind.FACT,
48
- 'module-dependency': Kind.FACT,
49
- };
50
-
51
- /** 从 knowledgeType 推导 kind */
52
- export function inferKind(knowledgeType) {
53
- return KIND_MAP[knowledgeType] || Kind.PATTERN;
54
- }
55
-
56
- /** Recipe 状态 */
57
- export const RecipeStatus = {
58
- DRAFT: 'draft', // 草稿
59
- ACTIVE: 'active', // 已发布
60
- DEPRECATED: 'deprecated', // 已弃用
61
- };
62
-
63
- /**
64
- * 知识类型 — 10 种维度,统一覆盖所有项目知识
65
- */
66
- export const KnowledgeType = {
67
- /** 代码规范: 命名规则、格式约定、编码标准 */
68
- CODE_STANDARD: 'code-standard',
69
- /** 代码模式: 可复用的代码片段/模板/idiom */
70
- CODE_PATTERN: 'code-pattern',
71
- /** 代码关联: 文件/类/方法间的引用与关系 */
72
- CODE_RELATION: 'code-relation',
73
- /** 继承与接口: 协议、接口、基类、实现关系 */
74
- INHERITANCE: 'inheritance',
75
- /** 调用链路: 方法/函数调用路径、生命周期流转 */
76
- CALL_CHAIN: 'call-chain',
77
- /** 数据流向: 数据从产生到消费的完整路径 */
78
- DATA_FLOW: 'data-flow',
79
- /** 模块与依赖: 包/模块/Target 间的依赖关系 */
80
- MODULE_DEPENDENCY: 'module-dependency',
81
- /** 模式与架构: 设计模式、架构模式、分层策略 */
82
- ARCHITECTURE: 'architecture',
83
- /** 最佳实践: 推荐做法、Anti-pattern 警告 */
84
- BEST_PRACTICE: 'best-practice',
85
- /** 边界约束: 限制条件、前/后置约束、不变量 */
86
- BOUNDARY_CONSTRAINT: 'boundary-constraint',
87
- /** 代码风格: 排版、缩进、注释风格、文件组织 */
88
- CODE_STYLE: 'code-style',
89
- /** 问题解决方案: 具体 Bug/性能/迁移问题的解决办法 */
90
- SOLUTION: 'solution',
91
- /** 反模式: force-unwrap、超长方法、循环引用等代码风险 */
92
- ANTI_PATTERN: 'anti-pattern',
93
- };
94
-
95
- /** 复杂度 */
96
- export const Complexity = {
97
- BEGINNER: 'beginner',
98
- INTERMEDIATE: 'intermediate',
99
- ADVANCED: 'advanced',
100
- };
101
-
102
- /**
103
- * 统一关系类型 — 涵盖结构性 + 语义性关系
104
- * (合并原 Recipe.RelationType 和 KnowledgeGraphService.RelationType)
105
- */
106
- export const RelationType = {
107
- // ── 结构性关系 (自动发现, Graph 层) ──
108
- INHERITS: 'inherits', // 继承
109
- IMPLEMENTS: 'implements', // 实现接口/协议
110
- CALLS: 'calls', // 调用
111
- DEPENDS_ON: 'depends_on', // 依赖
112
- DATA_FLOW_TO: 'data_flow_to', // 数据流向
113
- REFERENCES: 'references', // 引用
114
-
115
- // ── 语义性关系 (人工/AI 标注, Recipe 间) ──
116
- EXTENDS: 'extends', // 扩展
117
- CONFLICTS: 'conflicts', // 冲突
118
- RELATED: 'related', // 弱关联
119
- ALTERNATIVE: 'alternative', // 替代方案
120
- PREREQUISITE: 'prerequisite', // 前置条件
121
- DEPRECATED_BY: 'deprecated_by', // 被取代
122
- SOLVES: 'solves', // 解决问题
123
- ENFORCES: 'enforces', // 强制约束
124
- };
125
-
126
- // ─── 实体 ────────────────────────────────────────────────
127
-
128
- export class Recipe {
129
- /**
130
- * @param {Object} props
131
- */
132
- constructor(props) {
133
- // ── 标识 ──
134
- this.id = props.id || uuidv4();
135
- this.title = props.title;
136
- this.description = props.description || '';
137
- this.language = props.language || '';
138
- this.category = props.category || '';
139
-
140
- // ── 国际化摘要 & 使用指南(一级字段)──
141
- this.summaryCn = props.summaryCn ?? '';
142
- this.summaryEn = props.summaryEn ?? '';
143
- this.usageGuideCn = props.usageGuideCn ?? '';
144
- this.usageGuideEn = props.usageGuideEn ?? '';
145
-
146
- // ── 分类 ──
147
- this.knowledgeType = props.knowledgeType || KnowledgeType.CODE_PATTERN;
148
- this.kind = props.kind || inferKind(this.knowledgeType);
149
- this.complexity = props.complexity || Complexity.INTERMEDIATE;
150
- this.scope = props.scope || null; // universal | project-specific | target-specific
151
-
152
- // ── 内容 ──
153
- this.content = {
154
- /** 代码模式/示例代码(Markdown / literal code) */
155
- pattern: props.content?.pattern ?? '',
156
- /** 设计原理/架构说明 */
157
- rationale: props.content?.rationale ?? '',
158
- /** 步骤说明(解决方案、实施指南) */
159
- steps: props.content?.steps ?? [],
160
- /** 代码变更 [{ file, before, after, explanation }] */
161
- codeChanges: props.content?.codeChanges ?? [],
162
- /** 验证方式 { method, expectedResult, testCode } */
163
- verification: props.content?.verification ?? null,
164
- /** 原始 Markdown 全文(从 .md 文件同步时保存) */
165
- markdown: props.content?.markdown ?? '',
166
- };
167
-
168
- // ── 关系图 ──
169
- this.relations = {
170
- /** 继承关系 [{ target, description }] */
171
- inherits: props.relations?.inherits ?? [],
172
- /** 接口/协议实现 */
173
- implements: props.relations?.implements ?? [],
174
- /** 调用链路 */
175
- calls: props.relations?.calls ?? [],
176
- /** 依赖关系 */
177
- dependsOn: props.relations?.dependsOn ?? [],
178
- /** 数据流向 */
179
- dataFlow: props.relations?.dataFlow ?? [],
180
- /** 冲突 */
181
- conflicts: props.relations?.conflicts ?? [],
182
- /** 扩展 */
183
- extends: props.relations?.extends ?? [],
184
- /** 相关知识 */
185
- related: props.relations?.related ?? [],
186
- };
187
-
188
- // ── 约束 ──
189
- this.constraints = {
190
- /** 边界约束 ["最大并发数 100", "仅限 iOS 15+"] */
191
- boundaries: props.constraints?.boundaries ?? [],
192
- /** 前置条件 */
193
- preconditions: props.constraints?.preconditions ?? [],
194
- /** 副作用 */
195
- sideEffects: props.constraints?.sideEffects ?? [],
196
- /** 内联 Guard 规则 [{ pattern, severity, message }] */
197
- guards: props.constraints?.guards ?? [],
198
- };
199
-
200
- // ── 快捷激活关键词 ──
201
- this.trigger = props.trigger ?? ''; // @forEach, @singleton 等
202
-
203
- // ── 多维分类(扩展标签系统)──
204
- this.dimensions = props.dimensions || {}; // { platform, framework, paradigm, ... }
205
- this.tags = props.tags || []; // 自由标签
206
-
207
- // ── 状态 ──
208
- this.status = props.status || RecipeStatus.DRAFT;
209
-
210
- // ── 质量指标 (0-1) ──
211
- this.quality = {
212
- codeCompleteness: props.quality?.codeCompleteness ?? 0,
213
- projectAdaptation: props.quality?.projectAdaptation ?? 0,
214
- documentationClarity: props.quality?.documentationClarity ?? 0,
215
- overall: props.quality?.overall ?? 0,
216
- };
217
-
218
- // ── 统计 ──
219
- this.statistics = {
220
- adoptionCount: props.statistics?.adoptionCount ?? 0,
221
- applicationCount: props.statistics?.applicationCount ?? 0,
222
- guardHitCount: props.statistics?.guardHitCount ?? 0,
223
- viewCount: props.statistics?.viewCount ?? 0,
224
- successCount: props.statistics?.successCount ?? 0,
225
- feedbackScore: props.statistics?.feedbackScore ?? 0,
226
- };
227
-
228
- // ── 元数据 ──
229
- this.createdBy = props.createdBy || 'system';
230
- this.createdAt = props.createdAt || Math.floor(Date.now() / 1000);
231
- this.updatedAt = props.updatedAt || Math.floor(Date.now() / 1000);
232
- this.publishedAt = props.publishedAt ?? null;
233
- this.publishedBy = props.publishedBy ?? null;
234
- this.deprecation = props.deprecation ?? null; // { reason, deprecatedAt }
235
-
236
- // ── 来源追踪 ──
237
- this.sourceCandidate = props.sourceCandidate ?? null; // Candidate ID
238
- this.sourceFile = props.sourceFile ?? null; // 子仓库文件路径
239
-
240
- this.logger = Logger.getInstance();
241
- }
242
-
243
- /* ═══ 验证 ═══════════════════════════════════════════ */
244
-
245
- isValid() {
246
- return Boolean(
247
- this.title?.trim() &&
248
- (this.content.pattern || this.content.rationale ||
249
- this.content.steps.length > 0 || this.content.markdown)
250
- );
251
- }
252
-
253
- /* ═══ 状态转换 ═══════════════════════════════════════ */
254
-
255
- publish(publishedBy) {
256
- if (!this.isValid()) {
257
- return { success: false, error: '内容不完整,无法发布' };
258
- }
259
- if (this.status === RecipeStatus.ACTIVE) {
260
- return { success: false, error: '已经是发布状态' };
261
- }
262
-
263
- this.status = RecipeStatus.ACTIVE;
264
- this.publishedAt = Math.floor(Date.now() / 1000);
265
- this.publishedBy = publishedBy;
266
- this.updatedAt = Math.floor(Date.now() / 1000);
267
-
268
- this.logger.info('Recipe published', { recipeId: this.id, publishedBy });
269
- return { success: true, recipe: this };
270
- }
271
-
272
- deprecate(reason = '') {
273
- if (this.status === RecipeStatus.DEPRECATED) {
274
- return { success: false, error: '已经是弃用状态' };
275
- }
276
-
277
- this.status = RecipeStatus.DEPRECATED;
278
- this.updatedAt = Math.floor(Date.now() / 1000);
279
- this.deprecation = { reason, deprecatedAt: Math.floor(Date.now() / 1000) };
280
-
281
- this.logger.info('Recipe deprecated', { recipeId: this.id, reason });
282
- return { success: true, recipe: this };
283
- }
284
-
285
- /* ═══ 质量 ═══════════════════════════════════════════ */
286
-
287
- updateQuality(metrics) {
288
- const cc = metrics.codeCompleteness ?? this.quality.codeCompleteness;
289
- const pa = metrics.projectAdaptation ?? this.quality.projectAdaptation;
290
- const dc = metrics.documentationClarity ?? this.quality.documentationClarity;
291
- const overall = Math.round(((cc + pa + dc) / 3) * 100) / 100;
292
-
293
- this.quality = { codeCompleteness: cc, projectAdaptation: pa, documentationClarity: dc, overall };
294
- this.updatedAt = Math.floor(Date.now() / 1000);
295
-
296
- this.logger.debug('Recipe quality updated', { recipeId: this.id, quality: this.quality });
297
- return { success: true, recipe: this };
298
- }
299
-
300
- /* ═══ 统计 ═══════════════════════════════════════════ */
301
-
302
- incrementAdoption() { this.statistics.adoptionCount++; this.updatedAt = Math.floor(Date.now() / 1000); }
303
- incrementApplication() { this.statistics.applicationCount++; this.updatedAt = Math.floor(Date.now() / 1000); }
304
-
305
- /**
306
- * 通用使用计数递增
307
- * @param {'adoption'|'application'} type
308
- */
309
- incrementUsage(type) {
310
- if (type === 'application') { this.incrementApplication(); }
311
- else { this.incrementAdoption(); }
312
- }
313
- incrementView() { this.statistics.viewCount++; this.updatedAt = Math.floor(Date.now() / 1000); }
314
-
315
- /* ═══ 关系管理 ═══════════════════════════════════════ */
316
-
317
- /**
318
- * 添加关系
319
- * @param {'inherits'|'implements'|'calls'|'dependsOn'|'dataFlow'|'conflicts'|'extends'|'related'} type
320
- * @param {{ target: string, description?: string }} relation
321
- */
322
- addRelation(type, relation) {
323
- if (!this.relations[type]) {
324
- return { success: false, error: `未知关系类型: ${type}` };
325
- }
326
- // 避免重复
327
- const exists = this.relations[type].some(r => r.target === relation.target);
328
- if (exists) {
329
- return { success: false, error: `关系已存在: ${relation.target}` };
330
- }
331
- this.relations[type].push(relation);
332
- this.updatedAt = Math.floor(Date.now() / 1000);
333
- return { success: true };
334
- }
335
-
336
- /**
337
- * 移除关系
338
- */
339
- removeRelation(type, targetId) {
340
- if (!this.relations[type]) return { success: false, error: `未知关系类型: ${type}` };
341
- const before = this.relations[type].length;
342
- this.relations[type] = this.relations[type].filter(r => r.target !== targetId);
343
- if (this.relations[type].length < before) {
344
- this.updatedAt = Math.floor(Date.now() / 1000);
345
- return { success: true };
346
- }
347
- return { success: false, error: '关系不存在' };
348
- }
349
-
350
- /**
351
- * 获取所有关系(扁平化)
352
- */
353
- getAllRelations() {
354
- const all = [];
355
- for (const [type, list] of Object.entries(this.relations)) {
356
- for (const r of list) {
357
- all.push({ type, ...r });
358
- }
359
- }
360
- return all;
361
- }
362
-
363
- /* ═══ 约束管理 ═══════════════════════════════════════ */
364
-
365
- /**
366
- * 添加 Guard 规则(内联在 Recipe 中)
367
- * @param {{ pattern: string, severity?: string, message?: string }} guard
368
- */
369
- addGuard(guard) {
370
- if (!guard.pattern) return { success: false, error: '缺少 pattern' };
371
- this.constraints.guards.push({
372
- pattern: guard.pattern,
373
- severity: guard.severity || 'warning',
374
- message: guard.message || '',
375
- });
376
- this.updatedAt = Math.floor(Date.now() / 1000);
377
- return { success: true };
378
- }
379
-
380
- /* ═══ 序列化 ═════════════════════════════════════════ */
381
-
382
- toJSON() {
383
- return {
384
- id: this.id,
385
- title: this.title,
386
- description: this.description,
387
- language: this.language,
388
- category: this.category,
389
- summaryCn: this.summaryCn,
390
- summaryEn: this.summaryEn,
391
- usageGuideCn: this.usageGuideCn,
392
- usageGuideEn: this.usageGuideEn,
393
- kind: this.kind,
394
- knowledgeType: this.knowledgeType,
395
- complexity: this.complexity,
396
- scope: this.scope,
397
- content: this.content,
398
- relations: this.relations,
399
- constraints: this.constraints,
400
- dimensions: this.dimensions,
401
- tags: this.tags,
402
- status: this.status,
403
- quality: this.quality,
404
- statistics: this.statistics,
405
- createdBy: this.createdBy,
406
- createdAt: this.createdAt,
407
- updatedAt: this.updatedAt,
408
- publishedAt: this.publishedAt,
409
- publishedBy: this.publishedBy,
410
- deprecation: this.deprecation,
411
- sourceCandidate: this.sourceCandidate,
412
- sourceFile: this.sourceFile,
413
- };
414
- }
415
-
416
- static fromJSON(data) {
417
- return new Recipe(data);
418
- }
419
- }
420
-
421
- export default Recipe;
@@ -1,54 +0,0 @@
1
- /**
2
- * RecipeRepository - Recipe 统一知识实体仓储接口
3
- *
4
- * Recipe 是唯一的知识实体,通过 knowledgeType 区分 12 种知识维度。
5
- * 实现层负责映射 content_json / relations_json / constraints_json 等 JSON 列。
6
- */
7
- export class RecipeRepository {
8
- /** 创建 Recipe */
9
- async create(recipe) { throw new Error('Not implemented'); }
10
-
11
- /** 根据 ID 获取 */
12
- async findById(id) { throw new Error('Not implemented'); }
13
-
14
- /** 获取所有 Recipes(支持过滤) */
15
- async findAll(filters = {}) { throw new Error('Not implemented'); }
16
-
17
- /** 按状态查询 */
18
- async findByStatus(status) { throw new Error('Not implemented'); }
19
-
20
- /** 按语言查询 */
21
- async findByLanguage(language) { throw new Error('Not implemented'); }
22
-
23
- /** 按分类查询 */
24
- async findByCategory(category) { throw new Error('Not implemented'); }
25
-
26
- /** 按知识类型查询 */
27
- async findByKnowledgeType(knowledgeType) { throw new Error('Not implemented'); }
28
-
29
- /** 按 scope 查询 (universal | project | target-specific) */
30
- async findByScope(scope) { throw new Error('Not implemented'); }
31
-
32
- /** 搜索 Recipes(关键词匹配 title / content / constraints) */
33
- async search(keyword) { throw new Error('Not implemented'); }
34
-
35
- /** 更新 Recipe */
36
- async update(id, updates) { throw new Error('Not implemented'); }
37
-
38
- /** 删除 Recipe */
39
- async delete(id) { throw new Error('Not implemented'); }
40
-
41
- /** 查询与指定 Recipe 有关系的所有 Recipes */
42
- async findRelated(recipeId) { throw new Error('Not implemented'); }
43
-
44
- /** 查询包含 Guard 约束的 Recipes(用于 Guard 引擎) */
45
- async findWithGuards(language) { throw new Error('Not implemented'); }
46
-
47
- /** 获取推荐 Recipes */
48
- async getRecommendations(limit = 10) { throw new Error('Not implemented'); }
49
-
50
- /** 获取统计信息 */
51
- async getStats() { throw new Error('Not implemented'); }
52
- }
53
-
54
- export default RecipeRepository;
@@ -1,52 +0,0 @@
1
- /**
2
- * CandidateStatus - Candidate 状态枚举
3
- */
4
- export const CandidateStatus = {
5
- // 待处理:刚创建的 Candidate
6
- PENDING: 'pending',
7
- // 已批准:经过审批的 Candidate
8
- APPROVED: 'approved',
9
- // 已拒绝:被拒绝的 Candidate
10
- REJECTED: 'rejected',
11
- // 已应用:已被应用到 Recipe 中
12
- APPLIED: 'applied',
13
- };
14
-
15
- export const CandidateStatusDescription = {
16
- pending: '待处理',
17
- approved: '已批准',
18
- rejected: '已拒绝',
19
- applied: '已应用',
20
- };
21
-
22
- /**
23
- * 检查是否为有效的状态
24
- */
25
- export function isValidCandidateStatus(status) {
26
- return Object.values(CandidateStatus).includes(status);
27
- }
28
-
29
- /**
30
- * 检查状态转移是否合法
31
- * @param {string} fromStatus 当前状态
32
- * @param {string} toStatus 目标状态
33
- * @returns {boolean}
34
- */
35
- export function isValidStateTransition(fromStatus, toStatus) {
36
- const validTransitions = {
37
- [CandidateStatus.PENDING]: [
38
- CandidateStatus.APPROVED,
39
- CandidateStatus.REJECTED,
40
- ],
41
- [CandidateStatus.APPROVED]: [
42
- CandidateStatus.APPLIED,
43
- CandidateStatus.REJECTED,
44
- ],
45
- [CandidateStatus.REJECTED]: [],
46
- [CandidateStatus.APPLIED]: [],
47
- };
48
-
49
- return validTransitions[fromStatus]?.includes(toStatus) || false;
50
- }
51
-
52
- export default CandidateStatus;